summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2022-12-24 18:24:01 -0800
committerYuan Fu <casouri@gmail.com>2022-12-24 18:43:03 -0800
commitfbb4eb919b4c91dd8517a06934bf1f897eaa34bb (patch)
tree9b019410546f08047252fa8d02328ad3ee566f1b /lisp
parent6253184afc2e53c6782a41ec1b59779449152172 (diff)
downloademacs-fbb4eb919b4c91dd8517a06934bf1f897eaa34bb.tar.gz
emacs-fbb4eb919b4c91dd8517a06934bf1f897eaa34bb.tar.bz2
emacs-fbb4eb919b4c91dd8517a06934bf1f897eaa34bb.zip
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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/csharp-mode.el22
-rw-r--r--lisp/progmodes/java-ts-mode.el22
-rw-r--r--lisp/progmodes/js.el42
-rw-r--r--lisp/progmodes/json-ts-mode.el17
-rw-r--r--lisp/progmodes/python.el17
-rw-r--r--lisp/progmodes/rust-ts-mode.el55
-rw-r--r--lisp/textmodes/css-mode.el25
-rw-r--r--lisp/textmodes/toml-ts-mode.el16
8 files changed, 133 insertions, 83 deletions
diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el
index 2d13ae6930c..985e2e7b0bf 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 9da2c254f87..3e0439ddf54 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 1b34c0de418..14feed221fb 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 6c2f3805872..6725c5f2270 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 bdc9e6fa78c..d383fa57c04 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 8b2ed191019..81f5b8765f1 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 822097a86d8..99ef4f10a06 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 bca6a5e81ad..790de2133e8 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)