Skip to content

Commit 8a98d26

Browse files
committed
Imenu support for namespace, defn, and def forms
1 parent aaac7df commit 8a98d26

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

clojure-ts-mode.el

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,50 @@
344344
(parent-is "list_lit")) parent 1)
345345
((parent-is "set_lit") parent 2))))
346346

347+
(defun clojure-ts-mode--symbol-named-p (expected-symbol-name node)
348+
"Return non-nil if NODE is a symbol with text matching EXPECTED-SYMBOL-NAME."
349+
(and (string-equal "sym_lit" (treesit-node-type node))
350+
(string-equal expected-symbol-name
351+
(treesit-node-text (treesit-node-child-by-field-name node "name")))))
352+
353+
(defun clojure-ts-mode--definition-node-p (defintion-type-name node)
354+
"Return non-nil if NODE is a definition, defined by DEFINITION-TYPE-NAME.
355+
DEFINITION-TYPE-NAME might be a string like defn, def, defmulti, etc."
356+
(and
357+
(string-equal "list_lit" (treesit-node-type node))
358+
(clojure-ts-mode--symbol-named-p defintion-type-name (treesit-node-child node 0 t))))
359+
360+
(defun clojure-ts-mode--defn-node-p (node)
361+
"Return non-nil if NODE is a defn form."
362+
(clojure-ts-mode--definition-node-p "defn" node))
363+
364+
(defun clojure-ts-mode--ns-node-p (node)
365+
"Return non-nil if NODE is a ns form."
366+
(clojure-ts-mode--definition-node-p "ns" node))
367+
368+
(defun clojure-ts-mode--def-node-p (node)
369+
"Return non-nil if NODE is a def form."
370+
(clojure-ts-mode--definition-node-p "def" node))
371+
372+
(defun clojure-ts-mode--standard-definition-node-name (node)
373+
"Return the definition name for the given NODE.
374+
For example the node representing the expression (def foo 1) would return foo.
375+
The node representing (ns user) would return user."
376+
(let* ((sym (treesit-node-child node 1 t))
377+
(ns (treesit-node-child-by-field-name sym "ns"))
378+
(name (treesit-node-child-by-field-name sym "name")))
379+
(if ns
380+
(concat (treesit-node-text ns) "/" (treesit-node-text name))
381+
(treesit-node-text name))))
382+
383+
(defvar clojure-ts-mode--imenu-settings
384+
`(("Namespace" "list_lit" clojure-ts-mode--ns-node-p
385+
clojure-ts-mode--standard-definition-node-name)
386+
("Definition" "list_lit" clojure-ts-mode--defn-node-p
387+
clojure-ts-mode--standard-definition-node-name)
388+
("Variable" "list_lit" clojure-ts-mode--def-node-p
389+
clojure-ts-mode--standard-definition-node-name)))
390+
347391
(defvar clojure-ts-mode-map
348392
(let ((map (make-sparse-keymap)))
349393
;(set-keymap-parent map clojure-mode-map)
@@ -380,6 +424,7 @@ Requires Emacs 29 and libtree-sitter-clojure.so available somewhere in
380424
(keyword constant symbol bracket builtin)
381425
(deref quote metadata definition variable type doc regex tagged-literals)))
382426
(setq-local treesit-simple-indent-rules clojure-ts-mode--fixed-indent-rules)
427+
(setq-local treesit-simple-imenu-settings clojure-ts-mode--imenu-settings)
383428
(setq treesit--indent-verbose t)
384429
(treesit-major-mode-setup)
385430
(treesit-inspect-mode)

0 commit comments

Comments
 (0)