all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Gabriel Santos via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: dev@rjt.dev, Eli Zaretskii <eliz@gnu.org>, 74461@debbugs.gnu.org
Subject: bug#74461: [PATCH] Add go-work-ts-mode
Date: Wed, 25 Dec 2024 17:17:25 -0300	[thread overview]
Message-ID: <0F06447F-3926-4F70-86F0-5F512598A362@disroot.org> (raw)
In-Reply-To: <69C7AB3A-F058-4EBC-922E-3C24D1F4A9CB@disroot.org>

[-- 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


  reply	other threads:[~2024-12-25 20:17 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0F06447F-3926-4F70-86F0-5F512598A362@disroot.org \
    --to=bug-gnu-emacs@gnu.org \
    --cc=74461@debbugs.gnu.org \
    --cc=dev@rjt.dev \
    --cc=eliz@gnu.org \
    --cc=gabrielsantosdesouza@disroot.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.