Update tree-sitter major modes to use the new Imenu facility

See previous commit for more explanation.

* lisp/progmodes/c-ts-mode.el (c-ts-mode--defun-name): Handle more
types.
(c-ts-mode--imenu-1)
(c-ts-mode--imenu): Remove functions.
(c-ts-base-mode): Setup Imenu.
* lisp/progmodes/csharp-mode.el (csharp-ts-mode--imenu-1)
(csharp-ts-mode--imenu): Remove functions.
(csharp-ts-mode): Setup Imenu.
* lisp/progmodes/java-ts-mode.el (java-ts-mode--imenu-1)
(java-ts-mode--imenu): Remove functions.
(java-ts-mode): Setup Imenu.
* lisp/progmodes/js.el (js--treesit-imenu-1)
(js--treesit-imenu): Remove functions.
(js--treesit-valid-imenu-entry): New function.
(js-ts-mode): Setup Imenu.
* lisp/progmodes/json-ts-mode.el (json-ts-mode--defun-name): Trim the
quotes.
(json-ts-mode--imenu-1)
(json-ts-mode--imenu): Remove functions.
(json-ts-mode): Setup Imenu.
* lisp/progmodes/rust-ts-mode.el (rust-ts-mode--imenu)
(rust-ts-mode--imenu-1): Remove functions.
(rust-ts-mode): Setup Imenu.
* lisp/progmodes/typescript-ts-mode.el:
(typescript-ts-base-mode): Remove treesit-defun-prefer-top-level, it's
not used anymore.  Setup Imenu.  Setup treesit-defun-name-function.
* lisp/textmodes/css-mode.el (css--treesit-imenu-1)
(css--treesit-imenu): Remove functions.
(css-ts-mode): Setup Imenu.
* lisp/textmodes/toml-ts-mode.el (toml-ts-mode--defun-name): Fix it
and add a fallback.
(toml-ts-mode--imenu-1)
(toml-ts-mode--imenu): Remove functions.
(toml-ts-mode): Setup Imenu.
This commit is contained in:
Yuan Fu 2022-12-27 20:57:12 -08:00
parent b39dc7ab27
commit 248c13dcfe
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
9 changed files with 72 additions and 361 deletions

View file

