diff options
| author | Tom Tromey <tom@tromey.com> | 2017-08-01 07:37:31 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-08-01 07:37:31 -0600 |
| commit | 30a9d398fbdb88af16725248656956cb350c821d (patch) | |
| tree | 87169c668cc8b1d88f7299052cefea15093cd528 | |
| parent | 09efc45dee786cb220c233426ddd82b26ad950eb (diff) | |
| parent | 2a9fcd033b18bec27bbdeecc1397f2ddf4092bb1 (diff) | |
| download | rust-mode-30a9d398fbdb88af16725248656956cb350c821d.tar.gz | |
Merge pull request #221 from Wilfred/highlight_union_contextual_keyword
Add syntax highlighting and imenu support for `union`
| -rw-r--r-- | rust-mode-tests.el | 13 | ||||
| -rw-r--r-- | rust-mode.el | 24 |
2 files changed, 30 insertions, 7 deletions
diff --git a/rust-mode-tests.el b/rust-mode-tests.el index 614340c..7f1020f 100644 --- a/rust-mode-tests.el +++ b/rust-mode-tests.el @@ -1551,6 +1551,19 @@ this_is_not_a_string();)" "fn" font-lock-keyword-face "f" font-lock-function-name-face))) +(ert-deftest rust-test-union-context-sensitive () + (rust-test-font-lock + "let union = 7; union foo { x: &'union bar }" + '("let" font-lock-keyword-face + ;; Ignore the first union, it's an unhighlighted variable. + ;; The second union is a contextual keyword. + "union" font-lock-keyword-face + "foo" font-lock-type-face + "x" font-lock-variable-name-face + ;; This union is the name of a lifetime. + "union" font-lock-variable-name-face + "bar" font-lock-type-face))) + (ert-deftest indent-method-chains-no-align () (let ((rust-indent-method-chain nil)) (test-indent " diff --git a/rust-mode.el b/rust-mode.el index eac246f..46231fd 100644 --- a/rust-mode.el +++ b/rust-mode.el @@ -39,12 +39,18 @@ (defconst rust-re-vis "pub") (defconst rust-re-unsafe "unsafe") (defconst rust-re-extern "extern") +(defconst rust-re-union + (rx-to-string + `(seq + (or space line-start) + (group symbol-start "union" symbol-end) + (+ space) (regexp ,rust-re-ident)))) ;;; Start of a Rust item (defvar rust-top-item-beg-re (concat "\\s-*\\(?:priv\\|pub\\)?\\s-*" (regexp-opt - '("enum" "struct" "type" "mod" "use" "fn" "static" "impl" + '("enum" "struct" "union" "type" "mod" "use" "fn" "static" "impl" "extern" "trait")) "\\_>")) @@ -577,9 +583,12 @@ the desired identifiers), but does not match type annotations \"foo::<\"." (append `( ;; Keywords proper - ("\\_<\\(default\\)[[:space:]]+fn\\_>" 1 font-lock-keyword-face) (,(regexp-opt rust-mode-keywords 'symbols) . font-lock-keyword-face) + ;; Contextual keywords + ("\\_<\\(default\\)[[:space:]]+fn\\_>" 1 font-lock-keyword-face) + (,rust-re-union 1 font-lock-keyword-face) + ;; Special types (,(regexp-opt rust-special-types 'symbols) . font-lock-type-face) @@ -613,12 +622,13 @@ the desired identifiers), but does not match type annotations \"foo::<\"." ("\\?" . 'rust-question-mark-face) ) - ;; Item definitions + ;; Ensure we highlight `Foo` in `struct Foo` as a type. (mapcar #'(lambda (x) (list (rust-re-item-def (car x)) 1 (cdr x))) '(("enum" . font-lock-type-face) ("struct" . font-lock-type-face) + ("union" . font-lock-type-face) ("type" . font-lock-type-face) ("mod" . font-lock-constant-face) ("use" . font-lock-constant-face) @@ -671,7 +681,7 @@ the desired identifiers), but does not match type annotations \"foo::<\"." (rust-rewind-irrelevant) (rust-rewind-type-param-list) (cond - ((rust-looking-back-symbols '("fn" "trait" "enum" "struct" "impl" "type")) ident-pos) + ((rust-looking-back-symbols '("fn" "trait" "enum" "struct" "union" "impl" "type")) ident-pos) ((equal 5 (rust-syntax-class-before-point)) (backward-sexp) @@ -758,7 +768,7 @@ the desired identifiers), but does not match type annotations \"foo::<\"." (not (and (rust-rewind-to-decl-name) (progn (rust-rewind-irrelevant) - (rust-looking-back-symbols '("enum" "struct" "trait" "type")))))) + (rust-looking-back-symbols '("enum" "struct" "union" "trait" "type")))))) )) ((equal token 'ambiguous-operator) @@ -1167,7 +1177,7 @@ raw string, or to `end', whichever comes first." (defvar rust-imenu-generic-expression (append (mapcar #'(lambda (x) (list (capitalize x) (rust-re-item-def-imenu x) 1)) - '("enum" "struct" "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. @@ -1242,7 +1252,7 @@ This is written mainly to be used as `end-of-defun-function' for Rust." (error "Rustfmt failed, see *rustfmt* buffer for details")))) (delete-file tmpf)))) -(defconst rust--format-word "\\b\\(else\\|enum\\|fn\\|for\\|if\\|let\\|loop\\|match\\|struct\\|unsafe\\|while\\)\\b") +(defconst rust--format-word "\\b\\(else\\|enum\\|fn\\|for\\|if\\|let\\|loop\\|match\\|struct\\|union\\|unsafe\\|while\\)\\b") (defconst rust--format-line "\\([\n]\\)") ;; Counts number of matches of regex beginning up to max-beginning, |
