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
  0 siblings, 1 reply; 3+ 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] 3+ 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>
  0 siblings, 1 reply; 3+ 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] 3+ 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; 3+ 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] 3+ messages in thread

end of thread, other threads:[~2024-11-21 19:14 UTC | newest]

Thread overview: 3+ 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

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