@ -487,55 +487,17 @@ For NODE, OVERRIDE, START, and END, see
(defun c-ts-mode--defun-name (node) (defun c-ts-mode--defun-name (node)
"Return the name of the defun NODE. "Return the name of the defun NODE.
Return nil if NODE is not a defun node, return an empty string if Return nil if NODE is not a defun node or doesn't have a name."
NODE doesn't have a name."
(treesit-node-text (treesit-node-text
(pcase (treesit-node-type node) (pcase (treesit-node-type node)
((or "function_definition" "declaration") ((or "function_definition" "declaration")
(c-ts-mode--declarator-identifier (c-ts-mode--declarator-identifier
(treesit-node-child-by-field-name node "declarator"))) (treesit-node-child-by-field-name node "declarator")))
("struct_specifier" ((or "struct_specifier" "enum_specifier"
"union_specifier" "class_specifier")
(treesit-node-child-by-field-name node "name"))) (treesit-node-child-by-field-name node "name")))
t)) t))
(defun c-ts-mode--imenu-1 (node)
"Helper for `c-ts-mode--imenu'.
Find string representation for NODE and set marker, then recurse
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'c-ts-mode--imenu-1 (cdr node)))
(name (when ts-node
(treesit-defun-name ts-node)))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((or (null ts-node) (null name))
subtrees)
((null (c-ts-mode--defun-valid-p ts-node))
nil)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun c-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(func-tree (treesit-induce-sparse-tree
node "^function_definition$" nil 1000))
(var-tree (treesit-induce-sparse-tree
node "^declaration$" nil 1000))
(struct-tree (treesit-induce-sparse-tree
node "^struct_specifier$" nil 1000))
(func-index (c-ts-mode--imenu-1 func-tree))
(var-index (c-ts-mode--imenu-1 var-tree))
(struct-index (c-ts-mode--imenu-1 struct-tree)))
(append
(when struct-index `(("Struct" . ,struct-index)))
(when var-index `(("Variable" . ,var-index)))
(when func-index `(("Function" . ,func-index))))))
;;; Defun navigation ;;; Defun navigation
(defun c-ts-mode--defun-valid-p (node) (defun c-ts-mode--defun-valid-p (node)
@ -745,8 +707,17 @@ Set up:
(append "{}():;," electric-indent-chars)) (append "{}():;," electric-indent-chars))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'c-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) (let ((pred #'c-ts-mode--defun-valid-p))
`(("Struct" ,(rx bos (or "struct" "enum" "union")
"_specifier" eos)
,pred nil)
("Variable" ,(rx bos "declaration" eos) ,pred nil)
("Function" "\\`function_definition\\'" ,pred nil)
("Class" ,(rx bos (or "class_specifier"
"function_definition")
eos)
,pred nil))))
(setq-local treesit-font-lock-feature-list (setq-local treesit-font-lock-feature-list
'(( comment definition) '(( comment definition)

View file

@ -857,54 +857,6 @@ Return nil if there is no name or if NODE is not a defun node."
node "name") node "name")
t)))) t))))
(defun csharp-ts-mode--imenu-1 (node)
"Helper for `csharp-ts-mode--imenu'.
Find string representation for NODE and set marker, then recurse
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'csharp-ts-mode--imenu-1 (cdr node)))
(name (when ts-node
(or (treesit-defun-name ts-node)
"Unnamed node")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((null ts-node) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun csharp-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(class-tree (treesit-induce-sparse-tree
node "^class_declaration$" nil 1000))
(interface-tree (treesit-induce-sparse-tree
node "^interface_declaration$" nil 1000))
(enum-tree (treesit-induce-sparse-tree
node "^enum_declaration$" nil 1000))
(struct-tree (treesit-induce-sparse-tree
node "^struct_declaration$" nil 1000))
(record-tree (treesit-induce-sparse-tree
node "^record_declaration$" nil 1000))
(method-tree (treesit-induce-sparse-tree
node "^method_declaration$" nil 1000))
(class-index (csharp-ts-mode--imenu-1 class-tree))
(interface-index (csharp-ts-mode--imenu-1 interface-tree))
(enum-index (csharp-ts-mode--imenu-1 enum-tree))
(record-index (csharp-ts-mode--imenu-1 record-tree))
(struct-index (csharp-ts-mode--imenu-1 struct-tree))
(method-index (csharp-ts-mode--imenu-1 method-tree)))
(append
(when class-index `(("Class" . ,class-index)))
(when interface-index `(("Interface" . ,interface-index)))
(when enum-index `(("Enum" . ,enum-index)))
(when record-index `(("Record" . ,record-index)))
(when struct-index `(("Struct" . ,struct-index)))
(when method-index `(("Method" . ,method-index))))))
;;;###autoload ;;;###autoload
(add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode)) (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-mode))
@ -955,8 +907,14 @@ Key bindings:
( bracket delimiter))) ( bracket delimiter)))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'csharp-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) ;; Piggyback on imenu '(("Class" "\\`class_declaration\\'" nil nil)
("Interface" "\\`interface_declaration\\'" nil nil)
("Enum" "\\`enum_declaration\\'" nil nil)
("Record" "\\`record_declaration\\'" nil nil)
("Struct" "\\`struct_declaration\\'" nil nil)
("Method" "\\`method_declaration\\'" nil nil)))
(treesit-major-mode-setup)) (treesit-major-mode-setup))
(provide 'csharp-mode) (provide 'csharp-mode)

View file

