www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - A new emacs d-mode from scratch

reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I made a new emacs mode.
Here it is.

For some reason I couldn't get it to show up properly on Wiki4D so I'm 
attaching it here.

--bb
Mar 03 2007
next sibling parent reply "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.
 
 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.

Cool. I tried it, but I get the error "Cannot open load file: cc-defs.el". Is that mode the C mode? But I do seem to have proper C mode installed. Andrei
Mar 03 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Andrei Alexandrescu (See Website For Email) wrote:
 Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.

 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.

Cool. I tried it, but I get the error "Cannot open load file: cc-defs.el". Is that mode the C mode? But I do seem to have proper C mode installed.

Missing cc-defs.el means you've got an old cc-mode: ;; cc-mode version 5.30 or greater is required. ;; You can check your cc-mode with the command M-x c-version. ;; You can get the latest version of cc-mode at ;; http://cc-mode.sourceforge.net I just tried the cc-mode upgrade out with my emacs 21. Installation of the new cc-mode is pretty trivial. Unzip to a directory, add that directory to your emacs search path, M-x byte-compile-directory. I did get some errors trying to do the byte compiling with emacs 21. But I fixed em. So after upgrading your cc-mode, try the attached d-mode. --bb
Mar 03 2007
parent reply "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 Andrei Alexandrescu (See Website For Email) wrote:
 Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.

 For some reason I couldn't get it to show up properly on Wiki4D so 
 I'm attaching it here.

Cool. I tried it, but I get the error "Cannot open load file: cc-defs.el". Is that mode the C mode? But I do seem to have proper C mode installed.

Missing cc-defs.el means you've got an old cc-mode: ;; cc-mode version 5.30 or greater is required. ;; You can check your cc-mode with the command M-x c-version. ;; You can get the latest version of cc-mode at ;; http://cc-mode.sourceforge.net I just tried the cc-mode upgrade out with my emacs 21. Installation of the new cc-mode is pretty trivial. Unzip to a directory, add that directory to your emacs search path, M-x byte-compile-directory. I did get some errors trying to do the byte compiling with emacs 21. But I fixed em. So after upgrading your cc-mode, try the attached d-mode.

Thanks! Works great, modulo the warning I get during compilation: d-mode.el:266:1:Warning: defcustom for `d-font-lock-extra-types' fails to specify containing group As we all know, it's best to compile with zero warnings :o). Andrei
Mar 03 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Andrei Alexandrescu (See Website For Email) wrote:
 Bill Baxter wrote:
 Andrei Alexandrescu (See Website For Email) wrote:
 Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.

 For some reason I couldn't get it to show up properly on Wiki4D so 
 I'm attaching it here.

Cool. I tried it, but I get the error "Cannot open load file: cc-defs.el". Is that mode the C mode? But I do seem to have proper C mode installed.

Missing cc-defs.el means you've got an old cc-mode: ;; cc-mode version 5.30 or greater is required. ;; You can check your cc-mode with the command M-x c-version. ;; You can get the latest version of cc-mode at ;; http://cc-mode.sourceforge.net I just tried the cc-mode upgrade out with my emacs 21. Installation of the new cc-mode is pretty trivial. Unzip to a directory, add that directory to your emacs search path, M-x byte-compile-directory. I did get some errors trying to do the byte compiling with emacs 21. But I fixed em. So after upgrading your cc-mode, try the attached d-mode.

Thanks! Works great, modulo the warning I get during compilation: d-mode.el:266:1:Warning: defcustom for `d-font-lock-extra-types' fails to specify containing group As we all know, it's best to compile with zero warnings :o).

You can try commenting out that line with the d-font-lock-extra types on it. Maybe it isn't necessary. I just copied that part verbatim from the example on the cc-mode website. --bb
Mar 03 2007
prev sibling next sibling parent reply Howard Berkey <howard well.com> writes:
Bill Baxter Wrote:

 I made a new emacs mode.
 Here it is.
 
 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.
 

It's working great for me, thanks! Plus it gave me incentive to upgrade cc-mode too, which is a good thing. Howard
Mar 03 2007
parent Henrik Harmsen <henrik harmsen.se> writes:
Howard Berkey Wrote:

 Bill Baxter Wrote:
 
 I made a new emacs mode.
 Here it is.
 
 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.
 

It's working great for me, thanks! Plus it gave me incentive to upgrade cc-mode too, which is a good thing. Howard

