unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* 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
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ 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] 20+ 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
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 20+ 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] 20+ 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; 20+ 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] 20+ 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
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 20+ 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] 20+ 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
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 20+ 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] 20+ 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
  2024-11-30 10:17   ` Eli Zaretskii
  2024-12-18 22:57 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22  2:33 ` bug#74461: [PACH] " Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  5 siblings, 1 reply; 20+ 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] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-11-30 10:17   ` Eli Zaretskii
  2024-11-30 11:24     ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2024-11-30 10:17 UTC (permalink / raw)
  To: Gabriel Santos; +Cc: dev, 74461

> From: Gabriel Santos <gabrielsantosdesouza@disroot.org>
> Cc: 74461@debbugs.gnu.org, eliz@gnu.org
> Date: Fri, 22 Nov 2024 07:15:26 -0300
> 
> 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.

The patch LGTM, but if you have a later version, please post that.

The only comment I have is that for the commit log message:

> * 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.

These should mention the file name only once, and they all should
mention the names of functions/variables where the changes were made.
For new functions, just list them and say "New functions."

Also, the lines in the log message are too long: they should
preferably be at most 64 columns, and never more than 70.

How is your copyright assignment paperwork going?  I don't think I saw
any responses from the FSF copyright clerk; if more than 2 weeks have
passed since you emailed the assignment form, please ping them and CC
me.

Thanks.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-11-30 10:17   ` Eli Zaretskii
@ 2024-11-30 11:24     ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-01 20:42       ` Randy Taylor
  2024-12-22  3:10       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-11-30 11:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: dev, 74461

[-- Attachment #1: Type: text/plain, Size: 1485 bytes --]

> The only comment I have is that for the commit log message:
>
>> * 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.
>
> These should mention the file name only once, and they all should
> mention the names of functions/variables where the changes were made.
> For new functions, just list them and say "New functions."
>
> Also, the lines in the log message are too long: they should
> preferably be at most 64 columns, and never more than 70.

Thanks, got it, I broke down some of the lines,
longest one is at 54 columns.
Both vc and Magit have functions for adding logs to commits,
really useful:

- log-edit-generate-changelog-from-diff
- magit-commit-add-log

> How is your copyright assignment paperwork going?  I don't think I saw
> any responses from the FSF copyright clerk; if more than 2 weeks have
> passed since you emailed the assignment form, please ping them and CC
> me.

It has been a week since my first e-mail,
and five days since the second one.
I'll add a agenda entry for this to ping and CC you at 2024-12-09
(2 weeks and 2 days since the first e-mail).

> Thanks.

My pleasure, wouldn't be able to contribute to this great software
without all of the previous work of you and other maintainers and
contributors.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-go-work-ts-mode.patch --]
[-- Type: text/x-patch, Size: 11324 bytes --]

From 9e2cb7c416b6f1184c8f2b4a9dadbcbe77739dbc 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:
(languages):
* admin/notes/tree-sitter/build-module/build.sh:
(grammardir):
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.el:
Commentary:
Add the repositories for the grammars to
the commentary section.
(go-work-ts-mode--syntax-table):
(go-work-ts-mode--indent-rules):
(go-work-ts-mode--keywords):
(go-work-ts-mode--font-lock-settings):
New variables.
(go-work-ts-mode--in-directive-p):
(go-work-ts-mode):
New functions.
(go-mod-ts-mode--in-directive-p):
Be more specific on the directive location (modules).
* test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go:
* 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 and font-locking for Go
module and workspace files.
* test/lisp/progmodes/go-ts-mode-tests.el:
Add tests for 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,6 +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] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-11-30 11:24     ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-01 20:42       ` Randy Taylor
  2024-12-01 23:00         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22  3:10       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 20+ messages in thread
From: Randy Taylor @ 2024-12-01 20:42 UTC (permalink / raw)
  To: Gabriel Santos; +Cc: Eli Zaretskii, 74461

On Saturday, November 30th, 2024 at 06:24, Gabriel Santos <gabrielsantosdesouza@disroot.org> wrote:
> > The only comment I have is that for the commit log message:
> 
> > > * 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.
> > 
> > These should mention the file name only once, and they all should
> > mention the names of functions/variables where the changes were made.
> > For new functions, just list them and say "New functions."
> > 
> > Also, the lines in the log message are too long: they should
> > preferably be at most 64 columns, and never more than 70.
> 
> 
> Thanks, got it, I broke down some of the lines,
> longest one is at 54 columns.
> Both vc and Magit have functions for adding logs to commits,
> really useful:
> 
> - log-edit-generate-changelog-from-diff
> - magit-commit-add-log
> 
> > How is your copyright assignment paperwork going? I don't think I saw
> > any responses from the FSF copyright clerk; if more than 2 weeks have
> > passed since you emailed the assignment form, please ping them and CC
> > me.
> 
> 
> It has been a week since my first e-mail,
> and five days since the second one.
> I'll add a agenda entry for this to ping and CC you at 2024-12-09
> (2 weeks and 2 days since the first e-mail).
> 
> > Thanks.
> 
> 
> My pleasure, wouldn't be able to contribute to this great software
> without all of the previous work of you and other maintainers and
> contributors.

Thanks for working on this! The patch looks good to me.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-01 20:42       ` Randy Taylor
@ 2024-12-01 23:00         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-01 23:00 UTC (permalink / raw)
  To: Randy Taylor; +Cc: Eli Zaretskii, 74461