@ -266,50 +266,6 @@ Return nil if there is no name or if NODE is not a defun node."
(treesit-node-child-by-field-name node "name") (treesit-node-child-by-field-name node "name")
t)))) t))))
(defun java-ts-mode--imenu-1 (node)
"Helper for `java-ts-mode--imenu'.
Find string representation for NODE and set marker, then recurse
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'java-ts-mode--imenu-1 (cdr node)))
(name (when ts-node
(or (treesit-defun-name ts-node)
"Unnamed node")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((null ts-node) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun java-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(class-tree (treesit-induce-sparse-tree
node "^class_declaration$" nil 1000))
(interface-tree (treesit-induce-sparse-tree
node "^interface_declaration$" nil 1000))
(enum-tree (treesit-induce-sparse-tree
node "^enum_declaration$" nil 1000))
(record-tree (treesit-induce-sparse-tree
node "^record_declaration$" nil 1000))
(method-tree (treesit-induce-sparse-tree
node "^method_declaration$" nil 1000))
(class-index (java-ts-mode--imenu-1 class-tree))
(interface-index (java-ts-mode--imenu-1 interface-tree))
(enum-index (java-ts-mode--imenu-1 enum-tree))
(record-index (java-ts-mode--imenu-1 record-tree))
(method-index (java-ts-mode--imenu-1 method-tree)))
(append
(when class-index `(("Class" . ,class-index)))
(when interface-index `(("Interface" . ,interface-index)))
(when enum-index `(("Enum" . ,enum-index)))
(when record-index `(("Record" . ,record-index)))
(when method-index `(("Method" . ,method-index))))))
;;;###autoload ;;;###autoload
(define-derived-mode java-ts-mode prog-mode "Java" (define-derived-mode java-ts-mode prog-mode "Java"
"Major mode for editing Java, powered by tree-sitter." "Major mode for editing Java, powered by tree-sitter."
@ -352,8 +308,11 @@ the subtrees."
( bracket delimiter operator))) ( bracket delimiter operator)))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'java-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) ;; Piggyback on imenu '(("Class" "\\`class_declaration\\'" nil nil)
("Interface "\\`interface_declaration\\'" nil nil)
("Enum" "\\`record_declaration\\'" nil nil)
("Method" "\\`method_declaration\\'" nil nil)))
(treesit-major-mode-setup)) (treesit-major-mode-setup))
(provide 'java-ts-mode) (provide 'java-ts-mode)

View file

@ -3670,70 +3670,11 @@ Return nil if there is no name or if NODE is not a defun node."
"name") "name")
t)) t))
(defun js--treesit-imenu-1 (node) (defun js--treesit-valid-imenu-entry (node)
"Given a sparse tree, create an imenu alist. "Return nil if NODE is a non-top-level \"lexical_declaration\"."
(pcase (treesit-node-type node)
NODE is the root node of the tree returned by ("lexical_declaration" (treesit-node-top-level node))
`treesit-induce-sparse-tree' (not a tree-sitter node, its car is (_ t)))
a tree-sitter node). Walk that tree and return an imenu alist.
Return a list of ENTRY where
ENTRY := (NAME . MARKER)
| (NAME . ((JUMP-LABEL . MARKER)
ENTRY
...)
NAME is the function/class's name, JUMP-LABEL is like \"*function
definition*\"."
(let* ((ts-node (car node))
(children (cdr node))
(subtrees (mapcan #'js--treesit-imenu-1
children))
(type (pcase (treesit-node-type ts-node)
("lexical_declaration" 'variable)
("class_declaration" 'class)
("method_definition" 'method)
("function_declaration" 'function)))
;; The root of the tree could have a nil ts-node.
(name (when ts-node
(or (treesit-defun-name ts-node)
"Anonymous")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((null ts-node)
subtrees)
;; Don't included non-top-level variable declarations.
((and (eq type 'variable)
(treesit-node-top-level ts-node))
nil)
(subtrees
`((,name
,(cons "" marker)
,@subtrees)))
(t (list (cons name marker))))))
(defun js--treesit-imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(class-tree (treesit-induce-sparse-tree
node (rx (or "class_declaration"
"method_definition"))
nil 1000))
(func-tree (treesit-induce-sparse-tree
node "function_declaration" nil 1000))
(var-tree (treesit-induce-sparse-tree
node "lexical_declaration" nil 1000)))
;; When a sub-tree is empty, we should not return that pair at all.
(append
(and func-tree
`(("Function" . ,(js--treesit-imenu-1 func-tree))))
(and var-tree
`(("Variable" . ,(js--treesit-imenu-1 var-tree))))
(and class-tree
`(("Class" . ,(js--treesit-imenu-1 class-tree)))))))
;;; Main Function ;;; Main Function
@ -3875,10 +3816,14 @@ Currently there are `js-mode' and `js-ts-mode'."
identifier jsx number pattern property) identifier jsx number pattern property)
( bracket delimiter operator))) ( bracket delimiter operator)))
;; Imenu ;; Imenu
(setq-local imenu-create-index-function (setq-local treesit-simple-imenu-settings
#'js--treesit-imenu) `(("Function" "\\`function_declaration\\'" nil nil)
;; Which-func (use imenu). ("Variable" "\\`lexical_declaration\\'"
(setq-local which-func-functions nil) js--treesit-valid-imenu-entry nil)
("Class" ,(rx bos (or "class_declaration"
"method_definition")
eos)
nil nil)))
(treesit-major-mode-setup))) (treesit-major-mode-setup)))
;;;###autoload ;;;###autoload

View file

