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)
 
 

Reply via email to