CSharpMode

This is a major-mode for editing C# files.

The most current version of this package can always be found on github:

It provides an editing mode for C# code and includes code indentation, fontification, codedoc generation, and integration with imenu.el.

Note:

nXhtml includes a slightly modified version of latest csharp-mode.el.

Usage Notes and Hints

Imenu

Imenu support is new for v0.8.3. It indexes the entire .cs buffer and produces a menu of the classes, methods, properties, etc. For large buffers this can cause a delay in opening a file, of several seconds. If you don’t want this, see ‘csharp-want-imenu’ .

Flymake

To use flymake, just open a C# file. If you have flymake loaded (you can do (require ‘flymake) in your csharp-mode-hook fn) then it will automatically start working. The flymake stuff in csharp-mode assumes csc.exe is on your path; if it is not, you can explicitly specify the flymake command to use in code comments, like this:

http://i.imgur.com/28V7e.png

You can run FxCop for your flymake. This is really handy. To do so, you need at least v0.8.3, and you need a comment like this near the top of your file:

// flymake: c:\fxcop\FxCopcmd.exe /c /rid:-Microsoft.Naming#CA1704  /f:Base64stream.dll

All of the issues found by flymake will be highlighted in the buffer.

If you use Flymake - with any language - you may want to check out some complementary stuff.

http://i.imgur.com/SgoLa.png

Neither FlymakeCursor nor RFringe is part of csharp-mode or flymake; they are complementary, add-on things.

Compile

csharp-mode sets the ‘compilation-error-regexp-alist-alist’, so that error messages emitted by csc.exe will be properly handled by next-error and prev-error. The default build command is ‘nmake’ but you can specify it explicitly in each buffer with in-code comments:

// compile: c:\.NET3.5\csc.exe /t:module /r:MyAssembly.dll file.cs

Example:

http://i.imgur.com/28V7e.png

You can replace that compile command with whatever you like. For example:

// compile: msbuild.exe /p:Configuration:Release

YASnippet

yasnippet is a nice snippet expansion package, available elsewhere. csharp-mode defines some snippets automatically for you, and makes them available if you have yasnippet. This means you can type for<TAB> and get a template of a for loop. There are snips for switch statements, properties, while loops, and so on. Pretty handy. You can also define your own snips.

Other tidbits

There’s codedoc support starting with version v0.7.2 (but you should really upgrade to v0.8.?). For the code doc: position point above a method/class, and type three slashes; you will get a codedoc template inserted into the buffer, similar to the effect you may have seen in VisualStudio. Fill-paragraph works as expected in the documentation string; there should be no need to setq paragraph-separate in your csharp-mode hook function. – DinoChiesa

Example:

http://imgur.com/vFvf3.gif

It tries to be smart about which template to insert. If you type 3 slashes after a closing </para>, then you’ll get another set of <para></para> .

http://i44.tinypic.com/zl99bc.jpg

csharp-mode Works with Linum.el :

http://i42.tinypic.com/29pdmjd.jpg


Complementary Stuff / Minor Modes

yasnippet.eldynamically expand snippets, like dabbrev on steroids. How to use yasnippet with C#.
ImenuModeproduce an index of the contents of a C# buffer.
HideShowhide and show regions of code.How to use hideshow.el with C#
FlymakeCsharpnow included with csharp-mode. check syntax more-or-less continually, and use overlays to highlight syntax problems in the code.
FlymakeCursordisplay flymake messages in the minibuffer, automatically, after a delay.
aspx-mode.elmulti-mode for editing ASPX files within emacs. Handles HTML, JS, CSS, and C#.
web-mode.elmulti-mode for editing ASPX/JSP/PHP that also embed JS and CSS.
MSTFSEmacs integration with Team foundation server, via the tf.exe tool
Linum.elline numbers (See local elisp: Lisp:linum-ex.el)
Auto-Revertrefresh .cs buffers, after you’ve edited them externally, for example, in Visual Studio.
code completionCode completion elisp logic, that is integrated with csharp-mode. It runs powershell as an inferior shell within emacs, to dynamically compile code snippets, and then introspect the result to provide realtime (subsecond) code completion in csharp buffers. To get it to work, you need the C# code, and be sure to read the readme. Works only on Windows. Requires Powershell (free). Does not require Visual Studio, or SharpDevelop.
vj-completeIs C# Code Completion in emacs really possible? This is an alternative code completion effort that pre-dates the above.
ide-bridgeC# Code Completion/refactoring/navigation/compilation. Integrates Emacs with SharpDevelop.
Omnisharp-EmacsProvides smart completion, refactoring, finding implementations/usages, eldoc integration and more.

