[Mono-list] New improved Emacs C# mode

Dennis Haney davh@davh.dk
31 May 2002 20:05:15 +0200


--=-=-=

I have a thing for code who alters every file in the system to get
what they want especially if its completly unnecessary... So I ripped
out all of Brad Merrill's csharp code and put it in a file for
itself.

Please try it out and see if there is any regressions. (I altered the
indention for namespaces a little)

This also has the distinct benefit that cc-mode is again the one you
have installed, instead of the one Brad Merrill supplied you with.

This script is also available on http://davh.dk/script/

Diff below to add link to the documentation, this also renames Merryl
to Merrill, I expect he can spell his name better himself so Merrill
is better...

-- 
Dennis
use Inline C => qq{void p(char*g){printf("Just Another %s Hacker\n",g);}};p("Perl");


--=-=-=
Content-Type: application/emacs-lisp
Content-Disposition: attachment; filename=csharp-mode.el
Content-Description: C-sharp mode for emacs

;;; csharp-mode.el --- csharp-mode

;; Copyright (C) 2002  Free Software Foundation, Inc.

;; Authors: 2002 Dennis Haney <davh@davh.dk>
;;          2000 Brad Merrill <zbrad@cybercom.net>
;; Keywords: c, languages, oop
;; Version: 1.0
;; $Id: csharp-mode.el,v 1.5 2002/05/31 18:03:45 davh Exp $

;; This file 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, or (at your option)
;; any later version.

;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; Version one was ripped from version 3.0 from
;; http://www.cybercom.net/~zbrad/DotNet/Emacs/

;; Newest version of this can be found here:
;; http://davh.dk/script/

;; To activate put his in your .emacs:

