branch: elpa/zig-mode commit 4542a5d67b031659a9efa427715d3f57a1c16934 Author: Marcio Giaxa <i...@mgxm.me> Commit: Marcio Giaxa <i...@mgxm.me>
add imenu support --- tests.el | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ zig-mode.el | 15 ++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/tests.el b/tests.el index 304103e..83171f2 100644 --- a/tests.el +++ b/tests.el @@ -2,6 +2,7 @@ (require 'ert) (require 'zig-mode) +(require 'imenu) ;;===========================================================================;; ;; Font lock tests @@ -288,3 +289,69 @@ if (false) { // This comment shouldn't mess anything up. }")) ;;===========================================================================;; +;; Imenu tests + +;; taken from rust-mode +(defun test-imenu (code expected-items) + (with-temp-buffer + (zig-mode) + (insert code) + (let ((actual-items + ;; Replace ("item" . #<marker at ? in ?.el) with "item" + (mapcar (lambda (class) + (cons (car class) + (mapcar #'car (cdr class)))) + (imenu--generic-function zig-imenu-generic-expression)))) + (should (equal expected-items actual-items))))) + + +(ert-deftest test-imenu-struct () + (test-imenu + " +pub const Foo = struct {}; +pub const Bar = extern struct {}; +const FooBar = struct {}; +" + '(("Struct" + "Foo" + "Bar" + "FooBar")))) + +(ert-deftest test-imenu-enum () + (test-imenu + " +pub const Foo = enum {}; +const FooBarError = enum {}; +" + '(("Enum" + "Foo" + "FooBarError")))) + +(ert-deftest test-imenu-enum () + (test-imenu + " +pub const Foo = enum {}; +const FooBarError = enum {}; +" + '(("Enum" + "Foo" + "FooBarError")))) + +(ert-deftest test-imenu-all () + (test-imenu + " +const Foo = struct { + pub fn init() void {} +}; + +const FooError = enum {}; + +pub fn main() void { +} +" + '(("Fn" "init" "main") + ("Struct" "Foo") + ("Enum" "FooError")))) + + +;;===========================================================================;; diff --git a/zig-mode.el b/zig-mode.el index 4e4c99a..172899f 100644 --- a/zig-mode.el +++ b/zig-mode.el @@ -283,6 +283,20 @@ 'font-lock-doc-face 'font-lock-comment-face)))) +;;; Imenu support +(defun zig-re-structure-def-imenu (stype) + "Construct a regular expression for strucutres definitions of type STYPE." + (concat (zig-re-word "const") "[[:space:]]+" + (zig-re-grab zig-re-identifier) + ".*" + (zig-re-word stype))) + +(defvar zig-imenu-generic-expression + (append (mapcar #'(lambda (x) + (list (capitalize x) (zig-re-structure-def-imenu x) 1)) + '("enum" "struct" "union")) + `(("Fn" ,(zig-re-definition "fn") 1)))) + ;;;###autoload (define-derived-mode zig-mode prog-mode "Zig" "A major mode for the Zig programming language." @@ -295,6 +309,7 @@ (setq-local indent-line-function 'zig-mode-indent-line) (setq-local indent-tabs-mode nil) ; Zig forbids tab characters. (setq-local syntax-propertize-function 'zig-syntax-propertize) + (setq-local imenu-generic-expression zig-imenu-generic-expression) (setq font-lock-defaults '(zig-font-lock-keywords nil nil nil nil (font-lock-syntactic-face-function