Comments / Remarks / Gripes

With Omnisharp, it's amazing.

I have been using csharp-mode everyday in combination with Omnisharp-Emacs and it has been a joy. I am able to manage large solutions, and do my building from emacs. The code completion, and IDE like features from omnisharp provide little reason to use Visual Studio any longer. The base of csharp-mode is old and not updated, but it handles indenting and fontification and that’s really all I need from it.

Works Well

I currently use csharp-mode 0.7.5, on GNU emacs 22.2, on Windows (Vista). Every day. It works very well.

--DinoChiesa

Regarding Ongoing Maintenance

The mode works well today, but there are plenty of opportunities for improvement. Among them: better codedoc generation - for example automatically emit <param> elements for each parameter.

In May 2010, I put this up on a project hosted on googlecode: https://code.google.com/p/csharpmode/ . If you have requests, file them there. If you have changes you’d like to see added, submit them there.

Also, you can subscribe to updates via Freshmeat. Thanks to Dylan Moonfire for setting that up.

Inclusion into Emacs

An additional idea is to get this included into emacs formally. I think I know how to get started on that. I’m interested in assistance on that as well.

Trouble on Xemacs

I had quite a bit of trouble getting csharp-mode to work under Xemacs. The following lines helped, especially with the file available from http://davh.dk/script/

    ;;; Helpers for building regexps.
    (defmacro c-paren-re (re)
     `(concat "\\(" ,re "\\)"))
    (defmacro c-identifier-re (re)
     `(concat "\\[^_]"))

--JoeHealy


Working with Emacs 21.3.1 but small problem

I’ve got csharp-mode working with Emacs 21.3.1 using cc-mode 5.30.9. However there was a slight problem. In my .emacs file, I had to have the line:

