branch: elpa/d-mode
commit 27e7c62c23883bddaa6543768984edb6a08ad1e3
Merge: 46a9ad2 473fa33
Author: Russel Winder <[email protected]>
Commit: Russel Winder <[email protected]>
Merge pull request #14 from finalpatch/master
Improvements to d-mode
---
d-mode.el | 86 ++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 60 insertions(+), 26 deletions(-)
diff --git a/d-mode.el b/d-mode.el
index d8c63ca..a0983fc 100644
--- a/d-mode.el
+++ b/d-mode.el
@@ -86,6 +86,10 @@
"\\)"
"\\([^=]\\|$\\)"))
+;; D has fixed arrays
+(c-lang-defconst c-opt-type-suffix-key
+ d "\\(\\[[^]]*\\]\\|\\.\\.\\.\\)")
+
(c-lang-defconst c-identifier-ops
;; For recognizing "~this", ".foo", and "foo.bar.baz" as identifiers
d '((prefix "~")(prefix ".")(left-assoc ".")))
@@ -121,13 +125,8 @@
"List of the tokens made up of characters in the punctuation or
parenthesis syntax classes that have uses other than as expression
operators."
-
-; Emergency Emacs 23 fixes from
http://www.prowiki.org/wiki4d/wiki.cgi?EditorSupport/EmacsDMode
-
-; d (append '("/+" "+/" "..." ".." "!" "*" "&")
-; (c-lang-const c-other-op-syntax-tokens)))
-
- d '("/+" "+/" "..." ".." "!" "*" "&"))
+ d (append '("/+" "+/" "..." ".." "!" "*" "&")
+ (c-lang-const c-other-op-syntax-tokens)))
(c-lang-defconst c-block-comment-starter d "/*")
(c-lang-defconst c-block-comment-ender d "*/")
@@ -143,6 +142,11 @@ operators."
;; doc comments for D use "///", "/**" or doxygen's "/*!" "//!"
d "/\\*[*!]\\|//[/!]")
+(c-lang-defconst c-block-prefix-disallowed-chars
+ ;; Allow ':' for inherit list starters.
+ d (set-difference (c-lang-const c-block-prefix-disallowed-chars)
+ '(?:)))
+
;;----------------------------------------------------------------------------
;; Built-in basic types
@@ -188,20 +192,17 @@ operators."
;; d '("with" "version" "extern"))
(c-lang-defconst c-typedef-decl-kwds
-
-; Emergency Emacs 23 fixes from
http://www.prowiki.org/wiki4d/wiki.cgi?EditorSupport/EmacsDMode
-
-; d (append (c-lang-const c-typedef-decl-kwds)
-; '("typedef" "alias")))
-
- d '("typedef" "alias"))
+ d (append (c-lang-const c-typedef-decl-kwds)
+ '("typedef" "alias")))
(c-lang-defconst c-decl-hangon-kwds
d '("export"))
(c-lang-defconst c-protection-kwds
;; Access protection label keywords in classes.
- d '("export" "private" "package" "protected" "public"))
+ d '("deprecated" "static" "extern" "final" "synchronized" "override"
+ "abstract" "scope" "const" "inout" "shared" "__gshared"
+ "private" "package" "protected" "public" "export"))
;;(c-lang-defconst c-postfix-decl-spec-kwds
;; ;Keywords introducing extra declaration specifiers in the region
@@ -219,7 +220,7 @@ operators."
(c-lang-defconst c-colon-type-list-kwds
;; Keywords that may be followed (not necessarily directly) by a colon
;; and then a comma separated list of type identifiers.
- d '("class" "enum"))
+ d '("class" "enum" "interface"))
(c-lang-defconst c-paren-nontype-kwds
;;Keywords that may be followed by a parenthesis expression that doesn't
@@ -388,9 +389,9 @@ operators."
;; "return foo(x);" or "static if(x) {"
;; so we exclude type name 'static' or 'return' here
(while (let ((type (match-string 1)))
- (and type
- (or (string= type "static")
- (string= type "return"))))
+ (and pt type
+ (save-match-data
+ (string-match (c-lang-const c-regular-keywords-regexp)
type))))
(setq pt (re-search-backward d-imenu-method-name-pattern nil t)))
pt)
;; Do not count invisible definitions.
@@ -438,15 +439,48 @@ Key bindings:
(c-update-modeline)
(setq imenu-generic-expression d-imenu-generic-expression))
+;; Hideous hacks!
+;;
+;; * auto/immutable: If we leve them in c-modifier-kwds (like
+;; c++-mode) then in the form "auto var;" var will be highlighted in
+;; type name face. Moving auto/immutable to font-lock-add-keywords
+;; lets cc-mode seeing them as a type name, so the next symbol can
+;; be fontified as a variable.
+;;
+;; * public/protected/private appear both in c-modifier-kwds and in
+;; c-protection-kwds. This causes cc-mode to fail parsing the first
+;; declaration after an access level label (because cc-mode trys to
+;; parse them as modifier but will fail due to the colon). But
+;; unfortunately we cannot remove them from either c-modifier-kwds
+;; or c-protection-kwds. Removing them from the former causes valid
+;; syntax like "private int foo() {}" to fail. Removing them from
+;; the latter cause indentation of the access level labels to
+;; fail. The solution used here is to use font-lock-add-keywords to
+;; add back the syntax highlight.
+
+(defconst d-var-decl-pattern "^[ \t]*\\(?:[_a-zA-Z0-9]+[
\t\n]+\\)*\\([_a-zA-Z0-9.!]+\\)\\(?:\\[[^]]*\\]\\|\\*\\)?[
\t\n]+\\([_a-zA-Z0-9]+\\)[ \t\n]*[;=]")
+(defconst d-fun-decl-pattern "^[ \t]*\\(?:[_a-zA-Z0-9]+[
\t\n]+\\)*\\([_a-zA-Z0-9.!]+\\)\\(?:\\[[^]]*\\]\\|\\*\\)?[
\t\n]+\\([_a-zA-Z0-9]+\\)[ \t\n]*(")
+(defmacro d-try-match-decl (regex)
+ `(let ((pt))
+ (setq pt (re-search-forward ,regex limit t))
+ (while (let ((type (match-string 1)))
+ (and pt type
+ (save-match-data
+ (string-match (c-lang-const c-regular-keywords-regexp)
type))))
+ (setq pt (re-search-forward ,regex limit t)))
+ pt))
+(defun d-match-var-decl (limit)
+ (d-try-match-decl d-var-decl-pattern))
+(defun d-match-fun-decl (limit)
+ (d-try-match-decl d-fun-decl-pattern))
+(defun d-match-auto (limit)
+ (c-syntactic-re-search-forward "\\<\\(auto\\|immutable\\)\\>" limit t))
+
(font-lock-add-keywords
'd-mode
- '(("\\<\\(auto\\|immutable\\)\\>" 1 font-lock-keyword-face)
- ("^[ \t]*\\(?:[_a-zA-Z0-9]+[ \t\n]+\\)*\\([_a-zA-Z0-9.!]+\\)[][* ]*[
\t\n]+\\([_a-zA-Z0-9]+\\)[ \t\n]*;"
- (1 font-lock-type-face)
- (2 font-lock-variable-name-face))
- ("^[ \t]*\\(?:[_a-zA-Z0-9]+[ \t\n]+\\)*\\([_a-zA-Z0-9.!]+\\)[][* ]*[
\t\n]+\\([_a-zA-Z0-9]+\\)[ \t\n]*("
- (1 font-lock-type-face)
- (2 font-lock-function-name-face)))
+ '((d-match-auto 1 font-lock-keyword-face t)
+ (d-match-var-decl (1 font-lock-type-face) (2 font-lock-variable-name-face))
+ (d-match-fun-decl (1 font-lock-type-face) (2 font-lock-function-name-face)))
t)