@ -112,36 +112,11 @@
Return nil if there is no name or if NODE is not a defun node." Return nil if there is no name or if NODE is not a defun node."
(pcase (treesit-node-type node) (pcase (treesit-node-type node)
((or "pair" "object") ((or "pair" "object")
(treesit-node-text (string-trim (treesit-node-text
(treesit-node-child-by-field-name (treesit-node-child-by-field-name
node "key") node "key")
t)))) t)
"\"" "\""))))
(defun json-ts-mode--imenu-1 (node)
"Helper for `json-ts-mode--imenu'.
Find string representation for NODE and set marker, then recurse
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'json-ts-mode--imenu-1 (cdr node)))
(name (when ts-node
(or (treesit-defun-name ts-node)
"Anonymous")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((null ts-node) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun json-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(tree (treesit-induce-sparse-tree
node "pair" nil 1000)))
(json-ts-mode--imenu-1 tree)))
;;;###autoload ;;;###autoload
(define-derived-mode json-ts-mode prog-mode "JSON" (define-derived-mode json-ts-mode prog-mode "JSON"
@ -179,8 +154,8 @@ the subtrees."
(bracket delimiter error))) (bracket delimiter error)))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'json-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) ;; Piggyback on imenu '((nil "\\`pair\\'" nil nil)))
(treesit-major-mode-setup)) (treesit-major-mode-setup))

View file

@ -248,35 +248,6 @@
'((ERROR) @font-lock-warning-face)) '((ERROR) @font-lock-warning-face))
"Tree-sitter font-lock settings for `rust-ts-mode'.") "Tree-sitter font-lock settings for `rust-ts-mode'.")
(defun rust-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(enum-tree (treesit-induce-sparse-tree
node "enum_item" nil))
(enum-index (rust-ts-mode--imenu-1 enum-tree))
(func-tree (treesit-induce-sparse-tree
node "function_item" nil))
(func-index (rust-ts-mode--imenu-1 func-tree))
(impl-tree (treesit-induce-sparse-tree
node "impl_item" nil))
(impl-index (rust-ts-mode--imenu-1 impl-tree))
(mod-tree (treesit-induce-sparse-tree
node "mod_item" nil))
(mod-index (rust-ts-mode--imenu-1 mod-tree))
(struct-tree (treesit-induce-sparse-tree
node "struct_item" nil))
(struct-index (rust-ts-mode--imenu-1 struct-tree))
(type-tree (treesit-induce-sparse-tree
node "type_item" nil))
(type-index (rust-ts-mode--imenu-1 type-tree)))
(append
(when mod-index `(("Module" . ,mod-index)))
(when enum-index `(("Enum" . ,enum-index)))
(when impl-index `(("Impl" . ,impl-index)))
(when type-index `(("Type" . ,type-index)))
(when struct-index `(("Struct" . ,struct-index)))
(when func-index `(("Fn" . ,func-index))))))
(defun rust-ts-mode--defun-name (node) (defun rust-ts-mode--defun-name (node)
"Return the defun name of NODE. "Return the defun name of NODE.
Return nil if there is no name or if NODE is not a defun node." Return nil if there is no name or if NODE is not a defun node."
@ -304,27 +275,6 @@ Return nil if there is no name or if NODE is not a defun node."
(treesit-node-text (treesit-node-text
(treesit-node-child-by-field-name node "name") t)))) (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
the subtrees."
(let* ((ts-node (car node))
(children (cdr node))
(subtrees (mapcan #'rust-ts-mode--imenu-1
children))
(name (when ts-node
(or (treesit-defun-name ts-node)
"Anonymous")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((or (null ts-node) (null name)) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
;;;###autoload ;;;###autoload
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode)) (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
@ -350,8 +300,13 @@ the subtrees."
( bracket delimiter error operator))) ( bracket delimiter error operator)))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'rust-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) `(("Module" "\\`mod_item\\'" nil nil)
("Enum" "\\`enum_item\\'" nil nil)
("Impl" "\\`impl_item\\'" nil nil)
("Type" "\\`type_item\\'" nil nil)
("Struct" "\\`struct_item\\'" nil nil)
("Fn" "\\`function_item\\'" nil nil)))
;; Indent. ;; Indent.
(setq-local indent-tabs-mode nil (setq-local indent-tabs-mode nil

View file

@ -335,8 +335,6 @@ Argument LANGUAGE is either `typescript' or `tsx'."
;; Comments. ;; Comments.
(c-ts-mode-comment-setup) (c-ts-mode-comment-setup)
(setq-local treesit-defun-prefer-top-level t)
;; Electric ;; Electric
(setq-local electric-indent-chars (setq-local electric-indent-chars
(append "{}():;," electric-indent-chars)) (append "{}():;," electric-indent-chars))
@ -347,11 +345,17 @@ Argument LANGUAGE is either `typescript' or `tsx'."
"method_definition" "method_definition"
"function_declaration" "function_declaration"
"lexical_declaration"))) "lexical_declaration")))
;; Imenu. (setq-local treesit-defun-name-function #'js--treesit-defun-name)
(setq-local imenu-create-index-function #'js--treesit-imenu)
;; Which-func (use imenu). ;; Imenu (same as in `js-ts-mode').
(setq-local which-func-functions nil)) (setq-local treesit-simple-imenu-settings
`(("Function" "\\`function_declaration\\'" nil nil)
("Variable" "\\`lexical_declaration\\'"
js--treesit-valid-imenu-entry nil)
("Class" ,(rx bos (or "class_declaration"
"method_definition")
eos)
nil nil))))
;;;###autoload ;;;###autoload
(define-derived-mode typescript-ts-mode typescript-ts-base-mode "TypeScript" (define-derived-mode typescript-ts-mode typescript-ts-base-mode "TypeScript"

View file

@ -1425,33 +1425,6 @@ Return nil if there is no name or if NODE is not a defun node."
(treesit-node-start node) (treesit-node-start node)
(treesit-node-start block))))))) (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
the subtrees."
(let* ((ts-node (car node))
(subtrees (mapcan #'css--treesit-imenu-1 (cdr node)))
(name (when ts-node
(or (treesit-defun-name ts-node)
"Anonymous")))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((or (null ts-node) (null name)) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun css--treesit-imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(tree (treesit-induce-sparse-tree
node (rx (or "rule_set" "media_statement"))
nil 1000)))
(css--treesit-imenu-1 tree)))
;;; Completion ;;; Completion
(defun css--complete-property () (defun css--complete-property ()
@ -1847,8 +1820,9 @@ can also be used to fill comments.
'((selector comment query keyword) '((selector comment query keyword)
(property constant string) (property constant string)
(error variable function operator bracket))) (error variable function operator bracket)))
(setq-local imenu-create-index-function #'css--treesit-imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) `( nil ,(rx bos (or "rule_set" "media_statement") eos)
nil nil))
(treesit-major-mode-setup))) (treesit-major-mode-setup)))
;;;###autoload ;;;###autoload