Works great for me too! Thanks very much! -- Henrik
Mar 03 2007
prev sibling parent reply Charlie <charlie.fats gmail.com> writes:
Unfortunately the new cc-mode isn't compaitble with the existing 
php-mode :( , `Symbol's value as variable is void: c-symbol-key`

Charlie

Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.
 
 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.
 
 --bb
 
 
 ------------------------------------------------------------------------
 
 ;;; d-mode.el --- D Programming Language mode for (X)Emacs
 ;;;               Requires a cc-mode of version 5.30 or greater
 
 ;; Author:     2007 William Baxter
 ;; Maintainer: William Baxter
 ;; Created:    March 2007
 ;; Version:    2.0.0
 ;; Keywords:   D programming language emacs cc-mode
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; the Free Software Foundation; either version 2 of the License, or
 ;; (at your option) any later version.
 ;; 
 ;; This program is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 ;; 
 ;; You should have received a copy of the GNU General Public License
 ;; along with this program; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
 ;; Usage: 
 ;; Put these lines in your .emacs startup file.
 ;;   (autoload 'd-mode "d-mode" "Major mode for editing D code." t)
 ;;   (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))
 ;;
 ;; cc-mode version 5.30 or greater is required.
 ;; You can check your cc-mode with the command M-x c-version.
 ;; You can get the latest version of cc-mode at http://cc-mode.sourceforge.net
 ;;
 ;; Commentary:
 ;;   This mode supports most of D's syntax, including nested /+ +/
 ;;   comments and backquote `string literals`.
 ;;   
 ;;   This mode has been dubbed "2.0" because it is a complete rewrite
 ;;   from scratch.  The previous d-mode was based on cc-mode 5.28 or
 ;;   so.  This version is based on the cc-mode 5.30 derived mode
 ;;   example by Martin Stjernholm, 2002.
 ;;
 ;;
 ;; TODO:
 ;;   * "else static if" doesn't work properly. 
 ;;     (Incidentally "static else if" is fine, but unfortunately it's
 ;;      not valid D syntax.)
 ;;
 ;;   * I tried making "with" "version" and "extern" be their own
 ;;     c-other-block-decl-kwds.  Which is supposed to mean that you
 ;;     can control the indentation on the block following them
 ;;     individually.  It didn't seem to work right though.
 ;;
 ;; History:
 ;;   * 2007 March 3 - Release of 2.0.0 version
 
 ;;----------------------------------------------------------------------------
 ;; Code:
 
 (require 'cc-mode)
 
 ;; These are only required at compile time to get the sources for the
 ;; language constants.  (The cc-fonts require and the font-lock
 ;; related constants could additionally be put inside an
 ;; (eval-after-load "font-lock" ...) but then some trickery is
 ;; necessary to get them compiled.)
 ;; Coment out 'when-compile part for debugging
 (eval-when-compile
   (require 'cc-langs)
   (require 'cc-fonts)
 )
 
 (eval-and-compile
   ;; Make our mode known to the language constant system.  Use Java
   ;; mode as the fallback for the constants we don't change here.
   ;; This needs to be done also at compile time since the language
   ;; constants are evaluated then.
   (c-add-language 'd-mode 'java-mode))
 
 (c-lang-defconst c-identifier-ops
   ;; For recognizing "~this", ".foo", and "foo.bar.baz" as identifiers
   d '((prefix "~")(prefix ".")(left-assoc ".")))
 
 (c-lang-defconst c-after-id-concat-ops
   ;; Also for handling ~this
   d '("~"))
 
 (c-lang-defconst c-string-escaped-newlines
   ;; Set to true to indicate the D handles backslash escaped newlines in
strings
   d t)
 
 (c-lang-defconst c-multiline-string-start-char
   ;; Set to true to indicate that D doesn't mind raw embedded newlines in
strings
   d t)
 
 (c-lang-defconst c-opt-cpp-prefix
   ;; Preprocssor directive recognizer.  D doesn't have cpp, but it has #line
   d "\\s *#\\s *")
 
 (c-lang-defconst c-cpp-message-directives d nil)
 (c-lang-defconst c-cpp-include-directives d nil)
 (c-lang-defconst c-opt-cpp-macro-define d nil)
 (c-lang-defconst c-cpp-expr-directives d nil)
 (c-lang-defconst c-cpp-expr-functions d nil)
 
 (c-lang-defconst c-assignment-operators
   ;; List of all assignment operators.
   d  '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" ">>>=" "&=" "^=" "|=" "~="))
 
 (c-lang-defconst c-other-op-syntax-tokens
   "List of the tokens made up of characters in the punctuation or
 parenthesis syntax classes that have uses other than as expression
 operators."
   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 "*/")
 
 (c-lang-defconst c-comment-start-regexp  d "/[*+/]")
 (c-lang-defconst c-block-comment-start-regexp d "/[*+]")
 (c-lang-defconst c-literal-start-regexp 
  ;; Regexp to match the start of comments and string literals.
  d "/[*+/]\\|\"\\|`")
 
 (c-lang-defconst c-doc-comment-start-regexp
  ;; doc comments for D use "///",  "/**" or doxygen's "/*!" "//!"
  d "/\\(\\*[*!]\\|/[/!]\\)")
 
 ;;----------------------------------------------------------------------------
 
 ;; Built-in basic types
 (c-lang-defconst c-primitive-type-kwds
   d '("bit" "byte" "ubyte" "char" "delegate" "double" "float" "function" 
       "int" "long" "ubyte" "short" "uint" "ulong" "ushort" "cent" "ucent" 
       "real" "ireal" "ifloat" "creal" "cfloat" "cdouble"
       "wchar" "dchar" "void"))
 
 ;; Keywords that can prefix normal declarations of identifiers
 (c-lang-defconst c-modifier-kwds
   d '("auto" "abstract" "const" "deprecated" "extern" 
       "final" "lazy" "private" "protected" "public"
       "scope" "static" "synchronized" "volatile" "mixin"))
 
 (c-lang-defconst c-class-decl-kwds
   ;; Keywords introducing declarations where the following block (if any)
   ;; contains another declaration level that should be considered a class.
   d '("class" "struct" "union" "interface" "template"))
 
 (c-lang-defconst c-brace-list-decl-kwds
   d '("enum"))
 
 (c-lang-defconst c-type-modifier-kwds
   d '("const" "lazy" "volatile")
 )
 (c-lang-defconst c-type-prefix-kwds
   ;; Keywords where the following name - if any - is a type name, and
   ;; where the keyword together with the symbol works as a type in
   ;; declarations.  In this case, like "mixin foo!(x) bar;"
   d    '("mixin" "align"))
 
 ;;(c-lang-defconst c-other-block-decl-kwds
 ;;  ;; Keywords where the following block (if any) contains another
 ;;  ;; declaration level that should not be considered a class.
 ;;  ;; Each of these has associated offsets e.g. 
 ;;  ;;   'with-open', 'with-close' and 'inwith' 
 ;;  ;; that can be customized individually
 ;;  ;;   TODO: maybe also do this for 'static if' ?  in/out?
 ;;  ;;   TODO: figure out how to make this work properly
 ;;  d '("with" "version" "extern"))
 
 (c-lang-defconst c-typedef-decl-kwds
   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"))
 
 ;;(c-lang-defconst c-postfix-decl-spec-kwds
 ;;  ;Keywords introducing extra declaration specifiers in the region
 ;;  ;between the header and the body (i.e. the "K&R-region") in
 ;;  ;declarations.
 ;;; This doesn't seem to have any effect.  They aren't exactly "K&R-regions".
 ;;  d '("in" "out" "body"))
 
 (c-lang-defconst c-type-list-kwds
   d '("import"))
 
 (c-lang-defconst c-ref-list-kwds
   d '("module"))
 
 (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"))
 
 (c-lang-defconst c-paren-nontype-kwds
   ;;Keywords that may be followed by a parenthesis expression that doesn't
   ;; contain type identifiers.
   d '("version" "extern"))
 
 (c-lang-defconst c-paren-type-kwds
   ;; Keywords that may be followed by a parenthesis expression containing
   ;; type identifiers separated by arbitrary tokens.
   d  '("throw"))
 
 (c-lang-defconst c-block-stmt-1-kwds
   ;; Statement keywords followed directly by a substatement.
   ;; 'static' is there for the "else static if (...) {}" usage.
   d '("do" "else" "finally" "try" "in" "out" "debug" "body"))
 
 (c-lang-defconst c-block-stmt-2-kwds
   ;; Statement keywords followed by a paren sexp and then by a substatement.
   d '("for" "if" "switch" "while" "catch" "synchronized" "scope"
       "foreach" "foreach_reverse" "with"))
 
 (c-lang-defconst c-simple-stmt-kwds
   ;; Statement keywords followed by an expression or nothing.
   d '("break" "continue" "goto" "return" "throw"))
 
 (c-lang-defconst c-paren-stmt-kwds
   ;; Statement keywords followed by a parenthesis expression that
   ;; nevertheless contains a list separated with ';' and not ','."
   d '("for" "foreach" "foreach_reverse"))
 
 (c-lang-defconst c-asm-stmt-kwds
   ;; Statement keywords followed by an assembler expression.
   d '("asm"))
 
 (c-lang-defconst c-label-kwds
   ;; Keywords introducing colon terminated labels in blocks.
   d '("case" "default"))
 
 (c-lang-defconst c-before-label-kwds
   ;; Keywords that might be followed by a label identifier.
   d    '("goto" "break" "continue"))
 
 (c-lang-defconst c-constant-kwds
   ;; Keywords for constants.
   d '("null" "true" "false"))
 
 (c-lang-defconst c-primary-expr-kwds
   ;; Keywords besides constants and operators that start primary expressions.
   d '("this" "super"))
 
 (c-lang-defconst c-inexpr-class-kwds
   ;; Keywords that can start classes inside expressions.
   d    nil)
 
 (c-lang-defconst c-inexpr-brace-list-kwds
   ;; Keywords that can start brace list blocks inside expressions.
   d    nil)
 
 (c-lang-defconst c-other-decl-kwds
   d '("module" "import"))
 
 (c-lang-defconst c-other-kwds
   ;; Keywords not accounted for by any other `*-kwds' language constant.
   d '("assert"))
 
 
 (defcustom d-font-lock-extra-types nil
   "*List of extra types (aside from the type keywords) to recognize in D mode.
 Each list item should be a regexp matching a single identifier.")
 
 (defconst d-font-lock-keywords-1 (c-lang-const c-matchers-1 d)
   "Minimal highlighting for D mode.")
 
 (defconst d-font-lock-keywords-2 (c-lang-const c-matchers-2 d)
   "Fast normal highlighting for D mode.")
 
 (defconst d-font-lock-keywords-3 (c-lang-const c-matchers-3 d)
   "Accurate normal highlighting for D mode.")
 
 (defvar d-font-lock-keywords d-font-lock-keywords-3
   "Default expressions to highlight in D mode.")
 
 (defvar d-mode-syntax-table nil
   "Syntax table used in d-mode buffers.")
 (or d-mode-syntax-table
     (setq d-mode-syntax-table
 	 (let ((table (funcall (c-lang-const c-make-mode-syntax-table d))))
 	   ;; Make it recognize D `backquote strings`
 	   (modify-syntax-entry ?` "\"" table)
 
 	   ;; Make it recognize D's nested /+ +/ comments 
 	   (modify-syntax-entry ?+  ". 23n"   table)
 	   table)))
 
 (defvar d-mode-abbrev-table nil
   "Abbreviation table used in d-mode buffers.")
 (c-define-abbrev-table 'd-mode-abbrev-table
   ;; Use the abbrevs table to trigger indentation actions 
   ;; on keywords that, if they occur first on a line, might alter the
   ;; syntactic context.
   ;; Syntax for abbrevs is:
   ;; ( pattern replacement command initial-count)
   '(("else" "else" c-electric-continued-statement 0)
     ("while" "while" c-electric-continued-statement 0)
     ("catch" "catch" c-electric-continued-statement 0)
     ("finally" "finally" c-electric-continued-statement 0)))
 
 (defvar d-mode-map ()
   "Keymap used in d-mode buffers.")
 (if d-mode-map
     nil
   (setq d-mode-map (c-make-inherited-keymap))
   ;; Add bindings which are only useful for D
   ;; (define-key d-mode-map "\C-c\C-e"  'd-cool-function)
   )
 
 (c-lang-defconst c-mode-menu
   ;; The definition for the mode menu.  The menu title is prepended to
   ;; this before it's fed to `easy-menu-define'.
   t `(["Comment Out Region"     comment-region
        (c-fn-region-is-active-p)]
       ["Uncomment Region"       (comment-region (region-beginning)
 						(region-end) '(4))
        (c-fn-region-is-active-p)]
       ["Indent Expression"      c-indent-exp
        (memq (char-after) '(?\( ?\[ ?\{))]
       ["Indent Line or Region"  c-indent-line-or-region t]
       ["Fill Comment Paragraph" c-fill-paragraph t]
       "----"
       ["Backward Statement"     c-beginning-of-statement t]
       ["Forward Statement"      c-end-of-statement t]
       "----"
       ("Toggle..."
        ["Syntactic indentation" c-toggle-syntactic-indentation
 	:style toggle :selected c-syntactic-indentation]
        ["Electric mode"         c-toggle-electric-state
 	:style toggle :selected c-electric-flag]
        ["Auto newline"          c-toggle-auto-newline
 	:style toggle :selected c-auto-newline]
        ["Hungry delete"         c-toggle-hungry-state
 	:style toggle :selected c-hungry-delete-key]
        ["Subword mode"          c-subword-mode
 	:style toggle :selected (and (boundp 'c-subword-mode)
                                      c-subword-mode)])))
 
 (easy-menu-define d-menu d-mode-map "D Mode Commands"
   (cons "D" (c-lang-const c-mode-menu d)))
 
 ;;----------------------------------------------------------------------------
 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))
 
 ;;;###autoload
 (defun d-mode ()
   "Major mode for editing code written in the D Programming Language.
 See http://www.digitalmars.com/d for more information about the D language.
 The hook `c-mode-common-hook' is run with no args at mode
 initialization, then `d-mode-hook'.
 
 Key bindings:
 \\{d-mode-map}"
   (interactive)
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table d-mode-syntax-table)
   (setq major-mode 'd-mode
 	mode-name "D"
 	local-abbrev-table d-mode-abbrev-table
 	abbrev-mode t)
   (use-local-map d-mode-map)
   (c-init-language-vars d-mode)
   (c-common-init 'd-mode)
   (easy-menu-add d-menu)
   (c-run-mode-hooks 'c-mode-common-hook 'd-mode-hook)
   (c-update-modeline))
 
 
 (provide 'd-mode)
 
 ;;; d-mode.el ends here

Mar 05 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Charlie wrote:
 Unfortunately the new cc-mode isn't compaitble with the existing 
 php-mode :( , `Symbol's value as variable is void: c-symbol-key`

So stick with the old d-mode. And in the mean time, start bugging whoever maintains the php-mode to update it for cc-mode 5.30. It is rather annoying, though, that the cc-mode folks didn't come up with some solution for maintaining backwards compatibility, like side-by-side installs of both cc-mode versions. When Emacs 22 is officially release with its cc-mode 5.3x, massive numbers of niche, minimally-supported modes are going to break. And php isn't even really niche. --bb
 Charlie
 
 Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.

 For some reason I couldn't get it to show up properly on Wiki4D so I'm 
 attaching it here.

 --bb


 ------------------------------------------------------------------------

 ;;; d-mode.el --- D Programming Language mode for (X)Emacs
 ;;;               Requires a cc-mode of version 5.30 or greater

 ;; Author:     2007 William Baxter
 ;; Maintainer: William Baxter
 ;; Created:    March 2007
 ;; Version:    2.0.0
 ;; Keywords:   D programming language emacs cc-mode

 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; the Free Software Foundation; either version 2 of the License, or
 ;; (at your option) any later version.
 ;; ;; This program is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 ;; ;; You should have received a copy of the GNU General Public License
 ;; along with this program; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.

 ;; Usage: ;; Put these lines in your .emacs startup file.
 ;;   (autoload 'd-mode "d-mode" "Major mode for editing D code." t)
 ;;   (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))
 ;;
 ;; cc-mode version 5.30 or greater is required.
 ;; You can check your cc-mode with the command M-x c-version.
 ;; You can get the latest version of cc-mode at 
 http://cc-mode.sourceforge.net
 ;;
 ;; Commentary:
 ;;   This mode supports most of D's syntax, including nested /+ +/
 ;;   comments and backquote `string literals`.
 ;;   ;;   This mode has been dubbed "2.0" because it is a complete 
 rewrite
 ;;   from scratch.  The previous d-mode was based on cc-mode 5.28 or
 ;;   so.  This version is based on the cc-mode 5.30 derived mode
 ;;   example by Martin Stjernholm, 2002.
 ;;
 ;;
 ;; TODO:
 ;;   * "else static if" doesn't work properly. ;;     (Incidentally 
 "static else if" is fine, but unfortunately it's
 ;;      not valid D syntax.)
 ;;
 ;;   * I tried making "with" "version" and "extern" be their own
 ;;     c-other-block-decl-kwds.  Which is supposed to mean that you
 ;;     can control the indentation on the block following them
 ;;     individually.  It didn't seem to work right though.
 ;;
 ;; History:
 ;;   * 2007 March 3 - Release of 2.0.0 version

 ;;---------------------------------------------------------------------------- 

 ;; Code:

 (require 'cc-mode)

 ;; These are only required at compile time to get the sources for the
 ;; language constants.  (The cc-fonts require and the font-lock
 ;; related constants could additionally be put inside an
 ;; (eval-after-load "font-lock" ...) but then some trickery is
 ;; necessary to get them compiled.)
 ;; Coment out 'when-compile part for debugging
 (eval-when-compile
   (require 'cc-langs)
   (require 'cc-fonts)
 )

 (eval-and-compile
   ;; Make our mode known to the language constant system.  Use Java
   ;; mode as the fallback for the constants we don't change here.
   ;; This needs to be done also at compile time since the language
   ;; constants are evaluated then.
   (c-add-language 'd-mode 'java-mode))

 (c-lang-defconst c-identifier-ops
   ;; For recognizing "~this", ".foo", and "foo.bar.baz" as identifiers
   d '((prefix "~")(prefix ".")(left-assoc ".")))

 (c-lang-defconst c-after-id-concat-ops
   ;; Also for handling ~this
   d '("~"))

 (c-lang-defconst c-string-escaped-newlines
   ;; Set to true to indicate the D handles backslash escaped newlines 
 in strings
   d t)

 (c-lang-defconst c-multiline-string-start-char
   ;; Set to true to indicate that D doesn't mind raw embedded newlines 
 in strings
   d t)

 (c-lang-defconst c-opt-cpp-prefix
   ;; Preprocssor directive recognizer.  D doesn't have cpp, but it has 
 #line
   d "\\s *#\\s *")

 (c-lang-defconst c-cpp-message-directives d nil)
 (c-lang-defconst c-cpp-include-directives d nil)
 (c-lang-defconst c-opt-cpp-macro-define d nil)
 (c-lang-defconst c-cpp-expr-directives d nil)
 (c-lang-defconst c-cpp-expr-functions d nil)

 (c-lang-defconst c-assignment-operators
   ;; List of all assignment operators.
   d  '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" ">>>=" "&=" "^=" "|=" 
 "~="))

 (c-lang-defconst c-other-op-syntax-tokens
   "List of the tokens made up of characters in the punctuation or
 parenthesis syntax classes that have uses other than as expression
 operators."
   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 "*/")

 (c-lang-defconst c-comment-start-regexp  d "/[*+/]")
 (c-lang-defconst c-block-comment-start-regexp d "/[*+]")
 (c-lang-defconst c-literal-start-regexp  ;; Regexp to match the start 
 of comments and string literals.
  d "/[*+/]\\|\"\\|`")

 (c-lang-defconst c-doc-comment-start-regexp
  ;; doc comments for D use "///",  "/**" or doxygen's "/*!" "//!"
  d "/\\(\\*[*!]\\|/[/!]\\)")

 ;;---------------------------------------------------------------------------- 


 ;; Built-in basic types
 (c-lang-defconst c-primitive-type-kwds
   d '("bit" "byte" "ubyte" "char" "delegate" "double" "float" 
 "function"       "int" "long" "ubyte" "short" "uint" "ulong" "ushort" 
 "cent" "ucent"       "real" "ireal" "ifloat" "creal" "cfloat" "cdouble"
       "wchar" "dchar" "void"))

 ;; Keywords that can prefix normal declarations of identifiers
 (c-lang-defconst c-modifier-kwds
   d '("auto" "abstract" "const" "deprecated" "extern"       "final" 
 "lazy" "private" "protected" "public"
       "scope" "static" "synchronized" "volatile" "mixin"))

 (c-lang-defconst c-class-decl-kwds
   ;; Keywords introducing declarations where the following block (if any)
   ;; contains another declaration level that should be considered a 
 class.
   d '("class" "struct" "union" "interface" "template"))

 (c-lang-defconst c-brace-list-decl-kwds
   d '("enum"))

 (c-lang-defconst c-type-modifier-kwds
   d '("const" "lazy" "volatile")
 )
 (c-lang-defconst c-type-prefix-kwds
   ;; Keywords where the following name - if any - is a type name, and
   ;; where the keyword together with the symbol works as a type in
   ;; declarations.  In this case, like "mixin foo!(x) bar;"
   d    '("mixin" "align"))

 ;;(c-lang-defconst c-other-block-decl-kwds
 ;;  ;; Keywords where the following block (if any) contains another
 ;;  ;; declaration level that should not be considered a class.
 ;;  ;; Each of these has associated offsets e.g. ;;  ;;   'with-open', 
 'with-close' and 'inwith' ;;  ;; that can be customized individually
 ;;  ;;   TODO: maybe also do this for 'static if' ?  in/out?
 ;;  ;;   TODO: figure out how to make this work properly
 ;;  d '("with" "version" "extern"))

 (c-lang-defconst c-typedef-decl-kwds
   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"))

 ;;(c-lang-defconst c-postfix-decl-spec-kwds
 ;;  ;Keywords introducing extra declaration specifiers in the region
 ;;  ;between the header and the body (i.e. the "K&R-region") in
 ;;  ;declarations.
 ;;; This doesn't seem to have any effect.  They aren't exactly 
 "K&R-regions".
 ;;  d '("in" "out" "body"))

 (c-lang-defconst c-type-list-kwds
   d '("import"))

 (c-lang-defconst c-ref-list-kwds
   d '("module"))

 (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"))

 (c-lang-defconst c-paren-nontype-kwds
   ;;Keywords that may be followed by a parenthesis expression that 
 doesn't
   ;; contain type identifiers.
   d '("version" "extern"))

 (c-lang-defconst c-paren-type-kwds
   ;; Keywords that may be followed by a parenthesis expression containing
   ;; type identifiers separated by arbitrary tokens.
   d  '("throw"))

 (c-lang-defconst c-block-stmt-1-kwds
   ;; Statement keywords followed directly by a substatement.
   ;; 'static' is there for the "else static if (...) {}" usage.
   d '("do" "else" "finally" "try" "in" "out" "debug" "body"))

 (c-lang-defconst c-block-stmt-2-kwds
   ;; Statement keywords followed by a paren sexp and then by a 
 substatement.
   d '("for" "if" "switch" "while" "catch" "synchronized" "scope"
       "foreach" "foreach_reverse" "with"))

 (c-lang-defconst c-simple-stmt-kwds
   ;; Statement keywords followed by an expression or nothing.
   d '("break" "continue" "goto" "return" "throw"))

 (c-lang-defconst c-paren-stmt-kwds
   ;; Statement keywords followed by a parenthesis expression that
   ;; nevertheless contains a list separated with ';' and not ','."
   d '("for" "foreach" "foreach_reverse"))

 (c-lang-defconst c-asm-stmt-kwds
   ;; Statement keywords followed by an assembler expression.
   d '("asm"))

 (c-lang-defconst c-label-kwds
   ;; Keywords introducing colon terminated labels in blocks.
   d '("case" "default"))

 (c-lang-defconst c-before-label-kwds
   ;; Keywords that might be followed by a label identifier.
   d    '("goto" "break" "continue"))

 (c-lang-defconst c-constant-kwds
   ;; Keywords for constants.
   d '("null" "true" "false"))

 (c-lang-defconst c-primary-expr-kwds
   ;; Keywords besides constants and operators that start primary 
 expressions.
   d '("this" "super"))

 (c-lang-defconst c-inexpr-class-kwds
   ;; Keywords that can start classes inside expressions.
   d    nil)

 (c-lang-defconst c-inexpr-brace-list-kwds
   ;; Keywords that can start brace list blocks inside expressions.
   d    nil)

 (c-lang-defconst c-other-decl-kwds
   d '("module" "import"))

 (c-lang-defconst c-other-kwds
   ;; Keywords not accounted for by any other `*-kwds' language constant.
   d '("assert"))


 (defcustom d-font-lock-extra-types nil
   "*List of extra types (aside from the type keywords) to recognize in 
 D mode.
 Each list item should be a regexp matching a single identifier.")

 (defconst d-font-lock-keywords-1 (c-lang-const c-matchers-1 d)
   "Minimal highlighting for D mode.")

 (defconst d-font-lock-keywords-2 (c-lang-const c-matchers-2 d)
   "Fast normal highlighting for D mode.")

 (defconst d-font-lock-keywords-3 (c-lang-const c-matchers-3 d)
   "Accurate normal highlighting for D mode.")

 (defvar d-font-lock-keywords d-font-lock-keywords-3
   "Default expressions to highlight in D mode.")

 (defvar d-mode-syntax-table nil
   "Syntax table used in d-mode buffers.")
 (or d-mode-syntax-table
     (setq d-mode-syntax-table
      (let ((table (funcall (c-lang-const c-make-mode-syntax-table d))))
        ;; Make it recognize D `backquote strings`
        (modify-syntax-entry ?` "\"" table)

        ;; Make it recognize D's nested /+ +/ comments        
 (modify-syntax-entry ?+  ". 23n"   table)
        table)))

 (defvar d-mode-abbrev-table nil
   "Abbreviation table used in d-mode buffers.")
 (c-define-abbrev-table 'd-mode-abbrev-table
   ;; Use the abbrevs table to trigger indentation actions   ;; on 
 keywords that, if they occur first on a line, might alter the
   ;; syntactic context.
   ;; Syntax for abbrevs is:
   ;; ( pattern replacement command initial-count)
   '(("else" "else" c-electric-continued-statement 0)
     ("while" "while" c-electric-continued-statement 0)
     ("catch" "catch" c-electric-continued-statement 0)
     ("finally" "finally" c-electric-continued-statement 0)))

 (defvar d-mode-map ()
   "Keymap used in d-mode buffers.")
 (if d-mode-map
     nil
   (setq d-mode-map (c-make-inherited-keymap))
   ;; Add bindings which are only useful for D
   ;; (define-key d-mode-map "\C-c\C-e"  'd-cool-function)
   )

 (c-lang-defconst c-mode-menu
   ;; The definition for the mode menu.  The menu title is prepended to
   ;; this before it's fed to `easy-menu-define'.
   t `(["Comment Out Region"     comment-region
        (c-fn-region-is-active-p)]
       ["Uncomment Region"       (comment-region (region-beginning)
                         (region-end) '(4))
        (c-fn-region-is-active-p)]
       ["Indent Expression"      c-indent-exp
        (memq (char-after) '(?\( ?\[ ?\{))]
       ["Indent Line or Region"  c-indent-line-or-region t]
       ["Fill Comment Paragraph" c-fill-paragraph t]
       "----"
       ["Backward Statement"     c-beginning-of-statement t]
       ["Forward Statement"      c-end-of-statement t]
       "----"
       ("Toggle..."
        ["Syntactic indentation" c-toggle-syntactic-indentation
     :style toggle :selected c-syntactic-indentation]
        ["Electric mode"         c-toggle-electric-state
     :style toggle :selected c-electric-flag]
        ["Auto newline"          c-toggle-auto-newline
     :style toggle :selected c-auto-newline]
        ["Hungry delete"         c-toggle-hungry-state
     :style toggle :selected c-hungry-delete-key]
        ["Subword mode"          c-subword-mode
     :style toggle :selected (and (boundp 'c-subword-mode)
                                      c-subword-mode)])))

 (easy-menu-define d-menu d-mode-map "D Mode Commands"
   (cons "D" (c-lang-const c-mode-menu d)))

 ;;---------------------------------------------------------------------------- 

 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))

 ;;;###autoload
 (defun d-mode ()
   "Major mode for editing code written in the D Programming Language.
 See http://www.digitalmars.com/d for more information about the D 
 language.
 The hook `c-mode-common-hook' is run with no args at mode
 initialization, then `d-mode-hook'.

 Key bindings:
 \\{d-mode-map}"
   (interactive)
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table d-mode-syntax-table)
   (setq major-mode 'd-mode
     mode-name "D"
     local-abbrev-table d-mode-abbrev-table
     abbrev-mode t)
   (use-local-map d-mode-map)
   (c-init-language-vars d-mode)
   (c-common-init 'd-mode)
   (easy-menu-add d-menu)
   (c-run-mode-hooks 'c-mode-common-hook 'd-mode-hook)
   (c-update-modeline))

 
 (provide 'd-mode)

 ;;; d-mode.el ends here


Mar 05 2007
parent reply Charlie <charlie.fats gmail.com> writes:
 When Emacs 22 is
 officially release with its cc-mode 5.3x, massive numbers of niche,
 minimally-supported modes are going to break.

Yea , which apparently is right around the corner. I've got a few modes that are probably going to break. I'll let the php-mode guys know. I hope nxml doesn't rely on cc-mode, then I'll be stuck with 21. Charlie Bill Baxter wrote:
 Charlie wrote:
 Unfortunately the new cc-mode isn't compaitble with the existing 
 php-mode :( , `Symbol's value as variable is void: c-symbol-key`

So stick with the old d-mode. And in the mean time, start bugging whoever maintains the php-mode to update it for cc-mode 5.30. It is rather annoying, though, that the cc-mode folks didn't come up with some solution for maintaining backwards compatibility, like side-by-side installs of both cc-mode versions. When Emacs 22 is officially release with its cc-mode 5.3x, massive numbers of niche, minimally-supported modes are going to break. And php isn't even really niche. --bb
 Charlie

 Bill Baxter wrote:
 I made a new emacs mode.
 Here it is.

 For some reason I couldn't get it to show up properly on Wiki4D so 
 I'm attaching it here.

 --bb


 ------------------------------------------------------------------------

 ;;; d-mode.el --- D Programming Language mode for (X)Emacs
 ;;;               Requires a cc-mode of version 5.30 or greater

 ;; Author:     2007 William Baxter
 ;; Maintainer: William Baxter
 ;; Created:    March 2007
 ;; Version:    2.0.0
 ;; Keywords:   D programming language emacs cc-mode

 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; the Free Software Foundation; either version 2 of the License, or
 ;; (at your option) any later version.
 ;; ;; This program is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 ;; ;; You should have received a copy of the GNU General Public License
 ;; along with this program; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.

 ;; Usage: ;; Put these lines in your .emacs startup file.
 ;;   (autoload 'd-mode "d-mode" "Major mode for editing D code." t)
 ;;   (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))
 ;;
 ;; cc-mode version 5.30 or greater is required.
 ;; You can check your cc-mode with the command M-x c-version.
 ;; You can get the latest version of cc-mode at 
 http://cc-mode.sourceforge.net
 ;;
 ;; Commentary:
 ;;   This mode supports most of D's syntax, including nested /+ +/
 ;;   comments and backquote `string literals`.
 ;;   ;;   This mode has been dubbed "2.0" because it is a complete 
 rewrite
 ;;   from scratch.  The previous d-mode was based on cc-mode 5.28 or
 ;;   so.  This version is based on the cc-mode 5.30 derived mode
 ;;   example by Martin Stjernholm, 2002.
 ;;
 ;;
 ;; TODO:
 ;;   * "else static if" doesn't work properly. ;;     (Incidentally 
 "static else if" is fine, but unfortunately it's
 ;;      not valid D syntax.)
 ;;
 ;;   * I tried making "with" "version" and "extern" be their own
 ;;     c-other-block-decl-kwds.  Which is supposed to mean that you
 ;;     can control the indentation on the block following them
 ;;     individually.  It didn't seem to work right though.
 ;;
 ;; History:
 ;;   * 2007 March 3 - Release of 2.0.0 version

 ;;---------------------------------------------------------------------------- 

 ;; Code:

 (require 'cc-mode)

 ;; These are only required at compile time to get the sources for the
 ;; language constants.  (The cc-fonts require and the font-lock
 ;; related constants could additionally be put inside an
 ;; (eval-after-load "font-lock" ...) but then some trickery is
 ;; necessary to get them compiled.)
 ;; Coment out 'when-compile part for debugging
 (eval-when-compile
   (require 'cc-langs)
   (require 'cc-fonts)
 )

 (eval-and-compile
   ;; Make our mode known to the language constant system.  Use Java
   ;; mode as the fallback for the constants we don't change here.
   ;; This needs to be done also at compile time since the language
   ;; constants are evaluated then.
   (c-add-language 'd-mode 'java-mode))

 (c-lang-defconst c-identifier-ops
   ;; For recognizing "~this", ".foo", and "foo.bar.baz" as identifiers
   d '((prefix "~")(prefix ".")(left-assoc ".")))

 (c-lang-defconst c-after-id-concat-ops
   ;; Also for handling ~this
   d '("~"))

 (c-lang-defconst c-string-escaped-newlines
   ;; Set to true to indicate the D handles backslash escaped newlines 
 in strings
   d t)

 (c-lang-defconst c-multiline-string-start-char
   ;; Set to true to indicate that D doesn't mind raw embedded 
 newlines in strings
   d t)

 (c-lang-defconst c-opt-cpp-prefix
   ;; Preprocssor directive recognizer.  D doesn't have cpp, but it 
 has #line
   d "\\s *#\\s *")

 (c-lang-defconst c-cpp-message-directives d nil)
 (c-lang-defconst c-cpp-include-directives d nil)
 (c-lang-defconst c-opt-cpp-macro-define d nil)
 (c-lang-defconst c-cpp-expr-directives d nil)
 (c-lang-defconst c-cpp-expr-functions d nil)

 (c-lang-defconst c-assignment-operators
   ;; List of all assignment operators.
   d  '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" ">>>=" "&=" "^=" "|=" 
 "~="))

 (c-lang-defconst c-other-op-syntax-tokens
   "List of the tokens made up of characters in the punctuation or
 parenthesis syntax classes that have uses other than as expression
 operators."
   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 "*/")

 (c-lang-defconst c-comment-start-regexp  d "/[*+/]")
 (c-lang-defconst c-block-comment-start-regexp d "/[*+]")
 (c-lang-defconst c-literal-start-regexp  ;; Regexp to match the start 
 of comments and string literals.
  d "/[*+/]\\|\"\\|`")

 (c-lang-defconst c-doc-comment-start-regexp
  ;; doc comments for D use "///",  "/**" or doxygen's "/*!" "//!"
  d "/\\(\\*[*!]\\|/[/!]\\)")

 ;;---------------------------------------------------------------------------- 


 ;; Built-in basic types
 (c-lang-defconst c-primitive-type-kwds
   d '("bit" "byte" "ubyte" "char" "delegate" "double" "float" 
 "function"       "int" "long" "ubyte" "short" "uint" "ulong" "ushort" 
 "cent" "ucent"       "real" "ireal" "ifloat" "creal" "cfloat" "cdouble"
       "wchar" "dchar" "void"))

 ;; Keywords that can prefix normal declarations of identifiers
 (c-lang-defconst c-modifier-kwds
   d '("auto" "abstract" "const" "deprecated" "extern"       "final" 
 "lazy" "private" "protected" "public"
       "scope" "static" "synchronized" "volatile" "mixin"))

 (c-lang-defconst c-class-decl-kwds
   ;; Keywords introducing declarations where the following block (if 
 any)
   ;; contains another declaration level that should be considered a 
 class.
   d '("class" "struct" "union" "interface" "template"))

 (c-lang-defconst c-brace-list-decl-kwds
   d '("enum"))

 (c-lang-defconst c-type-modifier-kwds
   d '("const" "lazy" "volatile")
 )
 (c-lang-defconst c-type-prefix-kwds
   ;; Keywords where the following name - if any - is a type name, and
   ;; where the keyword together with the symbol works as a type in
   ;; declarations.  In this case, like "mixin foo!(x) bar;"
   d    '("mixin" "align"))

 ;;(c-lang-defconst c-other-block-decl-kwds
 ;;  ;; Keywords where the following block (if any) contains another
 ;;  ;; declaration level that should not be considered a class.
 ;;  ;; Each of these has associated offsets e.g. ;;  ;;   
 'with-open', 'with-close' and 'inwith' ;;  ;; that can be customized 
 individually
 ;;  ;;   TODO: maybe also do this for 'static if' ?  in/out?
 ;;  ;;   TODO: figure out how to make this work properly
 ;;  d '("with" "version" "extern"))

 (c-lang-defconst c-typedef-decl-kwds
   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"))

 ;;(c-lang-defconst c-postfix-decl-spec-kwds
 ;;  ;Keywords introducing extra declaration specifiers in the region
 ;;  ;between the header and the body (i.e. the "K&R-region") in
 ;;  ;declarations.
 ;;; This doesn't seem to have any effect.  They aren't exactly 
 "K&R-regions".
 ;;  d '("in" "out" "body"))

 (c-lang-defconst c-type-list-kwds
   d '("import"))

 (c-lang-defconst c-ref-list-kwds
   d '("module"))

 (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"))

 (c-lang-defconst c-paren-nontype-kwds
   ;;Keywords that may be followed by a parenthesis expression that 
 doesn't
   ;; contain type identifiers.
   d '("version" "extern"))

 (c-lang-defconst c-paren-type-kwds
   ;; Keywords that may be followed by a parenthesis expression 
 containing
   ;; type identifiers separated by arbitrary tokens.
   d  '("throw"))

 (c-lang-defconst c-block-stmt-1-kwds
   ;; Statement keywords followed directly by a substatement.
   ;; 'static' is there for the "else static if (...) {}" usage.
   d '("do" "else" "finally" "try" "in" "out" "debug" "body"))

 (c-lang-defconst c-block-stmt-2-kwds
   ;; Statement keywords followed by a paren sexp and then by a 
 substatement.
   d '("for" "if" "switch" "while" "catch" "synchronized" "scope"
       "foreach" "foreach_reverse" "with"))

 (c-lang-defconst c-simple-stmt-kwds
   ;; Statement keywords followed by an expression or nothing.
   d '("break" "continue" "goto" "return" "throw"))

 (c-lang-defconst c-paren-stmt-kwds
   ;; Statement keywords followed by a parenthesis expression that
   ;; nevertheless contains a list separated with ';' and not ','."
   d '("for" "foreach" "foreach_reverse"))

 (c-lang-defconst c-asm-stmt-kwds
   ;; Statement keywords followed by an assembler expression.
   d '("asm"))

 (c-lang-defconst c-label-kwds
   ;; Keywords introducing colon terminated labels in blocks.
   d '("case" "default"))

 (c-lang-defconst c-before-label-kwds
   ;; Keywords that might be followed by a label identifier.
   d    '("goto" "break" "continue"))

 (c-lang-defconst c-constant-kwds
   ;; Keywords for constants.
   d '("null" "true" "false"))

 (c-lang-defconst c-primary-expr-kwds
   ;; Keywords besides constants and operators that start primary 
 expressions.
   d '("this" "super"))

 (c-lang-defconst c-inexpr-class-kwds
   ;; Keywords that can start classes inside expressions.
   d    nil)

 (c-lang-defconst c-inexpr-brace-list-kwds
   ;; Keywords that can start brace list blocks inside expressions.
   d    nil)

 (c-lang-defconst c-other-decl-kwds
   d '("module" "import"))

 (c-lang-defconst c-other-kwds
   ;; Keywords not accounted for by any other `*-kwds' language constant.
   d '("assert"))


 (defcustom d-font-lock-extra-types nil
   "*List of extra types (aside from the type keywords) to recognize 
 in D mode.
 Each list item should be a regexp matching a single identifier.")

 (defconst d-font-lock-keywords-1 (c-lang-const c-matchers-1 d)
   "Minimal highlighting for D mode.")

 (defconst d-font-lock-keywords-2 (c-lang-const c-matchers-2 d)
   "Fast normal highlighting for D mode.")

 (defconst d-font-lock-keywords-3 (c-lang-const c-matchers-3 d)
   "Accurate normal highlighting for D mode.")

 (defvar d-font-lock-keywords d-font-lock-keywords-3
   "Default expressions to highlight in D mode.")

 (defvar d-mode-syntax-table nil
   "Syntax table used in d-mode buffers.")
 (or d-mode-syntax-table
     (setq d-mode-syntax-table
      (let ((table (funcall (c-lang-const c-make-mode-syntax-table d))))
        ;; Make it recognize D `backquote strings`
        (modify-syntax-entry ?` "\"" table)

        ;; Make it recognize D's nested /+ +/ comments        
 (modify-syntax-entry ?+  ". 23n"   table)
        table)))

 (defvar d-mode-abbrev-table nil
   "Abbreviation table used in d-mode buffers.")
 (c-define-abbrev-table 'd-mode-abbrev-table
   ;; Use the abbrevs table to trigger indentation actions   ;; on 
 keywords that, if they occur first on a line, might alter the
   ;; syntactic context.
   ;; Syntax for abbrevs is:
   ;; ( pattern replacement command initial-count)
   '(("else" "else" c-electric-continued-statement 0)
     ("while" "while" c-electric-continued-statement 0)
     ("catch" "catch" c-electric-continued-statement 0)
     ("finally" "finally" c-electric-continued-statement 0)))

 (defvar d-mode-map ()
   "Keymap used in d-mode buffers.")
 (if d-mode-map
     nil
   (setq d-mode-map (c-make-inherited-keymap))
   ;; Add bindings which are only useful for D
   ;; (define-key d-mode-map "\C-c\C-e"  'd-cool-function)
   )

 (c-lang-defconst c-mode-menu
   ;; The definition for the mode menu.  The menu title is prepended to
   ;; this before it's fed to `easy-menu-define'.
   t `(["Comment Out Region"     comment-region
        (c-fn-region-is-active-p)]
       ["Uncomment Region"       (comment-region (region-beginning)
                         (region-end) '(4))
        (c-fn-region-is-active-p)]
       ["Indent Expression"      c-indent-exp
        (memq (char-after) '(?\( ?\[ ?\{))]
       ["Indent Line or Region"  c-indent-line-or-region t]
       ["Fill Comment Paragraph" c-fill-paragraph t]
       "----"
       ["Backward Statement"     c-beginning-of-statement t]
       ["Forward Statement"      c-end-of-statement t]
       "----"
       ("Toggle..."
        ["Syntactic indentation" c-toggle-syntactic-indentation
     :style toggle :selected c-syntactic-indentation]
        ["Electric mode"         c-toggle-electric-state
     :style toggle :selected c-electric-flag]
        ["Auto newline"          c-toggle-auto-newline
     :style toggle :selected c-auto-newline]
        ["Hungry delete"         c-toggle-hungry-state
     :style toggle :selected c-hungry-delete-key]
        ["Subword mode"          c-subword-mode
     :style toggle :selected (and (boundp 'c-subword-mode)
                                      c-subword-mode)])))

 (easy-menu-define d-menu d-mode-map "D Mode Commands"
   (cons "D" (c-lang-const c-mode-menu d)))

 ;;---------------------------------------------------------------------------- 

 ;;;###autoload (add-to-list 'auto-mode-alist '("\\.d[i]?\\'" . d-mode))

 ;;;###autoload
 (defun d-mode ()
   "Major mode for editing code written in the D Programming Language.
 See http://www.digitalmars.com/d for more information about the D 
 language.
 The hook `c-mode-common-hook' is run with no args at mode
 initialization, then `d-mode-hook'.

 Key bindings:
 \\{d-mode-map}"
   (interactive)
   (kill-all-local-variables)
   (c-initialize-cc-mode t)
   (set-syntax-table d-mode-syntax-table)
   (setq major-mode 'd-mode
     mode-name "D"
     local-abbrev-table d-mode-abbrev-table
     abbrev-mode t)
   (use-local-map d-mode-map)
   (c-init-language-vars d-mode)
   (c-common-init 'd-mode)
   (easy-menu-add d-menu)
   (c-run-mode-hooks 'c-mode-common-hook 'd-mode-hook)
   (c-update-modeline))

 
 (provide 'd-mode)

 ;;; d-mode.el ends here



Mar 06 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Charlie wrote:
  > When Emacs 22 is
  > officially release with its cc-mode 5.3x, massive numbers of niche,
  > minimally-supported modes are going to break.
 
 Yea , which apparently is right around the corner.  I've got a few modes 
 that are probably going to break.
 
 I'll let the php-mode guys know.
 
 I hope nxml doesn't rely on cc-mode, then I'll be stuck with 21.

I would highly doubt that it does. cc-mode is really only useful as a base for languages that look more or less like C. Curly brace languages in other words. For instance python-mode and the ML mode I've seen are not based on cc-mode because the differences in the languages are too great. I'm sure the difference between C and XML is also too great. --bb
Mar 06 2007
parent reply "Andrei Alexandrescu (See Website For Email)" <SeeWebsiteForEmail erdani.org> writes:
Bill Baxter wrote:
 Charlie wrote:
  > When Emacs 22 is
  > officially release with its cc-mode 5.3x, massive numbers of niche,
  > minimally-supported modes are going to break.

 Yea , which apparently is right around the corner.  I've got a few 
 modes that are probably going to break.

 I'll let the php-mode guys know.

 I hope nxml doesn't rely on cc-mode, then I'll be stuck with 21.

I would highly doubt that it does. cc-mode is really only useful as a base for languages that look more or less like C. Curly brace languages in other words. For instance python-mode and the ML mode I've seen are not based on cc-mode because the differences in the languages are too great. I'm sure the difference between C and XML is also too great.

Suggestion for d-mode.el: add unittest to the list of keywords starting on line 218. Andrei
Mar 28 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Andrei Alexandrescu (See Website For Email) wrote:
 Bill Baxter wrote:
 Charlie wrote:
  > When Emacs 22 is
  > officially release with its cc-mode 5.3x, massive numbers of niche,
  > minimally-supported modes are going to break.

 Yea , which apparently is right around the corner.  I've got a few 
 modes that are probably going to break.

 I'll let the php-mode guys know.

 I hope nxml doesn't rely on cc-mode, then I'll be stuck with 21.

I would highly doubt that it does. cc-mode is really only useful as a base for languages that look more or less like C. Curly brace languages in other words. For instance python-mode and the ML mode I've seen are not based on cc-mode because the differences in the languages are too great. I'm sure the difference between C and XML is also too great.

Suggestion for d-mode.el: add unittest to the list of keywords starting on line 218. Andrei

Actually I think it should go at line 214 with the other "followed-directly-by-a-block" keywords. (a.k.a. "c-block-stmt-1-kwds"). I changed the wiki (which is actually the authoritative version). --bb
Mar 28 2007
parent reply Thomas de Grivel <billitch epita.fr> writes:
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Bill Baxter wrote:
 I changed the wiki (which is actually the authoritative version).

Hi, I patched some strange indentation of class constructor brackets when they are on their own line : I like to type
class Foo
{
  this ()
  {
    ...
  }

  void bar ()
  {
    ...
  }
}

But the wiki's d-mode would give me this
class Foo
{
  this ()
    {
      ...
    }

  void bar ()
  {
    ...
  }
}

Modifying d-mode.el by adding "this" to *c-modifier-kwds* at line 146 fixed it, and even if it does not exactly match the comment, it does not seem to break anything else. I am no D expert yet but I figured I would let you know, and I'm too shy to modify the wiki without prior asking =) -- Thomas de Grivel
May 28 2007
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Thomas de Grivel wrote:
 Bill Baxter wrote:
 I changed the wiki (which is actually the authoritative version).

Hi, I patched some strange indentation of class constructor brackets when they are on their own line : I like to type
 class Foo
 {
  this ()
  {
    ...
  }

  void bar ()
  {
    ...
  }
 }

But the wiki's d-mode would give me this
 class Foo
 {
  this ()
    {
      ...
    }

  void bar ()
  {
    ...
  }
 }

Modifying d-mode.el by adding "this" to *c-modifier-kwds* at line 146 fixed it, and even if it does not exactly match the comment, it does not seem to break anything else. I am no D expert yet but I figured I would let you know, and I'm too shy to modify the wiki without prior asking =)

Hmm, well I'd be more interested in the fix if A) I actually saw the problem in my setup (your code indents fine for me) and B) If you could explain why the fix (pretending it's a c-modifier-kwd) works (which would also help clarify if it will have any unwanted side effects). --bb
Jun 04 2007