[-- Attachment #1: Type: text/plain, Size: 158 bytes --]

> Thanks for working on this! The patch looks good to me.

And it will be able to be merged soon! I just got my FSF paper today,
will be signing it tomorrow.

^ permalink raw reply	[flat|nested] 20+ 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
                   ` (3 preceding siblings ...)
  2024-11-22 10:15 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-18 22:57 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22  2:33 ` bug#74461: [PACH] " Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  5 siblings, 0 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-18 22:57 UTC (permalink / raw)
  To: 74461; +Cc: Eli Zaretskii, Stefan Monnier

I got an e-mail back from the copyright clerk yesterday.

(This e-mail is from that same day, 2024/12/17. There was an error with
my mail client.)

My copyright is now signed!

I'll check first if there are any major changes related to tree-sitter
that I should update the patch too.

Regards,

--
Gabriel Santos





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PACH] 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
                   ` (4 preceding siblings ...)
  2024-12-18 22:57 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22  2:33 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22  7:04   ` Eli Zaretskii
  5 siblings, 1 reply; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22  2:33 UTC (permalink / raw)
  To: 74461; +Cc: Eli Zaretskii, Stefan Monnier

Greetings,

As of 2024-12-01, my copyright to the FSF has been signed.
I checked if any recent changes would require modifying
this patch and didn't found any,
so unless there's additional comments from Stefan this can be merged.

Sorry for my delay on this,
I had issues with multiple mail clients not delivering mail.

Hopefully this messages actually reaches
the mailing list.
--
Gabriel Santos





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-11-30 11:24     ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-01 20:42       ` Randy Taylor
@ 2024-12-22  3:10       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 11:32         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 20+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22  3:10 UTC (permalink / raw)
  To: Gabriel Santos; +Cc: dev, Eli Zaretskii, 74461

> --- 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()"))

Do we have a way to tell Eglot which LSP server(s) to use via some
buffer-local var, instead of having to change this centralized
"database"?

> @@ -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.

I'd use 3 or more semi-colons here, so it acts as a section separator.

> +(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'.")

The "4" above is weird since there's no "3".  Similarly, the use of "b"
is a bit odd since the "normal" comment is unused.

> +(defun go-work-ts-mode--in-directive-p ()
> +  "Return non-nil if point is inside a Go workspace directive.

This docstring doesn't seem right: the function returns another
function, not a boolean.

> +        (pcase (treesit-node-type (treesit-node-at (point)))
> +          ("replace" t)
> +          ("use" t))))))

AKA (member (treesit-node-type (treesit-node-at (point))) '("replace" "use"))

> +;;;###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

Why not use the standard name for the syntax-table (in which case you
don't even need this `:syntax-table` argument)?

> +    ;; Indent.
> +    (setq-local indent-tabs-mode t
> +                treesit-simple-indent-rules go-work-ts-mode--indent-rules)

Is this `indent-tabs-mode` setting required by the definition of the
go.work syntax/language, or is it a personal preference?  If it's
a personal preference then it doesn't belong in the major mode, and if
it's required by the syntax, then say so in a comment (ideally with
a URL pointing to the relevant part of the language definition).

> +(if (treesit-ready-p 'gowork)
> +    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))

Since we don't have another (non-treesitter) mode for these files, I'd
recommend you go straight for:

    ;;;###autoload
    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode))


- Stefan






^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PACH] Add go-work-ts-mode
  2024-12-22  2:33 ` bug#74461: [PACH] " Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22  7:04   ` Eli Zaretskii
  0 siblings, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2024-12-22  7:04 UTC (permalink / raw)
  To: Gabriel Santos; +Cc: monnier, 74461

