Skip to content

Commit c3fb8d9

Browse files
committed
Add imenu support
This is clashes with lsp-imenu if lsp is used, which can be disabled with (setq lsp-enable-imenu nil)
1 parent a778abd commit c3fb8d9

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

erlang-ts-imenu.el

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
;;; erlang-ts-imenu.el --- imenu helpers -*- lexical-binding: t; -*-
2+
;; %CopyrightBegin%
3+
;;
4+
;; Copyright Ericsson AB 2024-2025. All Rights Reserved.
5+
;;
6+
;; Licensed under the Apache License, Version 2.0 (the "License");
7+
;; you may not use this file except in compliance with the License.
8+
;; You may obtain a copy of the License at
9+
;;
10+
;; http://www.apache.org/licenses/LICENSE-2.0
11+
;;
12+
;; Unless required by applicable law or agreed to in writing, software
13+
;; distributed under the License is distributed on an "AS IS" BASIS,
14+
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
;; See the License for the specific language governing permissions and
16+
;; limitations under the License.
17+
;;
18+
;; %CopyrightEnd%
19+
;;
20+
21+
;;; Commentary:
22+
;; Imenu functionality using treesitter
23+
;; Conflicts with lsp-imenu functionality if lsp is used
24+
;; lsp's imenu functionality can be disabled with:
25+
;; `(setq lsp-enable-imenu nil)`
26+
27+
(require 'treesit)
28+
29+
;;; Code:
30+
31+
(defun erlang-ts-imenu-node-func-p (node)
32+
"Check if NODE is the first function clause is the first."
33+
(if (equal (treesit-node-type node) "fun_decl")
34+
(when-let ((prev (treesit-node-prev-sibling node))
35+
(name (erlang-ts-imenu-func-name node)))
36+
(not (and (equal (treesit-node-type prev) "fun_decl")
37+
(equal (erlang-ts-imenu-func-name prev) name))))
38+
nil))
39+
40+
(defun erlang-ts-imenu-func-name (node)
41+
"Fetch function name at NODE."
42+
(let ((clause (treesit-node-child-by-field-name node "clause")))
43+
(concat (treesit-node-text (treesit-node-child-by-field-name clause "name"))
44+
"/"
45+
(number-to-string
46+
(treesit-node-child-count
47+
(treesit-node-child-by-field-name clause "args")
48+
"args")))))
49+
50+
(defun erlang-ts-imenu-pp-name (node)
51+
"Fetch macro name at NODE."
52+
(let ((lhs (treesit-node-child-by-field-name node "lhs")))
53+
(let ((name (treesit-node-text (treesit-node-child-by-field-name lhs "name"))))
54+
(if-let* ((args (treesit-node-child-by-field-name lhs "args")))
55+
(concat name "/" (number-to-string (treesit-node-child-count args "args")))
56+
name))))
57+
58+
(defun erlang-ts-imenu-record-name (node)
59+
"Fetch record name at NODE."
60+
(let ((name (treesit-node-text (treesit-node-child-by-field-name node "name"))))
61+
(concat "#" name "{}")))
62+
63+
(defun erlang-ts-imenu-type-name (node)
64+
"Fetch type name at NODE."
65+
(let ((name (treesit-node-text
66+
(treesit-node-child-by-field-name
67+
(treesit-node-child-by-field-name node "name") "name"))))
68+
name))
69+
70+
(defun erlang-ts-imenu-setup ()
71+
"Setup imenu functions."
72+
(setq-local
73+
treesit-simple-imenu-settings
74+
'(
75+
("macros" "\\`pp_define\\'" nil erlang-ts-imenu-pp-name)
76+
("records" "\\`record_decl\\'" nil erlang-ts-imenu-record-name)
77+
("types" "\\`type_alias\\'" nil erlang-ts-imenu-type-name)
78+
("functions" "\\`fun_decl\\'" erlang-ts-imenu-node-func-p erlang-ts-imenu-func-name)
79+
)))
80+
81+
(provide 'erlang-ts-imenu)
82+
83+
;;; erlang-ts-imenu.el ends here

erlang-ts.el

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
(require 'treesit)
6868
(require 'erlang)
69+
(require 'erlang-ts-imenu)
6970

7071
;; Override erlang font-lock functions
7172
;; So the menus (and functions) work as expected
@@ -441,6 +442,10 @@ NODE is the treesit node to process."
441442
(advice-add #'erlang-font-lock-level-3 :around #'erlang-ts--font-lock-level-3)
442443
(advice-add #'erlang-font-lock-level-4 :around #'erlang-ts--font-lock-level-4)
443444

445+
;; This figths with lsp's imenu functionality if lsp is used
446+
;; Use (setq lsp-enable-imenu nil) to disable lsp-imenu
447+
(erlang-ts-imenu-setup)
448+
444449
(treesit-major-mode-setup)
445450
(setq-local syntax-propertize-function #'erlang-ts--syntax-propertize))
446451

0 commit comments

Comments
 (0)