(require 'cc-mode)

appear before:

(autoload 'csharp-mode "csharp-mode" "Major mode for editing C# code." t)
(require 'csharp-mode)

Otherwise, emacs would report the error:

error: "`c-lang-defconst' must be used in a file"

--DarrenSmith


Does not work with Emacs 22.0.50.1?

I’m not able to use csharp-mode working with Emacs 22.0.50.1 and cc-mode 5.31

I get

Eval error in the `c-lang-defconst' for `c-expr-kwds' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-keywords' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-regular-keywords-regexp' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-basic-matchers-before' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-matchers-2' in csharp-mode:
File mode specification error: (void-function c-filter-ops)

Any hint?

Yes, you may want to try removing any byte-compiled cc-mode files (.elc) that are in your emacs main tree (under /lisp/progmodes/cc-*.elc) . That worked for me when I had similar errors (on GNU Emacs 22.0.50.1 winXP)

Grab cc-mode from cvs. They have this issues fixed for cvs emacs.

--AZ


Working with EmacsW32, Emacs 22.0.50.1 but small problems

I just started using csharp-mode with EmacsW32, Emacs version 22.0.50.1. So far so good, with a few minor glitches. Here’s the code I use to set it up in my init:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; C# support

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

;; NOTE: The version of cc-langs.el that came with my Emacs
;; installation has the function c-filter-op defined only at compile
;; time, but it's needed by csharp-mode at run-time. I hacked
;; cc-langs.el and recompiled it to fix this.

;; Patterns for finding Microsoft C# compiler error messages:
(require 'compile)
(push '("^\\(.*\\)(\\([0-9]+\\),\\([0-9]+\\)): error" 1 2 3 2) compilation-error-regexp-alist)
(push '("^\\(.*\\)(\\([0-9]+\\),\\([0-9]+\\)): warning" 1 2 3 1) compilation-error-regexp-alist)

;; Patterns for defining blocks to hide/show:
(push '(csharp-mode
	"\\(^\\s *#\\s *region\\b\\)\\|{"
	"\\(^\\s *#\\s *endregion\\b\\)\\|}"
	"/[*/]"
	nil
	hs-c-like-adjust-block-beginning)
      hs-special-modes-alist)

Thanks for all the helpful comments on this page and elsewhere!

DanMuller

2011 may 18 - For minor glitches, please report them to http://code.google.com/p/csharpmode/issues/list . Also, as of v0.8.2, you do not need to modify the error/warning regexps – these are automatically added by csharp-mode when it starts.

Thanks for pointing out how to do the Hide/Show stuff, I haven’t figured it quite out, but I’ll see if I can add most of that automatically into the mode. Or at least as much as possible.

DylanMoonfire


Working with NTEmacs 21.3 + folding tip

I’m using Moonfire’s mode with NTEmacs version 21.3 and things are working well. I use the following hide-show setup for folding brace-blocks (just like c/c++ mode)

(unless (assoc 'csharp-mode hs-special-modes-alist)
          (push '(csharp-mode
                  "{" "}"
                  "/[*/]"
                  nil
                  hs-c-like-adjust-block-beginning)
                hs-special-modes-alist))

I also wrote a lineup function for multiline strings:

string foo = @"My very long string " +
              "that spans multiple lines.";

Here it is:

(defun csharp-lineup-string-cont (langelem)
  "Like `c-lineup-string-cont' but works with csharp string continuations."
  (save-excursion
    (back-to-indentation)
    (and (looking-at "@?\\s\"")
         (let ((quote (if (equal (char-after) ?@)
                          (char-after (1+ (point)))
                        (char-after)))
               pos)
           (while (and (progn (c-backward-syntactic-ws)
                              (when (eq (char-before) ?+)
                                (backward-char)
                                (c-backward-syntactic-ws))
                              (eq (char-before) quote))
                       (c-safe (c-backward-sexp) t)
                       ;; uncomment this to lineup under the @
                       ;;(progn (if (eq (char-before) ?@) (backward-char)) t)
                       (/= (setq pos (point)) (c-point 'boi))))
           (when pos
             (goto-char pos)
             (vector (current-column)))))))

Use for the statement-cont option in c-offsets-alist. I use it like so:

  (statement-cont . (my-lineup-csharp-string-cont +))

DaveS

2010 October 25. FYI: The v0.7.4 csharp-mode automatically and correctly lines up multiline strings. No external code is necessary.

--DinoChiesa


Problem with TAB

csharp-mode works well, but after it gets loaded (by visiting a csharp file) and switching back to an elisp file (like my config file) I get an error when indenting a line in the elisp file using TAB and it doesn’t indent:

Wrong type argument: stringp, nil

Anyway to fix this?

– Mark A. Nicolosi

v0.7.1 fixes this.

Awesome, that fixed it. Thanks Alex.

– Mark A. Nicolosi

Documentation comment help

In csharp-mode, fill-paragraph does not properly handle documentation comment tags. I modified the paragraph-separate regexp to interpret comment lines that contain only an XML tag as paragraph sepatators. This allows fill-paragraph to be used on text between two doc comment tags so that the tag lines don’t get pulled into the formatting.

I also made a helper function that inserts doc comment skeletons quickly. I’ve bound it (arbitrarily) to C-c C-z.

Here’s the relevant section from my .emacs:

(defun insert-doc-comment-skeleton (tagname arg)
  (c-indent-command)
  (insert (format "/// <%s" tagname))
  (if arg (insert (format " name=\"%s\"" arg)))
  (insert ">")
  (newline-and-indent)
  (insert "///")
  (newline-and-indent)
  (insert (format "/// </%s>" tagname))
  (forward-line -1)
  (end-of-line)
  (insert " "))

(defun insert-doc-comment ()
  (interactive)
  (let ((elem (read-string "Element name? "))
        (arg (read-string "Parameter name? (Leave empty to skip) ")))
    (insert-doc-comment-skeleton elem (if (string= arg "") nil arg))))

(defun my-csharp-mode-hook ()
  ; Interpret the XML tags of C# doc comments as paragraph separators so that
  ; fill-paragraph can be cleanly applied to text between them.
  ; Modified from the initial cc-mode paragraph-separate value:
  ; "[ \t]*\\(//+\\|\\**\\)[ \t]*$\\|^ "
  (setq paragraph-separate "[ \t]*\\(//+\\|\\**\\)[ \t]*\\($\\|<[^>]*>[ \t]*\\)\\|^ ")

  ; XXX: csharp-mode-map doesn't seem to work, c-mode-map does?
  (define-key c-mode-map "\C-c\C-z" 'insert-doc-comment))

(add-hook 'csharp-mode-hook 'my-csharp-mode-hook)

I don’t know why (define-key csharp-mode-map …) doesn’t work but c-mode-map does. Is this a bug?

– Risto Saarelma

As of v0.7.2? code-doc generation is included into csharp-mode; thanks for the idea. – DinoChisa


Load-time error under Emacs 23

Debugger entered--Lisp error: (error "`c-lang-defconst' must be used in a file")
  signal(error ("`c-lang-defconst' must be used in a file"))
  error("`c-lang-defconst' must be used in a file")
  c-define-lang-constant(c-mode-menu ((t cons ["Comment Out Region" comment-region ...] (cons ["Uncomment Region" ... ...] ...))))
  load("cc-langs" nil t)
  (let ((load-path ...)) (load "cc-mode" nil t) (load "cc-fonts" nil t) (load "cc-langs" nil t))
  (progn (let (...) (load "cc-mode" nil t) (load "cc-fonts" nil t) (load "cc-langs" nil t)))
  (eval-when-compile (let (...) (load "cc-mode" nil t) (load "cc-fonts" nil t) (load "cc-langs" nil t)))
  eval-buffer(#<buffer  *load*<2>> nil "/home/rjk/work/random/emacs/csharp-mode.el" nil t)  ; Reading at buffer position 5242
  load-with-code-conversion("/home/rjk/work/random/emacs/csharp-mode.el" "/home/rjk/work/random/emacs/csharp-mode.el" nil t)
  require(csharp-mode)
  eval-buffer(#<buffer  *load*> nil "/home/rjk/.emacs" nil t)  ; Reading at buffer position 174
  load-with-code-conversion("/home/rjk/.emacs" "/home/rjk/.emacs" t t)
  load("~/.emacs" t t)
  #[nil "<binary gunk>" [init-file-user system-type user-init-file-1 user-init-file otherfile source ms-dos "~" "/_emacs" windows-nt directory-files nil "^\\.emacs\\(\\.elc?\\)?$" "~/.emacs" "^_emacs\\(\\.elc?\\)?$" "~/_emacs" "/.emacs" t load expand-file-name "init" file-name-as-directory "/.emacs.d" file-name-extension "elc" file-name-sans-extension ".el" file-exists-p file-newer-than-file-p message "Warning: %s is newer than %s" sit-for 1 "default" alt inhibit-default-init inhibit-startup-screen] 7]()
  command-line()
  normal-top-level()

Emacs version is:

GNU Emacs 23.1.1 (x86_64-pc-linux-gnu, GTK+ Version 2.12.12) of 2009-10-19 on debian-build.int-office-er.priv, modified by Debian

This is still true with csharp-mode 0.7.2.

– Richard Kettlewell.

This is noted in the elisp file:

    ;;   This code doesn't seem to work when you compile it, then
    ;;   load/require in the emacs file. You will get an error (error
    ;;   "`c-lang-defconst' must be used in a file") which happens because
    ;;   cc-mode doesn't think it is in a buffer while loading directly
    ;;   from the init. However, if you call it based on a file extension,
    ;;   it works properly. Interestingly enough, this doesn't happen if
    ;;   you don't byte-compile cc-mode.

I think if you put (require ‘cc-mode) in your .emacs, or possibly at the top of csharp-mode.el, it may solve this problem.

Also see above, where a comment from AZ says that there was a problem fixed in cc-mode to correct this.

RJK: I’ve had (require ‘cc-mode) in my .emacs for ages. I tried the autoload suggestion and the result is:

Loading /home/rjk/work/random/emacs/csharp-mode.el
Loading cc-langs...done
Done loading /home/rjk/work/random/emacs/csharp-mode.el
Eval error in the `c-lang-defconst' for `c-block-prefix-disallowed-chars' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-block-prefix-charset' in csharp-mode:
Eval error in the `c-lang-defvar' or `c-lang-setver' for `c-block-prefix-charset' (source eval): (error "`c-block-prefix-disallowed-chars' got no (prior) value in csharp-mode (might be a cyclic reference)")
Error during redisplay: (wrong-type-argument stringp nil) [3 times]

Also (and this is true in Emacs 22 as well) if I type “/” I get “Wrong number of arguments: =, 3” and a beep. I have to type C-Q / to actually insert a /, which makes writing well-commented code a bit of a struggle!

– Richard Kettlewell.

csharp-mode v0.7.3 now includes a (require ‘cc-mode) at the top. I don’t know if this will fix it for you. Try it. Or try the latest cc-mode.

RJK: As of 0.7.4:

I still get the “error: ‘c-lang-defconst’ must be used in a file” error under Emacs 23. I tried the alternative approach of autoloading but that is also broken, albeit in a different way:

Loading cc-langs...done
Done loading /home/rjk/work/random/emacs/csharp-mode.el
Eval error in the `c-lang-defconst' for `c-block-prefix-disallowed-chars' in csharp-mode:
Eval error in the `c-lang-defconst' for `c-block-prefix-charset' in csharp-mode:
Eval error in the `c-lang-defvar' or `c-lang-setver' for `c-block-prefix-charset' (source eval): (error "`c-block-prefix-disallowed-chars' got no (prior) value in csharp-mode (might be a cyclic reference)")

The bug that ‘/’ wouldn’t insert is fixed, however; thanks.

Emacs version is 23.1.1, cc-mode is 5.31.7, which the comments imply is supported.

Put this in your .emacs

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

And then (on unix):

$: mv /usr/share/emacs/23.1/lisp/progmode/cc-mode.elc /usr/share/emacs/23.1/progmode/cc-mode.elc-bak
$: ungzip /usr/share/emacs/23.1/progmode/cc-mode.el.gz

– Isak Karlsson

VJ Complete and XEmacs

vj-complete does not seem to work with XEmacs.

ide-complete do work under windows only (funny to read that it has to be “ported” to Linux, whereas it’s written in C#!)

--GM/LIAR

Version 0.7.2 & Xemacs

I get a “Symbol’s function definition is void: line number-at-pos” when typing the third ‘/’ in ///

--GM/LIAR

I believe that is fixed in v0.7.4 and later. If still a problem, raise the issue on the googlecode repository. http://code.google.com/p/csharpmode/issues/list

Incorrect indentation

When not setting c-set-style “bsd” the indentation is incorrect for

get {} set {} if {} else {} else if {}

And when set - comments are indented incorrectly.

screenshot:

http://i30.tinypic.com/29da3hj.png

screenshot:

http://i26.tinypic.com/2exuis3.jpg

2010 October 25. Have you set the appropriate offsets with c-set-offset? The pictures here seem to just show code indented according to a particular style. (I don’t see any incorrect indenting of comments, for example) If you don’t like that indenting style you can change the offsets. Would that solve it? If not, in what version of csharp-mode do you see this behavior? There have been some changes in the indentation for v0.7.4, that may fix this for you.

--DinoChiesa

Some History: previous attempts at C# mode

http://mfgames.com/csharp-mode
Work by DylanMoonfire on a derived cc-mode. See these threads on sourceforge [1], [2] for more info. Bug Tracking (Broken link as of December 2009)
The above link was changed to point people to the Google Code page since I’m not working on it anymore. I left the link to the historical releases on the site. There were no reported issues when the bug tracker was shut down at the end of 2009. – DylanMoonfire (November 2010)
http://www.cybercom.net/~zbrad/DotNet/Emacs/
This is the original. It involves changes to a set of standard elisp files. It apparently doesn’t handle @”\” correctly.
http://davh.dk/script/
Is a mod of zbrad’s original. Collects all the changes into a single file. It also doesn’t solve the @”\” problem. [3]
http://csde.sourceforge.net/
Based on JavaDevelopmentEnvironment. Appears to be abandonware. Not sure if this has a C# mode or not.
http://www.devhood.com/tools/tool_details.aspx?tool_id=643
this is just a link to zbrad’s code.
http://www.loveshack.ukfsn.org/emacs/index.html#cc-php-js
A modified CC mode from Emacs 22, with .elcs for Emacs 21. Done by someone who doesn’t use C#, but reported deficiencies will probably get fixed.

CategoryModes ProgrammingModes