Subject: bug#74461: closed (Re: bug#74461: [PATCH] Add go-work-ts-mode)

From: [email-masked] (GNU bug Tracking System)
Date: Wed, 12 Feb 2025 05:55:02 +0000

Your bug report

#74461: [PATCH] Add go-work-ts-mode

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
74461: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=74461
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#74461: [PATCH] Add go-work-ts-mode
From: Stefan Kangas <[email-masked]>
To: Randy Taylor <[email-masked]>
Cc: [email-masked], Eli Zaretskii <[email-masked]>, Gabriel Santos <[email-masked]>, Stefan Monnier <[email-masked]>
Date: Tue, 11 Feb 2025 21:54:11 -0800
List-Id: <debbugs-submit.debbugs.gnu.org>

Version: 31.1

Randy Taylor <[email-masked]> writes:

> On Wednesday, January 1st, 2025 at 21:24, Gabriel Santos
> <[email-masked]> wrote:
>>
>>
>> Updated the patch to follow the suggestions made by Randy:
>>
>> - Rename go-mod-ts-mode--in-directive-p
>> - Add latest grammar versions of go-mod and go-work
>> - Removed the mention of the now defunct go-work-ts-mode--syntax-table
>> - Added back the syntax table for the regular Go tree-sitter mode
>>
>> --
>> Gabriel Santos
>
> Thanks, looks good to me.
>
> Eli, please install if you have no further comments. Thanks in
> advance.

The patch LGTM also, so I installed it on master as commit aade1b707c6.
Please note the changes I did to the commit message for any future
contributions.  Thanks Gabriel, for the patch.

I'm consequently closing this bug report.

Subject: [PATCH] Add go-work-ts-mode
From: Gabriel Santos <[email-masked]>
To: [email-masked]
Date: Thu, 21 Nov 2024 07:49:35 -0300
List-Id: <debbugs-submit.debbugs.gnu.org>

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

>From 3f05a09083411b8a849bf4ce8e622081873503c1 Mon Sep 17 00:00:00 2001
From: Gabriel <[email-masked]>
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".
+
 
 ----------------------------------------------------------------------
 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