;; (autoload 'csharp-mode "csharp-mode" 
;;   "Major mode for editing C# code." t)
;; (setq auto-mode-alist (cons '( "\\.cs\\'" . csharp-mode ) auto-mode-alist ))

;; $Log: csharp-mode.el,v $
;; Revision 1.5  2002/05/31 18:03:45  davh
;; Didnt get Merrills name with :(
;;
;; Revision 1.4  2002/05/31 17:48:00  davh
;; I moved a comment
;;
;; Revision 1.3  2002/05/31 17:45:31  davh
;; Added website 'n log
;;
;; 

;;; Code:

(provide 'csharp-mode)

(require 'cc-mode)

(defconst c-Csharp-extra-toplevel-key "\\(namespace\\)")

(defconst c-Csharp-attrib-key (concat "\[" c-symbol-key "\\(([^)]*)\\)?\]"))

(defconst c-Csharp-class-key
  (concat
  c-Csharp-attrib-key
  "\\(" 
    "\\("
	"new\\|"
	"public\\|"
	"protected\\|"
	"internal\\|"
	"private\\|"
	"abstract\\|"
	"sealed"
    "\\)"
   "\\s +\\)*"
   "\\(struct\\|class\\)\\s +"
   c-symbol-key				;name of the class
   "\\(" 		;maybe followed by parent
	"\\(\\s +:\\s *" c-symbol-key
		"\\(\\s *,\\s *" c-symbol-key "\\)*"
	"\\)*"
   "\\)?"
   ))

(defconst c-Csharp-conditional-key 
  (concat "\\b\\(" 
	  "for\\|if\\|do\\|else\\|while\\|switch"
	  "\\|try\\|catch"
	  "\\|finally"
	  "\\)\\b[^_]"))

(defconst c-Csharp-method-key
  (concat
   "\\(" c-Csharp-attrib-key "\\s *" "\\)?"
   "\\(" "\\("
	"new\\|"
	"public\\|"
	"protected\\|"
	"internal\\|"
	"private\\|"
	"static\\|"
	"virtual\\|"
	"override\\|"
	"abstract\\|"
	"extern"
    "\\)" "\\s +\\)*"
   c-symbol-key "\\s *"
   c-symbol-key "\\([.]" c-symbol-key "\\)*"
   "\\s *\\(([^)]*)\\)"
   ))

(defconst c-Csharp-access-key "\\(public\\|protected\\|internal\\|private\\)")

;
; 3 style of C# comments:
; 1) C block; 2) C++ line comment 3) C# xmldoc format
(defconst c-Csharp-comment-start-regexp "/\\(/[/]?\\|[*][*]?\\)")

(defconst c-Csharp-xmldoc-paragraph-start
  "@\\(remarks\\|summary\\|exception\\|param\\|returns\\|see\\|c\\)")

;; Support for Csharp

(defvar csharp-mode-abbrev-table nil
  "Abbreviation table used in csharp-mode buffers.")
(define-abbrev-table 'csharp-mode-abbrev-table ())

(defvar csharp-mode-map ()
  "Keymap used in csharp-mode buffers.")
(if csharp-mode-map
    nil
  (setq csharp-mode-map (c-make-inherited-keymap))
  ;; add bindings which are only useful for Csharp
  )

(defvar csharp-mode-syntax-table nil
  "Syntax table used in csharp-mode buffers.")
(if csharp-mode-syntax-table
    ()
  (setq csharp-mode-syntax-table (make-syntax-table))
  (c-populate-syntax-table csharp-mode-syntax-table))
;; @keyword can be used
  (modify-syntax-entry ?@ "_" csharp-mode-syntax-table)
;; try to treat "." as part of the sexp
  (modify-syntax-entry ?. "_" csharp-mode-syntax-table)
;; try to treat "." as part of the word
  (modify-syntax-entry ?. "w" csharp-mode-syntax-table)

(easy-menu-define c-csharp-menu csharp-mode-map "C# Mode Commands"
		  (c-mode-menu "C#"))

(defcustom csharp-mode-hook nil
  "*Hook called by `csharp-mode'."
  :type 'hook
  :group 'c)

(defcustom csharp-font-lock-extra-types
  '()
  "*List of extra types to fontify in C# mode.
Each list item should be a regexp not containing word-delimiters.
For example, a value of (\"System\") means the word string is treated as a type
name.

The value of this variable is used when Font Lock mode is turned on."
  :type 'font-lock-extra-types-widget
  :group 'font-lock-extra-types)

(defconst csharp-font-lock-keywords-1 nil
  "Subdued level highlighting for C# mode.")

(defconst csharp-font-lock-keywords-2 nil
  "Medium level highlighting for C# mode.
See also `csharp-font-lock-extra-types'.")

(defconst csharp-font-lock-keywords-3 nil
  "Gaudy level highlighting for C# mode.
See also `csharp-font-lock-extra-types'.")

(let* ((csharp-keywords
	(eval-when-compile
	  (regexp-opt
	   '(
	     "break" "continue" "do" "else" "for" "if" "return" "switch"
	     "while" "catch" "new" "base" "this" "throw" "try" "finally"
	     "explicit" "implicit"
	     "const" "static"
	     "sizeof" "typeof" "checked" "unchecked"
	     "foreach" "lock" "fixed"
;	     "virtual" "override" "abstract" "extern" "internal"
	     ) t)))
       (csharp-operators
	(eval-when-compile
	  (regexp-opt
	   '("+" "-" "*" "/" "%" "^" "&" "|" "~" "!" "=" "<" ">" "+=" "-="
	     "*=" "/=" "%=" "^=" "&=" "|=" "<<" ">>" ">>=" "<<=" "==" "!="
	     "<=" ">=" "&&" "||" "++" "--"))))
       ;;
       ;; Classes immediately followed by an object name.
       (csharp-type-names
	`(mapconcat 'identity
	  (cons 
	   (,@ (eval-when-compile
		 (regexp-opt '("bool" "char" "byte"
			       "short" "int" "long"
			       "ushort" "uint" "ulong" "sbyte"
			       "float" "double" "void"
			       "enum" "string" "delegate" "object"
			       ))))
	   csharp-font-lock-extra-types)
	  "\\|"))
       (csharp-type-names-depth `(regexp-opt-depth (,@ csharp-type-names)))
       ;;
       ;; These are eventually followed by an object name.
       (csharp-type-spec
	(eval-when-compile
	  (regexp-opt
	   '(
	     "public" "private" "protected" "sealed" "internal"
	     "class" "namespace" "enum"
	     "interface"
	     "in" "out" "ref"
	     "virtual" "override" "abstract" "extern" "struct" "using"
	     ))))
       (csharp-type-spec-depth
	(regexp-opt-depth csharp-type-spec))
       )
 (setq csharp-font-lock-keywords-1
  (list
   ;;
   ;; Fontify symbol names in #elif or #if ... defined preprocessor directives.
   '("^#[ \t]*\\(elif\\|if\\|endif\\)\\(\\sw+\\)?"
      (1 font-lock-builtin-face) (3 font-lock-variable-name-face nil t))

   ;; Fontify class names.
   '("\\<\\(class\\|interface\\)\\>[ \t]*\\(\\sw+\\)?"
     (1 font-lock-keyword-face) (2 font-lock-type-face nil t))
   )
  )

 (setq csharp-font-lock-keywords-2
  (append csharp-font-lock-keywords-1
   (list
    ;;
    ;; Fontify class names.
    `(eval .
      (cons (concat "\\<\\(" (,@ csharp-type-names) "\\)\\>")
	    '(1 font-lock-type-face)
	    ))
    ;;
    ;; Fontify operator overloading.
    (list (concat "\\<"
		  "\\(\\(implicit\\|explicit\\)"
		  "[ \t]*operator\\)"
		  "\\>[ \t]*"
		  "\\(" csharp-operators "\\)?")
	  '(1 font-lock-keyword-face)
	  '(2 font-lock-builtin-face nil t))
    ;;
    ;; Fontify all builtin keywords (except below).
    (concat "\\<\\(" csharp-keywords "\\|" csharp-type-spec "\\)\\>")
    ;;
    ;; Fontify keywords and targets, and case default/goto tags.
    (list "\\<\\(break\\|case\\|continue\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
	  '(1 font-lock-keyword-face)
	  '(2 font-lock-constant-face nil t)
	  )
    ;;
    ;; This must come after the one for keywords and targets.
    '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
	   (beginning-of-line) (end-of-line)
	   (1 font-lock-constant-face)
	   ))
    ;;
    ;; Fontify all constants.
    '("\\<\\(false\\|null\\|true\\)\\>" . font-lock-constant-face)
    )))

 (setq csharp-font-lock-keywords-3
  (append csharp-font-lock-keywords-2
   ;;
   ;; More complicated regexps for more complete highlighting for types.
   ;; (Note: Need to revisit the styling here.)
   (list
    ;;
    ;; Fontify random types immediately followed by an item or items.
    `(eval .
      (list (concat "\\<\\(" (,@ csharp-type-names) "\\)\\>"
		    "\\([ \t]*\\[[ \t]*\\]\\)*"
		    "\\([ \t]*\\sw\\)")
	    ;; Fontify each declaration item.
	    (list 'font-lock-match-c-style-declaration-item-and-skip-to-next
		  ;; Start with point after all type specifiers.
		  (list 'goto-char (list 'or
					 (list 'match-beginning
					       (+ (,@ csharp-type-names-depth) 2))
					 '(match-end 1)))
		  ;; Finish with point after first type specifier.
		  '(goto-char (match-end 1))
		  ;; Fontify as a variable or function name.
		  '(1 (if (match-beginning 2)
			  font-lock-function-name-face
			font-lock-variable-name-face)))))
    ;;
    ;; Fontify structures, or typedef names, plus their items.
    '("\\(}\\)[ \t*]*\\sw"
      (font-lock-match-c-style-declaration-item-and-skip-to-next
       (goto-char (match-end 1)) nil
       (1 font-lock-type-face)))
    ;;
    ;; Fontify anything at beginning of line as a declaration or definition.
    '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
      (1 font-lock-type-face)
      (font-lock-match-c-style-declaration-item-and-skip-to-next
       (goto-char (or (match-beginning 2) (match-end 1))) nil
       (1 (if (match-beginning 2)
	      font-lock-function-name-face
	    font-lock-variable-name-face))))
    )))
 )

