* bug#74461: [PATCH] Add go-work-ts-mode
@ 2024-11-21 10:49 Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 16:02 ` Eli Zaretskii
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-21 10:49 UTC (permalink / raw)
To: 74461
[-- Attachment #1: Type: text/plain, Size: 1108 bytes --]
Greetings,
I wrote a tree-sitter mode after founding there wasn't one for Go
Workspace files. I'd like to say thanks to Randy Taylor on his work to
the Go tree-sitter mode, helped me a lot in this process.
Commit message:
* admin/notes/tree-sitter/build-module/batch.sh:
* admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
* etc/NEWS: Mention go-work-ts-mode.
* lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
* lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
workspace files.
The parser can be found here:
https://github.com/omertuc/tree-sitter-go-work
And I tested changes locally with a package:
https://github.com/gs-101/go-work-ts-mode
Issues that could be found:
- Some syntax highlighting might be unecessary (ERROR face)
- The grammar might be outdated (I found no issues when testing)
- Eglot addition might be unecessary
- Grammar elements could be missing (I checked both grammar.js and
- grammar.json, and only found the keywords added here)
I will mail my copyright assignment to the FSF still today.
Regards,
-- Gabriel Santos
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Add go-work-ts-mode --]
[-- Type: text/x-patch, Size: 6485 bytes --]
From 3f05a09083411b8a849bf4ce8e622081873503c1 Mon Sep 17 00:00:00 2001
From: Gabriel <gabrielsantosdesouza@disroot.org>
Date: Wed, 20 Nov 2024 23:07:28 -0300
Subject: [PATCH] Add go-work-ts-mode
* admin/notes/tree-sitter/build-module/batch.sh:
* admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
* etc/NEWS: Mention go-work-ts-mode.
* lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
* lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
workspace files.
---
admin/notes/tree-sitter/build-module/batch.sh | 1 +
admin/notes/tree-sitter/build-module/build.sh | 5 +
etc/NEWS | 5 +
lisp/progmodes/eglot.el | 2 +-
lisp/progmodes/go-ts-mode.el | 96 +++++++++++++++++++
5 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/admin/notes/tree-sitter/build-module/batch.sh b/admin/notes/tree-sitter/build-module/batch.sh
index 012b5882e83..1b5214267f5 100755
--- a/admin/notes/tree-sitter/build-module/batch.sh
+++ b/admin/notes/tree-sitter/build-module/batch.sh
@@ -11,6 +11,7 @@ languages=(
'elixir'
'go'
'go-mod'
+ 'go-work'
'heex'
'html'
'java'
diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh
index 9a567bb094d..263de388b00 100755
--- a/admin/notes/tree-sitter/build-module/build.sh
+++ b/admin/notes/tree-sitter/build-module/build.sh
@@ -39,6 +39,11 @@ case "${lang}" in
lang="gomod"
org="camdencheek"
;;
+ "go-work")
+ # The parser is called "gowork".
+ lang="gomod"
+ org="omertuc"
+ ;;
"heex")
org="phoenixframework"
;;
diff --git a/etc/NEWS b/etc/NEWS
index b6c21018779..e7f753fcda1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -925,6 +925,11 @@ current buffer, if the major mode supports it. (Support for
Transformed images are smoothed using the bilinear interpolation by
means of the GDI+ library.
+---
+** New major mode 'go-work-ts-mode'.
+A major mode based on the tree-sitter library for editing "go.work"
+files. It is auto-enabled for files which are named "go.work".
+
\f
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index e5c27de81fc..4dbb0906b9e 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -273,7 +273,7 @@ automatically)."
(elm-mode . ("elm-language-server"))
(mint-mode . ("mint" "ls"))
((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server"))
- ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode)
+ ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode go-work-ts-mode)
. ("gopls"))
((R-mode ess-r-mode) . ("R" "--slave" "-e"
"languageserver::run()"))
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 86e74ad58a8..605fa324e7a 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -565,6 +565,102 @@ what the parent of the node would be if it were a node."
(if (treesit-ready-p 'gomod)
(add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode)))
+;; go.work support.
+
+(defvar go-work-ts-mode--syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?/ ". 124b" table)
+ (modify-syntax-entry ?\n "> b" table)
+ table)
+ "Syntax table for `go-work-ts-mode'.")
+
+(defvar go-work-ts-mode--indent-rules
+ `((gowork
+ ((node-is ")") parent-bol 0)
+ ((parent-is "replace_directive") parent-bol go-ts-mode-indent-offset)
+ ((parent-is "use_directive") parent-bol go-ts-mode-indent-offset)
+ ((go-work-ts-mode--in-directive-p) no-indent go-ts-mode-indent-offset)
+ (no-node no-indent 0)))
+ "Tree-sitter indent rules for `go-work-ts-mode'.")
+
+(defun go-work-ts-mode--in-directive-p ()
+ "Return non-nil if point is inside a directive.
+When entering an empty directive or adding a new entry to one, no node
+will be present meaning none of the indentation rules will match,
+because there is no parent to match against. This function determines
+what the parent of the node would be if it were a node."
+ (lambda (node _ _ &rest _)
+ (unless (treesit-node-type node)
+ (save-excursion
+ (backward-up-list)
+ (back-to-indentation)
+ (pcase (treesit-node-type (treesit-node-at (point)))
+ ("replace" t)
+ ("use" t))))))
+
+(defvar go-work-ts-mode--keywords
+ '("go" "replace" "use")
+ "go.work keywords for tree-sitter font-locking.")
+
+(defvar go-work-ts-mode--font-lock-settings
+ (treesit-font-lock-rules
+ :language 'gowork
+ :feature 'bracket
+ '((["(" ")"]) @font-lock-bracket-face)
+
+ :language 'gowork
+ :feature 'comment
+ '((comment) @font-lock-comment-face)
+
+ :language 'gowork
+ :feature 'keyword
+ `([,@go-work-ts-mode--keywords] @font-lock-keyword-face)
+
+ :language 'gowork
+ :feature 'number
+ '([(go_version) (version)] @font-lock-number-face)
+
+ :language 'gowork
+ :feature 'operator
+ '((["=>"]) @font-lock-warning-face)
+
+ :language 'gowork
+ :feature 'error
+ :override t
+ '((ERROR) @font-lock-warning-face))
+ "Tree-sitter font-lock settings for `go-work-ts-mode'.")
+
+;;;###autoload
+(define-derived-mode go-work-ts-mode prog-mode "Go Work"
+ "Major mode for editing go.work files, powered by tree-sitter."
+ :group 'go
+ :syntax-table go-work-ts-mode--syntax-table
+
+ (when (treesit-ready-p 'gowork)
+ (setq treesit-primary-parser (treesit-parser-create 'gowork))
+
+ ;; Comments.
+ (setq-local comment-start "// ")
+ (setq-local comment-end "")
+ (setq-local comment-start-skip (rx "//" (* (syntax whitespace))))
+
+ ;; Indent.
+ (setq-local indent-tabs-mode t
+ treesit-simple-indent-rules go-work-ts-mode--indent-rules)
+
+ ;; Font-lock.
+ (setq-local treesit-font-lock-settings go-work-ts-mode--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list
+ '((comment)
+ (keyword)
+ (number)
+ (bracket error operator)))
+
+ (treesit-major-mode-setup)))
+
+(if (treesit-ready-p 'gowork)
+ (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
+
(provide 'go-ts-mode)
;;; go-ts-mode.el ends here
--
2.47.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* bug#74461: [PATCH] Add go-work-ts-mode
2024-11-21 10:49 bug#74461: [PATCH] Add go-work-ts-mode Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-21 16:02 ` Eli Zaretskii
[not found] ` <F23F09F1-D3C4-4133-AC46-67E7E1C35BDA@disroot.org>
2024-11-22 0:13 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2024-11-21 16:02 UTC (permalink / raw)
To: Gabriel Santos, Stefan Monnier; +Cc: 74461
> Date: Thu, 21 Nov 2024 07:49:35 -0300
> From: Gabriel Santos via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>
> I wrote a tree-sitter mode after founding there wasn't one for Go
> Workspace files. I'd like to say thanks to Randy Taylor on his work to
> the Go tree-sitter mode, helped me a lot in this process.
>
> Commit message:
>
> * admin/notes/tree-sitter/build-module/batch.sh:
> * admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
> * etc/NEWS: Mention go-work-ts-mode.
> * lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
> * lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
> workspace files.
>
> The parser can be found here:
> https://github.com/omertuc/tree-sitter-go-work
I think the parser URL should be mentioned in the comments in
go-ts-mode.el.
> I will mail my copyright assignment to the FSF still today.
Thanks.
> +---
> +** New major mode 'go-work-ts-mode'.
> +A major mode based on the tree-sitter library for editing "go.work"
> +files. It is auto-enabled for files which are named "go.work".
The last sentence is factually inaccurate: the user needs to load
go-ts-mode to have this mode auto-enabled, right?
> +(defun go-work-ts-mode--in-directive-p ()
> + "Return non-nil if point is inside a directive.
"inside a go-work directive", I presume? IOW, the doc string's first
sentence sounds too general.
> +(if (treesit-ready-p 'gowork)
> + (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
Wouldn't it be better to have this in the default value of
auto-mode-alist, just conditioned by (treesit-ready-p 'gowork) ? That
way, loading go-ts-mode will not change auto-mode-alist.
Stefan, WDYT?
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74461: [PATCH] Add go-work-ts-mode
[not found] ` <F23F09F1-D3C4-4133-AC46-67E7E1C35BDA@disroot.org>
@ 2024-11-21 19:14 ` Eli Zaretskii
0 siblings, 0 replies; 6+ messages in thread
From: Eli Zaretskii @ 2024-11-21 19:14 UTC (permalink / raw)
To: Gabriel Santos; +Cc: 74461
[Please use Reply All to reply, to keep the bug tracker CC'ed.]
> Date: Thu, 21 Nov 2024 14:25:14 -0300
> From: Gabriel Santos <gabrielsantosdesouza@disroot.org>
>
> >> Date: Thu, 21 Nov 2024 07:49:35 -0300
> >> From: Gabriel Santos via "Bug reports for GNU Emacs,
> >> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> >>
> >> I wrote a tree-sitter mode after founding there wasn't one for Go
> >> Workspace files. I'd like to say thanks to Randy Taylor on his work to
> >> the Go tree-sitter mode, helped me a lot in this process.
> >>
> >> Commit message:
> >>
> >> * admin/notes/tree-sitter/build-module/batch.sh:
> >> * admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
> >> * etc/NEWS: Mention go-work-ts-mode.
> >> * lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
> >> * lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
> >> workspace files.
> >>
> >> The parser can be found here:
> >> https://github.com/omertuc/tree-sitter-go-work
> >
> >I think the parser URL should be mentioned in the comments in
> >go-ts-mode.el.
>
> Thanks, got it. I'll also add the links to the other parsers too. This is helpful information for users, as some of
> these aren't included in the tree-sitter organization (https://github.com/tree-sitter).
>
> >> I will mail my copyright assignment to the FSF still today.
> >
> >Thanks.
>
> On this, I missed the address of my house by a single number (astonishing how often I do this). To update
> the data in my request, can I just send another e-mail?
Yes, sure.
> >> +---
> >> +** New major mode 'go-work-ts-mode'.
> >> +A major mode based on the tree-sitter library for editing "go.work"
> >> +files. It is auto-enabled for files which are named "go.work".
> >
> >The last sentence is factually inaccurate: the user needs to load
> >go-ts-mode to have this mode auto-enabled, right?
>
> I got it from the original commit for the Go tree-sitter mode (fee2efe1b03 by Randy Taylor). I was working
> quite late at night on this, so I didn't have time to reflect. You're right, this mode won't be auto-loaded since
> tree-sitter modes currently require some user set-up to get working.
>
> >> +(defun go-work-ts-mode--in-directive-p ()
> >> + "Return non-nil if point is inside a directive.
> >
> >"inside a go-work directive", I presume? IOW, the doc string's first
> >sentence sounds too general.
>
> Again, I took this from the original commit. I'm currently viewing the new version of the
> `go-mod-ts-mode--in-directive-p' and the docstring is better written. I'll rewrite based on it, and also make
> sure to check the current state of files instead.
>
> >> +(if (treesit-ready-p 'gowork)
> >> + (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
> >
> >Wouldn't it be better to have this in the default value of
> >auto-mode-alist, just conditioned by (treesit-ready-p 'gowork) ? That
> >way, loading go-ts-mode will not change auto-mode-alist.
> >
> >Stefan, WDYT?
>
> This change was also included in the file already, so I followed it. Looking at the current values of
> auto-mode-alist (lisp/files.el), I don't see any tree-sitter modes here. And other tree-sitter modes (see
> list/progmodes/rust-ts-mode) also include the same behaviour. I don't have much knowledge on this matter,
> so I'll let you decide on this.
Tree-sitter modes are not listed where we have other modes for the
same files, to avoid breaking past behavior. I don't think this
danger is relevant to go.work files, but let's see what Stefan thinks
about that.
> Also, this is my first time on an e-mail workflow like this. Updating the patch based on your requests would
> only require a rebase + new e-mail, or a rebase + reply to this thread?
The latter. Using the same thread keeps all the discussions recorded
as part of the same issue number, which is good for future reviewing
of the discussion. For the same reason, please don't edit the Subject
of the responses, so that they all keep the same Subject.
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74461: [PATCH] Add go-work-ts-mode
2024-11-21 10:49 bug#74461: [PATCH] Add go-work-ts-mode Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 16:02 ` Eli Zaretskii
@ 2024-11-22 0:13 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-22 2:36 ` Randy Taylor
2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
3 siblings, 0 replies; 6+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-22 0:13 UTC (permalink / raw)
To: eliz; +Cc: 74461
[-- Attachment #1: Type: text/plain, Size: 1451 bytes --]
>[Please use Reply All to reply, to keep the bug tracker CC'ed.]
Thanks, got it. I didn't reply to all because the last e-mail was sent
from my phone. This one is from Emacs, and I added the following to the
header (before the e-mail body):
To: eliz@gnu.org
Cc: 74461@debbugs.gnu.org
Subject: Re: bug#74461: [PATCH] Add go-work-ts-mode
Let me know if I made any other mistakes in this e-mail.
>> Also, this is my first time on an e-mail workflow like this. Updating the patch based on your requests would
>> only require a rebase + new e-mail, or a rebase + reply to this thread?
>
>The latter. Using the same thread keeps all the discussions recorded
>as part of the same issue number, which is good for future reviewing
>of the discussion. For the same reason, please don't edit the Subject
>of the responses, so that they all keep the same Subject.
>
>Thanks.
>
Thanks, I used the current subject for this e-mail now.
Also, attached is the rebased commit featuring the changes you
requested. I also went ahead and clarified the documentation for
`go-mod-ts-mode--in-directive-p', to make it less generalized.
Through this contribution, I think I'll get more comfortable with the
e-mail workflow, and end up contributing more here. My next one would be
mentioning the parser URLs in the other tree-sitter modes. treesit-auto
(https://github.com/renzmann/treesit-auto) has a collection of them, so
this shouldn't be particularly difficult.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Add go-work-ts-mode --]
[-- Type: text/x-patch, Size: 7460 bytes --]
From 41571fc2d5515f0ede893eba0cc1ce316ef575a2 Mon Sep 17 00:00:00 2001
From: Gabriel <gabrielsantosdesouza@disroot.org>
Date: Wed, 20 Nov 2024 23:07:28 -0300
Subject: [PATCH] Add go-work-ts-mode
* admin/notes/tree-sitter/build-module/batch.sh:
* admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
* etc/NEWS: Mention go-work-ts-mode.
* lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
* lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
workspace files.
* lisp/progmodes/go-ts-mode: Add the repositories for the grammars to
the commentary section.
* lisp/progmodes/go-ts-mode (go-mod-ts-mode--in-directive-p): Be more
specific on the directive location.
---
admin/notes/tree-sitter/build-module/batch.sh | 1 +
admin/notes/tree-sitter/build-module/build.sh | 5 +
etc/NEWS | 6 ++
lisp/progmodes/eglot.el | 2 +-
lisp/progmodes/go-ts-mode.el | 101 +++++++++++++++++-
5 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/admin/notes/tree-sitter/build-module/batch.sh b/admin/notes/tree-sitter/build-module/batch.sh
index 012b5882e83..1b5214267f5 100755
--- a/admin/notes/tree-sitter/build-module/batch.sh
+++ b/admin/notes/tree-sitter/build-module/batch.sh
@@ -11,6 +11,7 @@ languages=(
'elixir'
'go'
'go-mod'
+ 'go-work'
'heex'
'html'
'java'
diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh
index 9a567bb094d..263de388b00 100755
--- a/admin/notes/tree-sitter/build-module/build.sh
+++ b/admin/notes/tree-sitter/build-module/build.sh
@@ -39,6 +39,11 @@ case "${lang}" in
lang="gomod"
org="camdencheek"
;;
+ "go-work")
+ # The parser is called "gowork".
+ lang="gomod"
+ org="omertuc"
+ ;;
"heex")
org="phoenixframework"
;;
diff --git a/etc/NEWS b/etc/NEWS
index b6c21018779..a07d9300fe9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -925,6 +925,12 @@ current buffer, if the major mode supports it. (Support for
Transformed images are smoothed using the bilinear interpolation by
means of the GDI+ library.
+---
+** New major mode 'go-work-ts-mode'.
+A major mode based on the tree-sitter library for editing "go.work"
+files. If tree-sitter is properly set-up by the user, it can be
+enabled for files named "go.work".
+
\f
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index e5c27de81fc..4dbb0906b9e 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -273,7 +273,7 @@ automatically)."
(elm-mode . ("elm-language-server"))
(mint-mode . ("mint" "ls"))
((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server"))
- ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode)
+ ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode go-work-ts-mode)
. ("gopls"))
((R-mode ess-r-mode) . ("R" "--slave" "-e"
"languageserver::run()"))
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 86e74ad58a8..288b543ae5c 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -24,6 +24,9 @@
;;; Commentary:
;;
+;; - Go grammar: https://github.com/tree-sitter/tree-sitter-go
+;; - Go module grammar: https://github.com/camdencheek/tree-sitter-go-mod
+;; - Go workspace grammar: https://github.com/omertuc/tree-sitter-go-work
;;; Code:
@@ -483,7 +486,7 @@ be run."
"Tree-sitter indent rules for `go-mod-ts-mode'.")
(defun go-mod-ts-mode--in-directive-p ()
- "Return non-nil if point is inside a directive.
+ "Return non-nil if point is inside a Go module directive.
When entering an empty directive or adding a new entry to one, no node
will be present meaning none of the indentation rules will match,
because there is no parent to match against. This function determines
@@ -565,6 +568,102 @@ what the parent of the node would be if it were a node."
(if (treesit-ready-p 'gomod)
(add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode)))
+;; go.work support.
+
+(defvar go-work-ts-mode--syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?/ ". 124b" table)
+ (modify-syntax-entry ?\n "> b" table)
+ table)
+ "Syntax table for `go-work-ts-mode'.")
+
+(defvar go-work-ts-mode--indent-rules
+ `((gowork
+ ((node-is ")") parent-bol 0)
+ ((parent-is "replace_directive") parent-bol go-ts-mode-indent-offset)
+ ((parent-is "use_directive") parent-bol go-ts-mode-indent-offset)
+ ((go-work-ts-mode--in-directive-p) no-indent go-ts-mode-indent-offset)
+ (no-node no-indent 0)))
+ "Tree-sitter indent rules for `go-work-ts-mode'.")
+
+(defun go-work-ts-mode--in-directive-p ()
+ "Return non-nil if point is inside a Go workspace directive.
+When entering an empty directive or adding a new entry to one, no node
+will be present meaning none of the indentation rules will match,
+because there is no parent to match against. This function determines
+what the parent of the node would be if it were a node."
+ (lambda (node _ _ &rest _)
+ (unless (treesit-node-type node)
+ (save-excursion
+ (backward-up-list)
+ (back-to-indentation)
+ (pcase (treesit-node-type (treesit-node-at (point)))
+ ("replace" t)
+ ("use" t))))))
+
+(defvar go-work-ts-mode--keywords
+ '("go" "replace" "use")
+ "go.work keywords for tree-sitter font-locking.")
+
+(defvar go-work-ts-mode--font-lock-settings
+ (treesit-font-lock-rules
+ :language 'gowork
+ :feature 'bracket
+ '((["(" ")"]) @font-lock-bracket-face)
+
+ :language 'gowork
+ :feature 'comment
+ '((comment) @font-lock-comment-face)
+
+ :language 'gowork
+ :feature 'keyword
+ `([,@go-work-ts-mode--keywords] @font-lock-keyword-face)
+
+ :language 'gowork
+ :feature 'number
+ '([(go_version) (version)] @font-lock-number-face)
+
+ :language 'gowork
+ :feature 'operator
+ '((["=>"]) @font-lock-warning-face)
+
+ :language 'gowork
+ :feature 'error
+ :override t
+ '((ERROR) @font-lock-warning-face))
+ "Tree-sitter font-lock settings for `go-work-ts-mode'.")
+
+;;;###autoload
+(define-derived-mode go-work-ts-mode prog-mode "Go Work"
+ "Major mode for editing go.work files, powered by tree-sitter."
+ :group 'go
+ :syntax-table go-work-ts-mode--syntax-table
+
+ (when (treesit-ready-p 'gowork)
+ (setq treesit-primary-parser (treesit-parser-create 'gowork))
+
+ ;; Comments.
+ (setq-local comment-start "// ")
+ (setq-local comment-end "")
+ (setq-local comment-start-skip (rx "//" (* (syntax whitespace))))
+
+ ;; Indent.
+ (setq-local indent-tabs-mode t
+ treesit-simple-indent-rules go-work-ts-mode--indent-rules)
+
+ ;; Font-lock.
+ (setq-local treesit-font-lock-settings go-work-ts-mode--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list
+ '((comment)
+ (keyword)
+ (number)
+ (bracket error operator)))
+
+ (treesit-major-mode-setup)))
+
+(if (treesit-ready-p 'gowork)
+ (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
+
(provide 'go-ts-mode)
;;; go-ts-mode.el ends here
--
2.47.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* bug#74461: [PATCH] Add go-work-ts-mode
2024-11-21 10:49 bug#74461: [PATCH] Add go-work-ts-mode Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 16:02 ` Eli Zaretskii
2024-11-22 0:13 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-22 2:36 ` Randy Taylor
2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
3 siblings, 0 replies; 6+ messages in thread
From: Randy Taylor @ 2024-11-22 2:36 UTC (permalink / raw)
To: Gabriel Santos; +Cc: Eli Zaretskii, 74461
On Thursday, November 21st, 2024 at 05:49, Gabriel Santos via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org> wrote:
>
> Greetings,
>
> I wrote a tree-sitter mode after founding there wasn't one for Go
> Workspace files. I'd like to say thanks to Randy Taylor on his work to
> the Go tree-sitter mode, helped me a lot in this process.
Thanks for working on this.
>
> Commit message:
>
> * admin/notes/tree-sitter/build-module/batch.sh:
> * admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
> * etc/NEWS: Mention go-work-ts-mode.
> * lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
> * lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
> workspace files.
>
> The parser can be found here:
> https://github.com/omertuc/tree-sitter-go-work
>
> And I tested changes locally with a package:
> https://github.com/gs-101/go-work-ts-mode
>
> Issues that could be found:
>
> - Some syntax highlighting might be unecessary (ERROR face)
Users can disable this if they desire.
> - The grammar might be outdated (I found no issues when testing)
> - Eglot addition might be unecessary
I think it's fine.
> - Grammar elements could be missing (I checked both grammar.js and
> - grammar.json, and only found the keywords added here)
>
> I will mail my copyright assignment to the FSF still today.
>
> Regards,
>
> -- Gabriel Santos
+ "go-work")
+ # The parser is called "gowork".
+ lang="gomod"
Copy paste error ("gowork" instead)?
It would be nice to have syntax highlighting and indentation tests for
this (ideally covering everything). If you're interested, take a look
at go-ts-mode-tests.el and the files it references for inspiration.
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#74461: [PATCH] Add go-work-ts-mode
2024-11-21 10:49 bug#74461: [PATCH] Add go-work-ts-mode Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
` (2 preceding siblings ...)
2024-11-22 2:36 ` Randy Taylor
@ 2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
3 siblings, 0 replies; 6+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-22 10:15 UTC (permalink / raw)
To: dev; +Cc: eliz, 74461
[-- Attachment #1: Type: text/plain, Size: 907 bytes --]
I fixed the mistake you pointed out in build.sh
> It would be nice to have syntax highlighting and indentation tests for
> this (ideally covering everything). If you're interested, take a look
> at go-ts-mode-tests.el and the files it references for inspiration.
I wrote some simple tests for both go-mod-ts-mode and go-work-ts-mode.
For syntax highlighting, I had them both use the same file
(font-lock-package.go), since they have some compatible elements, and
for indentation, I made a simple test for indenting multiple lines.
I also changed the face for operators (on go-work-ts-mode), as I
incorrectly used font-lock-warning-face.
Also, please let me know your opinion on how I layed out the grammars in
the commentary section. I think I'll go through the other tree-sitter
modes and add the grammar to their commentary section too, so it's nice
to get some feedback before making these changes.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Add go-work-ts-mode --]
[-- Type: text/x-patch, Size: 11214 bytes --]
From eb704432594e0ce5114184fe87152122c2b69595 Mon Sep 17 00:00:00 2001
From: Gabriel <gabrielsantosdesouza@disroot.org>
Date: Wed, 20 Nov 2024 23:07:28 -0300
Subject: [PATCH] Add go-work-ts-mode
* admin/notes/tree-sitter/build-module/batch.sh:
* admin/notes/tree-sitter/build-module/build.sh: Add go-work support.
* etc/NEWS: Mention go-work-ts-mode.
* lisp/progmodes/eglot.el (eglot-server-programs): Add go-work-ts-mode.
* lisp/progmodes/go-ts-mode: Add go-work-ts-mode for working with
workspace files.
* lisp/progmodes/go-ts-mode: Add the repositories for the grammars to
the commentary section.
* lisp/progmodes/go-ts-mode (go-mod-ts-mode--in-directive-p): Be more
specific on the directive location.
* test/lisp/progmodes/go-ts-mode-tests: Add tests for Go module and
workspace files.
* test/lisp/progmodes/go-ts-mode-resources/font-lock-package: New file
for both go-mod-ts-mode and go-work-ts-mode font-locking tests.
* test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts:
* test/lisp/progmodes/go-ts-mode-resources/indent-work.erts: New files
for testing indentation in Go module and workspace files.
---
admin/notes/tree-sitter/build-module/batch.sh | 1 +
admin/notes/tree-sitter/build-module/build.sh | 5 +
etc/NEWS | 6 ++
lisp/progmodes/eglot.el | 2 +-
lisp/progmodes/go-ts-mode.el | 101 +++++++++++++++++-
.../go-ts-mode-resources/font-lock-package.go | 4 +
.../go-ts-mode-resources/indent-mod.erts | 16 +++
.../go-ts-mode-resources/indent-work.erts | 16 +++
test/lisp/progmodes/go-ts-mode-tests.el | 24 +++++
9 files changed, 173 insertions(+), 2 deletions(-)
create mode 100644 test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go
create mode 100644 test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts
create mode 100644 test/lisp/progmodes/go-ts-mode-resources/indent-work.erts
diff --git a/admin/notes/tree-sitter/build-module/batch.sh b/admin/notes/tree-sitter/build-module/batch.sh
index 012b5882e83..1b5214267f5 100755
--- a/admin/notes/tree-sitter/build-module/batch.sh
+++ b/admin/notes/tree-sitter/build-module/batch.sh
@@ -11,6 +11,7 @@ languages=(
'elixir'
'go'
'go-mod'
+ 'go-work'
'heex'
'html'
'java'
diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh
index 9a567bb094d..4f3c6da3c5f 100755
--- a/admin/notes/tree-sitter/build-module/build.sh
+++ b/admin/notes/tree-sitter/build-module/build.sh
@@ -39,6 +39,11 @@ case "${lang}" in
lang="gomod"
org="camdencheek"
;;
+ "go-work")
+ # The parser is called "gowork".
+ lang="gowork"
+ org="omertuc"
+ ;;
"heex")
org="phoenixframework"
;;
diff --git a/etc/NEWS b/etc/NEWS
index b6c21018779..a07d9300fe9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -925,6 +925,12 @@ current buffer, if the major mode supports it. (Support for
Transformed images are smoothed using the bilinear interpolation by
means of the GDI+ library.
+---
+** New major mode 'go-work-ts-mode'.
+A major mode based on the tree-sitter library for editing "go.work"
+files. If tree-sitter is properly set-up by the user, it can be
+enabled for files named "go.work".
+
\f
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index e5c27de81fc..4dbb0906b9e 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -273,7 +273,7 @@ automatically)."
(elm-mode . ("elm-language-server"))
(mint-mode . ("mint" "ls"))
((kotlin-mode kotlin-ts-mode) . ("kotlin-language-server"))
- ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode)
+ ((go-mode go-dot-mod-mode go-dot-work-mode go-ts-mode go-mod-ts-mode go-work-ts-mode)
. ("gopls"))
((R-mode ess-r-mode) . ("R" "--slave" "-e"
"languageserver::run()"))
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 86e74ad58a8..8ab54a71f1b 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -24,6 +24,9 @@
;;; Commentary:
;;
+;; - Go grammar: https://github.com/tree-sitter/tree-sitter-go
+;; - Go module grammar: https://github.com/camdencheek/tree-sitter-go-mod
+;; - Go workspace grammar: https://github.com/omertuc/tree-sitter-go-work
;;; Code:
@@ -483,7 +486,7 @@ be run."
"Tree-sitter indent rules for `go-mod-ts-mode'.")
(defun go-mod-ts-mode--in-directive-p ()
- "Return non-nil if point is inside a directive.
+ "Return non-nil if point is inside a Go module directive.
When entering an empty directive or adding a new entry to one, no node
will be present meaning none of the indentation rules will match,
because there is no parent to match against. This function determines
@@ -565,6 +568,102 @@ what the parent of the node would be if it were a node."
(if (treesit-ready-p 'gomod)
(add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode)))
+;; go.work support.
+
+(defvar go-work-ts-mode--syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?/ ". 124b" table)
+ (modify-syntax-entry ?\n "> b" table)
+ table)
+ "Syntax table for `go-work-ts-mode'.")
+
+(defvar go-work-ts-mode--indent-rules
+ `((gowork
+ ((node-is ")") parent-bol 0)
+ ((parent-is "replace_directive") parent-bol go-ts-mode-indent-offset)
+ ((parent-is "use_directive") parent-bol go-ts-mode-indent-offset)
+ ((go-work-ts-mode--in-directive-p) no-indent go-ts-mode-indent-offset)
+ (no-node no-indent 0)))
+ "Tree-sitter indent rules for `go-work-ts-mode'.")
+
+(defun go-work-ts-mode--in-directive-p ()
+ "Return non-nil if point is inside a Go workspace directive.
+When entering an empty directive or adding a new entry to one, no node
+will be present meaning none of the indentation rules will match,
+because there is no parent to match against. This function determines
+what the parent of the node would be if it were a node."
+ (lambda (node _ _ &rest _)
+ (unless (treesit-node-type node)
+ (save-excursion
+ (backward-up-list)
+ (back-to-indentation)
+ (pcase (treesit-node-type (treesit-node-at (point)))
+ ("replace" t)
+ ("use" t))))))
+
+(defvar go-work-ts-mode--keywords
+ '("go" "replace" "use")
+ "go.work keywords for tree-sitter font-locking.")
+
+(defvar go-work-ts-mode--font-lock-settings
+ (treesit-font-lock-rules
+ :language 'gowork
+ :feature 'bracket
+ '((["(" ")"]) @font-lock-bracket-face)
+
+ :language 'gowork
+ :feature 'comment
+ '((comment) @font-lock-comment-face)
+
+ :language 'gowork
+ :feature 'keyword
+ `([,@go-work-ts-mode--keywords] @font-lock-keyword-face)
+
+ :language 'gowork
+ :feature 'number
+ '([(go_version) (version)] @font-lock-number-face)
+
+ :language 'gowork
+ :feature 'operator
+ '((["=>"]) @font-lock-operator-face)
+
+ :language 'gowork
+ :feature 'error
+ :override t
+ '((ERROR) @font-lock-warning-face))
+ "Tree-sitter font-lock settings for `go-work-ts-mode'.")
+
+;;;###autoload
+(define-derived-mode go-work-ts-mode prog-mode "Go Work"
+ "Major mode for editing go.work files, powered by tree-sitter."
+ :group 'go
+ :syntax-table go-work-ts-mode--syntax-table
+
+ (when (treesit-ready-p 'gowork)
+ (setq treesit-primary-parser (treesit-parser-create 'gowork))
+
+ ;; Comments.
+ (setq-local comment-start "// ")
+ (setq-local comment-end "")
+ (setq-local comment-start-skip (rx "//" (* (syntax whitespace))))
+
+ ;; Indent.
+ (setq-local indent-tabs-mode t
+ treesit-simple-indent-rules go-work-ts-mode--indent-rules)
+
+ ;; Font-lock.
+ (setq-local treesit-font-lock-settings go-work-ts-mode--font-lock-settings)
+ (setq-local treesit-font-lock-feature-list
+ '((comment)
+ (keyword)
+ (number)
+ (bracket error operator)))
+
+ (treesit-major-mode-setup)))
+
+(if (treesit-ready-p 'gowork)
+ (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
+
(provide 'go-ts-mode)
;;; go-ts-mode.el ends here
diff --git a/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go b/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go
new file mode 100644
index 00000000000..7bee6848810
--- /dev/null
+++ b/test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go
@@ -0,0 +1,4 @@
+replace gnu.org/go/package1 v1.0.0 => gnu.org/go/package2 v1.0.0
+// ^ font-lock-keyword-face
+// ^ font-lock-number-face
+// ^ font-lock-operator-face
diff --git a/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts b/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts
new file mode 100644
index 00000000000..2f7bfd9030b
--- /dev/null
+++ b/test/lisp/progmodes/go-ts-mode-resources/indent-mod.erts
@@ -0,0 +1,16 @@
+Code:
+ (lambda ()
+ (go-mod-ts-mode)
+ (indent-region (point-min) (point-max)))
+
+Point-Char: |
+
+Name: Basic
+
+=-=
+require (
+ gnu.org/go/package1 v1.0.0
+ gnu.org/go/package2 v1.0.0
+)
+
+=-=-=
diff --git a/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts b/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts
new file mode 100644
index 00000000000..b210974cedc
--- /dev/null
+++ b/test/lisp/progmodes/go-ts-mode-resources/indent-work.erts
@@ -0,0 +1,16 @@
+Code:
+ (lambda ()
+ (go-work-ts-mode)
+ (indent-region (point-min) (point-max)))
+
+Point-Char: |
+
+Name: Basic
+
+=-=
+use (
+ ./package1
+ ./package2
+)
+
+=-=-=
diff --git a/test/lisp/progmodes/go-ts-mode-tests.el b/test/lisp/progmodes/go-ts-mode-tests.el
index f36dbde5103..154c424064c 100644
--- a/test/lisp/progmodes/go-ts-mode-tests.el
+++ b/test/lisp/progmodes/go-ts-mode-tests.el
@@ -23,6 +23,8 @@
(require 'ert-x)
(require 'treesit)
+;; go-ts-mode
+
(ert-deftest go-ts-mode-test-indentation ()
(skip-unless (treesit-ready-p 'go))
(ert-test-erts-file (ert-resource-file "indent.erts")))
@@ -32,5 +34,27 @@
(let ((treesit-font-lock-level 4))
(ert-font-lock-test-file (ert-resource-file "font-lock.go") 'go-ts-mode)))
+;; go-mod-ts-mode
+
+(ert-deftest go-work-ts-mode-test-indentation ()
+ (skip-unless (treesit-ready-p 'gomod))
+ (ert-test-erts-file (ert-resource-file "indent-mod.erts")))
+
+(ert-deftest go-mod-ts-test-font-lock ()
+ (skip-unless (treesit-ready-p 'gomod))
+ (let ((treesit-font-lock-level 4))
+ (ert-font-lock-test-file (ert-resource-file "font-lock-package.go") 'go-mod-ts-mode)))
+
+;; go-work-ts-mode
+
+(ert-deftest go-work-ts-mode-test-indentation ()
+ (skip-unless (treesit-ready-p 'gowork))
+ (ert-test-erts-file (ert-resource-file "indent-work.erts")))
+
+(ert-deftest go-work-ts-test-font-lock ()
+ (skip-unless (treesit-ready-p 'gowork))
+ (let ((treesit-font-lock-level 4))
+ (ert-font-lock-test-file (ert-resource-file "font-lock-package.go") 'go-work-ts-mode)))
+
(provide 'go-ts-mode-tests)
;;; go-ts-mode-tests.el ends here
--
2.47.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-11-22 10:15 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-21 10:49 bug#74461: [PATCH] Add go-work-ts-mode Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-21 16:02 ` Eli Zaretskii
[not found] ` <F23F09F1-D3C4-4133-AC46-67E7E1C35BDA@disroot.org>
2024-11-21 19:14 ` Eli Zaretskii
2024-11-22 0:13 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-11-22 2:36 ` Randy Taylor
2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).