Skip to content

Commit d0f3f45

Browse files
authored
imenu: fn items: match async/const and all pub variants. (#346)
1 parent 4c8754b commit d0f3f45

File tree

2 files changed

+78
-19
lines changed

2 files changed

+78
-19
lines changed

rust-mode-tests.el

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3078,29 +3078,58 @@ type Foo<T> where T: Copy = Box<T>;
30783078
(ert-deftest rust-test-imenu-extern-unsafe-fn ()
30793079
(test-imenu
30803080
"
3081-
fn one() {
3081+
fn f1() {
30823082
}
30833083
3084-
unsafe fn two() {
3084+
unsafe fn f2() {
30853085
}
30863086
3087-
extern \"C\" fn three() {
3087+
extern \"C\" fn f3() {
30883088
}
30893089
3090-
pub extern fn four() {
3090+
pub extern fn f4() {
3091+
}
3092+
3093+
extern \"rust-intrinsic\" fn f5() {
3094+
}
3095+
3096+
async fn f6() {
3097+
}
3098+
3099+
const fn f7() {
3100+
}
30913101
3102+
async const fn not_a_match() {
30923103
}
30933104
3094-
extern \"rust-intrinsic\" fn five() {
3105+
fn f8<'a>() {
3106+
}
3107+
3108+
pub ( in self::super ) fn f9() {
3109+
}
3110+
3111+
pub ( in super ) fn f10() {
3112+
}
3113+
3114+
pub(in crate) fn f11() {
3115+
}
30953116
3117+
pub (in self) fn f12() {
30963118
}
30973119
"
30983120
'(("Fn"
3099-
"one"
3100-
"two"
3101-
"three"
3102-
"four"
3103-
"five"))))
3121+
"f1"
3122+
"f2"
3123+
"f3"
3124+
"f4"
3125+
"f5"
3126+
"f6"
3127+
"f7"
3128+
"f8"
3129+
"f9"
3130+
"f10"
3131+
"f11"
3132+
"f12"))))
31043133

31053134
(ert-deftest rust-test-imenu-impl-with-lifetime ()
31063135
(test-imenu

rust-mode.el

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,16 @@
3535
"Set variable VAR to value VAL in current buffer."
3636
(list 'set (list 'make-local-variable (list 'quote var)) val))))
3737

38+
(defun rust-re-word (inner) (concat "\\<" inner "\\>"))
39+
(defun rust-re-grab (inner) (concat "\\(" inner "\\)"))
40+
(defun rust-re-shy (inner) (concat "\\(?:" inner "\\)"))
41+
3842
(defconst rust-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
3943
(defconst rust-re-lc-ident "[[:lower:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
4044
(defconst rust-re-uc-ident "[[:upper:]][[:word:][:multibyte:]_[:digit:]]*")
41-
(defconst rust-re-vis "pub")
4245
(defconst rust-re-unsafe "unsafe")
4346
(defconst rust-re-extern "extern")
47+
(defconst rust-re-async-or-const "async\\|const")
4448
(defconst rust-re-generic
4549
(concat "<[[:space:]]*'" rust-re-ident "[[:space:]]*>"))
4650
(defconst rust-re-union
@@ -50,9 +54,34 @@
5054
(group symbol-start "union" symbol-end)
5155
(+ space) (regexp ,rust-re-ident))))
5256

57+
(defvar rust-re-vis
58+
;; pub | pub ( crate ) | pub ( self ) | pub ( super ) | pub ( in SimplePath )
59+
(concat
60+
"pub"
61+
(rust-re-shy
62+
(concat
63+
"[[:space:]]*([[:space:]]*"
64+
(rust-re-shy
65+
(concat "crate" "\\|"
66+
"\\(?:s\\(?:elf\\|uper\\)\\)" "\\|"
67+
;; in SimplePath
68+
(rust-re-shy
69+
(concat
70+
"in[[:space:]]+"
71+
rust-re-ident
72+
(rust-re-shy (concat "::" rust-re-ident)) "*"))))
73+
"[[:space:]]*)"))
74+
"?"))
75+
5376
;;; Start of a Rust item
5477
(defvar rust-top-item-beg-re
55-
(concat "\\s-*\\(?:priv\\|pub\\)?\\s-*"
78+
(concat "\\s-*"
79+
;; TODO some of this does only make sense for `fn' (unsafe, extern...)
80+
;; and not other items
81+
(rust-re-shy (concat (rust-re-shy rust-re-vis) "[[:space:]]+")) "?"
82+
83+
(rust-re-shy (concat (rust-re-shy rust-re-async-or-const) "[[:space:]]+")) "?"
84+
(rust-re-shy (concat (rust-re-shy rust-re-unsafe) "[[:space:]]+")) "?"
5685
(regexp-opt
5786
'("enum" "struct" "union" "type" "mod" "use" "fn" "static" "impl"
5887
"extern" "trait"))
@@ -578,17 +607,18 @@ buffer."
578607
symbol-end))
579608

580609
(defconst rust-re-pre-expression-operators "[-=!%&*/:<>[{(|.^;}]")
581-
(defun rust-re-word (inner) (concat "\\<" inner "\\>"))
582-
(defun rust-re-grab (inner) (concat "\\(" inner "\\)"))
583-
(defun rust-re-shy (inner) (concat "\\(?:" inner "\\)"))
584610
(defun rust-re-item-def (itype)
585611
(concat (rust-re-word itype)
586-
(rust-re-shy rust-re-generic) "?"
587-
"[[:space:]]+" (rust-re-grab rust-re-ident)))
612+
(rust-re-shy rust-re-generic) "?"
613+
"[[:space:]]+" (rust-re-grab rust-re-ident)))
614+
615+
;; TODO some of this does only make sense for `fn' (unsafe, extern...)
616+
;; and not other items
588617
(defun rust-re-item-def-imenu (itype)
589618
(concat "^[[:space:]]*"
590-
(rust-re-shy (concat (rust-re-word rust-re-vis) "[[:space:]]+")) "?"
619+
(rust-re-shy (concat rust-re-vis "[[:space:]]+")) "?"
591620
(rust-re-shy (concat (rust-re-word "default") "[[:space:]]+")) "?"
621+
(rust-re-shy (concat (rust-re-shy rust-re-async-or-const) "[[:space:]]+")) "?"
592622
(rust-re-shy (concat (rust-re-word rust-re-unsafe) "[[:space:]]+")) "?"
593623
(rust-re-shy (concat (rust-re-word rust-re-extern) "[[:space:]]+"
594624
(rust-re-shy "\"[^\"]+\"[[:space:]]+") "?")) "?"
@@ -1292,7 +1322,7 @@ whichever comes first."
12921322
(defvar rust-imenu-generic-expression
12931323
(append (mapcar #'(lambda (x)
12941324
(list (capitalize x) (rust-re-item-def-imenu x) 1))
1295-
'("async fn" "enum" "struct" "union" "type" "mod" "fn" "trait" "impl"))
1325+
'("enum" "struct" "union" "type" "mod" "fn" "trait" "impl"))
12961326
`(("Macro" ,(rust-re-item-def-imenu "macro_rules!") 1)))
12971327
"Value for `imenu-generic-expression' in Rust mode.
12981328

0 commit comments

Comments
 (0)