emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/csharp-mode 497a70e 009/459: Simplify csharp-mode; elim


From: ELPA Syncer
Subject: [elpa] externals/csharp-mode 497a70e 009/459: Simplify csharp-mode; eliminate flymake-for-csharp.el (unnecessary)
Date: Sun, 22 Aug 2021 13:58:44 -0400 (EDT)

branch: externals/csharp-mode
commit 497a70e0916544f3d4d05626e4d5905267a9c7c9
Author: Dino Chiesa <dpchiesa@hotmail.com>
Commit: Dino Chiesa <dpchiesa@hotmail.com>

    Simplify csharp-mode; eliminate flymake-for-csharp.el (unnecessary)
---
 Readme.txt     |   44 +-
 csharp-mode.el | 3248 +++++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 2285 insertions(+), 1007 deletions(-)

diff --git a/Readme.txt b/Readme.txt
index 888c57f..0a19f30 100644
--- a/Readme.txt
+++ b/Readme.txt
@@ -1,10 +1,10 @@
-Mon, 24 May 2010  17:21
+Created Mon, 24 May 2010  17:21
+Updated Fri, 13 May 2011  13:02
 
 This is the readme for csharp-mode.
 
 You can use csharp-mode alone.  To do so,
 
-
  put this in your .emacs:
 
    (autoload 'csharp-mode "csharp-mode" "Major mode for editing C# code." t)
@@ -28,42 +28,10 @@ You can use csharp-mode alone.  To do so,
 
 =======================================================
 
-You can also take advantage of C# code completion.
-To do so, put csharp-completion.el, csharp-shell.el , and powershell.el
-on your load-path.
-
-You must also have semantic, from the CEDET package, on your load path.
-
-Put the CscompUtilities.dll in the same location as csharp-shell.el.
-
-Put this in your .emacs file:
-
-
-    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    ;; C# code completion (requires CEDET semantic)
-
-    (setq load-path
-          (append '("~/users/dinoch/elisp/cedet/semantic"
-                    "~/users/dinoch/elisp/cedet/semantic/bovine"
-                    "~/users/dinoch/elisp/cedet/common"
-                    "~/users/dinoch/elisp/cedet/eieio"
-                    "~/users/dinoch/elisp/cedet/contrib"
-                    )  load-path ))
-
-    (load "semantic")
-    (load "semantic-load")
-    (load "wisent-csharp")
-
-    (require 'csharp-completion)
-    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-In your csharp-mode-hook, bind a key to the cscomp completion trigger.
-Like this:
-
-         ;; C# code completion
-         (local-set-key "\M-\\"   'cscomp-complete-at-point)
-         (local-set-key "\M-\."   'cscomp-complete-at-point-menu)
+The c# code completion is undergoing  some changes.
+For now, don't use it.
 
+=======================================================
 
+x-URL: http://code.google.com/p/csharpmode/
 
diff --git a/csharp-mode.el b/csharp-mode.el
index 6e2d57d..4389e4c 100644
--- a/csharp-mode.el
+++ b/csharp-mode.el
@@ -3,11 +3,11 @@
 ;; Author     : Dylan R. E. Moonfire (original)
 ;; Maintainer : Dino Chiesa <dpchiesa@hotmail.com>
 ;; Created    : Feburary 2005
-;; Modified   : April 2010
-;; Version    : 0.7.6
+;; Modified   : May 2011
+;; Version    : 0.8.2
 ;; Keywords   : c# languages oop mode
 ;; X-URL      : http://code.google.com/p/csharpmode/
-;; Last-saved : <2010-May-24 21:53:58>
+;; Last-saved : <2011-May-13 11:59:16>
 
 ;;
 ;; This program is free software; you can redistribute it and/or modify
@@ -27,8 +27,9 @@
 
 ;;; Commentary:
 ;;
-;;    This is a separate mode to implement the C# constructs and
-;;    font-locking. It is based on the java-mode example from cc-mode.
+;;    This is a major mode for editing C# code. It performs automatic
+;;    indentation of C# syntax; font locking; integration with compile.el;
+;;    integration with flymake.el; integration with yasnippet.el.
 ;;
 ;;    csharp-mode requires CC Mode 5.30 or later.  It works with
 ;;    cc-mode 5.31.3, which is current at this time.
@@ -47,35 +48,155 @@
 ;;
 ;;   - automagic code-doc generation when you type three slashes.
 ;;
-;;   - intelligent inserttion of matched pairs of curly braces.
+;;   - intelligent insertion of matched pairs of curly braces.
 ;;
-;;   - sets the compiler regex for next-error, for csc.exe output.
+;;   - compile tweaks. Infers the compile command from special comments
+;;     in the file header.  Also, sets the regex for next-error, so that
+;;     compile.el can handle csc.exe output.
 ;;
+;;   - flymake integration
+;;       - select flymake command from code comments
+;;       - infer flymake command otherwise (presence of makefile, etc)
+;;       - Turn off query-on-exit-flag for the flymake process.
+;;       - define advice to flymake-goto-line , to allow it to goto the
+;;         appropriate column for the error on a given line. This works
+;;         with `flymake-goto-next-error' etc.
 ;;
+;;   - yasnippet integration
+;;       - preloaded snippets
+;;       -?
 
-;;; To use:
+
+;; Installation instructions
+;; --------------------------------
 ;;
-;; put this in your .emacs:
+;; Put csharp-mode.el somewhere in your load path, optionally byte-compile
+;; it, and add the following to your .emacs file:
 ;;
 ;;   (autoload 'csharp-mode "csharp-mode" "Major mode for editing C# code." t)
-;;
-;; or:
-;;
-;;   (require 'csharp-mode)
+;;   (setq auto-mode-alist
+;;      (append '(("\\.cs$" . csharp-mode)) auto-mode-alist))
 ;;
 ;;
-;; AND:
+;; Optionally, define and register a mode-hook function. To do so, use
+;; something like this in your .emacs file:
 ;;
-;;   (setq auto-mode-alist
-;;      (append '(("\\.cs$" . csharp-mode)) auto-mode-alist))
 ;;   (defun my-csharp-mode-fn ()
 ;;      "function that runs when csharp-mode is initialized for a buffer."
-;;      ...insert your code here...
-;;      ...most commonly, your custom key bindings ...
+;;      (turn-on-auto-revert-mode)
+;;      (setq indent-tabs-mode nil)
+;;      (require 'flymake)
+;;      (flymake-mode 1)
+;;      (require 'yasnippet)
+;;      (yas/minor-mode-on)
+;;      (require 'rfringe)
+;;      ...insert more code here...
+;;      ...including any custom key bindings you might want ...
 ;;   )
 ;;   (add-hook  'csharp-mode-hook 'my-csharp-mode-fn t)
 ;;
 ;;
+;;  General
+;;  ----------------------------
+;;
+;;  Mostly C# mode will "just work."  Use `describe-mode' to see the
+;;  default keybindings and the highlights of the mode.
+;;
+;;
+;;  Flymake Integration
+;;  ----------------------------
+;;
+;;  You can use flymake with csharp mode to automatically check the
+;;  syntax of your csharp code, and highlight errors.  To do so, add a
+;;  comment line like this to each .cs file that you use flymake with:
+;;
+;;   //  flymake-command: c:\.net3.5\csc.exe /t:module /nologo /R:Foo.dll
+;;
+;;  That lines specifies a command "stub".  Flymake appends the name of
+;;  the file to compile, and then runs the command to check
+;;  syntax. Flymake assumes that syntax errors will be noted in the
+;;  output of the command in a form that fits one of the regexs in the
+;;  `compilation-error-regexp-alist-alist'. Check the flymake module for
+;;  more information on that.
+;;
+;;  Some rules for the command:
+;;
+;;    1. it must appear all on a single line.
+;;
+;;    2. csharp-mode generally looks for the marker line in the first N
+;;       lines of the file, where N is set in
+;;       `csharp-cmd-line-limit'.  See the documentation on that
+;;       variable for more information.
+;;
+;;    3. the command SHOULD NOT include the name of the source file
+;;       currently being edited. This is because flymake saves a copy of
+;;       the buffer into a temporary file with a unique name, and then
+;;       compiles that temporary file. The name of the temporary file is
+;;       automatically appended to the end of the command.  The command
+;;       should include /R options specifying external libraries that
+;;       the code depends on.
+;;
+;;  If you have no external dependencies, then you need not specify any
+;;  flymake-command at all. csharp-mode will implicitly act as ifyou had
+;;  specified the command:
+;;
+;;      // flymake-command: c:\.net3.5\csc.exe /t:module /nologo
+;;
+;;
+;;  If you use csc.exe as the syntax check tool (as almost everyone
+;;  will), the /t:module is important. csharp-mode assumes that the
+;;  syntax-check compile command will produce a file named
+;;  NAME.netmodule, which is the default when using /t:module. (Remember
+;;  than NAME is dynamically generated).  csharp-mode will remove the
+;;  generated netmodule file after the syntax check is complete. If you
+;;  don't specify /t:module, then csharp-mode won't know what file to
+;;  delete.
+;;
+;;  csharp-mode also fiddles with some other flymake things.  In
+;;  particular it: adds .cs to the flymake "allowed filename masks";
+;;  adds parsing for csc error messages; and adds advice to the error
+;;  parsing logic. This all should be pretty benign for all other
+;;  flymake buffers.  But it might not be.
+;;
+;;  You can explicitly turn the flymake integration for C# off by
+;;  setting `csharp-want-flymake-fixup' to nil.
+;;
+;;
+;;  Compile Integration
+;;  ----------------------------
+;;
+;;  csharp-mode binds the function `csharp-invoke-compile-interactively'
+;;  to "\C-x\C-e" .  This function attempts to intellgently guess the
+;;  format of the compile command to use for a buffer.  It looks in the
+;;  comments at the head of the buffer for a line that begins with
+;;  compile: .  If found, csharp-mode suggests the text that follows as
+;;  the compilation command when running `compile' .  If such a line is
+;;  not found, csharp-mode falls back to a msbuild or nmake command.
+;;  See the documentation on `csharp-cmd-line-limit' for further
+;;  information.
+;;
+;;  Also, csharp-mode installs an error regexp for csc.exe into
+;;  `compilation-error-regexp-alist-alist', which allows `next-error'
+;;  and `previous-error' (defined in compile.el) to navigate to the next
+;;  and previous compile errors in the cs buffer, after you've run `compile'.
+;;
+;;
+;;  YASnippet integration
+;;  -----------------------------
+;;
+;;  csharp-mode defines some built-in snippets for
+;;  convenience.  For example, if statements, for, foreach, and
+;;  so on.  You can see them on the YASnippet menu that is displayed
+;;  when a csharp-mode buffer is opened.  csharp-mode defines this
+;;  snippets happens only if ya-snippet is available. (It is done in an
+;;  `eval-after-load' clause.)  The builtin snippets will not overwrite
+;;  snippets that use the same name, if they are defined in the normal
+;;  way (in a compiled bundle) with ya-snippet.
+;;
+;;  You can explicitly turn off ya-snippet integration. See the var,
+;;  `csharp-want-yasnippet-fixup'.
+;;
+;;
 
 ;;; Known Bugs:
 ;;
@@ -162,7 +283,7 @@
 ;;          - intelligent curly-brace insertion
 ;;    0.7.4 - added a C# style
 ;;          - using is now a keyword and gets fontified correctly
-;;          - fixed a bug that had crept into the codedoc insertion
+;;          - fixed a bug that had crept into the codedoc insertion.
 ;;    0.7.5 - now fontify namespaces in the using statements. This is
 ;;            done in the csharp value for c-basic-matchers-before .
 ;;          - also fontify the name following namespace decl.
@@ -174,12 +295,25 @@
 ;;          - Constructors are now fontified.
 ;;          - Field/Prop names inside object initializers are now fontified.
 ;;
-
-
+;;    0.7.7 - relocate running c-run-mode-hooks to the end of
+;;            csharp-mode, to allow user to modify key bindings in a
+;;            hook if he doesn't like the defaults.
 ;;
+;;    0.7.8 - redefine csharp-log to insert timestamp.
+;;
+;;          - Fix byte-compile errors on emacs 23.2 ?  Why was
+;;            c-filter-ops duplicated here?  What is the purpose of its
+;;            presence here, I am not clear.
+;;
+;;    0.8.0 - include flymake magic into this module.
+;;          - include yasnippet integration
+;;
+;;    0.8.2 - small tweaks; now set a one-time bool for flymake installation
+;;          - some doc updates on flymake
 
 
 (require 'cc-mode)
+;;(require 'cl)
 
 (message  (concat "Loading " load-file-name))
 
@@ -188,39 +322,43 @@
 ;; c# upfront stuff
 ;; ==================================================================
 
-;; This is a copy of the function in cc-mode which is used to handle
-;; the eval-when-compile which is needed during other times.
-(defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
-  ;; See cc-langs.el, a direct copy.
-  (unless (listp (car-safe ops))
-    (setq ops (list ops)))
-  (cond ((eq opgroup-filter t)
-         (setq opgroup-filter (lambda (opgroup) t)))
-        ((not (functionp opgroup-filter))
-         (setq opgroup-filter `(lambda (opgroup)
-                                 (memq opgroup ',opgroup-filter)))))
-  (cond ((eq op-filter t)
-         (setq op-filter (lambda (op) t)))
-        ((stringp op-filter)
-         (setq op-filter `(lambda (op)
-                            (string-match ,op-filter op)))))
-  (unless xlate
-    (setq xlate 'identity))
-  (c-with-syntax-table (c-lang-const c-mode-syntax-table)
-    (delete-duplicates
-     (mapcan (lambda (opgroup)
-               (when (if (symbolp (car opgroup))
-                         (when (funcall opgroup-filter (car opgroup))
-                           (setq opgroup (cdr opgroup))
-                           t)
-                       t)
-                 (mapcan (lambda (op)
-                           (when (funcall op-filter op)
-                             (let ((res (funcall xlate op)))
-                               (if (listp res) res (list res)))))
-                         opgroup)))
-             ops)
-     :test 'equal)))
+;; This is a copy of the function in cc-mode which is used to handle the
+;; eval-when-compile which is needed during other times.
+;;
+;; NB: I think this is needed to satisfy requirements when this module
+;; calls `c-lang-defconst'. (DPC)
+
+;; (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
+;;   ;; See cc-langs.el, a direct copy.
+;;   (unless (listp (car-safe ops))
+;;     (setq ops (list ops)))
+;;   (cond ((eq opgroup-filter t)
+;;          (setq opgroup-filter (lambda (opgroup) t)))
+;;         ((not (functionp opgroup-filter))
+;;          (setq opgroup-filter `(lambda (opgroup)
+;;                                  (memq opgroup ',opgroup-filter)))))
+;;   (cond ((eq op-filter t)
+;;          (setq op-filter (lambda (op) t)))
+;;         ((stringp op-filter)
+;;          (setq op-filter `(lambda (op)
+;;                             (string-match ,op-filter op)))))
+;;   (unless xlate
+;;     (setq xlate 'identity))
+;;   (c-with-syntax-table (c-lang-const c-mode-syntax-table)
+;;     (delete-duplicates
+;;      (mapcan (lambda (opgroup)
+;;                (when (if (symbolp (car opgroup))
+;;                          (when (funcall opgroup-filter (car opgroup))
+;;                            (setq opgroup (cdr opgroup))
+;;                            t)
+;;                        t)
+;;                  (mapcan (lambda (op)
+;;                            (when (funcall op-filter op)
+;;                              (let ((res (funcall xlate op)))
+;;                                (if (listp res) res (list res)))))
+;;                          opgroup)))
+;;              ops)
+;;      :test 'equal)))
 
 
 
@@ -229,6 +367,7 @@
 ;; related constants could additionally be put inside an
 ;; (eval-after-load "font-lock" ...) but then some trickery is
 ;; necessary to get them compiled.)
+
 (eval-when-compile
   (let ((load-path
          (if (and (boundp 'byte-compile-dest-file)
@@ -255,9 +394,40 @@
 
 
 ;; ==================================================================
-;; csharp-mode utility and feature defuns
+;; constants used in this module
 ;; ==================================================================
 
+;;(error (byte-compile-dest-file))
+;;(error (c-get-current-file))
+
+(defconst csharp-aspnet-directive-re
+  "<%@.+?%>"
+  "Regex for matching directive blocks in ASP.NET files (.aspx, .ashx, .ascx)")
+
+(defconst csharp-enum-decl-re
+  (concat
+   "\\<enum[ \t\n\r\f\v]+"
+   "\\([[:alpha:]_][[:alnum:]_]*\\)"
+   "[ \t\n\r\f\v]*"
+   "\\(:[ \t\n\r\f\v]*"
+   "\\("
+   (c-make-keywords-re nil
+     (list "sbyte" "byte" "short" "ushort" "int" "uint" "long" "ulong"))
+   "\\)"
+   "\\)?")
+  "Regex that captures an enum declaration in C#"
+  )
+
+;; ==================================================================
+
+
+
+
+
+
+;; ==================================================================
+;; csharp-mode utility and feature defuns
+;; ==================================================================
 
 (defun csharp-at-vsemi-p (&optional pos)
   "Determines if there is a virtual semicolon at POS or point.
@@ -283,7 +453,6 @@ directives.
 Returns t if at a position where a virtual-semicolon is.
 Otherwise nil.
 "
-
   (save-excursion
     (let ((pos-or-point (progn (if pos (goto-char pos)) (point))))
 
@@ -369,6 +538,39 @@ Another option is to use `csharp-lineup-region'.
 
 
 
+  (defun csharp-in-literal (&optional lim detect-cpp)
+    "Return the type of literal point is in, if any.
+Basically this works like `c-in-literal' except it doesn't
+use or fill the cache (`c-in-literal-cache').
+
+The return value is `c' if in a C-style comment, `c++' if in a C++
+style comment, `string' if in a string literal, `pound' if DETECT-CPP
+is non-nil and in a preprocessor line, or nil if somewhere else.
+Optional LIM is used as the backward limit of the search.  If omitted,
+or nil, `c-beginning-of-syntax' is used.
+
+Note that this function might do hidden buffer changes.  See the
+comment at the start of cc-engine.el for more info."
+
+    (let ((rtn
+           (save-excursion
+             (let* ((pos (point))
+                    (lim (or lim (progn
+                                   (c-beginning-of-syntax)
+                                   (point))))
+                    (state (parse-partial-sexp lim pos)))
+               (csharp-log 4 "parse lim(%d) state: %s" lim (prin1-to-string 
state))
+               (cond
+                ((elt state 3)
+                 (csharp-log 4 "in literal string (%d)" pos)
+                 'string)
+                ((elt state 4)
+                 (csharp-log 4 "in literal comment (%d)" pos)
+                 (if (elt state 7) 'c++ 'c))
+                ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
+                (t nil))))))
+      rtn))
+
 
 (defun csharp-insert-open-brace ()
   "Intelligently insert a pair of curly braces. This fn is most
@@ -450,7 +652,7 @@ Another option is to use `csharp-lineup-region'.
         (newline)
         (insert "};")
         (c-indent-region tpoint (point))
-        (previous-line)
+        (forward-line -1)
         (indent-according-to-mode)
         (end-of-line)
         (setq tpoint (point)))
@@ -486,7 +688,7 @@ Another option is to use `csharp-lineup-region'.
         (insert "}")
         ;;(c-indent-command) ;; not sure of the difference here
         (c-indent-line-or-region)
-        (previous-line)
+        (forward-line -1)
         (end-of-line)
         (newline-and-indent)
         ;; point ends up on an empty line, within the braces, properly indented
@@ -501,49 +703,10 @@ Another option is to use `csharp-lineup-region'.
 
 
 
-
-
-
 ;; ==================================================================
 ;; c# values for "language constants" defined in cc-langs.el
 ;; ==================================================================
 
-
-;; Java uses a series of regexes to change the font-lock for class
-;; references. The problem comes in because Java uses Pascal (leading
-;; space in names, SomeClass) for class and package names, but
-;; Camel-casing (initial lowercase, upper case in words,
-;; i.e. someVariable) for variables. The notation suggested by EMCA for C# is
-;; to use Pascal notation for everything, except inner variables. So,
-;; the Java regex and formatting produces very wrong results in C#.
-;;(error (byte-compile-dest-file))
-;;(error (c-get-current-file))
-
-(defconst csharp-aspnet-directive-re
-  "<%@.+?%>"
-  "Regex for matching directive blocks in ASP.NET files (.aspx, .ashx, .ascx)")
-
-(defconst csharp-enum-decl-re
-  (concat
-   "\\<enum[ \t\n\r\f\v]+"
-   "\\([[:alpha:]_][[:alnum:]_]*\\)"
-   "[ \t\n\r\f\v]*"
-   "\\(:[ \t\n\r\f\v]*"
-   "\\("
-   (c-make-keywords-re nil
-     (list "sbyte" "byte" "short" "ushort" "int" "uint" "long" "ulong"))
-   "\\)"
-   "\\)?")
-  "Regex that captures an enum declaration in C#"
-  )
-
-
-
-;; X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+
-
-;; vsemi's allow proper indentation of code that includes inline
-;; attributes and ASPNET directives. These are c#-specific things that
-;; need custom treatment.
 (c-lang-defconst c-at-vsemi-p-fn
   csharp 'csharp-at-vsemi-p)
 
@@ -1052,11 +1215,8 @@ Another option is to use `csharp-lineup-region'.
                                  (c-put-font-lock-face (match-beginning 3)
                                                        (match-end 3)
                                                        
'font-lock-function-name-face))
-                             (goto-char (match-end 0))
-                             )
-                           ))
-                       nil))
-                  )))
+                             (goto-char (match-end 0)))))
+                       nil)))))
 
 
            ;; Case 4: using clause. Without this, using (..) gets fontified as 
a fn.
@@ -1399,9 +1559,7 @@ Another option is to use `csharp-lineup-region'.
 ;; variable here, to provide the regex explicitly.
 ;;
 (c-lang-defconst c-decl-block-key
-
-  csharp 
'"\\(namespace\\)\\([^[:alnum:]_]\\|$\\)\\|\\(class\\|interface\\|struct\\)\\([^[:alnum:]_]\\|$\\)"
-  )
+  csharp 
'"\\(namespace\\)\\([^[:alnum:]_]\\|$\\)\\|\\(class\\|interface\\|struct\\)\\([^[:alnum:]_]\\|$\\)"
 )
 
 
 
@@ -1525,10 +1683,133 @@ Another option is to use `csharp-lineup-region'.
       ;; preprocessor support, so include it.
       (c-lang-const c-cpp-matchers)))
 
-(defcustom csharp-font-lock-extra-types nil
-  "*List of extra types (aside from the type keywords) to recognize in C# mode.
-Each list item should be a regexp matching a single identifier."
-  :type 'list :group 'csharp)
+
+
+;; Custom variables
+;;;###autoload
+(defcustom csharp-mode-hook nil
+    "*Hook called by `csharp-mode'."
+    :type 'hook
+    :group 'csharp)
+
+
+  ;; The following fn allows this:
+  ;;    (csharp-log 3 "scan result...'%s'" state)
+
+  (defcustom csharp-log-level 0
+    "The current log level for CSharp-mode-specific operations.
+This is used in particular by the verbatim-literal
+string scanning.
+
+Most other csharp functions are not instrumented.
+0 = NONE, 1 = Info, 2 = VERBOSE, 3 = DEBUG, 4 = SHUTUP ALREADY. "
+    :type 'integer
+    :group 'csharp)
+
+
+;;;###autoload
+(defcustom csharp-want-flymake-fixup t
+  "*Whether to enable the builtin C# support for flymake. This is meaningful
+only if flymake is loaded."
+  :type 'boolean :group 'csharp)
+
+;;;###autoload
+(defcustom csharp-want-yasnippet-fixup t
+  "*Whether to enable the builtin C# support for yasnippet. This is meaningful
+only if flymake is loaded."
+  :type 'boolean :group 'csharp)
+
+
+;;;###autoload
+(defcustom csharp-make-tool "nmake"
+  "*The make tool to use. Defaults to nmake, found on path. Specify
+a full path or alternative program name, to tell csharp-mode to use
+a different make tool in compile commands.
+
+See also, `csharp-msbuild-tool'.
+
+"
+  :type 'string :group 'csharp)
+
+
+;;;###autoload
+(defcustom csharp-msbuild-tool "msbuild"
+  "*The tool to use to build .csproj files. Defaults to msbuild, found on
+path. Specify a full path or alternative program name, to tell csharp-mode
+to use a different make tool in compile commands.
+
+See also, `csharp-make-tool'.
+
+"
+  :type 'string :group 'csharp)
+
+
+;;;###autoload
+(defcustom csharp-cmd-line-limit 28
+  "The number of lines at the top of the file to look in, to find
+the command that csharp-mode will use to compile the current
+buffer, or the command \"stub\" that csharp-mode will use to
+check the syntax of the current buffer via flymake.
+
+If the value of this variable is zero, then csharp-mode looks
+everywhere in the file.  If the value is positive, then only in
+the first N lines. If negative, then only in the final N lines.
+
+The line should appear in a comment inside the C# buffer.
+
+
+Compile
+--------
+
+In the case of compile, the compile command must be prefixed with
+\"compile:\".  For example,
+
+ // compile: csc.exe /r:Hallo.dll Arfie.cs
+
+
+This command will be suggested as the compile command when the
+user invokes `compile' for the first time.
+
+
+Flymake
+--------
+
+In the case of flymake, the command \"stub\" string must be
+prefixed with \"flymake-command:\".  For example,
+
+  // flymake-command: DOTNETDIR\csc.exe /target:netmodule /r:foo.dll
+
+In the case of flymake-command, the string should NOT
+include the name of the file for the buffer being checked.
+csharp-mode appends the name of the source file to compile, to
+this command \"stub\" before passing the command to flymake to
+run it.
+
+If for some reason the command is invalid or illegal, flymake
+will report an error and disable itself.
+
+
+In all cases
+------------
+
+Be sure to specify the proper path for your csc.exe, whatever
+version that might be, or no path if you want to use the system
+PATH search.
+
+If the buffer depends on external libraries, then you will want
+to include /R arguments to that csc.exe command.
+
+To be clear, this variable sets the number of lines to search for
+the command.  This cariable is an integer.
+
+If the marker string (either \"compile:\" or \"flymake-command:\"
+is present in the given set of lines, csharp-mode will take
+anything after the marker string as the command to run.
+
+"
+  :type 'integer   :group 'csharp)
+
+
 
 (defconst csharp-font-lock-keywords-1 (c-lang-const c-matchers-1 csharp)
   "Minimal highlighting for C# mode.")
@@ -1542,6 +1823,7 @@ Each list item should be a regexp matching a single 
identifier."
 (defvar csharp-font-lock-keywords csharp-font-lock-keywords-3
   "Default expressions to highlight in C# mode.")
 
+
 (defvar csharp-mode-syntax-table nil
   "Syntax table used in csharp-mode buffers.")
 (or csharp-mode-syntax-table
@@ -1565,6 +1847,37 @@ Each list item should be a regexp matching a single 
identifier."
   "Keymap used in csharp-mode buffers.")
 
 
+(defvar csharp--yasnippet-has-been-fixed nil
+  "indicates whether yasnippet has been patched for use with csharp.
+Intended for internal use only.")
+
+(defvar csharp--flymake-has-been-installed  nil
+  "one-time use boolean, to check whether csharp tweaks for flymake (advice 
etc)
+have been installed.")
+
+
+(defvar csharp-flymake-csc-arguments
+  (list "/t:module" "/nologo")
+  "A list of arguments to use with the csc.exe
+compiler, when using flymake with a
+direct csc.exe build for syntax checking purposes.")
+
+
+(defvar csharp-flymake-aux-error-info nil
+  "a list of auxiliary flymake error info items. Each item in the
+list is a pair, consisting of a line number and a column number.
+This info is set by advice to flymake-parse-line, and used by
+advice attached to flymake-goto-line, to navigate to the proper
+error column when possible. ")
+
+
+(defvar csharp-flymake-csc-error-pattern
+  "^[ \t]*\\([_A-Za-z0-9][^(]+\\.cs\\)(\\([0-9]+\\)[,]\\([0-9]+\\)) ?: 
\\(\\(error\\|warning\\) CS[0-9]+:[ \t\n]*\\(.+\\)\\)"
+  "The regex pattern for C# compiler error messages. Follows
+the same form as an entry in `flymake-err-line-patterns'. The
+value is a STRING, a
+regex.")
+
 ;; TODO
 ;; Defines our constant for finding attributes.
 ;;(defconst csharp-attribute-regex "\\[\\([XmlType]+\\)(")
@@ -1585,372 +1898,906 @@ Each list item should be a regexp matching a single 
identifier."
 
 
 
-;; ==================================================================
-;; C# code-doc insertion magic
-;; ==================================================================
-;;
-;; In Visual Studio, if you type three slashes, it immediately expands into
-;; an inline code-documentation fragment.  The following method does the
-;; same thing.
-;;
-;; This is the kind of thing that could be handled by YASnippet or
-;; another similarly flexible snippet framework. But I don't want to
-;; introduce a dependency on yasnippet to csharp-mode. So the capability
-;; must live within csharp-mode itself.
 
-(defun csharp-maybe-insert-codedoc (arg)
+;; ========================================================================
+;; Flymake integration
 
-  "Insert an xml code documentation template as appropriate, when
-typing slashes.  This fn gets bound to / (the slash key), in
-csharp-mode.  If the slash being inserted is not the third
-consecutive slash, the slash is inserted as normal.  If it is the
-third consecutive slash, then a xml code documentation template
-may be inserted in some cases. For example,
+(defun csharp-flymake-init ()
+  (csharp-flymake-init-impl
+   'flymake-create-temp-inplace t t 'csharp-flymake-get-cmdline))
 
-  a <summary> template is inserted if the prior line is empty,
-        or contains only an open curly brace;
-  a <remarks> template is inserted if the prior word
-        closes the <summary> element;
-  a <returns> template is inserted if the prior word
-        closes the <remarks> element;
-  an <example> template is inserted if the prior word closes
-        the <returns> element;
-  a <para> template is inserted if the prior word closes
-        a <para> element.
+(defun csharp-flymake-init-impl (create-temp-f use-relative-base-dir 
use-relative-source get-cmdline-f)
+  "Create syntax check command line for a directly checked source file.
+Use CREATE-TEMP-F for creating temp copy."
+  (let* ((args nil)
+        (temp-source-file-name  (flymake-init-create-temp-buffer-copy 
create-temp-f)))
+    (setq args (flymake-get-syntax-check-program-args
+                temp-source-file-name "."
+                use-relative-base-dir use-relative-source
+                get-cmdline-f))
+    args))
 
-In all other cases the slash is inserted as normal.
 
-If you want the default cc-mode behavior, which implies no automatic
-insertion of xml code documentation templates, then use this in
-your `csharp-mode-hook' function:
+(defun csharp-flymake-cleanup ()
+  "Delete the temporary .netmodule file created in syntax checking
+a C# buffer, then call through to flymake-simple-cleanup."
 
-     (local-set-key (kbd \"/\") 'c-electric-slash)
+  (if flymake-temp-source-file-name
+      (progn
+        (let* ((netmodule-name
+                (concat (file-name-sans-extension 
flymake-temp-source-file-name)
+                        ".netmodule"))
+               (expanded-netmodule-name (expand-file-name netmodule-name ".")))
+          (if (file-exists-p expanded-netmodule-name)
+              (flymake-safe-delete-file expanded-netmodule-name)))
+        ))
+  (flymake-simple-cleanup))
 
- "
-  (interactive "*p")
-  ;;(message "csharp-maybe-insert-codedoc")
-  (let (
-        (cur-point (point))
-        (char last-command-char)
-        (cb0 (char-before (- (point) 0)))
-        (cb1 (char-before (- (point) 1)))
-        is-first-non-whitespace
-        did-auto-insert
-        )
-
-    ;; check if two prior chars were slash
-    (if (and
-         (= char ?/)
-         cb0 (= ?/ cb0)
-         cb1 (= ?/ cb1)
-         )
 
-        (progn
-          ;;(message "yes - this is the third consecutive slash")
-          (setq is-first-non-whitespace
-                (save-excursion
-                  (back-to-indentation)
-                  (= cur-point (+ (point) 2))))
-
-          (if is-first-non-whitespace
-              ;; This is a 3-slash sequence.  It is the first non-whitespace 
text
-              ;; on the line. Now we need to examine the surrounding context
-              ;; in order to determine which xml cod doc template to insert.
-              (let (word-back char0 char1
-                    word-fore char-0 char-1
-                    text-to-insert         ;; text to insert in lieu of slash
-                    fn-to-call     ;; func to call after inserting text
-                    (preceding-line-is-empty (or
-                                              (= (line-number-at-pos) 1)
-                                              (save-excursion
-                                               (previous-line)
-                                               (beginning-of-line)
-                                               (looking-at "[ \t]*$\\|[ \t]*{[ 
\t]*$"))))
-                    (flavor 0) ;; used only for diagnostic purposes
-                    )
+(defun csharp-split-string-respecting-quotes (s)
+  "splits a string into tokens, respecting double quotes
+For example, the string 'This is \"a string\"' will be split into 3 tokens.
 
-                ;;(message "starting a 3-slash comment")
-                ;; get the prior word, and the 2 chars preceding it.
-                (backward-word)
-
-                (setq word-back (thing-at-point 'word)
-                      char0 (char-before (- (point) 0))
-                      char1 (char-before (- (point) 1)))
-
-                ;; restore prior position
-                (goto-char cur-point)
-
-                ;; get the following word, and the 2 chars preceding it.
-                (forward-word)
-                (backward-word)
-                (setq word-fore (thing-at-point 'word)
-                      char-0 (char-before (- (point) 0))
-                      char-1 (char-before (- (point) 1)))
-
-                ;; restore prior position again
-                (goto-char cur-point)
-
-                (cond
-                 ;; The preceding line is empty, or all whitespace, or
-                 ;; contains only an open-curly.  In this case, insert a
-                 ;; summary element pair.
-                 (preceding-line-is-empty
-                  (setq text-to-insert  "/ <summary>\n///   \n/// </summary>"
-                        flavor 1) )
-
-                 ;; The preceding word closed a summary element.  In this case,
-                 ;; if the forward word does not open a remarks element, then
-                 ;; insert a remarks element.
-                 ((and (string-equal word-back "summary") (eq char0 ?/)  (eq 
char1 ?<))
-                  (if (not (and (string-equal word-fore "remarks") (eq char-0 
?<)))
-                      (setq text-to-insert "/ <remarks>\n///   <para>\n///     
\n///   </para>\n/// </remarks>"
-                            flavor 2)))
-
-                 ;; The preceding word closed the remarks section.  In this 
case,
-                 ;; insert an example element.
-                 ((and (string-equal word-back "remarks")  (eq char0 ?/)  (eq 
char1 ?<))
-                  (setq text-to-insert "/ <example>\n///   \n/// </example>"
-                        flavor 3))
-
-                 ;; The preceding word closed the example section.  In this
-                 ;; case, insert an returns element.  This isn't always
-                 ;; correct, because sometimes the xml code doc is attached to
-                 ;; a class or a property, neither of which has a return
-                 ;; value. A more intelligent implementation would inspect the
-                 ;; syntax state and only inject a returns element if
-                 ;; appropriate.
-                 ((and (string-equal word-back "example")  (eq char0 ?/)  (eq 
char1 ?<))
-                  (setq text-to-insert "/ <returns></returns>"
-                        fn-to-call (lambda ()
-                                     (backward-word)
-                                     (backward-char)
-                                     (backward-char)
-                                     (c-indent-line-or-region)
-                                     )
-                        flavor 4))
-
-                 ;; The preceding word opened the remarks section, or it
-                 ;; closed a para section. In this case, insert a para
-                 ;; element, using appropriate indentation with respect to the
-                 ;; prior tag.
-                 ((or
-                   (and (string-equal word-back "remarks")  (eq char0 ?<)  (or 
(eq char1 32) (eq char1 9)))
-                   (and (string-equal word-back "para")     (eq char0 ?/)  (eq 
char1 ?<)))
-
-                  (let (prior-point spacer)
-                    (save-excursion
-                      (backward-word)
-                      (backward-char)
-                      (backward-char)
-                      (setq prior-point (point))
-                      (skip-chars-backward "\t ")
-                      (setq spacer (buffer-substring (point) prior-point))
-                      ;;(message (format "pt(%d) prior(%d) spacer(%s)" (point) 
prior-point spacer))
-                      )
-
-                    (if (string-equal word-back "remarks")
-                        (setq spacer (concat spacer "   ")))
-
-                    (setq text-to-insert (format "/%s<para>\n///%s  
\n///%s</para>"
-                                                 spacer spacer spacer)
-                          flavor 6)))
-
-                 ;; The preceding word opened a para element.  In this case, if
-                 ;; the forward word does not close the para element, then
-                 ;; close the para element.
-                 ;; --
-                 ;; This is a nice idea but flawed.  Suppose I have a para 
element with some
-                 ;; text in it. If I position the cursor at the first line, 
then type 3 slashes,
-                 ;; I get a close-element, and that would be inappropriate.  
Not sure I can
-                 ;; easily solve that problem, so the best thing might be to 
simply punt, and
-                 ;; require people to close their own elements.
-                 ;;
-                 ;;              ( (and (string-equal word-back "para")  (eq 
char0 60)  (or (eq char1 32) (eq char1 9)))
-                 ;;                (if (not (and (string-equal word-fore 
"para") (eq char-0 47) (eq char-1 60) ))
-                 ;;                    (setq text-to-insert "/   \n/// 
</para>\n///"
-                 ;;                          fn-to-call (lambda ()
-                 ;;                                       (previous-line)
-                 ;;                                       (end-of-line)
-                 ;;                                       )
-                 ;;                          flavor 7) )
-                 ;;                )
-
-                 ;; the default case - do nothing
-                 (t nil))
-
-                (if text-to-insert
-                    (progn
-                      ;;(message (format "inserting special text (f(%d))" 
flavor))
+More pertinently, the string
+   'csc /t:module /R:\"c:\abba dabba\dooo\Foo.dll\"'
 
-                      ;; set the flag, that we actually inserted text
-                      (setq did-auto-insert t)
+...will be split into 3 tokens.
 
-                      ;; save point of beginning of insertion
-                      (setq cur-point (point))
+This fn also removes quotes from the tokens that have them. This is for
+compatibility with flymake and the process-start fn.
 
-                      ;; actually insert the text
-                      (insert text-to-insert)
+"
+  (let ((local-s s)
+        (my-re-1 "[^ \"]+\"[^\"]+\"\\|[^ \"]+")
+        (my-re-2 "\\([^ \"]+\\)\"\\([^\"]+\\)\"")
+        (tokens))
+    (while (string-match my-re-1 local-s)
+      (let ((token (match-string 0 local-s))
+            (remainder (substring local-s (match-end 0))))
+        (if (string-match my-re-2 token)
+            (setq token (concat (match-string 1 token) (match-string 2 
token))))
+        ;;(message "token: %s" token)
+        (setq tokens (append tokens (list token)))
+        (setq local-s remainder)))
+    tokens))
 
-                      ;; indent the inserted string, and re-position point, 
either through
-                      ;; the case-specific fn, or via the default progn.
-                      (if fn-to-call
-                          (funcall fn-to-call)
 
-                        (let ((newline-count 0) (pos 0) ix)
+(defun csharp-get-value-from-comments (marker-string line-limit)
+  "gets a string from the header comments in the current buffer.
 
-                          ;; count the number of newlines in the inserted 
string
-                          (while (string-match "\n" text-to-insert pos)
-                            (setq pos (match-end 0)
-                                  newline-count (+ newline-count 1) )
-                            )
+This is used to extract the flymake command and the compile
+command from the comments.
 
-                          ;; indent what we just inserted
-                          (c-indent-region cur-point (point) t)
+It looks for \"marker-string:\" and returns the string that
+follows it, or returns nil if that string is not found.
 
-                          ;; move up n/2 lines. This assumes that the
-                          ;; inserted text is ~symmetric about the halfway 
point.
-                          ;; The assumption holds if the xml code doc uses a
-                          ;; begin-elt and end-elt on a new line all by 
themselves,
-                          ;; and a blank line in between them where the point 
should be.
-                          ;; A more intelligent implementation would use a 
specific
-                          ;; marker string, like @@DOT, to note the desired 
point.
-                          (previous-line (/ newline-count 2))
-                          (end-of-line)))))))))
+eg, when marker-string is \"flymake\", and the following
+string is found at the top of the buffer:
 
-    (if (not did-auto-insert)
-        (self-insert-command (prefix-numeric-value arg)))))
+     flymake: csc.exe /r:Hallo.dll
 
-;; ==================================================================
-;; end of c# code-doc insertion magic
-;; ==================================================================
+...then this command will return the string
 
+     \"csc.exe /r:Hallo.dll\"
 
+It's ok to have whitespace between the marker and the following
+colon.
 
+"
 
-;; ==================================================================
-;; c# fontification extensions
-;; ==================================================================
-;; Commentary:
+  (let (start search-limit found)
+    ;; determine what lines to look in
+    (save-excursion
+      (save-restriction
+        (widen)
+        (cond ((> line-limit 0)
+               (goto-char (setq start (point-min)))
+               (forward-line line-limit)
+               (setq search-limit (point)))
+              ((< line-limit 0)
+               (goto-char (setq search-limit (point-max)))
+               (forward-line line-limit)
+               (setq start (point)))
+              (t                        ;0 => no limit (use with care!)
+               (setq start (point-min))
+               (setq search-limit (point-max))))))
+
+    ;; look in those lines
+    (save-excursion
+      (save-restriction
+        (widen)
+        (let ((re-string
+               (concat "\\b" marker-string "[ \t]*:[ \t]*\\(.+\\)$")))
+          (if (and start
+                   (< (goto-char start) search-limit)
+                   (re-search-forward re-string search-limit 'move))
+
+              (buffer-substring-no-properties
+               (match-beginning 1)
+               (match-end 1))))))))
+
+
+
+
+(defun csharp-replace-command-tokens (explicitly-specified-command)
+  "Replace tokens in the flymake or compile command extracted from the
+buffer, to allow specification of the original and modified
+filenames.
+
+  @@ORIG@@ - gets replaced with the original filename
+  @@FILE@@ - gets replaced with the name of the temporary file
+      created by flymake
+
+"
+  (let ((massaged-command explicitly-specified-command))
+    (if (string-match "@@SRC@@" massaged-command)
+        (setq massaged-command
+              (replace-match
+               (file-relative-name flymake-temp-source-file-name) t t 
massaged-command)))
+    (if (string-match "@@ORIG@@" massaged-command)
+        (setq massaged-command
+              (replace-match
+               (file-relative-name buffer-file-name) t t massaged-command)))
+    massaged-command))
+
+
+;;(setq flymake-log-level 3)
+
+(defun csharp-flymake-get-final-csc-arguments (initial-arglist)
+  "Gets the command used by csc.exe for flymake runs.
+This may inject a /t:module into an arglist, where it is not
+present.
+
+This fn burps if a different /t: argument is found.
+
+"
+  (interactive)
+  (let ((args initial-arglist)
+        arg
+        (found nil))
+    (while args
+      (setq arg (car args))
+      (cond
+       ((string-equal arg "/t:module") (setq found t))
+       ((string-match "^/t:" arg)
+        (setq found t)
+        (message "csharp-mode: WARNING /t: option present in arglist, and not 
/t:module; fix this.")))
+
+      (setq args (cdr args)))
+
+    (setq args
+          (if found
+              initial-arglist
+            (append (list "/t:module") initial-arglist)))
+
+    (if (called-interactively-p 'any)
+        (message "result: %s" (prin1-to-string args)))
+
+    args))
+
+
+(defun csharp-flymake-get-cmdline (source base-dir)
+  "Gets the cmd line for running a flymake session in a C# buffer.
+This gets called by flymake itself.
+
+The fn looks in the buffer for a line that looks like:
+
+  flymake: <command goes here>
+
+  (It should be embedded into a comment)
+
+Typically the command will be a line that runs nmake.exe,
+msbuild.exe, or csc.exe, with various options. It should
+eventually run the CSC.exe compiler, or something else that emits
+error messages in the same form as the C# compiler.
+
+Some notes on implementation:
+
+  1. csharp-mode copies the buffer to a temporary file and
+     compiles *that*.  This temporary file has a different name
+     than the actual file name for the buffer - _flymake gets
+     appended to the basename.  Therefore, you should specify
+     xxx_flymake.cs for the filename, if you want to explicitly
+     refer to it.
+
+     If you want to refer to it implicitly, you can use the special
+     token \"@@SRC@@\" in the command. It will get replaced with the
+     name of the temporary file at runtime. If you want to refer to
+     the original name of the buffer, use @@ORIG@@.
+
+  2. In general, when running the compiler, you should use a
+     target type of \"module\" (eg, /t:module) to allow
+     csharp-mode to clean up the products of the build.
+
+  3. See `csharp-cmd-line-limit' for a way to restrict where
+     csharp-mode will search for the command.
+
+  4. If this string is not found, then this fn will fallback to
+     a generic, generated csc.exe command.
+
+"
+  (let ((explicitly-specified-command
+         (csharp-get-value-from-comments "flymake" csharp-cmd-line-limit)))
+
+    (cond
+     (explicitly-specified-command
+
+      ;; the marker string was found in the buffer
+      (let ((tokens (csharp-split-string-respecting-quotes
+                      (csharp-replace-command-tokens 
explicitly-specified-command))))
+
+        (list (car tokens) (cdr tokens))))
+
+        ;; ;; implicitly append? the name of the temporary source file
+        ;; (list (car tokens) (append (cdr tokens) (list 
flymake-temp-source-file-name)))))
+
+     (t
+      ;; fallback
+      (list "csc.exe"
+            (append (csharp-flymake-get-final-csc-arguments
+                     csharp-flymake-csc-arguments)
+                    (list source)))))))
+
+
+;; (defun csharp-flymake-get-cmdline (source base-dir)
+;;   "Gets the cmd line for running a flymake session in a C# buffer.
+;; This gets called by flymake itself.
+;;
+;; The fn looks in the buffer for a line that looks like:
+;;
+;;   flymake-command: <command goes here>
+;;
+;;   (It should be embedded into a comment)
 ;;
-;; The purpose of the following code is to fix font-lock for C#,
-;; specifically for the verbatim-literal strings. C# is a cc-mode
-;; language and strings are handled mostly like other c-based
-;; languages. The one exception is the verbatim-literal string, which
-;; uses the syntax @"...".
+;; Typically the command will be a line that runs nmake.exe,
+;; msbuild.exe, or cscc.exe, with various options. It should
+;; eventually run the CSC.exe compiler, or something else that emits
+;; error messages in the same form as the C# compiler.
 ;;
-;; `parse-partial-sexp' treats those strings as just regular strings,
-;; with the @ a non-string character.  This is fine, except when the
-;; verblit string ends in a slash, in which case, font-lock breaks from
-;; that point onward in the buffer.
+;; In general, when running the compiler, you should use a target
+;; type of \"module\" (eg, /t:module) to allow csharp-mode to
+;; clean up the products of the build.
 ;;
-;; This is an attempt to fix that.
+;; See `csharp-cmd-line-limit' for a way to restrict where
+;; csharp-mode will search for the command.
 ;;
-;; The idea is to scan the buffer in full for verblit strings, and apply the
-;; appropriate syntax-table text properties for verblit strings. Also setting
-;; `parse-sexp-lookup-properties' to t tells `parse-partial-sexp'
-;; to use the syntax-table text properties set up by the scan as it does
-;; its parse.
+;; If this string is not found, then this fn will fallback to a
+;; generic, generated csc.exe command.
 ;;
-;; Also need to re-scan after any changes in the buffer, but on a more
-;; limited region.
+;; "
+;;   (let ((explicitly-specified-command
+;;          (let ((line-limit csharp-cmd-line-limit)
+;;                start search-limit found)
+;;            ;; determine what lines to look in
+;;            (save-excursion
+;;              (save-restriction
+;;                (widen)
+;;                (cond ((> line-limit 0)
+;;                       (goto-char (setq start (point-min)))
+;;                       (forward-line line-limit)
+;;                       (setq search-limit (point)))
+;;                      ((< line-limit 0)
+;;                       (goto-char (setq search-limit (point-max)))
+;;                       (forward-line line-limit)
+;;                       (setq start (point)))
+;;                      (t                        ;0 => no limit (use with 
care!)
+;;                       (setq start (point-min))
+;;                       (setq search-limit (point-max))))))
 ;;
+;;            ;; look in those lines
+;;            (save-excursion
+;;              (save-restriction
+;;                (widen)
+;;                (if (and start
+;;                         (< (goto-char start) search-limit)
+;;                         (re-search-forward "\\bflymake-command[ \t]*:[ 
\t]*\\(.+\\)$" search-limit 'move))
+;;
+;;                    (buffer-substring-no-properties
+;;                     (match-beginning 1)
+;;                     (match-end 1))))))))
+;;
+;;     (cond
+;;      (explicitly-specified-command
+;;       ;; the marker string was found in the buffer
+;;       (let ((tokens (csharp-split-string-respecting-quotes
+;;                      explicitly-specified-command)))
+;;         ;; implicitly append the name of the temporary source file
+;;         (list (car tokens) (append (cdr tokens) (list 
flymake-temp-source-file-name)))))
+;;
+;;      (t
+;;       ;; fallback
+;;       (list "csc.exe"
+;;             (append (csharp-flymake-get-final-csc-arguments
+;;                      csharp-flymake-csc-arguments)
+;;                     (list source)))))))
 
 
-;; ;; I don't remember what this is supposed to do,
-;; ;; or how I figured out the value.
-;; ;;
-;; (defconst csharp-font-lock-syntactic-keywords
-;;   '(("\\(@\\)\\(\"\\)[^\"]*\\(\"\\)\\(\"\\)[^\"]*\\(\"\\)[^\"]"
-;;      (1 '(6)) (2 '(7)) (3 '(1)) (4 '(1)) (5 '(7))
-;;                  ))
-;;   "Highlighting of verbatim literal strings. See also the variable
-;;   `font-lock-keywords'.")
 
 
 
-;; The following fn allows this:
-;;    (csharp-log 3 "scan result...'%s'" state)
 
-(defvar csharp-log-level 0
-  "The current log level for CSharp-specific operations.
-This is used in particular by the verbatim-literal
-string scanning.
 
-Most other csharp functions are not instrumented.
-0 = NONE, 1 = Info, 2 = VERBOSE, 3 = DEBUG, 4 = SHUTUP ALREADY. ")
 
-(defun csharp-log (level text &rest args)
-  "Log a message at level LEVEL.
+(defun csharp-flymake-install ()
+
+  "Change flymake variables and fns to work with C#.
+
+This fn does these things:
+
+1. add a C# entry to the flymake-allowed-file-name-masks,
+   or replace it if it already exists.
+
+2. add a C# entry to flymake-err-line-patterns.
+   This isn't strictly necessary because of item #4.
+
+3. override the definition for flymake-process-sentinel
+   to NOT check the process status on exit. MSBuild.exe
+   sets a non-zero status code when compile errors occur,
+   which causes flymake to disable itself with the regular
+   flymake-process-sentinel.
+
+4. redefine flymake-start-syntax-check-process to unset the
+   query-on-exit flag for flymake processes. This allows emacs to
+   exit even if flymake is currently running.
+
+5. provide advice to flymake-parse-line and
+   flymake-parse-err-lines, specifically set up for C#
+   buffers. This allows optimized searching for errors in csc.exe
+   output, and storing column numbers, for use in #6.
+
+6. define advice to flymake-goto-line , to allow it to goto the
+   appropriate column for the error on a given line. This advice
+   looks in flymake-er-info, a list, and uses the heuristic that
+   the first error that matches the given line number, is the error
+   we want. This will break if there is more than one error on a
+   single line.
+
+"
+
+  (flymake-log 2 "csharp-flymake-install")
+
+  (or csharp--flymake-has-been-installed
+      (progn
+
+  ;; 1. add a C# entry to the flymake-allowed-file-name-masks
+  (let* ((key "\\.cs\\'")
+         (csharpentry (assoc key flymake-allowed-file-name-masks)))
+    (if csharpentry
+        (setcdr csharpentry '(csharp-flymake-init csharp-flymake-cleanup))
+      (add-to-list
+       'flymake-allowed-file-name-masks
+       (list key 'csharp-flymake-init 'csharp-flymake-cleanup))))
+
+
+  ;; 2. add a C# entry to flymake-err-line-patterns
+  ;;
+  ;; The value of each entry is a list, (STRING IX1 IX2 IX3 IX4), where
+  ;; STRING is the regex, and the other 4 values are indexes into the
+  ;; regex captures for the filename, line, column, and error text,
+  ;; respectively.
+  (add-to-list
+   'flymake-err-line-patterns
+   (list csharp-flymake-csc-error-pattern 1 2 3 4))
+
+
+
+  ;; 3.  override the definition for flymake-process-sentinel
+  ;;
+  ;; DPC - 2011 Feb 26
+  ;; Redefining a function is a bit unusual, but I think it is necessary
+  ;; to remove the check on process exit status.  For VBC.exe, it gives
+  ;; a 1 status when compile errors result. Likewise msbuild.exe.  This
+  ;; means flymake turns itself off, which we don't want. This really
+  ;; ought to be tunable in flymake, but I guess no one asked for that
+  ;; feature yet.
+  (defun flymake-process-sentinel (process event)
+    "Sentinel for syntax check buffers."
+    (when (memq (process-status process) '(signal exit))
+      (let* ((exit-status       (process-exit-status process))
+             (command           (process-command process))
+             (source-buffer     (process-buffer process))
+             (cleanup-f         (flymake-get-cleanup-function 
(buffer-file-name source-buffer))))
+
+        (flymake-log 2 "process %d exited with code %d"
+                     (process-id process) exit-status)
+        (condition-case err
+            (progn
+              (flymake-log 3 "cleaning up using %s" cleanup-f)
+              (when (buffer-live-p source-buffer)
+                (with-current-buffer source-buffer
+                  (funcall cleanup-f)))
+
+              (delete-process process)
+              (setq flymake-processes (delq process flymake-processes))
+
+              (when (buffer-live-p source-buffer)
+                (with-current-buffer source-buffer
+
+                  (flymake-parse-residual)
+                  ;;(flymake-post-syntax-check exit-status command)
+                  (flymake-post-syntax-check 0 command)
+                  (setq flymake-is-running nil))))
+          (error
+           (let ((err-str (format "Error in process sentinel for buffer %s: %s"
+                                  source-buffer (error-message-string err))))
+             (flymake-log 0 err-str)
+             (with-current-buffer source-buffer
+               (setq flymake-is-running nil))))))))
+
+
+  ;; 4. redefine this fn - the reason is to allow exit without query on
+  ;; flymake processes.  Not sure why this is not the default.
+  (defun flymake-start-syntax-check-process (cmd args dir)
+    "Start syntax check process."
+    (let* ((process nil))
+      (condition-case err
+          (progn
+            (when dir
+              (let ((default-directory dir))
+                (flymake-log 3 "starting process on dir %s" 
default-directory)))
+            (setq process (apply 'start-process "flymake-proc" 
(current-buffer) cmd args))
+
+            ;; dino - exit without query on active flymake processes
+            (set-process-query-on-exit-flag process nil)
+
+            (set-process-sentinel process 'flymake-process-sentinel)
+            (set-process-filter process 'flymake-process-filter)
+            (push process flymake-processes)
+
+            (setq flymake-is-running t)
+            (setq flymake-last-change-time nil)
+            (setq flymake-check-start-time (flymake-float-time))
+
+            (flymake-report-status nil "*")
+            (flymake-log 2 "started process %d, command=%s, dir=%s"
+                         (process-id process) (process-command process)
+                         default-directory)
+            process)
+        (error
+         (let* ((err-str (format "Failed to launch syntax check process '%s' 
with args %s: %s"
+                                 cmd args (error-message-string err)))
+                (source-file-name buffer-file-name)
+                (cleanup-f        (flymake-get-cleanup-function 
source-file-name)))
+           (flymake-log 0 err-str)
+           (funcall cleanup-f)
+           (flymake-report-fatal-status "PROCERR" err-str))))))
+
+
+  ;; 5. define some advice for the error parsing
+  (defadvice flymake-parse-err-lines (before
+                                      csharp-flymake-parse-line-patch-1
+                                      activate compile)
+    (if (string-match "\\.[Cc][Ss]$"  (file-relative-name buffer-file-name))
+        ;; clear the auxiliary line information list, when a new parse
+        ;; starts.
+        (setq csharp-flymake-aux-error-info nil)))
+
+  (defadvice flymake-parse-line (around
+                                 csharp-flymake-parse-line-patch-2
+                                 activate compile)
+    ;; This advice will run in all buffers.  Let's may sure we
+    ;; actually execute the important stiff only when a C# buffer is active.
+    (if (string-match "\\.[Cc][Ss]$"  (file-relative-name buffer-file-name))
+
+        (let (raw-file-name
+              e-text
+              result
+              (pattern (list csharp-flymake-csc-error-pattern 1 2 3 4))
+              (line-no 0)
+              (col-no 0)
+              (err-type "e"))
+          (if (string-match (car pattern) line)
+              (let* ((file-idx (nth 1 pattern))
+                     (line-idx (nth 2 pattern))
+                     (col-idx (nth 3 pattern))
+                     (e-idx (nth 4 pattern)))
+                (flymake-log 3 "parse line: fx=%s lx=%s ex=%s"
+                             file-idx line-idx e-idx)
+                (setq raw-file-name (if file-idx (match-string file-idx line) 
nil))
+                (setq line-no       (if line-idx (string-to-number 
(match-string line-idx line)) 0))
+                (setq col-no        (if col-idx  (string-to-number 
(match-string col-idx line)) 0))
+                (setq e-text      (if e-idx
+                                      (match-string e-idx line)
+                                    (flymake-patch-e-text (substring line 
(match-end 0)))))
+                (or e-text (setq e-text "<no error text>"))
+                (if (and e-text (string-match "^[wW]arning" e-text))
+                    (setq err-type "w"))
+                (flymake-log 3 "parse line: fx=%s/%s lin=%s/%s col=%s/%s 
text=%s"
+                             file-idx raw-file-name
+                             line-idx line-no
+                             col-idx (prin1-to-string col-no)
+                             e-text)
+
+                ;; add one entry to the list of auxiliary error information.
+                (add-to-list 'csharp-flymake-aux-error-info
+                             (list line-no col-no))
+
+                (setq ad-return-value
+                      (flymake-ler-make-ler raw-file-name line-no err-type 
e-text nil))
+                )))
+
+      ;; else - not in a C# buffer
+      ad-do-it))
+
+
+  ;; 6. finally, define some advice for the line navigation.  It moves
+  ;; to the proper column, given the line number containing the
+  ;; error. It first calls the normal `flymake-goto-line', and assumes
+  ;; that the result is that the cursor is on the line that contains the
+  ;; error.  At exit from that fn, the column is not important. This advice
+  ;; sets the column.
+  (defadvice flymake-goto-line (around
+                                csharp-flymake-goto-line-patch
+                                activate compile)
+    ;; This advice will run in all buffers.  Let's may sure we
+    ;; actually execute the important stuff only when a C# buffer is active.
+    ad-do-it
+    (if (string-match "\\.[Cc][Ss]$"  (file-relative-name buffer-file-name))
+        (let* ((lno (ad-get-arg 0))
+              (epair (assoc lno csharp-flymake-aux-error-info)))
+          (if epair
+              (forward-char (- (cadr epair) (current-column) 1))))))
+
+
+  ;; 7. finally, set the flag
+  (setq csharp--flymake-has-been-installed t))))
+
+
+
+;; ++++++++++++++++++++++
+
+
+
+
+;; Need to temporarily turn off flymake while reverting.
+;; There' some kind of race-condition where flymake is trying
+;; to compile while the buffer is being changed, and that
+;; causes flymake to choke.
+(defadvice revert-buffer (around
+                          csharp-advise-revert-buffer
+                          activate compile)
+  (let ((is-flymake-enabled
+         (and (fboundp 'flymake-mode)
+              flymake-mode)))
+    ;; disable
+    (if is-flymake-enabled
+        (flymake-mode-off))
+
+    ;; revert
+    ad-do-it
+
+    ;; enable
+    (if is-flymake-enabled
+        (flymake-mode-on))))
+
+
+
+
+  ;; ==================================================================
+  ;; C# code-doc insertion magic
+  ;; ==================================================================
+  ;;
+  ;; In Visual Studio, if you type three slashes, it immediately expands into
+  ;; an inline code-documentation fragment.  The following method does the
+  ;; same thing.
+  ;;
+  ;; This is the kind of thing that could be handled by YASnippet or
+  ;; another similarly flexible snippet framework. But I don't want to
+  ;; introduce a dependency on yasnippet to csharp-mode. So the capability
+  ;; must live within csharp-mode itself.
+
+  (defun csharp-maybe-insert-codedoc (arg)
+
+    "Insert an xml code documentation template as appropriate, when
+typing slashes.  This fn gets bound to / (the slash key), in
+csharp-mode.  If the slash being inserted is not the third
+consecutive slash, the slash is inserted as normal.  If it is the
+third consecutive slash, then a xml code documentation template
+may be inserted in some cases. For example,
+
+  a <summary> template is inserted if the prior line is empty,
+        or contains only an open curly brace;
+  a <remarks> template is inserted if the prior word
+        closes the <summary> element;
+  a <returns> template is inserted if the prior word
+        closes the <remarks> element;
+  an <example> template is inserted if the prior word closes
+        the <returns> element;
+  a <para> template is inserted if the prior word closes
+        a <para> element.
+
+In all other cases the slash is inserted as normal.
+
+If you want the default cc-mode behavior, which implies no automatic
+insertion of xml code documentation templates, then use this in
+your `csharp-mode-hook' function:
+
+     (local-set-key (kbd \"/\") 'c-electric-slash)
+
+ "
+    (interactive "*p")
+    ;;(message "csharp-maybe-insert-codedoc")
+    (let (
+          (cur-point (point))
+          (char last-command-event)
+          (cb0 (char-before (- (point) 0)))
+          (cb1 (char-before (- (point) 1)))
+          is-first-non-whitespace
+          did-auto-insert
+          )
+
+      ;; check if two prior chars were slash, in other words,
+      ;; check if this is the third slash in a row.
+      (if (and (= char ?/) cb0 (= ?/ cb0) cb1 (= ?/ cb1))
+
+          (progn
+            ;;(message "yes - this is the third consecutive slash")
+            (setq is-first-non-whitespace
+                  (save-excursion
+                    (back-to-indentation)
+                    (= cur-point (+ (point) 2))))
+
+            (if is-first-non-whitespace
+                ;; This is a 3-slash sequence.  It is the first non-whitespace 
text
+                ;; on the line. Now we need to examine the surrounding context
+                ;; in order to determine which xml cod doc template to insert.
+                (let (word-back char0 char1
+                                word-fore char-0 char-1
+                                text-to-insert         ;; text to insert in 
lieu of slash
+                                fn-to-call     ;; func to call after inserting 
text
+                                (preceding-line-is-empty (or
+                                                          (= 
(line-number-at-pos) 1)
+                                                          (save-excursion
+                                                            (forward-line -1)
+                                                            (beginning-of-line)
+                                                            (looking-at "[ 
\t]*$\\|[ \t]*{[ \t]*$"))))
+                                (flavor 0) ;; used only for diagnostic purposes
+                                )
+
+                  ;;(message "starting a 3-slash comment")
+                  ;; get the prior word, and the 2 chars preceding it.
+                  (backward-word)
+
+                  (setq word-back (thing-at-point 'word)
+                        char0 (char-before (- (point) 0))
+                        char1 (char-before (- (point) 1)))
+
+                  ;; restore prior position
+                  (goto-char cur-point)
+
+                  ;; get the following word, and the 2 chars preceding it.
+                  (forward-word)
+                  (backward-word)
+                  (setq word-fore (thing-at-point 'word)
+                        char-0 (char-before (- (point) 0))
+                        char-1 (char-before (- (point) 1)))
+
+                  ;; restore prior position again
+                  (goto-char cur-point)
+
+                  (cond
+                   ;; The preceding line is empty, or all whitespace, or
+                   ;; contains only an open-curly.  In this case, insert a
+                   ;; summary element pair.
+                   (preceding-line-is-empty
+                    (setq text-to-insert  "/ <summary>\n///   \n/// </summary>"
+                          flavor 1) )
+
+                   ;; The preceding word closed a summary element.  In this 
case,
+                   ;; if the forward word does not open a remarks element, then
+                   ;; insert a remarks element.
+                   ((and (string-equal word-back "summary") (eq char0 ?/)  (eq 
char1 ?<))
+                    (if (not (and (string-equal word-fore "remarks") (eq 
char-0 ?<)))
+                        (setq text-to-insert "/ <remarks>\n///   <para>\n///   
  \n///   </para>\n/// </remarks>"
+                              flavor 2)))
+
+                   ;; The preceding word closed the remarks section.  In this 
case,
+                   ;; insert an example element.
+                   ((and (string-equal word-back "remarks")  (eq char0 ?/)  
(eq char1 ?<))
+                    (setq text-to-insert "/ <example>\n///   \n/// </example>"
+                          flavor 3))
+
+                   ;; The preceding word closed the example section.  In this
+                   ;; case, insert an returns element.  This isn't always
+                   ;; correct, because sometimes the xml code doc is attached 
to
+                   ;; a class or a property, neither of which has a return
+                   ;; value. A more intelligent implementation would inspect 
the
+                   ;; syntax state and only inject a returns element if
+                   ;; appropriate.
+                   ((and (string-equal word-back "example")  (eq char0 ?/)  
(eq char1 ?<))
+                    (setq text-to-insert "/ <returns></returns>"
+                          fn-to-call (lambda ()
+                                       (backward-word)
+                                       (backward-char)
+                                       (backward-char)
+                                       (c-indent-line-or-region)
+                                       )
+                          flavor 4))
+
+                   ;; The preceding word opened the remarks section, or it
+                   ;; closed a para section. In this case, insert a para
+                   ;; element, using appropriate indentation with respect to 
the
+                   ;; prior tag.
+                   ((or
+                     (and (string-equal word-back "remarks")  (eq char0 ?<)  
(or (eq char1 32) (eq char1 9)))
+                     (and (string-equal word-back "para")     (eq char0 ?/)  
(eq char1 ?<)))
+
+                    (let (prior-point spacer)
+                      (save-excursion
+                        (backward-word)
+                        (backward-char)
+                        (backward-char)
+                        (setq prior-point (point))
+                        (skip-chars-backward "\t ")
+                        (setq spacer (buffer-substring (point) prior-point))
+                        ;;(message (format "pt(%d) prior(%d) spacer(%s)" 
(point) prior-point spacer))
+                        )
+
+                      (if (string-equal word-back "remarks")
+                          (setq spacer (concat spacer "   ")))
+
+                      (setq text-to-insert (format "/%s<para>\n///%s  
\n///%s</para>"
+                                                   spacer spacer spacer)
+                            flavor 6)))
+
+                   ;; The preceding word opened a para element.  In this case, 
if
+                   ;; the forward word does not close the para element, then
+                   ;; close the para element.
+                   ;; --
+                   ;; This is a nice idea but flawed.  Suppose I have a para 
element with some
+                   ;; text in it. If I position the cursor at the first line, 
then type 3 slashes,
+                   ;; I get a close-element, and that would be inappropriate.  
Not sure I can
+                   ;; easily solve that problem, so the best thing might be to 
simply punt, and
+                   ;; require people to close their own elements.
+                   ;;
+                   ;;              ( (and (string-equal word-back "para")  (eq 
char0 60)  (or (eq char1 32) (eq char1 9)))
+                   ;;                (if (not (and (string-equal word-fore 
"para") (eq char-0 47) (eq char-1 60) ))
+                   ;;                    (setq text-to-insert "/   \n/// 
</para>\n///"
+                   ;;                          fn-to-call (lambda ()
+                   ;;                                       (previous-line)
+                   ;;                                       (end-of-line)
+                   ;;                                       )
+                   ;;                          flavor 7) )
+                   ;;                )
+
+                   ;; the default case - do nothing
+                   (t nil))
+
+                  (if text-to-insert
+                      (progn
+                        ;;(message (format "inserting special text (f(%d))" 
flavor))
+
+                        ;; set the flag, that we actually inserted text
+                        (setq did-auto-insert t)
+
+                        ;; save point of beginning of insertion
+                        (setq cur-point (point))
+
+                        ;; actually insert the text
+                        (insert text-to-insert)
+
+                        ;; indent the inserted string, and re-position point, 
either through
+                        ;; the case-specific fn, or via the default progn.
+                        (if fn-to-call
+                            (funcall fn-to-call)
+
+                          (let ((newline-count 0) (pos 0) ix)
+
+                            ;; count the number of newlines in the inserted 
string
+                            (while (string-match "\n" text-to-insert pos)
+                              (setq pos (match-end 0)
+                                    newline-count (+ newline-count 1) )
+                              )
+
+                            ;; indent what we just inserted
+                            (c-indent-region cur-point (point) t)
+
+                            ;; move up n/2 lines. This assumes that the
+                            ;; inserted text is ~symmetric about the halfway 
point.
+                            ;; The assumption holds if the xml code doc uses a
+                            ;; begin-elt and end-elt on a new line all by 
themselves,
+                            ;; and a blank line in between them where the 
point should be.
+                            ;; A more intelligent implementation would use a 
specific
+                            ;; marker string, like @@DOT, to note the desired 
point.
+                            (forward-line (- 0 (/ newline-count 2)))
+                            (end-of-line)))))))))
+
+      (if (not did-auto-insert)
+          (self-insert-command (prefix-numeric-value arg)))))
+
+  ;; ==================================================================
+  ;; end of c# code-doc insertion magic
+  ;; ==================================================================
+
+
+
+
+  ;; ==================================================================
+  ;; c# fontification extensions
+  ;; ==================================================================
+  ;; Commentary:
+  ;;
+  ;; The purpose of the following code is to fix font-lock for C#,
+  ;; specifically for the verbatim-literal strings. C# is a cc-mode
+  ;; language and strings are handled mostly like other c-based
+  ;; languages. The one exception is the verbatim-literal string, which
+  ;; uses the syntax @"...".
+  ;;
+  ;; `parse-partial-sexp' treats those strings as just regular strings,
+  ;; with the @ a non-string character.  This is fine, except when the
+  ;; verblit string ends in a slash, in which case, font-lock breaks from
+  ;; that point onward in the buffer.
+  ;;
+  ;; This is an attempt to fix that.
+  ;;
+  ;; The idea is to scan the buffer in full for verblit strings, and apply the
+  ;; appropriate syntax-table text properties for verblit strings. Also setting
+  ;; `parse-sexp-lookup-properties' to t tells `parse-partial-sexp'
+  ;; to use the syntax-table text properties set up by the scan as it does
+  ;; its parse.
+  ;;
+  ;; Also need to re-scan after any changes in the buffer, but on a more
+  ;; limited region.
+  ;;
+
+
+  ;; ;; I don't remember what this is supposed to do,
+  ;; ;; or how I figured out the value.
+  ;; ;;
+  ;; (defconst csharp-font-lock-syntactic-keywords
+  ;;   '(("\\(@\\)\\(\"\\)[^\"]*\\(\"\\)\\(\"\\)[^\"]*\\(\"\\)[^\"]"
+  ;;      (1 '(6)) (2 '(7)) (3 '(1)) (4 '(1)) (5 '(7))
+  ;;                  ))
+  ;;   "Highlighting of verbatim literal strings. See also the variable
+  ;;   `font-lock-keywords'.")
+
+
+
+  (defun csharp-time ()
+    "returns the time of day as a string.  Used in the `csharp-log' function."
+    (substring (current-time-string) 11 19)) ;24-hr time
+
+
+  (defun csharp-log (level text &rest args)
+    "Log a message at level LEVEL.
 If LEVEL is higher than `csharp-log-level', the message is
 ignored.  Otherwise, it is printed using `message'.
 TEXT is a format control string, and the remaining arguments ARGS
 are the string substitutions (see `format')."
-  (if (<= level csharp-log-level)
-      (let* ((msg (apply 'format text args)))
-        (message "C#: %s" msg))
-    t))
+    (if (<= level csharp-log-level)
+        (let* ((msg (apply 'format text args)))
+          (message "C# %s %s" (cscomp-time) msg))))
 
 
 
-(defun csharp-max-beginning-of-stmt ()
-  "Return the greater of `c-beginning-of-statement-1' and
+  (defun csharp-max-beginning-of-stmt ()
+    "Return the greater of `c-beginning-of-statement-1' and
 `c-beginning-of-statement' .  I don't understand why both of
 these methods are necessary or why they differ. But they do."
 
-  (let (dash
-        nodash
-        (curpos (point)))
+    (let (dash
+          nodash
+          (curpos (point)))
 
-    ;; I think this may need a save-excursion...
-    ;; Calling c-beginning-of-statement-1 resets the point!
+      ;; I think this may need a save-excursion...
+      ;; Calling c-beginning-of-statement-1 resets the point!
 
-    (setq dash (progn (c-beginning-of-statement-1) (point)))
-    (csharp-log 3 "max-bostmt dash(%d)" dash)
-    (goto-char curpos)
+      (setq dash (progn (c-beginning-of-statement-1) (point)))
+      (csharp-log 3 "max-bostmt dash(%d)" dash)
+      (goto-char curpos)
 
-    (setq nodash (progn (c-beginning-of-statement 1) (point)))
-    (csharp-log 3 "max-bostmt nodash(%d)" nodash)
-    (goto-char curpos)
+      (setq nodash (progn (c-beginning-of-statement 1) (point)))
+      (csharp-log 3 "max-bostmt nodash(%d)" nodash)
+      (goto-char curpos)
 
-    (max dash nodash)))
+      (max dash nodash)))
 
 
-(defun csharp-in-literal (&optional lim detect-cpp)
-  "Return the type of literal point is in, if any.
-Basically this works like `c-in-literal' except it doesn't
-use or fill the cache (`c-in-literal-cache').
 
-The return value is `c' if in a C-style comment, `c++' if in a C++
-style comment, `string' if in a string literal, `pound' if DETECT-CPP
-is non-nil and in a preprocessor line, or nil if somewhere else.
-Optional LIM is used as the backward limit of the search.  If omitted,
-or nil, `c-beginning-of-syntax' is used.
 
-Note that this function might do hidden buffer changes.  See the
-comment at the start of cc-engine.el for more info."
 
-  (let ((rtn
-        (save-excursion
-          (let* ((pos (point))
-                 (lim (or lim (progn
-                                (c-beginning-of-syntax)
-                                (point))))
-                 (state (parse-partial-sexp lim pos)))
-            (csharp-log 4 "parse lim(%d) state: %s" lim (prin1-to-string 
state))
-            (cond
-             ((elt state 3)
-              (csharp-log 4 "in literal string (%d)" pos)
-              'string)
-             ((elt state 4)
-              (csharp-log 4 "in literal comment (%d)" pos)
-              (if (elt state 7) 'c++ 'c))
-             ((and detect-cpp (c-beginning-of-macro lim)) 'pound)
-             (t nil))))))
-    rtn))
-
-
-(defun csharp-set-vliteral-syntax-table-properties (beg end)
-  "Scan the buffer text between BEG and END, a verbatim literal
+  (defun csharp-set-vliteral-syntax-table-properties (beg end)
+    "Scan the buffer text between BEG and END, a verbatim literal
 string, setting and clearing syntax-table text properties where
 necessary.
 
@@ -1965,72 +2812,72 @@ for the list of syntax table numeric codes.
 
 "
 
-  (csharp-log 3 "set-vlit-syntax-table:  beg(%d) end(%d)" beg end)
+    (csharp-log 3 "set-vlit-syntax-table:  beg(%d) end(%d)" beg end)
 
-  (if (and (> beg 0) (> end 0))
+    (if (and (> beg 0) (> end 0))
 
-      (let ((curpos beg)
-            (state 0))
+        (let ((curpos beg)
+              (state 0))
 
-        (c-clear-char-properties beg end 'syntax-table)
+          (c-clear-char-properties beg end 'syntax-table)
 
-        (while (<= curpos end)
+          (while (<= curpos end)
 
-          (cond
-           ((= state 0)
-            (if (= (char-after curpos) ?@)
-                (progn
-                  (c-put-char-property curpos 'syntax-table '(6)) ; (6) = 
expression prefix, (3) = symbol
-                  ;;(message (format "set-s-t: prefix pos(%d) chr(%c)" beg 
(char-after beg)))
-                  )
-              )
-            (setq state (+ 1 state)))
-
-           ((= state 1)
-            (if (= (char-after curpos) ?\")
-                (progn
-                  (c-put-char-property curpos 'syntax-table '(7)) ; (7) = 
string quote
-                  ;;(message (format "set-s-t: open quote pos(%d) chr(%c)"
-                  ;; curpos (char-after curpos)))
-                  ))
-            (setq state (+ 1 state)))
-
-           ((= state 2)
             (cond
-             ;; handle backslash inside the string
-             ((= (char-after curpos) ?\\)
-              (c-put-char-property curpos 'syntax-table '(2)) ; (1) = 
punctuation, (2) = word
-              ;;(message (format "set-s-t: backslash word pos(%d) chr(%c)" 
curpos (char-after curpos)))
-              )
-
-             ;; doubled double-quote
-             ((and
-               (= (char-after curpos) ?\")
-               (= (char-after (+ 1 curpos)) ?\"))
-              (c-put-char-property curpos 'syntax-table '(2)) ; (1) = 
punctuation, (2) = word
-              (c-put-char-property (+ 1 curpos) 'syntax-table '(2)) ; (1) = 
punctuation
-              ;;(message (format "set-s-t: double doublequote pos(%d) chr(%c)" 
curpos (char-after curpos)))
-              (setq curpos (+ curpos 1))
-              )
-
-             ;; a single double-quote, which should be a string terminator
-             ((= (char-after curpos) ?\")
-              (c-put-char-property curpos 'syntax-table '(7)) ; (7) = string 
quote
-              ;;(message (format "set-s-t: close quote pos(%d) chr(%c)" curpos 
(char-after curpos)))
-              ;;go no further
+             ((= state 0)
+              (if (= (char-after curpos) ?@)
+                  (progn
+                    (c-put-char-property curpos 'syntax-table '(6)) ; (6) = 
expression prefix, (3) = symbol
+                    ;;(message (format "set-s-t: prefix pos(%d) chr(%c)" beg 
(char-after beg)))
+                    )
+                )
               (setq state (+ 1 state)))
 
-             ;; everything else
-             (t
-              ;;(message (format "set-s-t: none pos(%d) chr(%c)" curpos 
(char-after curpos)))
-              nil))))
-          ;; next char
-          (setq curpos (+ curpos 1))))))
-
-
+             ((= state 1)
+              (if (= (char-after curpos) ?\")
+                  (progn
+                    (c-put-char-property curpos 'syntax-table '(7)) ; (7) = 
string quote
+                    ;;(message (format "set-s-t: open quote pos(%d) chr(%c)"
+                    ;; curpos (char-after curpos)))
+                    ))
+              (setq state (+ 1 state)))
 
-(defun csharp-end-of-verbatim-literal-string (&optional lim)
-  "Moves to and returns the position of the end quote of the verbatim literal
+             ((= state 2)
+              (cond
+               ;; handle backslash inside the string
+               ((= (char-after curpos) ?\\)
+                (c-put-char-property curpos 'syntax-table '(2)) ; (1) = 
punctuation, (2) = word
+                ;;(message (format "set-s-t: backslash word pos(%d) chr(%c)" 
curpos (char-after curpos)))
+                )
+
+               ;; doubled double-quote
+               ((and
+                 (= (char-after curpos) ?\")
+                 (= (char-after (+ 1 curpos)) ?\"))
+                (c-put-char-property curpos 'syntax-table '(2)) ; (1) = 
punctuation, (2) = word
+                (c-put-char-property (+ 1 curpos) 'syntax-table '(2)) ; (1) = 
punctuation
+                ;;(message (format "set-s-t: double doublequote pos(%d) 
chr(%c)" curpos (char-after curpos)))
+                (setq curpos (+ curpos 1))
+                )
+
+               ;; a single double-quote, which should be a string terminator
+               ((= (char-after curpos) ?\")
+                (c-put-char-property curpos 'syntax-table '(7)) ; (7) = string 
quote
+                ;;(message (format "set-s-t: close quote pos(%d) chr(%c)" 
curpos (char-after curpos)))
+                ;;go no further
+                (setq state (+ 1 state)))
+
+               ;; everything else
+               (t
+                ;;(message (format "set-s-t: none pos(%d) chr(%c)" curpos 
(char-after curpos)))
+                nil))))
+            ;; next char
+            (setq curpos (+ curpos 1))))))
+
+
+
+  (defun csharp-end-of-verbatim-literal-string (&optional lim)
+    "Moves to and returns the position of the end quote of the verbatim literal
 string.  When calling, point should be on the @ of the verblit string.
 If it is not, then no movement is performed and `point' is returned.
 
@@ -2038,38 +2885,38 @@ This function ignores text properties. In fact it is the
 underlying scanner used to set the text properties in a C# buffer.
 "
 
-  (csharp-log 3 "end-of-vlit-string: point(%d) c(%c)" (point) (char-after))
+    (csharp-log 3 "end-of-vlit-string: point(%d) c(%c)" (point) (char-after))
 
-  (let (curpos
-        (max (or lim (point-max))))
+    (let (curpos
+          (max (or lim (point-max))))
 
-    (if (not (looking-at "@\""))
-        (point)
-    (forward-char 2) ;; pass up the @ sign and first quote
-    (setq curpos (point))
+      (if (not (looking-at "@\""))
+          (point)
+        (forward-char 2) ;; pass up the @ sign and first quote
+        (setq curpos (point))
 
-    ;; Within a verbatim literal string, a doubled double-quote
-    ;; escapes the double-quote."
-    (while (and                                  ;; process characters...
-            (or                                  ;; while...
-             (not (eq (char-after curpos) ?\"))  ;; it's not a quote
-             (eq (char-after (+ curpos 1)) ?\")) ;; or, its a double (double) 
quote
-            (< curpos max))                      ;; and we're not done yet
+        ;; Within a verbatim literal string, a doubled double-quote
+        ;; escapes the double-quote."
+        (while (and                                  ;; process characters...
+                (or                                  ;; while...
+                 (not (eq (char-after curpos) ?\"))  ;; it's not a quote
+                 (eq (char-after (+ curpos 1)) ?\")) ;; or, its a double 
(double) quote
+                (< curpos max))                      ;; and we're not done yet
 
-      (cond
-       ((and (eq (char-after curpos) ?\")        ;; it's a double-quote.
-             (eq (char-after (+ curpos 1)) ?\"))
-        (setq curpos (+ 2 curpos)))              ;; Skip 2
-       (t                                        ;; anything else
-        (setq curpos (+ 1 curpos)))))            ;; skip fwd 1
-    curpos)))
+          (cond
+           ((and (eq (char-after curpos) ?\")        ;; it's a double-quote.
+                 (eq (char-after (+ curpos 1)) ?\"))
+            (setq curpos (+ 2 curpos)))              ;; Skip 2
+           (t                                        ;; anything else
+            (setq curpos (+ 1 curpos)))))            ;; skip fwd 1
+        curpos)))
 
 
 
 
-(defun csharp-scan-for-verbatim-literals-and-set-props (&optional beg end)
+  (defun csharp-scan-for-verbatim-literals-and-set-props (&optional beg end)
 
-"Scans the buffer, between BEG and END, for verbatim literal
+    "Scans the buffer, between BEG and END, for verbatim literal
 strings, and sets override text properties on each string to
 allow proper syntax highlighting, indenting, and cursor movement.
 
@@ -2092,135 +2939,135 @@ buffer.  Otherwise it is the last cursor position 
examined by the
 scan.
 "
 
-  (if (not (c-major-mode-is 'csharp-mode)) ;; don't scan if not csharp mode
-      nil
-    (save-excursion
-      (c-save-buffer-state
-          ((curpos (or beg (point-min)))
-           (lastpos (or end (point-max)))
-           (state 0) (start 0) (cycle 0)
-           literal eos limits)
-
-        (csharp-log 3 "scan")
-        (goto-char curpos)
-
-        (while (and (< curpos lastpos) (< cycle 10000))
-          (cond
-
-           ;; Case 1: current char is a @ sign
-           ;; --------------------------------------------
-           ;; Check to see if it demarks the beginning of a verblit
-           ;; string.
-           ((= ?@ (char-after curpos))
+    (if (not (c-major-mode-is 'csharp-mode)) ;; don't scan if not csharp mode
+        nil
+      (save-excursion
+        (c-save-buffer-state
+            ((curpos (or beg (point-min)))
+             (lastpos (or end (point-max)))
+             (state 0) (start 0) (cycle 0)
+             literal eos limits)
 
-            ;; are we in a comment?   a string?  Maybe the @ is a prefix
-            ;; to allow the use of a reserved word as a symbol. Let's find out.
+          (csharp-log 3 "scan")
+          (goto-char curpos)
 
-            ;; not sure why I need both of the following.
-            (syntax-ppss-flush-cache 1)
-            (parse-partial-sexp 1 curpos)
-            (goto-char curpos)
-            (setq literal (csharp-in-literal))
+          (while (and (< curpos lastpos) (< cycle 10000))
             (cond
 
-             ;; Case 1.A: it's a @ within a string.
+             ;; Case 1: current char is a @ sign
              ;; --------------------------------------------
-             ;; This should never happen, because this scanner hops over 
strings.
-             ;; But it might happen if the scan starts at an odd place.
-             ((eq literal 'string) nil)
-
-             ;; Case 1.B: The @ is within a comment.  Hop over it.
-             ((and (memq literal '(c c++))
-                   ;; This is a kludge for XEmacs where we use
-                   ;; `buffer-syntactic-context', which doesn't correctly
-                   ;; recognize "\*/" to end a block comment.
-                   ;; `parse-partial-sexp' which is used by
-                   ;; `c-literal-limits' will however do that in most
-                   ;; versions, which results in that we get nil from
-                   ;; `c-literal-limits' even when `c-in-literal' claims
-                   ;; we're inside a comment.
-                   ;;(setq limits (c-literal-limits start)))
-                   (setq limits (c-literal-limits)))
-
-              ;; advance to the end of the comment
-              (if limits
-                  (progn
-                    (csharp-log 4 "scan: jump end comment A (%d)" (cdr limits))
-                    (setq curpos (cdr limits)))))
+             ;; Check to see if it demarks the beginning of a verblit
+             ;; string.
+             ((= ?@ (char-after curpos))
+
+              ;; are we in a comment?   a string?  Maybe the @ is a prefix
+              ;; to allow the use of a reserved word as a symbol. Let's find 
out.
+
+              ;; not sure why I need both of the following.
+              (syntax-ppss-flush-cache 1)
+              (parse-partial-sexp 1 curpos)
+              (goto-char curpos)
+              (setq literal (csharp-in-literal))
+              (cond
+
+               ;; Case 1.A: it's a @ within a string.
+               ;; --------------------------------------------
+               ;; This should never happen, because this scanner hops over 
strings.
+               ;; But it might happen if the scan starts at an odd place.
+               ((eq literal 'string) nil)
+
+               ;; Case 1.B: The @ is within a comment.  Hop over it.
+               ((and (memq literal '(c c++))
+                     ;; This is a kludge for XEmacs where we use
+                     ;; `buffer-syntactic-context', which doesn't correctly
+                     ;; recognize "\*/" to end a block comment.
+                     ;; `parse-partial-sexp' which is used by
+                     ;; `c-literal-limits' will however do that in most
+                     ;; versions, which results in that we get nil from
+                     ;; `c-literal-limits' even when `c-in-literal' claims
+                     ;; we're inside a comment.
+                     ;;(setq limits (c-literal-limits start)))
+                     (setq limits (c-literal-limits)))
+
+                ;; advance to the end of the comment
+                (if limits
+                    (progn
+                      (csharp-log 4 "scan: jump end comment A (%d)" (cdr 
limits))
+                      (setq curpos (cdr limits)))))
 
 
-             ;; Case 1.B: curpos is at least 2 chars before the last
-             ;; position to examine, and, the following char is a
-             ;; double-quote (ASCII 34).
-             ;; --------------------------------------------
-             ;; This looks like the beginning of a verbatim string
-             ;; literal.
-             ((and (< (+ 2 curpos) lastpos)
-                   (= ?\" (char-after (+ 1 curpos))))
-
-              (setq eos (csharp-end-of-verbatim-literal-string))
-              ;; set override syntax properties on the verblit string
-              (csharp-set-vliteral-syntax-table-properties curpos eos)
-
-              (csharp-log 4 "scan: jump end verblit string (%d)" eos)
-              (setq curpos eos))))
-
-
-           ;; Case 2: current char is a double-quote.
-           ;; --------------------------------------------
-           ;; If this is a string, we hop over it, on the assumption that
-           ;; this scanner need not bother with regular literal strings, which
-           ;; get the proper syntax with the generic approach.
-           ;; If in a comment, hop over the comment.
-           ((= ?\" (char-after curpos))
-            (goto-char curpos)
-            (setq literal (c-in-literal))
-            (cond
+               ;; Case 1.B: curpos is at least 2 chars before the last
+               ;; position to examine, and, the following char is a
+               ;; double-quote (ASCII 34).
+               ;; --------------------------------------------
+               ;; This looks like the beginning of a verbatim string
+               ;; literal.
+               ((and (< (+ 2 curpos) lastpos)
+                     (= ?\" (char-after (+ 1 curpos))))
 
-             ;; Case 2.A: a quote within a string
-             ;; --------------------------------------------
-             ;; This shouldn't happen, because we hop over strings.
-             ;; But it might.
-             ((eq literal 'string) nil)
+                (setq eos (csharp-end-of-verbatim-literal-string))
+                ;; set override syntax properties on the verblit string
+                (csharp-set-vliteral-syntax-table-properties curpos eos)
 
-             ;; Case 2.B: a quote within a comment
-             ;; --------------------------------------------
-             ((and (memq literal '(c c++))
-                   ;; This is a kludge for XEmacs where we use
-                   ;; `buffer-syntactic-context', which doesn't correctly
-                   ;; recognize "\*/" to end a block comment.
-                   ;; `parse-partial-sexp' which is used by
-                   ;; `c-literal-limits' will however do that in most
-                   ;; versions, which results in that we get nil from
-                   ;; `c-literal-limits' even when `c-in-literal' claims
-                   ;; we're inside a comment.
-                   ;;(setq limits (c-literal-limits start)))
-                   (setq limits (c-literal-limits)))
-
-              ;; advance to the end of the comment
-              (if limits
-                  (progn
-                    (setq curpos (cdr limits))
-                    (csharp-log 3 "scan: jump end comment B (%s)" curpos))))
+                (csharp-log 4 "scan: jump end verblit string (%d)" eos)
+                (setq curpos eos))))
 
 
-             ;; Case 2.C: Not in a comment, and not in a string.
+             ;; Case 2: current char is a double-quote.
              ;; --------------------------------------------
-             ;; This is the beginning of a literal (but not verbatim) string.
-             (t
-              (forward-char 1) ;; pass up the quote
-              (if (consp (setq limits (c-literal-limits)))
-                  (progn
-                    (csharp-log 4 "scan: jump end literal (%d)" (cdr limits))
-                    (setq curpos (cdr limits))))))))
+             ;; If this is a string, we hop over it, on the assumption that
+             ;; this scanner need not bother with regular literal strings, 
which
+             ;; get the proper syntax with the generic approach.
+             ;; If in a comment, hop over the comment.
+             ((= ?\" (char-after curpos))
+              (goto-char curpos)
+              (setq literal (c-in-literal))
+              (cond
+
+               ;; Case 2.A: a quote within a string
+               ;; --------------------------------------------
+               ;; This shouldn't happen, because we hop over strings.
+               ;; But it might.
+               ((eq literal 'string) nil)
+
+               ;; Case 2.B: a quote within a comment
+               ;; --------------------------------------------
+               ((and (memq literal '(c c++))
+                     ;; This is a kludge for XEmacs where we use
+                     ;; `buffer-syntactic-context', which doesn't correctly
+                     ;; recognize "\*/" to end a block comment.
+                     ;; `parse-partial-sexp' which is used by
+                     ;; `c-literal-limits' will however do that in most
+                     ;; versions, which results in that we get nil from
+                     ;; `c-literal-limits' even when `c-in-literal' claims
+                     ;; we're inside a comment.
+                     ;;(setq limits (c-literal-limits start)))
+                     (setq limits (c-literal-limits)))
+
+                ;; advance to the end of the comment
+                (if limits
+                    (progn
+                      (setq curpos (cdr limits))
+                      (csharp-log 3 "scan: jump end comment B (%s)" curpos))))
+
+
+               ;; Case 2.C: Not in a comment, and not in a string.
+               ;; --------------------------------------------
+               ;; This is the beginning of a literal (but not verbatim) string.
+               (t
+                (forward-char 1) ;; pass up the quote
+                (if (consp (setq limits (c-literal-limits)))
+                    (progn
+                      (csharp-log 4 "scan: jump end literal (%d)" (cdr limits))
+                      (setq curpos (cdr limits))))))))
 
-          (setq cycle (+ 1 cycle))
-          (setq curpos (+ 1 curpos))
-          (c-safe (goto-char curpos)))))))
+            (setq cycle (+ 1 cycle))
+            (setq curpos (+ 1 curpos))
+            (c-safe (goto-char curpos)))))))
 
 
-(defun csharp-before-font-lock (beg end old-len)
-  "Adjust`syntax-table' properties on the region affected by the change
+  (defun csharp-before-font-lock (beg end old-len)
+    "Adjust`syntax-table' properties on the region affected by the change
 in a csharp-mode buffer.
 
 This function is the C# value for `c-before-font-lock-function'.
@@ -2244,36 +3091,33 @@ The return value is meaningless, and is ignored by 
cc-mode.
 
 
 
-(c-lang-defconst c-before-font-lock-function
-  csharp 'csharp-before-font-lock)
-
-;; ==================================================================
-;; end of c# fontification extensions
-;; ==================================================================
-
+  (c-lang-defconst c-before-font-lock-function
+    csharp 'csharp-before-font-lock)
 
+  ;; ==================================================================
+  ;; end of c# fontification extensions
+  ;; ==================================================================
 
 
 
-;; ==================================================================
-;; C#-specific optimizations of cc-mode funcs
-;; ==================================================================
-
 
 
-;; There's never a need to move over an Obj-C directive in csharp-mode.
-(defadvice c-forward-objc-directive (around
-                                 csharp-mode-advice-2
-                                 compile activate)
-  (if (c-major-mode-is 'csharp-mode)
-      nil
-    ad-do-it)
-  )
+  ;; ==================================================================
+  ;; C#-specific optimizations of cc-mode funcs
+  ;; ==================================================================
 
-;; ==================================================================
-;; end of C#-specific optimizations of cc-mode funcs
-;; ==================================================================
+  ;; There's never a need to move over an Obj-C directive in csharp-mode.
+  (defadvice c-forward-objc-directive (around
+                                       csharp-mode-advice-2
+                                       compile activate)
+    (if (c-major-mode-is 'csharp-mode)
+        nil
+      ad-do-it)
+    )
 
+  ;; ==================================================================
+  ;; end of C#-specific optimizations of cc-mode funcs
+  ;; ==================================================================
 
 
 
@@ -2281,185 +3125,186 @@ The return value is meaningless, and is ignored by 
cc-mode.
 
 
 
-;; ==================================================================
-;; c# - monkey-patching of basic parsing logic
-;; ==================================================================
-;;
-;; The following 2 defuns redefine functions from cc-mode, to add
-;; special cases for C#.  These primarily deal with indentation of
-;; instance initializers, which are somewhat unique to C#.  I couldn't
-;; figure out how to get cc-mode to do what C# needs, without modifying
-;; these defuns.
-;;
 
-(defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end)
-  ;; Return non-nil if we're looking at the beginning of a block
-  ;; inside an expression.  The value returned is actually a cons of
-  ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
-  ;; position of the beginning of the construct.
+  ;; ==================================================================
+  ;; c# - monkey-patching of basic parsing logic
+  ;; ==================================================================
   ;;
-  ;; LIM limits the backward search.  CONTAINING-SEXP is the start
-  ;; position of the closest containing list.  If it's nil, the
-  ;; containing paren isn't used to decide whether we're inside an
-  ;; expression or not.  If both LIM and CONTAINING-SEXP are used, LIM
-  ;; needs to be farther back.
+  ;; The following 2 defuns redefine functions from cc-mode, to add
+  ;; special cases for C#.  These primarily deal with indentation of
+  ;; instance initializers, which are somewhat unique to C#.  I couldn't
+  ;; figure out how to get cc-mode to do what C# needs, without modifying
+  ;; these defuns.
   ;;
-  ;; If CHECK-AT-END is non-nil then extra checks at the end of the
-  ;; brace block might be done.  It should only be used when the
-  ;; construct can be assumed to be complete, i.e. when the original
-  ;; starting position was further down than that.
-  ;;
-  ;; This function might do hidden buffer changes.
 
-  (save-excursion
-    (let ((res 'maybe) passed-paren
-          (closest-lim (or containing-sexp lim (point-min)))
-          ;; Look at the character after point only as a last resort
-          ;; when we can't disambiguate.
-          (block-follows (and (eq (char-after) ?{) (point))))
-
-      (while (and (eq res 'maybe)
-                  (progn (c-backward-syntactic-ws)
-                         (> (point) closest-lim))
-                  (not (bobp))
-                  (progn (backward-char)
-                         (looking-at "[\]\).]\\|\\w\\|\\s_"))
-                  (c-safe (forward-char)
-                          (goto-char (scan-sexps (point) -1))))
-
-        (setq res
-              (if (looking-at c-keywords-regexp)
-                  (let ((kw-sym (c-keyword-sym (match-string 1))))
-                    (cond
-                     ((and block-follows
-                           (c-keyword-member kw-sym 'c-inexpr-class-kwds))
-                      (and (not (eq passed-paren ?\[))
-
-                           ;; dinoch Thu, 22 Apr 2010  18:20
-                           ;; ============================================
-                           ;; looking at new MyType() { ... }
-                           ;; means this is a brace list, so, return nil,
-                           ;; implying NOT looking-at-inexpr-block
-                           (not
-                            (and (c-major-mode-is 'csharp-mode)
-                                 (looking-at "new\s+\\([[:alnum:]_]+\\)\\b")))
-
-                           (or (not (looking-at c-class-key))
-                               ;; If the class instantiation is at the start of
-                               ;; a statement, we don't consider it an
-                               ;; in-expression class.
-                               (let ((prev (point)))
-                                 (while (and
-                                         (= (c-backward-token-2 1 nil 
closest-lim) 0)
-                                         (eq (char-syntax (char-after)) ?w))
-                                   (setq prev (point)))
-                                 (goto-char prev)
-                                 (not (c-at-statement-start-p)))
-                               ;; Also, in Pike we treat it as an
-                               ;; in-expression class if it's used in an
-                               ;; object clone expression.
-                               (save-excursion
-                                 (and check-at-end
-                                      (c-major-mode-is 'pike-mode)
-                                      (progn (goto-char block-follows)
-                                             (zerop (c-forward-token-2 1 t)))
-                                      (eq (char-after) ?\())))
-                           (cons 'inexpr-class (point))))
-                     ((c-keyword-member kw-sym 'c-inexpr-block-kwds)
-                      (when (not passed-paren)
-                        (cons 'inexpr-statement (point))))
-                     ((c-keyword-member kw-sym 'c-lambda-kwds)
-                      (when (or (not passed-paren)
-                                (eq passed-paren ?\())
-                        (cons 'inlambda (point))))
-                     ((c-keyword-member kw-sym 'c-block-stmt-kwds)
-                      nil)
-                     (t
-                      'maybe)))
-
-                (if (looking-at "\\s(")
-                    (if passed-paren
-                        (if (and (eq passed-paren ?\[)
-                                 (eq (char-after) ?\[))
-                            ;; Accept several square bracket sexps for
-                            ;; Java array initializations.
-                            'maybe)
-                      (setq passed-paren (char-after))
-                      'maybe)
-                  'maybe))))
-
-      (if (eq res 'maybe)
-          (when (and c-recognize-paren-inexpr-blocks
-                     block-follows
-                     containing-sexp
-                     (eq (char-after containing-sexp) ?\())
-            (goto-char containing-sexp)
-            (if (or (save-excursion
-                      (c-backward-syntactic-ws lim)
-                      (and (> (point) (or lim (point-min)))
-                           (c-on-identifier)))
-                    (and c-special-brace-lists
-                         (c-looking-at-special-brace-list)))
-                nil
-              (cons 'inexpr-statement (point))))
-
-        res))))
-
-
-
-
-
-(defun c-inside-bracelist-p (containing-sexp paren-state)
-  ;; return the buffer position of the beginning of the brace list
-  ;; statement if we're inside a brace list, otherwise return nil.
-  ;; CONTAINING-SEXP is the buffer pos of the innermost containing
-  ;; paren.  PAREN-STATE is the remainder of the state of enclosing
-  ;; braces
-  ;;
-  ;; N.B.: This algorithm can potentially get confused by cpp macros
-  ;; placed in inconvenient locations.  It's a trade-off we make for
-  ;; speed.
-  ;;
-  ;; This function might do hidden buffer changes.
-  (or
-   ;; This will pick up brace list declarations.
-   (c-safe
+  (defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end)
+    ;; Return non-nil if we're looking at the beginning of a block
+    ;; inside an expression.  The value returned is actually a cons of
+    ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
+    ;; position of the beginning of the construct.
+    ;;
+    ;; LIM limits the backward search.  CONTAINING-SEXP is the start
+    ;; position of the closest containing list.  If it's nil, the
+    ;; containing paren isn't used to decide whether we're inside an
+    ;; expression or not.  If both LIM and CONTAINING-SEXP are used, LIM
+    ;; needs to be farther back.
+    ;;
+    ;; If CHECK-AT-END is non-nil then extra checks at the end of the
+    ;; brace block might be done.  It should only be used when the
+    ;; construct can be assumed to be complete, i.e. when the original
+    ;; starting position was further down than that.
+    ;;
+    ;; This function might do hidden buffer changes.
+
     (save-excursion
-      (goto-char containing-sexp)
-      (c-safe (c-forward-sexp -1))
-      (let (bracepos)
-        (if (and (or (looking-at c-brace-list-key)
-
-                     (progn
-                       (c-safe (c-forward-sexp -1))
-                       (looking-at c-brace-list-key))
-
-                     ;; dinoch Thu, 22 Apr 2010  18:20
-                     ;; ============================================
-                     ;; looking enum Foo : int
-                     ;; means this is a brace list, so, return nil,
-                     ;; implying NOT looking-at-inexpr-block
-
-                     (and (c-major-mode-is 'csharp-mode)
-                          (progn
-                            (c-safe (c-forward-sexp -1))
-                            (looking-at csharp-enum-decl-re))))
-
-                 (setq bracepos (c-down-list-forward (point)))
-                 (not (c-crosses-statement-barrier-p (point)
-                                                     (- bracepos 2))))
-            (point)))))
-
-   ;; this will pick up array/aggregate init lists, even if they are nested.
-   (save-excursion
-     (let ((class-key
-            ;; Pike can have class definitions anywhere, so we must
-            ;; check for the class key here.
-            (and (c-major-mode-is 'pike-mode)
-                 c-decl-block-key))
-           bufpos braceassignp lim next-containing)
-       (while (and (not bufpos)
-                   containing-sexp)
+      (let ((res 'maybe) passed-paren
+            (closest-lim (or containing-sexp lim (point-min)))
+            ;; Look at the character after point only as a last resort
+            ;; when we can't disambiguate.
+            (block-follows (and (eq (char-after) ?{) (point))))
+
+        (while (and (eq res 'maybe)
+                    (progn (c-backward-syntactic-ws)
+                           (> (point) closest-lim))
+                    (not (bobp))
+                    (progn (backward-char)
+                           (looking-at "[\]\).]\\|\\w\\|\\s_"))
+                    (c-safe (forward-char)
+                            (goto-char (scan-sexps (point) -1))))
+
+          (setq res
+                (if (looking-at c-keywords-regexp)
+                    (let ((kw-sym (c-keyword-sym (match-string 1))))
+                      (cond
+                       ((and block-follows
+                             (c-keyword-member kw-sym 'c-inexpr-class-kwds))
+                        (and (not (eq passed-paren ?\[))
+
+                             ;; dinoch Thu, 22 Apr 2010  18:20
+                             ;; ============================================
+                             ;; looking at new MyType() { ... }
+                             ;; means this is a brace list, so, return nil,
+                             ;; implying NOT looking-at-inexpr-block
+                             (not
+                              (and (c-major-mode-is 'csharp-mode)
+                                   (looking-at 
"new\s+\\([[:alnum:]_]+\\)\\b")))
+
+                             (or (not (looking-at c-class-key))
+                                 ;; If the class instantiation is at the start 
of
+                                 ;; a statement, we don't consider it an
+                                 ;; in-expression class.
+                                 (let ((prev (point)))
+                                   (while (and
+                                           (= (c-backward-token-2 1 nil 
closest-lim) 0)
+                                           (eq (char-syntax (char-after)) ?w))
+                                     (setq prev (point)))
+                                   (goto-char prev)
+                                   (not (c-at-statement-start-p)))
+                                 ;; Also, in Pike we treat it as an
+                                 ;; in-expression class if it's used in an
+                                 ;; object clone expression.
+                                 (save-excursion
+                                   (and check-at-end
+                                        (c-major-mode-is 'pike-mode)
+                                        (progn (goto-char block-follows)
+                                               (zerop (c-forward-token-2 1 t)))
+                                        (eq (char-after) ?\())))
+                             (cons 'inexpr-class (point))))
+                       ((c-keyword-member kw-sym 'c-inexpr-block-kwds)
+                        (when (not passed-paren)
+                          (cons 'inexpr-statement (point))))
+                       ((c-keyword-member kw-sym 'c-lambda-kwds)
+                        (when (or (not passed-paren)
+                                  (eq passed-paren ?\())
+                          (cons 'inlambda (point))))
+                       ((c-keyword-member kw-sym 'c-block-stmt-kwds)
+                        nil)
+                       (t
+                        'maybe)))
+
+                  (if (looking-at "\\s(")
+                      (if passed-paren
+                          (if (and (eq passed-paren ?\[)
+                                   (eq (char-after) ?\[))
+                              ;; Accept several square bracket sexps for
+                              ;; Java array initializations.
+                              'maybe)
+                        (setq passed-paren (char-after))
+                        'maybe)
+                    'maybe))))
+
+        (if (eq res 'maybe)
+            (when (and c-recognize-paren-inexpr-blocks
+                       block-follows
+                       containing-sexp
+                       (eq (char-after containing-sexp) ?\())
+              (goto-char containing-sexp)
+              (if (or (save-excursion
+                        (c-backward-syntactic-ws lim)
+                        (and (> (point) (or lim (point-min)))
+                             (c-on-identifier)))
+                      (and c-special-brace-lists
+                           (c-looking-at-special-brace-list)))
+                  nil
+                (cons 'inexpr-statement (point))))
+
+          res))))
+
+
+
+
+
+  (defun c-inside-bracelist-p (containing-sexp paren-state)
+    ;; return the buffer position of the beginning of the brace list
+    ;; statement if we're inside a brace list, otherwise return nil.
+    ;; CONTAINING-SEXP is the buffer pos of the innermost containing
+    ;; paren.  PAREN-STATE is the remainder of the state of enclosing
+    ;; braces
+    ;;
+    ;; N.B.: This algorithm can potentially get confused by cpp macros
+    ;; placed in inconvenient locations.  It's a trade-off we make for
+    ;; speed.
+    ;;
+    ;; This function might do hidden buffer changes.
+    (or
+     ;; This will pick up brace list declarations.
+     (c-safe
+       (save-excursion
+         (goto-char containing-sexp)
+         (c-safe (c-forward-sexp -1))
+         (let (bracepos)
+           (if (and (or (looking-at c-brace-list-key)
+
+                        (progn
+                          (c-safe (c-forward-sexp -1))
+                          (looking-at c-brace-list-key))
+
+                        ;; dinoch Thu, 22 Apr 2010  18:20
+                        ;; ============================================
+                        ;; looking enum Foo : int
+                        ;; means this is a brace list, so, return nil,
+                        ;; implying NOT looking-at-inexpr-block
+
+                        (and (c-major-mode-is 'csharp-mode)
+                             (progn
+                               (c-safe (c-forward-sexp -1))
+                               (looking-at csharp-enum-decl-re))))
+
+                    (setq bracepos (c-down-list-forward (point)))
+                    (not (c-crosses-statement-barrier-p (point)
+                                                        (- bracepos 2))))
+               (point)))))
+
+     ;; this will pick up array/aggregate init lists, even if they are nested.
+     (save-excursion
+       (let ((class-key
+              ;; Pike can have class definitions anywhere, so we must
+              ;; check for the class key here.
+              (and (c-major-mode-is 'pike-mode)
+                   c-decl-block-key))
+             bufpos braceassignp lim next-containing)
+         (while (and (not bufpos)
+                     containing-sexp)
            (when paren-state
              (if (consp (car paren-state))
                  (setq lim (cdr (car paren-state))
@@ -2557,113 +3402,172 @@ The return value is meaningless, and is ignored by 
cc-mode.
                 (c-most-enclosing-brace paren-state))
                (setq bufpos (point))))
            )
-       bufpos))
-   ))
+         bufpos))
+     ))
 
-;; ==================================================================
-;; end of monkey-patching of basic parsing logic
-;; ==================================================================
+  ;; ==================================================================
+  ;; end of monkey-patching of basic parsing logic
+  ;; ==================================================================
 
 
 
 
-;;(easy-menu-define csharp-menu csharp-mode-map "C# Mode Commands"
-;;                ;; Can use `csharp' as the language for `c-mode-menu'
-;;                ;; since its definition covers any language.  In
-;;                ;; this case the language is used to adapt to the
-;;                ;; nonexistence of a cpp pass and thus removing some
-;;                ;; irrelevant menu alternatives.
-;;                (cons "C#" (c-lang-const c-mode-menu csharp)))
+  ;;(easy-menu-define csharp-menu csharp-mode-map "C# Mode Commands"
+  ;;                ;; Can use `csharp' as the language for `c-mode-menu'
+  ;;                ;; since its definition covers any language.  In
+  ;;                ;; this case the language is used to adapt to the
+  ;;                ;; nonexistence of a cpp pass and thus removing some
+  ;;                ;; irrelevant menu alternatives.
+  ;;                (cons "C#" (c-lang-const c-mode-menu csharp)))
 
 ;;; Autoload mode trigger
 ;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode))
-
-
-
-(c-add-style "C#"
- '("Java"
-   (c-basic-offset . 4)
-   (c-comment-only-line-offset . (0 . 0))
-   (c-offsets-alist . (
-       (access-label          . -)
-       (arglist-close         . c-lineup-arglist)
-       (arglist-cont          . 0)
-       (arglist-cont-nonempty . c-lineup-arglist)
-       (arglist-intro         . c-lineup-arglist-intro-after-paren)
-       (block-close           . 0)
-       (block-open            . 0)
-       (brace-entry-open      . 0)
-       (brace-list-close      . 0)
-       (brace-list-entry      . 0)
-       (brace-list-intro      . +)
-       (brace-list-open       . +)
-       (c                     . c-lineup-C-comments)
-       (case-label            . +)
-       (catch-clause          . 0)
-       (class-close           . 0)
-       (class-open            . 0)
-       (comment-intro         . c-lineup-comment)
-       (cpp-macro             . 0)
-       (cpp-macro-cont        . c-lineup-dont-change)
-       (defun-block-intro     . +)
-       (defun-close           . 0)
-       (defun-open            . 0)
-       (do-while-closure      . 0)
-       (else-clause           . 0)
-       (extern-lang-close     . 0)
-       (extern-lang-open      . 0)
-       (friend                . 0)
-       (func-decl-cont        . +)
-       (inclass               . +)
-       (inexpr-class          . +)
-       (inexpr-statement      . 0)
-       (inextern-lang         . +)
-       (inher-cont            . c-lineup-multi-inher)
-       (inher-intro           . +)
-       (inlambda              . c-lineup-inexpr-block)
-       (inline-close          . 0)
-       (inline-open           . 0)
-       (innamespace           . +)
-       (knr-argdecl           . 0)
-       (knr-argdecl-intro     . 5)
-       (label                 . 0)
-       (lambda-intro-cont     . +)
-       (member-init-cont      . c-lineup-multi-inher)
-       (member-init-intro     . +)
-       (namespace-close       . 0)
-       (namespace-open        . 0)
-       (statement             . 0)
-       (statement-block-intro . +)
-       (statement-case-intro  . +)
-       (statement-case-open   . +)
-       (statement-cont        . +)
-       (stream-op             . c-lineup-streamop)
-       (string                . c-lineup-dont-change)
-       (substatement          . +)
-       (substatement-open     . 0)
-       (template-args-cont c-lineup-template-args +)
-       (topmost-intro         . 0)
-       (topmost-intro-cont    . +)
-       ))
-   ))
-
-
+  (add-to-list 'auto-mode-alist '("\\.cs$" . csharp-mode))
+
+
+  (c-add-style "C#"
+               '("Java"
+                 (c-basic-offset . 4)
+                 (c-comment-only-line-offset . (0 . 0))
+                 (c-offsets-alist . (
+                                     (access-label          . -)
+                                     (arglist-close         . c-lineup-arglist)
+                                     (arglist-cont          . 0)
+                                     (arglist-cont-nonempty . c-lineup-arglist)
+                                     (arglist-intro         . 
c-lineup-arglist-intro-after-paren)
+                                     (block-close           . 0)
+                                     (block-open            . 0)
+                                     (brace-entry-open      . 0)
+                                     (brace-list-close      . 0)
+                                     (brace-list-entry      . 0)
+                                     (brace-list-intro      . +)
+                                     (brace-list-open       . +)
+                                     (c                     . 
c-lineup-C-comments)
+                                     (case-label            . +)
+                                     (catch-clause          . 0)
+                                     (class-close           . 0)
+                                     (class-open            . 0)
+                                     (comment-intro         . c-lineup-comment)
+                                     (cpp-macro             . 0)
+                                     (cpp-macro-cont        . 
c-lineup-dont-change)
+                                     (defun-block-intro     . +)
+                                     (defun-close           . 0)
+                                     (defun-open            . 0)
+                                     (do-while-closure      . 0)
+                                     (else-clause           . 0)
+                                     (extern-lang-close     . 0)
+                                     (extern-lang-open      . 0)
+                                     (friend                . 0)
+                                     (func-decl-cont        . +)
+                                     (inclass               . +)
+                                     (inexpr-class          . +)
+                                     (inexpr-statement      . 0)
+                                     (inextern-lang         . +)
+                                     (inher-cont            . 
c-lineup-multi-inher)
+                                     (inher-intro           . +)
+                                     (inlambda              . 
c-lineup-inexpr-block)
+                                     (inline-close          . 0)
+                                     (inline-open           . 0)
+                                     (innamespace           . +)
+                                     (knr-argdecl           . 0)
+                                     (knr-argdecl-intro     . 5)
+                                     (label                 . 0)
+                                     (lambda-intro-cont     . +)
+                                     (member-init-cont      . 
c-lineup-multi-inher)
+                                     (member-init-intro     . +)
+                                     (namespace-close       . 0)
+                                     (namespace-open        . 0)
+                                     (statement             . 0)
+                                     (statement-block-intro . +)
+                                     (statement-case-intro  . +)
+                                     (statement-case-open   . +)
+                                     (statement-cont        . +)
+                                     (stream-op             . 
c-lineup-streamop)
+                                     (string                . 
c-lineup-dont-change)
+                                     (substatement          . +)
+                                     (substatement-open     . 0)
+                                     (template-args-cont 
c-lineup-template-args +)
+                                     (topmost-intro         . 0)
+                                     (topmost-intro-cont    . +)
+                                     ))
+                 ))
+
+
+
+(defun csharp-guess-compile-command ()
+  "set `compile-command' intelligently depending on the
+current buffer, or the contents of the current directory.
+"
+  (interactive)
+  (set (make-local-variable 'compile-command)
+
+       (cond
+        ((or (file-expand-wildcards "*.csproj" t)
+             (file-expand-wildcards "*.vcproj" t)
+             (file-expand-wildcards "*.vbproj" t)
+             (file-expand-wildcards "*.shfbproj" t)
+             (file-expand-wildcards "*.sln" t))
+         (concat csharp-msbuild-tool " "))
+
+        ;; sometimes, not sure why, the buffer-file-name is
+        ;; not set.  Can use it only if set.
+        (buffer-file-name
+         (let ((filename (file-name-nondirectory buffer-file-name)))
+           (cond
+
+            ;; editing a c# file - check for an explicitly-specified command
+            ((string-equal (substring buffer-file-name -3) ".cs")
+             (let ((explicitly-specified-command
+                    (csharp-get-value-from-comments "compile" 
csharp-cmd-line-limit)))
+
+
+               (if explicitly-specified-command
+                   (csharp-replace-command-tokens explicitly-specified-command)
+                   (concat csharp-make-tool " " ;; assume a makefile exists
+                           (file-name-sans-extension filename)
+                           ".exe"))))
+
+            ;; something else - do a typical .exe build
+            (t
+             (concat csharp-make-tool " "
+                     (file-name-sans-extension filename)
+                     ".exe")))))
+        (t
+         ;; punt
+         (concat csharp-make-tool " ")))))
+
+
+
+(defun csharp-invoke-compile-interactively ()
+  "fn to wrap the `compile' function.  This simply
+checks to see if `compile-command' has been previously set, and
+if not, invokes `csharp-guess-compile-command' to set the value.
+Then it invokes the `compile' function, interactively.
+
+The effect is to guess the compile command only once, per buffer.
+
+I tried doing this with advice attached to the `compile'
+function, but because of the interactive nature of the fn, it
+didn't work the way I wanted it to. So this fn should be bound to
+the key sequence the user likes for invoking compile, like ctrl-c
+ctrl-e.
 
+"
+  (interactive)
+  (cond
+   ((not (boundp 'csharp-local-compile-command-has-been-set))
+    (csharp-guess-compile-command)
+    (set (make-local-variable 'csharp-local-compile-command-has-been-set) t)))
+  ;; local compile command has now been set
+  (call-interactively 'compile))
 
-;; Custom variables
-;;;###autoload
-(defcustom csharp-mode-hook nil
-  "*Hook called by `csharp-mode'."
-  :type 'hook
-  :group 'c)
 
 
 
 ;;; The entry point into the mode
 ;;;###autoload
-(defun csharp-mode ()
-  "Major mode for editing C# code. This mode is derived from CC Mode to
+  (defun csharp-mode ()
+    "Major mode for editing C# code. This mode is derived from CC Mode to
 support C#.
 
 The hook `c-mode-common-hook' is run with no args at mode
@@ -2675,86 +3579,492 @@ respectively, for Csc.exe error and warning messages.
 
 Key bindings:
 \\{csharp-mode-map}"
-  (interactive)
-  (kill-all-local-variables)
-  (make-local-variable 'beginning-of-defun-function)
-  (make-local-variable 'end-of-defun-function)
-  (c-initialize-cc-mode t)
-  (set-syntax-table csharp-mode-syntax-table)
-
-  ;; define underscore as part of a word in the Csharp syntax table
-  (modify-syntax-entry ?_ "w" csharp-mode-syntax-table)
-
-  ;; define @ as an expression prefix in Csharp syntax table
-  (modify-syntax-entry ?@ "'" csharp-mode-syntax-table)
-
-  (setq major-mode 'csharp-mode
-        mode-name "C#"
-        local-abbrev-table csharp-mode-abbrev-table
-        abbrev-mode t)
-  (use-local-map csharp-mode-map)
-
-  ;; `c-init-language-vars' is a macro that is expanded at compile
-  ;; time to a large `setq' with all the language variables and their
-  ;; customized values for our language.
-  (c-init-language-vars csharp-mode)
-
-
-  ;; `c-common-init' initializes most of the components of a CC Mode
-  ;; buffer, including setup of the mode menu, font-lock, etc.
-  ;; There's also a lower level routine `c-basic-common-init' that
-  ;; only makes the necessary initialization to get the syntactic
-  ;; analysis and similar things working.
-  (c-common-init 'csharp-mode)
-
-  ;; csc.exe, the C# Compiler, produces errors like this:
-  ;; file.cs(6,18): error CS1006: Name of constructor must match name of class
-  (if (boundp 'compilation-error-regexp-alist-alist)
-      (progn
-        (add-to-list
-         'compilation-error-regexp-alist-alist
-         '(ms-csharp "^[ 
\t]*\\([A-Za-z0-9_][^(]*\\.cs\\)(\\([0-9]+\\)[,]\\([0-9]+\\)) ?: 
\\(error\\|warning\\) CS[0-9]+:" 1 2 3))
-        (add-to-list
-         'compilation-error-regexp-alist
-         'ms-csharp)))
+    (interactive)
+    (kill-all-local-variables)
+    (make-local-variable 'beginning-of-defun-function)
+    (make-local-variable 'end-of-defun-function)
+    (c-initialize-cc-mode t)
+    (set-syntax-table csharp-mode-syntax-table)
+
+    ;; define underscore as part of a word in the Csharp syntax table
+    (modify-syntax-entry ?_ "w" csharp-mode-syntax-table)
+
+    ;; define @ as an expression prefix in Csharp syntax table
+    (modify-syntax-entry ?@ "'" csharp-mode-syntax-table)
+
+    (setq major-mode 'csharp-mode
+          mode-name "C#"
+          local-abbrev-table csharp-mode-abbrev-table
+          abbrev-mode t)
+    (use-local-map csharp-mode-map)
+
+    ;; `c-init-language-vars' is a macro that is expanded at compile
+    ;; time to a large `setq' with all the language variables and their
+    ;; customized values for our language.
+    (c-init-language-vars csharp-mode)
+
+    ;; `c-common-init' initializes most of the components of a CC Mode
+    ;; buffer, including setup of the mode menu, font-lock, etc.
+    ;; There's also a lower level routine `c-basic-common-init' that
+    ;; only makes the necessary initialization to get the syntactic
+    ;; analysis and similar things working.
+    (c-common-init 'csharp-mode)
+
+    ;; compile
+    (local-set-key "\C-x\C-e"  'csharp-invoke-compile-interactively)
+
+    ;; to allow next-error to work with csc.exe:
+    (setq compilation-scroll-output t)
+
+    ;; csc.exe, the C# Compiler, produces errors like this:
+    ;; file.cs(6,18): error CS1006: Name of constructor must match name of 
class
+    (if (boundp 'compilation-error-regexp-alist-alist)
+        (progn
+          (add-to-list
+           'compilation-error-regexp-alist-alist
+           '(ms-csharp "^[ 
\t]*\\([-_:A-Za-z0-9][^(]*\\.\\(?:cs\\|xaml\\)\\)(\\([0-9]+\\)[,]\\([0-9]+\\)) 
?: \\(error\\|warning\\) CS[0-9]+:" 1 2 3))
+          (add-to-list
+           'compilation-error-regexp-alist
+           'ms-csharp)))
+
+    ;; flymake
+    (eval-after-load "flymake"
+      '(progn
+         (if csharp-want-flymake-fixup
+             (csharp-flymake-install))))
+
+    (eval-after-load  "yasnippet"
+      '(progn
+         (if csharp-want-yasnippet-fixup
+             (csharp-yasnippet-fixup))))
 
 
-  ;; to allow next-error to work with csc.exe:
-  (setq compilation-scroll-output t)
+    (local-set-key (kbd "/") 'csharp-maybe-insert-codedoc)
+    (local-set-key (kbd "{") 'csharp-insert-open-brace)
 
+    ;; Need the following for parse-partial-sexp to work properly with
+    ;; verbatim literal strings Setting this var to non-nil tells
+    ;; `parse-partial-sexp' to pay attention to the syntax text
+    ;; properties on the text in the buffer.  If csharp-mode attaches
+    ;; text syntax to @"..." then, `parse-partial-sexp' will treat those
+    ;; strings accordingly.
+    (set (make-local-variable 'parse-sexp-lookup-properties) t)
 
-  (local-set-key (kbd "/") 'csharp-maybe-insert-codedoc)
-  (local-set-key (kbd "{") 'csharp-insert-open-brace)
+    ;; scan the entire buffer for verblit strings
+    (csharp-scan-for-verbatim-literals-and-set-props nil nil)
 
+    ;; Allow fill-paragraph to work on xml code doc
+    ;; This setting gets overwritten quietly by c-run-mode-hooks,
+    ;; so I put it afterwards to make it stick.
+    (make-local-variable 'paragraph-separate)
 
-  ;; Need the following for parse-partial-sexp to work properly with
-  ;; verbatim literal strings Setting this var to non-nil tells
-  ;; `parse-partial-sexp' to pay attention to the syntax text
-  ;; properties on the text in the buffer.  If csharp-mode attaches
-  ;; text syntax to @"..." then, `parse-partial-sexp' will treat those
-  ;; strings accordingly.
-  (set (make-local-variable 'parse-sexp-lookup-properties)
-       t)
+    ;;(message "C#: set paragraph-separate")
 
-  ;; scan the entire buffer for verblit strings
-  (csharp-scan-for-verbatim-literals-and-set-props nil nil)
+    ;; Speedbar handling
+    (if (fboundp 'speedbar-add-supported-extension)
+        (speedbar-add-supported-extension '(".cs"))) ;; idempotent
 
-  (c-run-mode-hooks 'c-mode-common-hook 'csharp-mode-hook)
+    (c-update-modeline)
+    (c-run-mode-hooks 'c-mode-common-hook 'csharp-mode-hook)
 
-  ;; Allow fill-paragraph to work on xml code doc
-  ;; This setting gets overwritten quietly by c-run-mode-hooks,
-  ;; so I put it afterwards to make it stick.
-  (make-local-variable 'paragraph-separate)
-  (setq paragraph-separate
-       "[ \t]*\\(//+\\|\\**\\)\\([ \t]+\\|[ \t]+<.+?>\\)$\\|^\f")
+    ;; The paragraph-separate variable was getting stomped by
+    ;; other hooks, so it must reside here.
+    (setq paragraph-separate
+          "[ \t]*\\(//+\\|\\**\\)\\([ \t]+\\|[ \t]+<.+?>\\)$\\|^\f")
 
-  ;;(message "C#: set paragraph-separate")
+    (set (make-local-variable 'comment-auto-fill-only-comments) t)
+    )
+
+
+
+
+  ;; =======================================================
+  ;;
+  ;; This section attempts to workaround an anomalous display behavior
+  ;; for tooltips.  It's not strictly necessary, only for aesthetics.  The
+  ;; issue is that tooltips can get clipped.  This is the topic of Emacs
+  ;; bug #5908, unfixed in v23 and present in v22.
+
+
+  (defadvice tooltip-show (before
+                           flymake-for-csharp-fixup-tooltip
+                           (arg &optional use-echo-area)
+                           activate compile)
+    (progn
+      (if ;;(and (not use-echo-area) (eq major-mode 'csharp-mode))
+          (not use-echo-area)
+          (let ((orig (ad-get-arg 0)))
+            (ad-set-arg 0 (concat " " (cheeso-string-trim 
(cheeso-reform-string 74 orig) ?\ )))
+            ))))
+
+
+
+
+;; ========================================================================
+;; YA-snippet integration
+
+(defun csharp-yasnippet-fixup ()
+  "Sets snippets into ya-snippet for C#, if yasnippet is loaded,
+and if the snippets do not already exist.
+"
+  (if (not csharp--yasnippet-has-been-fixed)
+      (if (fboundp 'yas/snippet-table-fetch)
+          ;; yasnippet is present
+          (let ((snippet-table (yas/snippet-table 'csharp-mode))
+                (keymap (if yas/use-menu
+                            (yas/menu-keymap-for-mode mode)
+                          nil))
+                (yas/require-template-condition nil)
+                (builtin-snips
+                 '(
+  ("xmls" "{
+      XmlSerializer s1 = new XmlSerializer(typeof(${1:type}));
+
+      // use this to \"suppress\" the default xsd and xsd-instance namespaces
+      XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
+      ns.Add(\"\", \"\");
+
+      s1.Serialize(new XTWFND(System.Console.Out), object, ns);
+      System.Console.WriteLine(\"\\n\");
+}
+
+  $0
+  /// XmlTextWriterFormattedNoDeclaration
+  /// helper class : eliminates the XML Documentation at the
+  /// start of a XML doc.
+  /// XTWFND = XmlTextWriterFormattedNoDeclaration
+  /// usage:       s1.Serialize(new XTWFND(System.Console.Out), thing, ns);
+
+  public class XTWFND : System.Xml.XmlTextWriter
+  {
+    public XTWFND(System.IO.StringWriter w) : base(w) { 
Formatting=System.Xml.Formatting.Indented;  }
+    public XTWFND(System.IO.TextWriter w) : base(w) { Formatting = 
System.Xml.Formatting.Indented; }
+    public XTWFND(System.IO.Stream s) : base(s, null) { Formatting = 
System.Xml.Formatting.Indented; }
+    public XTWFND(string filename) : base(filename, null) { Formatting = 
System.Xml.Formatting.Indented; }
+    public override void WriteStartDocument() { }
+  }
+
+" "xmlserializer { ... }" nil)
+  ("wl" "System.Console.WriteLine(${0://thing to do});
+" "WriteLine( ... );" nil)
+  ("while" "while (${1:condition})
+{
+    ${0://thing to do}
+}" "while (...) { ... }" nil)
+  ("using" "using (${1:type} ${2:var} = new ${1:type}(${4:ctor args}))
+{
+    ${5:// body...}
+}" "using ... { ... }" nil)
+  ("try" "try
+{
+  $0
+}
+catch (System.Exception exc1)
+{
+  throw new Exception(\"uncaught exception\", exc1);
+}" "try { ... } catch { ... }" nil)
+  ("sum" "/// <summary>
+///  ${1:description}
+/// </summary>
+///
+/// <remarks>
+///  ${2:comments}
+/// </remarks>
+" "/// <summary>..." nil)
+  ("sing" "#region Singleton ${1:className}
+public sealed class $1
+{
+    private readonly static $1 _instance = new $1();
+    public static $1 Instance  { get { return _instance; } }
+    static $1() { /* required for lazy init */ }
+    private $1()
+    {
+        // implementation here
+    }
+}
+
+#endregion
+" "public sealed class Singleton {...}" nil)
+  ("setting" " #region Property${1:PropName}
+
+    private string default$1 = ${2:defaultValue};
+    private string _$1;
+    public string $1
+    {
+        get
+        {
+                if (_$1 == null)
+                {
+                    _$1 = 
System.Configuration.ConfigurationManager.AppSettings[\"$1\"];
+
+                    if (string.IsNullOrEmpty(_$1))
+                    {
+                        _$1 = default$1;
+                    }
+                }
+                return this._$1;
+            }
+        set
+        {
+            string new$1 = value;
+            // optional validation:
+            //Validation.EnforceXxxx(new$1, \"$1\");
+            _$1 = new$1;
+        }
+    }
+
+#endregion
+" "config setting" nil)
+  ("prop" "private ${1:Type} _${2:Name};
+public ${1:Type} ${2:Name}
+{
+  get
+  {
+    ${3://get impl}
+  }
+
+  set
+  {
+    ${4://get impl}
+  }
+
+}" "property ... { ... }" nil)
+  ("pa" "        for (int i=0; i < args.Length; i++)
+        {
+            switch (args[i])
+            {
+            case \"-?\":
+            case \"-help\":
+                throw new ArgumentException(args[i]);
+
+            default: // positional args
+                if ($2 != 0)
+                    // we have all the args we need
+                    throw new ArgumentException(args[i]);
+
+                if ($1 == null)
+                    $1 = args[i];
+
+                else
+                    $2 = System.Int32.Parse(args[i]);
+
+                break;
+            }
+        }
+
+        // check values
+        if ($1 == null)
+            throw new ArgumentException();
+
+        if ($2 == 0)
+            throw new ArgumentException();
+
+
+" "switch(args[0]) {...}" nil)
+  ("openread" "        using(Stream src = File.OpenRead($1))
+        {
+          using(Stream dest= File.Create($2))
+          {
+            if (compress)
+              Compress(src, dest);
+            else
+              Decompress(src, dest);
+          }
+        }
+" "File.OpenRead(...)" nil)
+  ("ofd" "var dlg = new System.Windows.Forms.OpenFileDialog();
+dlg.Filter = \"${1:filter string}\"; // ex: \"C# (*.cs)|*.cs|Text 
(*.txt)|*.txt\";
+if (dlg.ShowDialog() == DialogResult.OK)
+{
+    string fileName = dlg.FileName;
+    $0
+}
+" "new OpenFileDialog; if (DialogResult.OK) { ... }" nil)
+  ("ife" "if (${1:predicate})
+{
+  ${2:// then clause}
+}
+else
+{
+  ${3:// else clause}
+}" "if (...) { ... } else { ... }" nil)
+  ("fore" "foreach (${1:type} ${2:var} in ${3:IEnumerable})
+{
+    ${4:// body...}
+}" "foreach ... { ... }" nil)
+  ("for" "for (int ${1:index}=0; $1 < ${2:Limit}; $1++)
+{
+    ${3:// body...}
+}" "for (...) { ... }" nil)
+  ("fbd" "using (FolderBrowserDialog dialog = new FolderBrowserDialog())
+{
+    dialog.Description = \"Open a folder which contains the xml output\";
+    dialog.ShowNewFolderButton = false;
+    dialog.RootFolder = Environment.SpecialFolder.MyComputer;
+    if(dialog.ShowDialog() == DialogResult.OK)
+    {
+        string folder = dialog.SelectedPath;
+        foreach (string fileName in Directory.GetFiles(folder, \"*.xml\", 
SearchOption.TopDirectoryOnly))
+        {
+            SQLGenerator.GenerateSQLTransactions(Path.GetFullPath(fileName));
+        }
+    }
+}
+
+" "new FolderBrowserDialog; if (DialogResult.OK) { ... }" nil)
+  ("doc" "/// <summary>
+/// ${1:summary}
+/// </summary>
+///
+/// <remarks>
+/// ${2:remarks}
+/// </remarks>
+$0" "XML Documentation" nil)
+  ("conv" "  List<String> Values = new List<String>() { \"7\", \"13\", \"41\", 
\"3\" };
+
+  // ConvertAll maps the given delegate across all the List elements
+  var foo = Values.ConvertAll((s) => { return System.Convert.ToInt32(s); }) ;
+
+  System.Console.WriteLine(\"typeof(foo) = {0}\", foo.GetType().ToString());
+
+  Array.ForEach(foo.ToArray(),Console.WriteLine);
+" "ConvertAll((s) => { ... });" nil)
+  ("cla" "public class ${1:Classname}
+{
+  // default ctor
+  public ${1:Classname}()
+  {
+  }
+
+  ${2:// methods here}
+}" "class ... { ... }" nil)
+  ("ca" "  List<String> Values = new List<String>() { \"7\", \"13\", \"41\", 
\"3\" };
+
+  // ConvertAll maps the given delegate across all the List elements
+  var foo = Values.ConvertAll((s) => { return System.Convert.ToInt32(s); }) ;
+
+  System.Console.WriteLine(\"typeof(foo) = {0}\", foo.GetType().ToString());
+
+  Array.ForEach(foo.ToArray(),Console.WriteLine);
+" "ConvertAll((s) => { ... });" nil)
+  ("ass" "
+
+[assembly: AssemblyTitle(\"$1\")]
+[assembly: AssemblyCompany(\"${2:YourCoName}\")]
+[assembly: AssemblyProduct(\"${3}\")]
+[assembly: AssemblyCopyright(\"Copyright � ${4:Someone} 2011\")]
+[assembly: AssemblyTrademark(\"\")]
+[assembly: AssemblyCulture(\"\")]
+[assembly: AssemblyConfiguration(\"\")]
+[assembly: AssemblyDescription(\"${5}\")]
+[assembly: AssemblyVersion(\"${6:1.0.1.0}\")]
+[assembly: AssemblyFileVersion(\"${7:1.0.1.0}\")]
+
+" "assembly info" nil)
+  ("args" "for (int i=0; i < args.Length; i++)
+{
+    switch (args[i])
+    {
+        case \"-f\":
+            i++;
+            if (args.Length <= i) throw new ArgumentException(args[i-1]);
+            _file = args[i];
+            break;
+
+        case \"-p\":
+            i++;
+            if (args.Length <= i) throw new ArgumentException(args[i-1]);
+            _password = args[i];
+            break;
+
+        case \"-d\":
+            i++;
+            if (args.Length <= i) throw new ArgumentException(args[i-1]);
+            _dir = args[i];
+            break;
+
+        case \"-i\":
+            i++;
+            if (args.Length <= i) throw new ArgumentException(args[i-1]);
+            if (_intParam != DefaultIntParamValue)
+                throw new ArgumentException(args[i]);
+            if (args[i].StartsWith(\"0x\"))
+                _intParam = System.Int32.Parse(args[i].Substring(2), 
System.Globalization.NumberStyles.AllowHexSpecifier );
+            else
+                _intParam = System.Int32.Parse(args[i]);
+            break;
+
+
+        case \"-s\":
+            i++;
+            if (args.Length <= i) throw new Exception(args[i-1]);
+            if (args[i].ToUpper().EndsWith(\"K\"))
+                _size = 
System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024;
+            else if (args[i].ToUpper().EndsWith(\"KB\"))
+                _size = 
System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024;
+            else if (args[i].ToUpper().EndsWith(\"M\"))
+                _size = 
System.Int32.Parse(args[i].Substring(0,args[i].Length-1)) * 1024*1024;
+            else if (args[i].ToUpper().EndsWith(\"MB\"))
+                _size = 
System.Int32.Parse(args[i].Substring(0,args[i].Length-2)) * 1024*1024;
+            else
+                _size = Int32.Parse(args[i]);
+            break;
+
+
+
+        case \"-?\":
+            throw new ArgumentException(args[i]);
+
+        default:
+            if (_positionalArg != null)
+                throw new ArgumentException(args[i]);
+
+            _positionalArg = args[i];
+            break;
+    }
+}
+" "switch on args" nil)
+  )))
+
+
+            (setq csharp--yasnippet-has-been-fixed t)
+
+            (add-to-list 'yas/known-modes 'csharp-mode))
+
+            ;; It's possible that Csharp-mode is not on the yasnippet menu
+            ;; Install it here.
+            (when yas/use-menu
+              (define-key
+                yas/menu-keymap
+                (vector 'csharp-mode)
+                `(menu-item "C#" ,keymap)))
+
+            ;; Insert the snippets from above into the table if they
+            ;; are not already defined.
+            (mapcar
+             '(lambda (item)
+                (let* ((full-key (car item))
+                       (existing-snip
+                        (yas/snippet-table-fetch snippet-table full-key)))
+                  (if (not existing-snip)
+                      (let* ((key (file-name-sans-extension full-key))
+                             (name (caddr item))
+                             (condition (nth 3 item))
+                             (template (yas/make-template (cadr item)
+                                                          (or name key)
+                                                          condition)))
+                        (yas/snippet-table-store snippet-table
+                                                 full-key
+                                                 key
+                                                 template)
+                        (when yas/use-menu
+                          (define-key keymap (vector (make-symbol full-key))
+                            `(menu-item ,(yas/template-name template)
+                                        ,(yas/make-menu-binding 
(yas/template-content template))
+                                        :keys ,(concat key 
yas/trigger-symbol))))))))
+             builtin-snips))))
 
-  ;; Speedbar handling
-  (if (fboundp 'speedbar-add-supported-extension)
-      (speedbar-add-supported-extension '(".cs"))) ;; idempotent
 
-  (c-update-modeline))
 
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]