View file

@ -112,39 +112,8 @@
Return nil if there is no name or if NODE is not a defun node." Return nil if there is no name or if NODE is not a defun node."
(pcase (treesit-node-type node) (pcase (treesit-node-type node)
((or "table" "table_array_element") ((or "table" "table_array_element")
(car (cdr (treesit-node-children node)))))) (or (treesit-node-text (treesit-node-child node 1) t)
"Root table"))))
(defun toml-ts-mode--imenu-1 (node)
"Helper for `toml-ts-mode--imenu'.
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 (or (treesit-defun-name ts-node)
"Root table"))
(marker (when ts-node
(set-marker (make-marker)
(treesit-node-start ts-node)))))
(cond
((null ts-node) subtrees)
(subtrees
`((,name ,(cons name marker) ,@subtrees)))
(t
`((,name . ,marker))))))
(defun toml-ts-mode--imenu ()
"Return Imenu alist for the current buffer."
(let* ((node (treesit-buffer-root-node))
(table-tree (treesit-induce-sparse-tree
node "^table$" nil 1000))
(table-array-tree (treesit-induce-sparse-tree
node "^table_array_element$" nil 1000))
(table-index (toml-ts-mode--imenu-1 table-tree))
(table-array-index (toml-ts-mode--imenu-1 table-array-tree)))
(append
(when table-index `(("Headers" . ,table-index)))
(when table-array-index `(("Arrays" . ,table-array-index))))))
;;;###autoload ;;;###autoload
(add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode)) (add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode))
@ -179,8 +148,9 @@ the subtrees."
(delimiter error))) (delimiter error)))
;; Imenu. ;; Imenu.
(setq-local imenu-create-index-function #'toml-ts-mode--imenu) (setq-local treesit-simple-imenu-settings
(setq-local which-func-functions nil) ;; Piggyback on imenu '(("Header" "\\`table\\'" nil nil)
("Array" "\\`table_array_element\\'" nil nil)))
(treesit-major-mode-setup))) (treesit-major-mode-setup)))