branch: elpa/rust-mode
commit d0f3f45cc4fe1c5b72466253f051294d275a4b64
Author: Nathan Moreau <[email protected]>
Commit: GitHub <[email protected]>
imenu: fn items: match async/const and all pub variants. (#346)
---
rust-mode-tests.el | 49 +++++++++++++++++++++++++++++++++++++++----------
rust-mode.el | 48 +++++++++++++++++++++++++++++++++++++++---------
2 files changed, 78 insertions(+), 19 deletions(-)
diff --git a/rust-mode-tests.el b/rust-mode-tests.el
index e2e1218..b680548 100644
--- a/rust-mode-tests.el
+++ b/rust-mode-tests.el
@@ -3078,29 +3078,58 @@ type Foo<T> where T: Copy = Box<T>;
(ert-deftest rust-test-imenu-extern-unsafe-fn ()
(test-imenu
"
-fn one() {
+fn f1() {
}
-unsafe fn two() {
+unsafe fn f2() {
}
-extern \"C\" fn three() {
+extern \"C\" fn f3() {
}
-pub extern fn four() {
+pub extern fn f4() {
+}
+
+extern \"rust-intrinsic\" fn f5() {
+}
+
+async fn f6() {
+}
+
+const fn f7() {
+}
+async const fn not_a_match() {
}
-extern \"rust-intrinsic\" fn five() {
+fn f8<'a>() {
+}
+
+pub ( in self::super ) fn f9() {
+}
+
+pub ( in super ) fn f10() {
+}
+
+pub(in crate) fn f11() {
+}
+pub (in self) fn f12() {
}
"
'(("Fn"
- "one"
- "two"
- "three"
- "four"
- "five"))))
+ "f1"
+ "f2"
+ "f3"
+ "f4"
+ "f5"
+ "f6"
+ "f7"
+ "f8"
+ "f9"
+ "f10"
+ "f11"
+ "f12"))))
(ert-deftest rust-test-imenu-impl-with-lifetime ()
(test-imenu
diff --git a/rust-mode.el b/rust-mode.el
index 026b481..92f7daa 100644
--- a/rust-mode.el
+++ b/rust-mode.el
@@ -35,12 +35,16 @@
"Set variable VAR to value VAL in current buffer."
(list 'set (list 'make-local-variable (list 'quote var)) val))))
+(defun rust-re-word (inner) (concat "\\<" inner "\\>"))
+(defun rust-re-grab (inner) (concat "\\(" inner "\\)"))
+(defun rust-re-shy (inner) (concat "\\(?:" inner "\\)"))
+
(defconst rust-re-ident
"[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
(defconst rust-re-lc-ident
"[[:lower:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
(defconst rust-re-uc-ident "[[:upper:]][[:word:][:multibyte:]_[:digit:]]*")
-(defconst rust-re-vis "pub")
(defconst rust-re-unsafe "unsafe")
(defconst rust-re-extern "extern")
+(defconst rust-re-async-or-const "async\\|const")
(defconst rust-re-generic
(concat "<[[:space:]]*'" rust-re-ident "[[:space:]]*>"))
(defconst rust-re-union
@@ -50,9 +54,34 @@
(group symbol-start "union" symbol-end)
(+ space) (regexp ,rust-re-ident))))
+(defvar rust-re-vis
+ ;; pub | pub ( crate ) | pub ( self ) | pub ( super ) | pub ( in SimplePath
)
+ (concat
+ "pub"
+ (rust-re-shy
+ (concat
+ "[[:space:]]*([[:space:]]*"
+ (rust-re-shy
+ (concat "crate" "\\|"
+ "\\(?:s\\(?:elf\\|uper\\)\\)" "\\|"
+ ;; in SimplePath
+ (rust-re-shy
+ (concat
+ "in[[:space:]]+"
+ rust-re-ident
+ (rust-re-shy (concat "::" rust-re-ident)) "*"))))
+ "[[:space:]]*)"))
+ "?"))
+
;;; Start of a Rust item
(defvar rust-top-item-beg-re
- (concat "\\s-*\\(?:priv\\|pub\\)?\\s-*"
+ (concat "\\s-*"
+ ;; TODO some of this does only make sense for `fn' (unsafe, extern...)
+ ;; and not other items
+ (rust-re-shy (concat (rust-re-shy rust-re-vis) "[[:space:]]+")) "?"
+
+ (rust-re-shy (concat (rust-re-shy rust-re-async-or-const)
"[[:space:]]+")) "?"
+ (rust-re-shy (concat (rust-re-shy rust-re-unsafe) "[[:space:]]+")) "?"
(regexp-opt
'("enum" "struct" "union" "type" "mod" "use" "fn" "static" "impl"
"extern" "trait"))
@@ -578,17 +607,18 @@ buffer."
symbol-end))
(defconst rust-re-pre-expression-operators "[-=!%&*/:<>[{(|.^;}]")
-(defun rust-re-word (inner) (concat "\\<" inner "\\>"))
-(defun rust-re-grab (inner) (concat "\\(" inner "\\)"))
-(defun rust-re-shy (inner) (concat "\\(?:" inner "\\)"))
(defun rust-re-item-def (itype)
(concat (rust-re-word itype)
- (rust-re-shy rust-re-generic) "?"
- "[[:space:]]+" (rust-re-grab rust-re-ident)))
+ (rust-re-shy rust-re-generic) "?"
+ "[[:space:]]+" (rust-re-grab rust-re-ident)))
+
+;; TODO some of this does only make sense for `fn' (unsafe, extern...)
+;; and not other items
(defun rust-re-item-def-imenu (itype)
(concat "^[[:space:]]*"
- (rust-re-shy (concat (rust-re-word rust-re-vis) "[[:space:]]+")) "?"
+ (rust-re-shy (concat rust-re-vis "[[:space:]]+")) "?"
(rust-re-shy (concat (rust-re-word "default") "[[:space:]]+")) "?"
+ (rust-re-shy (concat (rust-re-shy rust-re-async-or-const)
"[[:space:]]+")) "?"
(rust-re-shy (concat (rust-re-word rust-re-unsafe) "[[:space:]]+"))
"?"
(rust-re-shy (concat (rust-re-word rust-re-extern) "[[:space:]]+"
(rust-re-shy "\"[^\"]+\"[[:space:]]+") "?")) "?"
@@ -1292,7 +1322,7 @@ whichever comes first."
(defvar rust-imenu-generic-expression
(append (mapcar #'(lambda (x)
(list (capitalize x) (rust-re-item-def-imenu x) 1))
- '("async fn" "enum" "struct" "union" "type" "mod" "fn"
"trait" "impl"))
+ '("enum" "struct" "union" "type" "mod" "fn" "trait" "impl"))
`(("Macro" ,(rust-re-item-def-imenu "macro_rules!") 1)))
"Value for `imenu-generic-expression' in Rust mode.