> Date: Sat, 21 Dec 2024 23:33:39 -0300
> From: Gabriel Santos <gabrielsantosdesouza@disroot.org>
> CC: Eli Zaretskii <eliz@gnu.org>, Stefan Monnier <monnier@iro.umontreal.ca>
> 
> Greetings,
> 
> As of 2024-12-01, my copyright to the FSF has been signed.
> I checked if any recent changes would require modifying
> this patch and didn't found any,
> so unless there's additional comments from Stefan this can be merged.
> 
> Sorry for my delay on this,
> I had issues with multiple mail clients not delivering mail.
> 
> Hopefully this messages actually reaches
> the mailing list.

Please rebase the patch on the current master branch and post the
result, with the commit log message.  Then we can install this.

Thanks.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22  3:10       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22 11:32         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 12:12           ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22 11:32 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: dev, Eli Zaretskii, 74461

>> --- 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()"))
>
>Do we have a way to tell Eglot which LSP server(s) to use via some
>buffer-local var, instead of having to change this centralized
>"database"?

Looking at the following commits:

- 5f56bc1 <https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=5f56bc1cdfcd474dd9cfad07240df6c252abd35c>
- e37754f <https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=e37754fc59bac409881d456a83aa0bf2468c94fb>

That doesn't seem to be the case.

>> @@ -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.
>
>I'd use 3 or more semi-colons here, so it acts as a section separator.

I think 4 would be better in this case.
That would make these comments sub-sections
Of ";;; Code:"

>> +(defun go-work-ts-mode--in-directive-p ()
>> +  "Return non-nil if point is inside a Go workspace directive.
>
>This docstring doesn't seem right: the function returns another
>function, not a boolean.

Huh, that is true (it returns a lambda function).
Thankfully Randy is CC'ed here, so maybe
he can comment on that.

>> +        (pcase (treesit-node-type (treesit-node-at (point)))
>> +          ("replace" t)
>> +          ("use" t))))))
>
>AKA (member (treesit-node-type (treesit-node-at (point))) '("replace" "use"))

Thanks, It works. I'll also update the workspace function.

>> +;;;###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
>
>Why not use the standard name for the syntax-table (in which case you
>don't even need this `:syntax-table` argument)?

That's how it's done in the workspace
configuration,
but I removed it for work now
and testing by using treesit-explore
on the grammar's corpus shows nothing
out of the elements there.

Thanks again.

>> +    ;; Indent.
>> +    (setq-local indent-tabs-mode t
>> +                treesit-simple-indent-rules go-work-ts-mode--indent-rules)
>
>Is this `indent-tabs-mode` setting required by the definition of the
>go.work syntax/language, or is it a personal preference?  If it's
>a personal preference then it doesn't belong in the major mode, and if
>it's required by the syntax, then say so in a comment (ideally with
>a URL pointing to the relevant part of the language definition).

Go uses tabs for indentation,
and spaces for alignment.

This is valid even for workspace files,
as adding more than one package modifies
the use directive to multiple lines
indented with tabs.

<https://0x0.st/8r82.png>
(tabs added by running go work use, not by me)

<https://go.dev/doc/effective_go#formatting>

<https://pkg.go.dev/cmd/gofmt>

The language specification doesn't mention
that, but I think it should.
Maybe I should send them an e-mail about that.

<https://go.dev/ref/spec>


>> +(if (treesit-ready-p 'gowork)
>> +    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)))
>
>Since we don't have another (non-treesitter) mode for these files, I'd
>recommend you go straight for:
>
>    ;;;###autoload
>    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode))


Sorry if I misunderstand,
but that doesn't seem to be the case
for other tree-sitter modes.

See rust-ts-mode for instance:

<https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/rust-ts-mode.el?id=59367f6a3a9dd7fb30429494b622ebdec94e6e32>

The non-treesitter mode for this language is an external package.

And Elixir too:

<https://git.savannah.gnu.org/cgit/emacs.git/tree/lisp/progmodes/elixir-ts-mode.el?id=59367f6a3a9dd7fb30429494b622ebdec94e6e32>

Seems like we need further conversation on this topic.

I'll make the changes you requested and send the updated patch after I'm done.

--
Gabriel Santos





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22 11:32         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22 12:12           ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-25 20:17             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22 12:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: dev, Eli Zaretskii, 74461

>I'll make the changes you requested and send the updated patch after I'm done.

