emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 fbb4eb919b 5/5: Support treesit-defun-name in tree-sitter major


From: Yuan Fu
Subject: emacs-29 fbb4eb919b 5/5: Support treesit-defun-name in tree-sitter major modes
Date: Sat, 24 Dec 2022 21:43:13 -0500 (EST)

branch: emacs-29
commit fbb4eb919b4c91dd8517a06934bf1f897eaa34bb
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Support treesit-defun-name in tree-sitter major modes
    
    * lisp/progmodes/csharp-mode.el (csharp-ts-mode--defun-name): New
    function.
    (csharp-ts-mode--imenu-1): Extract into new function.
    (csharp-ts-mode): Setup treesit-defun-name-function.
    * lisp/progmodes/java-ts-mode.el (java-ts-mode--defun-name): New
    function.
    (java-ts-mode--imenu-1): Extract into new function.
    (java-ts-mode): Setup treesit-defun-name-function.
    * lisp/progmodes/js.el (js-treesit-current-defun): Remove function.
    This function is not used (for a while already).
    (js--treesit-defun-name): New function.
    (js--treesit-imenu-1): Extract into new function.
    (js-ts-mode): Setup treesit-defun-name-function.
    * lisp/progmodes/json-ts-mode.el (json-ts-mode--defun-name): New
    function.
    (json-ts-mode--imenu-1): Extract into new function.
    (json-ts-mode): Setup treesit-defun-name-function.
    * lisp/progmodes/python.el (python--treesit-defun-name): New function.
    (python--imenu-treesit-create-index-1): Extract into new function.
    (python-ts-mode): Setup treesit-defun-name-function.
    * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--defun-name): New
    function.
    (rust-ts-mode--imenu-1): Extract into new function.
    (rust-ts-mode): Setup treesit-defun-name-function.
    * lisp/textmodes/css-mode.el (css--treesit-defun-name): New function.
    (css--treesit-imenu-1): Extract into new function.
    (css-ts-mode): Setup treesit-defun-name-function.
    * lisp/textmodes/toml-ts-mode.el (toml-ts-mode--get-table-name):
    Remove function.
    (toml-ts-mode--defun-name): New function.
    (toml-ts-mode--imenu-1): Extract into new function.
    (toml-ts-mode): Setup treesit-defun-name-function.
---
 lisp/progmodes/csharp-mode.el  | 22 ++++++++++++++---
 lisp/progmodes/java-ts-mode.el | 22 ++++++++++++++---
 lisp/progmodes/js.el           | 42 ++++++++++++--------------------
 lisp/progmodes/json-ts-mode.el | 17 ++++++++++---
 lisp/progmodes/python.el       | 17 ++++++++++---
 lisp/progmodes/rust-ts-mode.el | 55 +++++++++++++++++++++++-------------------
 lisp/textmodes/css-mode.el     | 25 ++++++++++++-------
 lisp/textmodes/toml-ts-mode.el | 16 ++++++------
 8 files changed, 133 insertions(+), 83 deletions(-)

diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el
index 2d13ae6930..985e2e7b0b 100644
--- a/lisp/progmodes/csharp-mode.el
+++ b/lisp/progmodes/csharp-mode.el
@@ -837,6 +837,22 @@ compilation and evaluation time conflicts."
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode))
 
