]> git.eshelyaron.com Git - emacs.git/commitdiff
Support treesit-defun-name in tree-sitter major modes
authorYuan Fu <casouri@gmail.com>
Sun, 25 Dec 2022 02:24:01 +0000 (18:24 -0800)
committerYuan Fu <casouri@gmail.com>
Sun, 25 Dec 2022 02:43:03 +0000 (18:43 -0800)
* 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
lisp/progmodes/java-ts-mode.el
lisp/progmodes/js.el
lisp/progmodes/json-ts-mode.el
lisp/progmodes/python.el
lisp/progmodes/rust-ts-mode.el
lisp/textmodes/css-mode.el
lisp/textmodes/toml-ts-mode.el

index 2d13ae6930c9778bad9afb6927ad678e464f5611..985e2e7b0bf8e46441d2f5403dbbaee6930bbef2 100644 (file)
@@ -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)
index 9da2c254f879213131eed7d6d2b22dd2dd5607b3..3e0439ddf548765ad4eb144578b76efe93c11080 100644 (file)
    '((["," ":" ";"]) @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)
index 1b34c0de418c4d6e7f3ea129b6df8e806b5e48a9..14feed221fb72a7d23195d0cafab1b6510072d26 100644 (file)
@@ -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
index 6c2f38058720e652a5c785b035e245663203bbd2..6725c5f22708cad2dd10870d7edeec0988843208 100644 (file)
    '((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)
index bdc9e6fa78cca4d9c97808d17faf04c506426a7d..d383fa57c04154ce5e5efd5f75bc843789957673 100644 (file)
@@ -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
index 8b2ed191019a6ed7324972c44017027eccb8691e..81f5b8765f18f2dfd9c64f5a217b550ff1a5213b 100644 (file)
      (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)))
 
index 822097a86d831e52c1f1e71429382a0ee814decf..99ef4f10a062cb0eaa39f8ccfb1d06acf80a1aca 100644 (file)
@@ -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)
index bca6a5e81ad1bee7d39a86cc21bf53b35aef22a4..790de2133e8357690d0b5d2bca633436cbbad4de 100644 (file)
    '((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)