(defvar csharp-font-lock-keywords csharp-font-lock-keywords-3
  "Default expressions to highlight in C# mode.
See also `csharp-font-lock-extra-types'.")

(defvar cc-imenu-csharp-generic-expression
  cc-imenu-c++-generic-expression
  "Imenu generic expression for C# mode.  See `imenu-generic-expression'.")

(c-add-style "C#"
 '("Java"
   (c-basic-offset . 2)
   (c-comment-only-line-offset . (0 . 0))
   (c-offsets-alist 
    . (
       (c			. c-lineup-C-comments)
       (namespace-open		. 0)
       (namespace-close		. 0)
       (innamespace		. ++)
       (class-open		. +)
       (class-close		. +)
       (inclass			. 0)
       (inline-open		. ++)
       (defun-block-intro	. 0)
       (statement-block-intro	. 0)
       (topmost-intro-cont	. +)
       (statement-block-intro	. +)
       (substatement-open	. +)
       (label			. 0)
       (statement-case-open	. +)
       (statement-cont		. +)
       (arglist-intro		. +)
       (arglist-close		. +)
       (access-label		. 0)
       (inher-cont		. c-lineup-multi-inher)
       ))
   ))


;;;###autoload
(defun csharp-mode ()
  "Major mode for editing C# code.
To submit a problem report, enter `\\[c-submit-bug-report]' from a
csharp-mode buffer.  This automatically sets up a mail buffer with
version information already added.  You just need to add a description
of the problem, including a reproducible test case and send the
message.

To see what version of CC Mode you are running, enter `\\[c-version]'.

The hook variable `csharp-mode-hook' is run with no args, if that value
is bound and has a non-nil value.  Also the common hook
`c-mode-common-hook' is run first.  Note that this mode automatically
sets the \"C#\" style before calling any hooks so be careful if you
set styles in `c-mode-common-hook'.

Key bindings:
\\{csharp-mode-map}"
  (interactive)
  (c-initialize-cc-mode)
  (kill-all-local-variables)
  (set-syntax-table csharp-mode-syntax-table)
  (setq major-mode 'csharp-mode
 	mode-name "C#"
 	local-abbrev-table csharp-mode-abbrev-table)
  (use-local-map csharp-mode-map)
  (c-common-init)
  (setq comment-start "// "
 	comment-end   ""
 	c-conditional-key c-Csharp-conditional-key
 	c-comment-start-regexp c-C++-comment-start-regexp
  	c-class-key c-Csharp-class-key
	c-extra-toplevel-key c-Csharp-extra-toplevel-key
	c-method-key c-Csharp-method-key
 	c-baseclass-key nil
	c-recognize-knr-p nil
 	c-access-key  c-Csharp-access-key
	c-inexpr-class-key nil
	imenu-generic-expression cc-imenu-csharp-generic-expression
	imenu-case-fold-search nil
	)
  ;; Font lock
  (make-local-variable 'font-lock-defaults)
  (setq font-lock-defaults
	'((csharp-font-lock-keywords csharp-font-lock-keywords-1
				     csharp-font-lock-keywords-2 csharp-font-lock-keywords-3)
	  nil nil ((?_ . "w") (?$ . "w")) nil
	  (font-lock-mark-block-function . mark-defun)))
  ;; hocks
  (run-hooks 'c-mode-common-hook)
  (run-hooks 'csharp-mode-hook)
  (c-update-modeline))

;;; csharp-mode.el ends here

--=-=-=
Content-Disposition: attachment
Content-Description: Diff to doc

Index: contributing
===================================================================
RCS file: /mono/mono/doc/contributing,v
retrieving revision 1.24
diff -u -b -B -r1.24 contributing
--- contributing	25 Apr 2002 11:01:55 -0000	1.24
+++ contributing	31 May 2002 18:02:15 -0000
@@ -107,8 +107,11 @@
 
 * Emacs support
 
-	Brad Merryl's C# mode for Emacs is available: <a
+	Brad Merrill's C# mode for Emacs is available: <a
 	href="http://www.cybercom.net/~zbrad/DotNet/Emacs/">http://www.cybercom.net/~zbrad/DotNet/Emacs/</a>
+
+	Dennis Haney's C# mode for Emacs (based on Brad's) is available: <a
+	href="http://www.davh.dk/script/">http://www.davh.dk/script/</a>
 
 * Books on C# and DotNet.
 

--=-=-=--