+(defun csharp-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ((or "method_declaration"
+         "record_declaration"
+         "struct_declaration"
+         "enum_declaration"
+         "interface_declaration"
+         "class_declaration"
+         "class_declaration")
+     (treesit-node-text
+      (treesit-node-child-by-field-name
+       node "name")
+      t))))
+
 (defun csharp-ts-mode--imenu-1 (node)
   "Helper for `csharp-ts-mode--imenu'.
 Find string representation for NODE and set marker, then recurse
@@ -844,10 +860,7 @@ the subtrees."
   (let* ((ts-node (car node))
          (subtrees (mapcan #'csharp-ts-mode--imenu-1 (cdr node)))
          (name (when ts-node
-                 (or (treesit-node-text
-                      (or (treesit-node-child-by-field-name
-                           ts-node "name"))
-                      t)
+                 (or (treesit-defun-name ts-node)
                      "Unnamed node")))
          (marker (when ts-node
                    (set-marker (make-marker)
@@ -935,6 +948,7 @@ Key bindings:
 
   ;; Navigation.
   (setq-local treesit-defun-type-regexp "declaration")
+  (setq-local treesit-defun-name-function #'csharp-ts-mode--defun-name)
 
   ;; Font-lock.
   (setq-local treesit-font-lock-settings csharp-ts-mode--font-lock-settings)
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index 9da2c254f8..3e0439ddf5 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -248,6 +248,22 @@
    '((["," ":" ";"]) @font-lock-delimiter-face))
   "Tree-sitter font-lock settings for `java-ts-mode'.")
 
+(defun java-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ((or "method_declaration"
+         "class_declaration"
+         "record_declaration"
+         "interface_declaration"
+         "enum_declaration"
+         "import_declaration"
+         "package_declaration"
+         "module_declaration")
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name")
+      t))))
+
 (defun java-ts-mode--imenu-1 (node)
   "Helper for `java-ts-mode--imenu'.
 Find string representation for NODE and set marker, then recurse
@@ -255,10 +271,7 @@ the subtrees."
   (let* ((ts-node (car node))
          (subtrees (mapcan #'java-ts-mode--imenu-1 (cdr node)))
          (name (when ts-node
-                 (or (treesit-node-text
-                      (or (treesit-node-child-by-field-name
-                           ts-node "name"))
-                      t)
+                 (or (treesit-defun-name ts-node)
                      "Unnamed node")))
          (marker (when ts-node
                    (set-marker (make-marker)
@@ -334,6 +347,7 @@ the subtrees."
                             "import_declaration"
                             "package_declaration"
                             "module_declaration")))
+  (setq-local treesit-defun-name-function #'java-ts-mode--defun-name)
 
   ;; Font-lock.
   (setq-local treesit-font-lock-settings java-ts-mode--font-lock-settings)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 1b34c0de41..14feed221f 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3656,24 +3656,18 @@ OVERRIDE is the override flag described in
       (setq font-beg (treesit-node-end child)
             child (treesit-node-next-sibling child)))))
 
-(defun js-treesit-current-defun ()
-  "Return name of surrounding function.
-This function can be used as a value in `which-func-functions'"
-  (let ((node (treesit-node-at (point)))
-        (name-list ()))
-    (cl-loop while node
-             if (pcase (treesit-node-type node)
-                  ("function_declaration" t)
-                  ("method_definition" t)
-                  ("class_declaration" t)
-                  ("variable_declarator" t)
-                  (_ nil))
-             do (push (treesit-node-text
-                       (treesit-node-child-by-field-name node "name")
-                       t)
-                      name-list)
-             do (setq node (treesit-node-parent node))
-             finally return  (string-join name-list "."))))
+(defun js--treesit-defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (treesit-node-text
+   (treesit-node-child-by-field-name
+    (pcase (treesit-node-type node)
+      ("lexical_declaration"
+       (treesit-search-subtree node "variable_declarator" nil nil 1))
+      ((or "function_declaration" "method_definition" "class_declaration")
+       node))
+    "name")
+   t))
 
 (defun js--treesit-imenu-1 (node)
   "Given a sparse tree, create an imenu alist.
@@ -3702,15 +3696,8 @@ definition*\"."
                  ("function_declaration" 'function)))
          ;; The root of the tree could have a nil ts-node.
          (name (when ts-node
-                 (let ((ts-node-1
-                        (if (eq type 'variable)
-                            (treesit-search-subtree
-                             ts-node "variable_declarator" nil nil 1)
-                          ts-node)))
-                   (treesit-node-text
-                    (treesit-node-child-by-field-name
-                     ts-node-1 "name")
-                    t))))
+                 (or (treesit-defun-name ts-node)
+                     "Anonymous")))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -3885,6 +3872,7 @@ Currently there are `js-mode' and `js-ts-mode'."
                         "method_definition"
                         "function_declaration"
                         "lexical_declaration")))
+    (setq-local treesit-defun-name-function #'js--treesit-defun-name)
     ;; Fontification.
     (setq-local treesit-font-lock-settings js--treesit-font-lock-settings)
     (setq-local treesit-font-lock-feature-list
diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el
index 6c2f380587..6725c5f227 100644
--- a/lisp/progmodes/json-ts-mode.el
+++ b/lisp/progmodes/json-ts-mode.el
@@ -107,6 +107,16 @@
    '((ERROR) @font-lock-warning-face))
   "Font-lock settings for JSON.")
 
+(defun json-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ((or "pair" "object")
+     (treesit-node-text
+      (treesit-node-child-by-field-name
+       node "key")
+      t))))
+
 (defun json-ts-mode--imenu-1 (node)
   "Helper for `json-ts-mode--imenu'.
 Find string representation for NODE and set marker, then recurse
@@ -114,10 +124,8 @@ the subtrees."
   (let* ((ts-node (car node))
          (subtrees (mapcan #'json-ts-mode--imenu-1 (cdr node)))
          (name (when ts-node
-                 (treesit-node-text
-                  (treesit-node-child-by-field-name
-                   ts-node "key")
-                  t)))
+                 (or (treesit-defun-name ts-node)
+                     "Anonymous")))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -161,6 +169,7 @@ the subtrees."
   ;; Navigation.
   (setq-local treesit-defun-type-regexp
               (rx (or "pair" "object")))
+  (setq-local treesit-defun-name-function #'json-ts-mode--defun-name)
 
   ;; Font-lock.
   (setq-local treesit-font-lock-settings json-ts-mode--font-lock-settings)
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index bdc9e6fa78..d383fa57c0 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5448,6 +5448,16 @@ To this:
 
 ;;; Tree-sitter imenu
 
+(defun python--treesit-defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ((or "function_definition" "class_definition")
+     (treesit-node-text
+      (treesit-node-child-by-field-name
+       node "name")
+      t))))
+
 (defun python--imenu-treesit-create-index-1 (node)
   "Given a sparse tree, create an imenu alist.
 
@@ -5473,9 +5483,8 @@ definition*\"."
                  ("class_definition" 'class)))
          ;; The root of the tree could have a nil ts-node.
          (name (when ts-node
-                 (treesit-node-text
-                  (treesit-node-child-by-field-name
-                   ts-node "name") t)))
+                 (or (treesit-defun-name ts-node)
+                     "Anonymous")))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -6643,6 +6652,8 @@ implementations: `python-mode' and `python-ts-mode'."
                 #'python-imenu-treesit-create-index)
     (setq-local treesit-defun-type-regexp (rx (or "function" "class")
                                               "_definition"))
+    (setq-local treesit-defun-name-function
+                #'python--treesit-defun-name)
     (treesit-major-mode-setup)
 
     (when python-indent-guess-indent-offset
diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el
index 8b2ed19101..81f5b8765f 100644
--- a/lisp/progmodes/rust-ts-mode.el
+++ b/lisp/progmodes/rust-ts-mode.el
@@ -273,6 +273,33 @@
      (when struct-index `(("Struct" . ,struct-index)))
      (when func-index `(("Fn" . ,func-index))))))
 
+(defun rust-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ("enum_item"
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name") t))
+    ("function_item"
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name") t))
+    ("impl_item"
+     (let ((trait-node (treesit-node-child-by-field-name node "trait")))
+       (concat
+        (treesit-node-text trait-node t)
+        (when trait-node " for ")
+        (treesit-node-text
+         (treesit-node-child-by-field-name node "type") t))))
+    ("mod_item"
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name") t))
+    ("struct_item"
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name") t))
+    ("type_item"
+     (treesit-node-text
+      (treesit-node-child-by-field-name node "name") t))))
+
 (defun rust-ts-mode--imenu-1 (node)
   "Helper for `rust-ts-mode--imenu'.
 Find string representation for NODE and set marker, then recurse
@@ -282,31 +309,8 @@ the subtrees."
          (subtrees (mapcan #'rust-ts-mode--imenu-1
                            children))
          (name (when ts-node
-                 (pcase (treesit-node-type ts-node)
-                   ("enum_item"
-                    (treesit-node-text
-                     (treesit-node-child-by-field-name ts-node "name") t))
-                   ("function_item"
-                    (treesit-node-text
-                     (treesit-node-child-by-field-name ts-node "name") t))
-                   ("impl_item"
-                    (let ((trait-node (treesit-node-child-by-field-name 
ts-node "trait")))
-                      (concat
-                       (treesit-node-text
-                        trait-node t)
-                       (when trait-node
-                         " for ")
-                       (treesit-node-text
-                        (treesit-node-child-by-field-name ts-node "type") t))))
-                   ("mod_item"
-                    (treesit-node-text
-                     (treesit-node-child-by-field-name ts-node "name") t))
-                   ("struct_item"
-                    (treesit-node-text
-                     (treesit-node-child-by-field-name ts-node "name") t))
-                   ("type_item"
-                    (treesit-node-text
-                     (treesit-node-child-by-field-name ts-node "name") t)))))
+                 (or (treesit-defun-name ts-node)
+                     "Anonymous")))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -363,6 +367,7 @@ the subtrees."
                               "function_item"
                               "impl_item"
                               "struct_item")))
+    (setq-local treesit-defun-name-function #'rust-ts-mode--defun-name)
 
     (treesit-major-mode-setup)))
 
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 822097a86d..99ef4f10a0 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -1412,6 +1412,19 @@ for determining whether point is within a selector."
    '((ERROR) @error))
   "Tree-sitter font-lock settings for `css-ts-mode'.")
 
+(defun css--treesit-defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ("rule_set" (treesit-node-text
+                 (treesit-node-child node 0) t))
+    ("media_statement"
+     (let ((block (treesit-node-child node -1)))
+       (string-trim
+        (buffer-substring-no-properties
+         (treesit-node-start node)
+         (treesit-node-start block)))))))
+
 (defun css--treesit-imenu-1 (node)
   "Helper for `css--treesit-imenu'.
 Find string representation for NODE and set marker, then recurse
@@ -1419,15 +1432,8 @@ the subtrees."
   (let* ((ts-node (car node))
          (subtrees (mapcan #'css--treesit-imenu-1 (cdr node)))
          (name (when ts-node
-                 (pcase (treesit-node-type ts-node)
-                   ("rule_set" (treesit-node-text
-                                (treesit-node-child ts-node 0) t))
-                   ("media_statement"
-                    (let ((block (treesit-node-child ts-node -1)))
-                      (string-trim
-                       (buffer-substring-no-properties
-                        (treesit-node-start ts-node)
-                        (treesit-node-start block))))))))
+                 (or (treesit-defun-name ts-node)
+                     "Anonymous")))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -1835,6 +1841,7 @@ can also be used to fill comments.
     (treesit-parser-create 'css)
     (setq-local treesit-simple-indent-rules css--treesit-indent-rules)
     (setq-local treesit-defun-type-regexp "rule_set")
+    (setq-local treesit-defun-name-function #'css--treesit-defun-name)
     (setq-local treesit-font-lock-settings css--treesit-settings)
     (setq-local treesit-font-lock-feature-list
                 '((selector comment query keyword)
diff --git a/lisp/textmodes/toml-ts-mode.el b/lisp/textmodes/toml-ts-mode.el
index bca6a5e81a..790de2133e 100644
--- a/lisp/textmodes/toml-ts-mode.el
+++ b/lisp/textmodes/toml-ts-mode.el
@@ -107,12 +107,12 @@
    '((ERROR) @font-lock-warning-face))
   "Font-lock settings for TOML.")
 
-(defun toml-ts-mode--get-table-name (node)
-  "Obtains the header-name for the associated tree-sitter `NODE'."
-  (if node
-      (treesit-node-text
-       (car (cdr (treesit-node-children node))))
-    "Root table"))
+(defun toml-ts-mode--defun-name (node)
+  "Return the defun name of NODE.
+Return nil if there is no name or if NODE is not a defun node."
+  (pcase (treesit-node-type node)
+    ((or "table" "table_array_element")
+     (car (cdr (treesit-node-children node))))))
 
 (defun toml-ts-mode--imenu-1 (node)
   "Helper for `toml-ts-mode--imenu'.
@@ -120,7 +120,8 @@ Find string representation for NODE and set marker, then 
recurse
 the subtrees."
   (let* ((ts-node (car node))
          (subtrees (mapcan #'toml-ts-mode--imenu-1 (cdr node)))
-         (name (toml-ts-mode--get-table-name ts-node))
+         (name (or (treesit-defun-name ts-node)
+                   "Root table"))
          (marker (when ts-node
                    (set-marker (make-marker)
                                (treesit-node-start ts-node)))))
@@ -167,6 +168,7 @@ the subtrees."
     ;; Navigation.
     (setq-local treesit-defun-type-regexp
                 (rx (or "table" "table_array_element")))
+    (setq-local treesit-defun-name-function #'toml-ts-mode--defun-name)
 
     ;; Font-lock.
     (setq-local treesit-font-lock-settings toml-ts-mode--font-lock-settings)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]