I just finished updating the patch,
but I think it's best to only send it after
the point about *--in-directive-p is clarified.
--
Gabriel Santos





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22 11:32         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 12:12           ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 16:05             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-23  3:31             ` Dmitry Gutov
  1 sibling, 2 replies; 20+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22 15:33 UTC (permalink / raw)
  To: Gabriel Santos; +Cc: dev, Eli Zaretskii, 74461

>>Do we have a way to tell Eglot which LSP server(s) to use via some
>>buffer-local var, instead of having to change this centralized
>>"database"?
>
> Looking at the following commits:
>
> - 5f56bc1
> <https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=5f56bc1cdfcd474dd9cfad07240df6c252abd35c>
> - e37754f
> <https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=e37754fc59bac409881d456a83aa0bf2468c94fb>
>
> That doesn't seem to be the case.

It was a kind of rethorical question: whether we do or not, we *should*
have such a mechanism and we should use it here.

> Go uses tabs for indentation,
> and spaces for alignment.
[...]
> The language specification doesn't mention
> that, but I think it should.
> Maybe I should send them an e-mail about that.

I don't think the language cares (or should care).  It's only a convention.
But if it's the only convention in use in Go, that's fine: just add
a link to https://go.dev/doc/effective_go#formatting that justifies
the setting.

>>Since we don't have another (non-treesitter) mode for these files, I'd
>>recommend you go straight for:
>>
>>    ;;;###autoload
>>    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode))
>
>
> Sorry if I misunderstand,
> but that doesn't seem to be the case
> for other tree-sitter modes.

Past practice does not always reflect best practices, especially when
talking about relatively new practices.


        Stefan






^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-22 16:05             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-23  3:31             ` Dmitry Gutov
  1 sibling, 0 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-22 16:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: dev, Eli Zaretskii, 74461

>It was a kind of rethorical question: whether we do or not, we *should*
>have such a mechanism and we should use it here.

Oh definitely, another point for discussion.

>> Go uses tabs for indentation,
>> and spaces for alignment.
>[...]
>> The language specification doesn't mention
>> that, but I think it should.
>> Maybe I should send them an e-mail about that.
>
>I don't think the language cares (or should care).  It's only a convention.
>
>But if it's the only convention in use in Go, that's fine: just add
>a link to https://go.dev/doc/effective_go#formatting that justifies
>the setting.

I added it to the commentary section:

+;; Go uses tabs as a convention for indentation:
+;; https://go.dev/doc/effective_go#formatting
+;; so indent-tabs-mode is enabled for the modes.

>>>Since we don't have another (non-treesitter) mode for these files, I'd
>>>recommend you go straight for:
>>>
>>>    ;;;###autoload
>>>    (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode))
>>
>>
>> Sorry if I misunderstand,
>> but that doesn't seem to be the case
>> for other tree-sitter modes.
>
>Past practice does not always reflect best practices, especially when
>talking about relatively new practices.

I'll change that, but after this is accepted
I'll make this change to the other modes,
CCing emacs-devel and the respective maintainers.


--
Gabriel Santos





^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-22 16:05             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-23  3:31             ` Dmitry Gutov
  1 sibling, 0 replies; 20+ messages in thread
From: Dmitry Gutov @ 2024-12-23  3:31 UTC (permalink / raw)
  To: Stefan Monnier, Gabriel Santos; +Cc: dev, Eli Zaretskii, 74461

On 22/12/2024 17:33, Stefan Monnier via Bug reports for GNU Emacs, the 
Swiss army knife of text editors wrote:
>>> Do we have a way to tell Eglot which LSP server(s) to use via some
>>> buffer-local var, instead of having to change this centralized
>>> "database"?
>> Looking at the following commits:
>>
>> - 5f56bc1
>> <https://git.savannah.gnu.org/cgit/emacs.git/commit/? 
>> id=5f56bc1cdfcd474dd9cfad07240df6c252abd35c>
>> - e37754f
>> <https://git.savannah.gnu.org/cgit/emacs.git/commit/? 
>> id=e37754fc59bac409881d456a83aa0bf2468c94fb>
>>
>> That doesn't seem to be the case.
> It was a kind of rethorical question: whether we do or not, we*should*
> have such a mechanism and we should use it here.

Just to remind, Eglot is in GNU ELPA, whereas go-work-ts-mode is not 
(same for other ts modes). Preferred language servers tend to change 
over time.






^ permalink raw reply	[flat|nested] 20+ messages in thread

* bug#74461: [PATCH] Add go-work-ts-mode
  2024-12-22 12:12           ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-25 20:17             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 20+ messages in thread
From: Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-25 20:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: dev, Eli Zaretskii, 74461

[-- Attachment #1: Type: text/plain, Size: 440 bytes --]

Actually, since it's not that big of an issue, I'll send in the patch now.

Em 22 de dezembro de 2024 09:12:21 BRT, Gabriel Santos <gabrielsantosdesouza@disroot.org> escreveu:
>>I'll make the changes you requested and send the updated patch after I'm done.
>
>I just finished updating the patch,
>but I think it's best to only send it after
>the point about *--in-directive-p is clarified.
>--
>Gabriel Santos

--
Gabriel Santos

[-- Attachment #2: 0001-Add-go-work-ts-mode.diff --]
[-- Type: text/plain, Size: 12378 bytes --]

From d8c77b044caea7f67f7556bf837f2df3825d2d7d 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:
(languages):
* admin/notes/tree-sitter/build-module/build.sh:
(grammardir):
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.el:
Commentary:
Add the repositories for the grammars to
the commentary section.
(go-work-ts-mode--syntax-table):
(go-work-ts-mode--indent-rules):
(go-work-ts-mode--keywords):
(go-work-ts-mode--font-lock-settings):
New variables.
(go-work-ts-mode--in-directive-p):
(go-work-ts-mode):
New functions.
(go-mod-ts-mode--in-directive-p):
Be more specific on the directive location (modules).
Use member instead of pcase to check node types.
* test/lisp/progmodes/go-ts-mode-resources/font-lock-package.go:
* 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 and font-locking for Go
module and workspace files.
* test/lisp/progmodes/go-ts-mode-tests.el:
Add tests for 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                  | 112 ++++++++++++++++--
 .../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, 176 insertions(+), 10 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 8adead78a32..c2d225d51e7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1142,6 +1142,12 @@ means of the GDI+ library.
 In addition to ':file FILE' for playing a sound from a file, ':data
 DATA' can now be used to play a sound from memory.
 
+---
+** 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 816a1e67eca..5623139e35c 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 f3adeb9b2f3..f0959dbbbae 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -24,6 +24,12 @@
 
 ;;; 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
+;; Go uses tabs as a convention for indentation:
+;; https://go.dev/doc/effective_go#formatting
+;; so indent-tabs-mode is enabled for the modes.
 
 ;;; Code:
 
@@ -251,7 +257,6 @@
 
 \\{go-ts-mode-map}"
   :group 'go
-  :syntax-table go-ts-mode--syntax-table
 
   (when (treesit-ready-p 'go)
     (setq treesit-primary-parser (treesit-parser-create 'go))
@@ -453,7 +458,7 @@ be run."
                    (go-ts-mode--get-build-tags-flag)
                    default-directory)))
 
-;; go.mod support.
+;;;; go.mod support.
 
 (defvar go-mod-ts-mode--syntax-table
   (let ((table (make-syntax-table)))
@@ -475,7 +480,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
@@ -485,12 +490,12 @@ what the parent of the node would be if it were a node."
       (save-excursion
         (backward-up-list)
         (back-to-indentation)
-        (pcase (treesit-node-type (treesit-node-at (point)))
-          ("exclude" t)
-          ("module" t)
-          ("replace" t)
-          ("require" t)
-          ("retract" t))))))
+        (member (treesit-node-type (treesit-node-at (point)))
+                '("exclude"
+                  "module"
+                  "replace"
+                  "require"
+                  "retract"))))))
 
 (defvar go-mod-ts-mode--keywords
   '("exclude" "go" "module" "replace" "require" "retract")
@@ -557,6 +562,95 @@ 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--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)
+        (member (treesit-node-type (treesit-node-at (point)))
+                '("replace"
+                  "use"))))))
+
+(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)))
+
+;;;###autoload
+(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,6 +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] 20+ messages in thread

end of thread, other threads:[~2024-12-25 20:17 UTC | newest]

Thread overview: 20+ 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
2024-11-30 10:17   ` Eli Zaretskii
2024-11-30 11:24     ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-01 20:42       ` Randy Taylor
2024-12-01 23:00         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22  3:10       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22 11:32         ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22 12:12           ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-25 20:17             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22 15:33           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22 16:05             ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-23  3:31             ` Dmitry Gutov
2024-12-18 22:57 ` Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22  2:33 ` bug#74461: [PACH] " Gabriel Santos via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-22  7:04   ` Eli Zaretskii

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).