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

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

[elpa] externals/csharp-mode 756f086 003/459: Few updates to csharp-mode


From: ELPA Syncer
Subject: [elpa] externals/csharp-mode 756f086 003/459: Few updates to csharp-mode. First checkin of aspx-mode.el, for ASPX files.
Date: Sun, 22 Aug 2021 13:58:43 -0400 (EDT)

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

    Few updates to csharp-mode.  First checkin of aspx-mode.el, for ASPX files.
---
 aspx-mode.el   | 496 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 csharp-mode.el | 262 +++++++++++++++++++++---------
 2 files changed, 686 insertions(+), 72 deletions(-)

diff --git a/aspx-mode.el b/aspx-mode.el
new file mode 100644
index 0000000..984e907
--- /dev/null
+++ b/aspx-mode.el
@@ -0,0 +1,496 @@
+;;; aspx-mode.el --- mode for editing ASPX files
+;;
+;; Copyright (C) 2010  Dino Chiesa
+;;
+;; Author:   Dino Chiesa <dpchiesa@hotmail.com>
+;; Created:  May 2010
+;; Version:  0.1
+;; Keywords: C#, languages, extensions, files
+;; URL:      ???
+;;
+;; This is an emacs mode for editing single-file ASPX modules,
+;; which can contain HTML, javascript, C# or VB, and
+;; CSS code.
+;;
+;; It relies on multi-mode.
+;; (see http://www.loveshack.ukfsn.org/emacs )
+;;
+;; It provides context-sensitive fontification and indent in all of the
+;; various chunks o an ASPX file. Browser-side Javascript within script
+;; blocks gets fontified correctly. Server-side script blocks get
+;; fontified properly. CSS gets indented and fontified. And of course
+;; HTML.
+;;
+;; It relies on espresso for the javascript mode, css-mode for CSS,
+;; html-mode for HTML, and csharp-mode 0.7.5 or later for the
+;; server-side c# code.
+;;
+;; Bugs:
+;;
+;;  - The fontification sort of turns on and off as you cursor through
+;;    the buffer, making for a somewhat odd user experience.
+;;
+;;  - the fontification sometimes doesn't happen within a chunk, til you
+;;    modify the text within the chunk.  There's probably a fix for
+;;    this.
+;;
+;;
+;; Thu, 13 May 2010  23:44
+;;
+;; Licensed according to the Microsoft Public License (Ms-PL)
+;;
+;; This license governs use of the accompanying software. If you use
+;; the software, you accept this license. If you do not accept the
+;; license, do not use the software.
+;;
+;; 1. Definitions
+;;
+;; The terms "reproduce," "reproduction," "derivative
+;; works," and "distribution" have the same meaning here as under
+;; U.S. copyright law.
+;;
+;; A "contribution" is the original software, or any additions or
+;; changes to the software.
+;;
+;; A "contributor" is any person that distributes its contribution
+;; under this license.
+;;
+;; "Licensed patents" are a contributor's patent claims that read
+;; directly on its contribution.
+;;
+;; 2. Grant of Rights
+;;
+;; (A) Copyright Grant- Subject to the terms of this license,
+;; including the license conditions and limitations in section 3,
+;; each contributor grants you a non-exclusive, worldwide,
+;; royalty-free copyright license to reproduce its contribution,
+;; prepare derivative works of its contribution, and distribute its
+;; contribution or any derivative works that you create.
+;;
+;; (B) Patent Grant- Subject to the terms of this license, including
+;; the license conditions and limitations in section 3, each
+;; contributor grants you a non-exclusive, worldwide, royalty-free
+;; license under its licensed patents to make, have made, use, sell,
+;; offer for sale, import, and/or otherwise dispose of its
+;; contribution in the software or derivative works of the
+;; contribution in the software.
+;;
+;; 3. Conditions and Limitations
+;;
+;; (A) No Trademark License- This license does not grant you rights
+;; to use any contributors' name, logo, or trademarks.
+;;
+;; (B) If you bring a patent claim against any contributor over
+;; patents that you claim are infringed by the software, your patent
+;; license from such contributor to the software ends automatically.
+;;
+;; (C) If you distribute any portion of the software, you must
+;; retain all copyright, patent, trademark, and attribution notices
+;; that are present in the software.
+;;
+;; (D) If you distribute any portion of the software in source code
+;; form, you may do so only under this license by including a
+;; complete copy of this license with your distribution. If you
+;; distribute any portion of the software in compiled or object code
+;; form, you may only do so under a license that complies with this
+;; license.
+;;
+;; (E) The software is licensed "as-is." You bear the risk of using
+;; it. The contributors give no express warranties, guarantees or
+;; conditions. You may have additional consumer rights under your
+;; local laws which this license cannot change. To the extent
+;; permitted under your local laws, the contributors exclude the
+;; implied warranties of merchantability, fitness for a particular
+;; purpose and non-infringement.
+;;
+;;;
+
+
+(require 'multi-mode)
+(require 'csharp-mode)
+(require 'espresso "espresso.el")
+;;(require 'javascript-mode "javascript.el")
+(require 'css-mode)
+
+
+
+(defvar aspx-mode-log-level 0
+  "The current log level for operatopms specific to aspx-mode.
+0 = NONE, 1 = Info, 2 = VERBOSE, 3 = DEBUG, 4 = SHUTUP ALREADY. ")
+
+
+(defun aspx-mode-log (level text &rest args)
+  "Log a message at level LEVEL.
+If LEVEL is higher than `aspx-mode-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 aspx-mode-log-level)
+      (let* ((msg (apply 'format text args)))
+        (message "aspx-mode: %s" msg))
+    t))
+
+
+(defconst aspx-mode-server-lang-re
+  "\\([Cc]#\\|[Vv][Bb]\\)"
+  "Regex for matching on the ASPX langauge.")
+
+
+(defconst aspx-mode-server-script-start-re
+  (concat
+   "<\\(script\\|SCRIPT\\)[ \t\n\r\v\f]+"
+   "\\("
+   "language=[\"']"
+   aspx-mode-server-lang-re
+   "[\"'][ \t\n\r\v\f]+runat=[\"']server[\"']"
+   "\\|"
+   "runat=[\"']server[\"'][ \t\n\r\v\f]+language=[\"']"
+   aspx-mode-server-lang-re
+   "[\"']"
+   "\\)[ \t\n\r\v\f]*>"
+   )
+"Regex for matching the <script> tag that begins a block of
+ASPX server-side code.  It tries to match on <script language='C#' 
runat='server'...>
+as well as <script runat='server' language='C#' ...>
+" )
+
+
+(defconst aspx-mode-page-decl-re
+  (concat
+   "<%@"
+   "[ \t\n\r\v\f]+"
+   "\\(Page\\|Control\\)"
+   "[ \t\n\r\v\f]+"
+   )
+
+  "Regex for matching the page/control declaration"
+  )
+
+
+(defconst aspx-mode-browser-script-start-re
+  (concat
+   "<\\(script\\|SCRIPT\\)[ \t\n\r\v\f]+"
+   "\\("
+   "type=[\"']text/javascript[\"'][ 
\t\n\r\v\f]+language=[\"'][Jj]ava[Ss]cript[\"']"
+   "\\|"
+   "language=[\"'][Jj]ava[Ss]cript[\"'][ 
\t\n\r\v\f]+type=[\"']text/javascript[\"']"
+   "\\|"
+   "type=[\"']text/javascript[\"']"
+   "\\|"
+   "language=[\"'][Jj]ava[Ss]cript[\"']"
+   "\\)")
+
+"Regex for matching the <script> tag that begins a block of
+browser-side javascript code.  It tries to match on
+<script language='javascript' ...>  or
+<script type='text/javascript' ...>  or
+<script type='text/javascript' language='javascript' ...> or
+<script language='javascript' type='text/javascript' ...>
+")
+
+
+(defconst aspx-mode-css-block-start-re
+  (concat
+   "<\\(style\\|STYLE\\)"
+   "[ \t\n\r\v\f]+"
+   "type=[\"']text/css[\"']"
+   "[ \t\n\r\v\f]*"
+   ">")
+  "Regex to match the beginning of a CSS block."
+  )
+
+
+
+(defvar aspx-mode--last-chunk-result nil
+  "cached result of the last chunk analysis")
+
+(defvar aspx-mode-update-interval 1
+  "The amount of time in seconds after the last change before trying to
+re-fontify the current block.")
+
+(defvar aspx-mode-timer nil)
+
+
+
+
+
+;; When in multi-mode, I want espresso to indent to the
+;; <script> tag.  Use advice on the espresso indentation
+;; calculation, to make that happen.
+(defadvice espresso--proper-indentation (after
+                                         aspx-mode-advice-1
+                                         compile activate)
+  (if (and (boundp 'multi-mode)
+           multi-mode)
+      (if (eq ad-return-value 0)
+          (setq ad-return-value (+ ad-return-value 4)))))
+
+
+
+
+;; =======================================================
+;; dinoch - Thu, 13 May 2010  23:38
+;; factored out so that I can attach advice to it.
+;; Did this for multi-mode support in ASPX files.
+;; =======================================================
+(defun css--proper-indentation ()
+  (save-excursion
+    (back-to-indentation)
+    (let ((p (parse-partial-sexp (point-min) (point)))
+          (end-brace-p (looking-at "}")))
+      (cond
+       ((or (nth 8 p) (looking-at "/[/*]"))
+        (current-indentation))
+       ((save-excursion
+          (and (skip-chars-backward " \t\n:,")
+               (looking-at "[:,]")))
+        (save-excursion
+          (css-re-search-backward "^[ \t]*\\w")
+          (+ (current-indentation) css-indent-level)))
+       ((nth 1 p)
+        (save-excursion
+          (goto-char (nth 1 p))
+          (+ (current-indentation) (if end-brace-p 0 css-indent-level))))
+       (t
+        0)))))
+
+
+(defun css-indent-line ()
+  (interactive)
+  (let ((indent (css--proper-indentation))
+        (offset (- (current-column) (current-indentation))))
+    (indent-line-to indent)
+    (if (> offset 0) (forward-char offset))))
+
+
+
+;; Likewise with css-mode indentation.
+(defadvice css--proper-indentation (after
+                                    aspx-mode-advice-2
+                                    compile activate)
+  (if (and (boundp 'multi-mode)
+           multi-mode)
+      (if (eq ad-return-value 0)
+          (setq ad-return-value (+ ad-return-value 4)))))
+
+
+
+
+
+
+(defun aspx-mode-timer-elapsed ()
+  (aspx-mode-log 2 "timer fired.")
+  ;;(run-hooks 'aspx-mode-timer-elapsed-hook)
+  (aspx-mode-refontify-current-chunk-after-idle))
+
+
+(defun aspx-mode-restart-timer ()
+  (if (timerp aspx-mode-timer) (cancel-timer aspx-mode-timer))
+  (setq aspx-mode-timer
+        (run-with-timer aspx-mode-update-interval nil 
'aspx-mode-timer-elapsed)))
+
+(defun aspx-mode-after-change-fn (begin end length)
+  (aspx-mode-maybe-invalidate-cached-chunk begin end length)
+  (if multi-mode (aspx-mode-restart-timer)))
+
+
+
+(defun aspx-mode-maybe-invalidate-cached-chunk (begin end old-length)
+  (let ((new-length (- end begin))
+        (old-end (+ begin old-length)))
+
+    ;; Invalidate if the length changed (we need to recalc the chunk limits)
+    ;; or if the change traversed the end of the chunk.
+    (if (and aspx-mode--last-chunk-result
+             (or (/= old-length new-length)
+                 (>= old-end  (nth 2 aspx-mode--last-chunk-result))))
+        (setq aspx-mode--last-chunk-result nil))))
+
+
+
+(defun aspx-mode-refontify-current-chunk-after-idle ()
+  "Fontify the current (cached) chunk.  This fn is called after a timer
+expires, when the buffer has sats idle for 2s.
+"
+  (aspx-mode-log 2 "fontifying (%d %d)"
+           (nth 1 aspx-mode--last-chunk-result)
+           (nth 2 aspx-mode--last-chunk-result))
+
+  (if aspx-mode--last-chunk-result
+      ;; Remove text props in the chunk, to force a new fontification
+      ;; later.  Do this within a save-buffer-state, because we're not
+      ;; *really* changing the buffer.
+      (c-save-buffer-state  ()
+        (set-text-properties (nth 1 aspx-mode--last-chunk-result)
+                             (nth 2 aspx-mode--last-chunk-result)
+                             nil))))
+
+
+
+
+
+
+(defun aspx-mode-determine-current-chunk (pos)
+  "Determine the type (mode) and limits of the chunk at POS.
+Return (MODE START END), where MODE is one of `csharp-mode',
+`javascript-mode', `html-mode', or `css-mode',
+and START and END are the limits of the chunk.
+
+Or, maybe return nil if not sure what mode it should be.
+I don't know. The doc is thin and the code is impenetrable.
+
+This method attempts to cache the calculated result and use it
+intelligently.  For example if the first execution determines
+that the POS is within a C# chunk, the limits of that chunk
+are cached. If a subsequent invocation of this method provides a
+POS that is within those limits, the function can safely return
+the same chunk response, without further scanning.
+
+This works as long as the buffer hasn't changed - in other words
+it's just cursor navigation.
+"
+
+  ;; If we're in the right zone, then use the cached value.
+  ;; Don't use the cache if it is HTML mode, because an HTML
+  ;; chunk can contain a javascript chunk, a CSS chunk, a
+  ;; csharp chunk.
+  (if (and aspx-mode--last-chunk-result
+           (> pos (nth 1 aspx-mode--last-chunk-result))
+           (< pos (nth 2 aspx-mode--last-chunk-result))
+           (not (eq 'html-mode (nth 0 aspx-mode--last-chunk-result))))
+      (progn
+        (aspx-mode-log 3 "determine-chunk: pos %d chunk cache %s"
+                       pos
+                       (prin1-to-string aspx-mode--last-chunk-result))
+        aspx-mode--last-chunk-result)
+
+    (let ((mode 'html-mode)
+          (start-of-block (point-min))
+          (end-of-block (point-max))
+          sp ep
+          new-result)
+
+      (save-excursion
+        (save-restriction
+          (widen)
+          (goto-char pos)
+          (cond
+
+           ;; Between <script language='javascript' ..> and </script>?
+           ((save-excursion
+              (and (and (re-search-backward aspx-mode-browser-script-start-re 
nil t)
+                        (setq sp (match-end 0)))
+                   (and (re-search-forward "</\\(script\\|SCRIPT\\)>" nil t)
+                        (setq ep (line-beginning-position)))
+                   (> ep pos)))
+
+            (setq
+             ;;mode 'javascript-mode
+             mode 'espresso-mode
+             start-of-block sp
+             end-of-block (1- ep) ))
+
+
+           ;; Between <style type="text/css"> and </style>?
+           ((save-excursion
+              (and (and (re-search-backward aspx-mode-css-block-start-re nil t)
+                        (setq sp (match-end 0)))
+                   (and (re-search-forward "</\\(style\\|style\\)>" nil t)
+                        (setq ep (line-beginning-position)))
+                   (> ep pos)))
+            (setq mode 'css-mode
+                  start-of-block sp
+                  end-of-block (1- ep) ))
+
+
+           ;; Between <script language='??'  runat='server'> and </script>?
+           ((save-excursion
+              (and (and (re-search-backward aspx-mode-server-script-start-re 
nil t)
+                        (setq sp (match-end 0)))
+                   (and (re-search-forward "</\\(script\\|SCRIPT\\)>" nil t)
+                        (setq ep (line-beginning-position)))
+                   (> ep pos)))
+
+            ;; TODO: support VBNET-mode, too.  Check the language at the
+            ;; start block.
+            (setq mode 'csharp-mode
+                  start-of-block sp
+                  end-of-block (1- ep) ))
+
+           ;; Between <%@ Page...>  and the first <html>
+           ((save-excursion
+              (and (and (re-search-forward "<\\(html\\|HTML\\)>" nil t)
+                        (setq ep (line-beginning-position)))
+                   (> ep pos)))
+
+            ;; TODO: support VBNET-mode, too.  Check the specified language at 
the
+            ;; start block.
+            ;; This works only because csharp-mode has smarts to fontify the
+            ;; @Page directive.
+            (setq mode 'csharp-mode
+                  start-of-block 1
+                  end-of-block (1- ep) ))
+
+
+
+           ;;              ;; Between <html..> and </html>
+           ;;              ((save-excursion
+           ;;                 (and (and (re-search-backward 
"<\\(HTML\\|html\\)>" nil t)
+           ;;                           (setq sp (match-beginning 0)))
+           ;;                      (and (re-search-forward 
"</\\(html\\|HTML\\)>" nil t)
+           ;;                           (setq ep (line-end-position)))
+           ;;                      (> ep pos)))
+           ;;               (setq mode 'html-mode
+           ;;                     start-of-block sp
+           ;;                     end-of-block (1- ep) ))
+
+           (t
+            nil))))
+
+      ;; multi-make-list does not actually make a new list.
+      ;; Instead it destructively modifies the existing list.
+      ;; The doc says it wants to avoid producing a cons cell
+      ;; in the post-command-hook.
+      ;; Therefore, to cache the result, we need to actually
+      ;; cons a distinct list.  To check that the new item is
+      ;; distinct, we need to compare each elt in the list.
+      ;; If that's the case, start a timer.
+      (setq new-result (list mode start-of-block end-of-block))
+
+      (if (or (not (eq (nth 0 new-result) (nth 0 
aspx-mode--last-chunk-result)))
+              (not (eq (nth 1 new-result) (nth 1 
aspx-mode--last-chunk-result)))
+              (not (eq (nth 2 new-result) (nth 2 
aspx-mode--last-chunk-result))))
+          (progn
+            (aspx-mode-log 3 "new chunk, restart timer")
+            (aspx-mode-restart-timer)))
+
+      (setq aspx-mode--last-chunk-result
+            (multi-make-list mode start-of-block end-of-block))
+
+      )))
+
+
+
+(defun aspx-mode ()
+  "Mode for editing ASPX files with embedded C# script blocks,
+as well as CSS, Javascript, and HTML.
+"
+  (interactive)
+  (set (make-local-variable 'multi-mode-alist)
+       ;; This is a very odd data structure. It doesn't make sense that
+       ;; it is formatted this way. The documentation is completely
+       ;; unhelpful.
+       '(
+         (csharp-mode      . aspx-mode-determine-current-chunk)
+         (espresso-mode    . nil)  ;; javascript
+         (css-mode         . nil)
+         (html-mode        . nil)
+         ))
+  (add-hook 'after-change-functions 'aspx-mode-after-change-fn nil t)
+  (multi-mode-install-modes))
+
+
+
+
+
+(provide 'aspx-mode)
diff --git a/csharp-mode.el b/csharp-mode.el
index 6bd9e96..69467f0 100644
--- a/csharp-mode.el
+++ b/csharp-mode.el
@@ -6,6 +6,7 @@
 ;; Modified:   April 2010
 ;; Version:    0.7.5
 ;; Keywords:   c# languages oop mode
+;; X-URL:      http://code.google.com/p/csharpmode/
 
 ;; This program is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
@@ -74,7 +75,6 @@
 ;;
 ;;
 
-
 ;;; Known Bugs:
 ;;
 ;;   Leading identifiers are no longer being fontified, for some reason.
@@ -256,55 +256,79 @@
 ;; csharp-mode utility and feature defuns
 ;; ==================================================================
 
-;; Indention: csharp-mode follows normal indention rules except for
-;; when indenting the #region and #endregion blocks. This function
-;; defines a custom indention to indent the #region blocks properly
-;;
-
 
 (defun csharp-at-vsemi-p (&optional pos)
   "Determines if there is a virtual semicolon at POS or point.
 This is the C# version of the function.
 
 A vsemi is a cc-mode concept implying end-of-statement, without
-a semicolon or close-brace. This happens in C# with an
-attribute decorating a class, method, field, or property.
+a semicolon or close-brace. This happens in 2 cases in C#:
+
+ - after an attribute that decorates a class, method, field, or
+   property.
+
+ - after an ASPNET directive, that appears in a aspx/ashx/ascx file
+
+An example of the former is  [WebMethod] or [XmlElement].
+An example of the latter is something like this:
+
+    <%@ WebHandler Language=\"C#\" Class=\"Handler\" %>
+
 Providing this function allows the indenting in csharp-mode
-to work properly with syntax items that follow attributes.
+to work properly with code that includes attributes and ASPNET
+directives.
 
-Returns t if at the end of a attribute. Otherwise nil.
+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))))
 
-    (if (and (c-safe (backward-sexp) t)
-             (re-search-forward
-              (concat
-                  "\\(\\["
-                  "[ \t\n\r\f\v]*"
-                  "\\("
-                  "\\(?:[A-Za-z_][[:alnum:]]*\\.\\)*"
-                  "[A-Za-z_][[:alnum:]]*"
-                  "\\)"
-                  "[^]]*\\]\\)"
-                  )
-          (1+ pos-or-point) t))
+      (cond
 
-        (progn
-          (c-safe (backward-sexp))
-          (c-backward-syntactic-ws)
-          (cond
+       ;; put a vsemi after an ASPNET directive, like
+       ;; <%@ WebHandler Language="C#" Class="Handler" %>
+       ((looking-back (concat csharp-aspnet-directive-re "$") nil t)
+        t)
+
+       ;; put a vsemi after an attribute, as with
+       ;;   [XmlElement]
+       ((c-safe (backward-sexp) t)
+        (cond
+           ((re-search-forward
+             (concat
+              "\\(\\["
+              "[ \t\n\r\f\v]*"
+              "\\("
+              "\\(?:[A-Za-z_][[:alnum:]]*\\.\\)*"
+              "[A-Za-z_][[:alnum:]]*"
+              "\\)"
+              "[^]]*\\]\\)"
+              )
+             (1+ pos-or-point) t)
 
-           ((eq (char-before) 93)  ;; close sq brace
-            (csharp-at-vsemi-p (point)))
+             (c-safe (backward-sexp))
+             (c-backward-syntactic-ws)
+             (cond
+
+              ((eq (char-before) 93) ;; close sq brace
+               (csharp-at-vsemi-p (point)))
+
+              ((or
+                (eq (char-before) 59) ;; semicolon
+                (eq (char-before) 123) ;; open curly
+                (eq (char-before) 125)) ;; close curly
+               t)
+
+              (t nil)))
+
+           (t nil)))
+
+        (t nil))
+      )))
 
-           ((or
-             (eq (char-before) 59)  ;; semicolon
-             (eq (char-before) 123) ;; open curly
-             (eq (char-before) 125)) ;; close curly
-            t)
 
-           (t nil)))))))
 
 
 (defun csharp-lineup-region (langelem)
@@ -490,7 +514,9 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 ;;(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
@@ -510,7 +536,9 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 
 ;; 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)
 
@@ -528,14 +556,14 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 
 
 ;; The matchers elements can be of many forms.  It gets pretty
-;; complicated.  do a describe-variable on font-lock-keywords to get a
+;; complicated.  Do a describe-variable on font-lock-keywords to get a
 ;; description.  (Why on font-lock-keywords? I don't know, but that's
 ;; where you get the help.)
 ;;
-;; Aside from documentation, the other option of course, is to use
-;; the source code. Look in the source to see what to do.  The
-;; source in cc-fonts uses a defun c-make-font-lock-search-function
-;; to produce most of the matchers.  Called this way:
+;; Aside from the provided documentation, the other option of course, is
+;; to look in the source code as an example for what to do.  The source
+;; in cc-fonts uses a defun c-make-font-lock-search-function to produce
+;; most of the matchers.  Called this way:
 ;;
 ;;   (c-make-font-lock-search-function  regexp '(A B c))
 ;;
@@ -556,14 +584,14 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 ;;        Prop1 = "foo"
 ;;     }
 ;;
-;; sharp-mode needs to fontify the properties in the
+;; csharp-mode needs to fontify the properties in the
 ;; initializer block in font-lock-variable-name-face. The key thing is
 ;; to set the text property on the open curly, using type c-type and
-;; value c-decl-id-start. This apparently allows parse-partial-sexp to
+;; value c-decl-id-start. This apparently allows `parse-partial-sexp' to
 ;; do the right thing, later.
 ;;
 ;; This simple case is easy to handle in a regex, using the basic
-;; c-make-font-lock-search-function form.  But the general syntax for a
+;; `c-make-font-lock-search-function' form.  But the general syntax for a
 ;; constructor + object initializer in C# is more complex:
 ;;
 ;;     new MyType(..arglist..) {
@@ -579,9 +607,9 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 ;; skip over the sexp defined by the parens, then set the text property on
 ;; the appropriate open-curly.
 ;;
-;; To make that happen I needed insight into what the matcher really
-;; ought to be doin.  The output of c-make-font-lock-search-function
-;; before byte-compiling, is:
+;; To make that happen, it's good to have insight into what the matcher
+;; really does.  The output of `c-make-font-lock-search-function' before
+;; byte-compiling, is:
 ;;
 ;; (lambda (limit)
 ;;   (let ((parse-sexp-lookup-properties
@@ -751,15 +779,47 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
   csharp `(
 
            ;; option 1:
-           ;;            ,@(when t
+           ;;            ,@(when condition
            ;;                `((,(byte-compile
            ;;                     `(lambda (limit) ...
-
+           ;;
            ;; option 2:
            ;;            ,`((lambda (limit) ...
+           ;;
+           ;; I don't know how to avoid the (when condition ...) in the
+           ;; byte-compiled version.
+           ;;
+           ;; 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+
+
+           ;; Case 1: invocation of constructor + maybe an object
+           ;; initializer.  Some possible examples that satisfy:
+           ;;
+           ;;   new Foo ();
+           ;;
+           ;;   new Foo () { };
+           ;;
+           ;;   new Foo {  };
+           ;;
+           ;;   new Foo { Prop1= 7 };
+           ;;
+           ;;   new Foo {
+           ;;     Prop1= 7
+           ;;   };
+           ;;
+           ;;   new Foo {
+           ;;     Prop1= 7,
+           ;;     Prop2= "Fred"
+           ;;   };
+           ;;
+           ;;   new Foo {
+           ;;      Prop1= new Bar()
+           ;;   };
+           ;;
+           ;;   new Foo {
+           ;;      Prop1= new Bar { PropA = 5.6F }
+           ;;   };
+           ;;
 
-
-           ;; Case 1: invocation of constructor + maybe an object initializer
            ,@(when t
                `((,(byte-compile
                     `(lambda (limit)
@@ -869,7 +929,15 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
                     )))
 
 
-           ;; Case 2: declaration of enum with or without an explicit base type
+           ;; Case 2: declaration of enum with or without an explicit
+           ;; base type.
+           ;;
+           ;; Examples:
+           ;;
+           ;;  public enum Foo { ... }
+           ;;
+           ;;  public enum Foo : uint { ... }
+           ;;
            ,@(when t
                `((,(byte-compile
                     `(lambda (limit)
@@ -905,6 +973,11 @@ but I could not figure out how to do it.  So I wrote this 
alternative.
 
 
            ;; Case 3: declaration of constructor
+           ;;
+           ;; Example:
+           ;;
+           ;; private Foo(...) {...}
+           ;;
            ,@(when t
                `((,(byte-compile
                     `(lambda (limit)
@@ -1064,6 +1137,51 @@ but I could not figure out how to do it.  So I wrote 
this alternative.
                 nil))
 
 
+           ;; Case 6: directive blocks for .aspx/.ashx/.ascx
+           ,`((lambda (limit)
+                (let ((parse-sexp-lookup-properties
+                       (cc-eval-when-compile
+                         (boundp 'parse-sexp-lookup-properties))))
+
+                  (while (re-search-forward csharp-aspnet-directive-re limit t)
+                    (csharp-log 3 "aspnet template? - %d limit(%d)" 
(match-beginning 1)
+                                limit)
+
+                    (unless
+                        (progn
+                          (goto-char (match-beginning 0))
+                          (c-skip-comments-and-strings limit))
+
+                        (save-match-data
+                          (let ((end-open (+ (match-beginning 0) 3))
+                                (beg-close (- (match-end 0) 2)))
+                            (c-put-font-lock-face (match-beginning 0)
+                                                  end-open
+                                                  'font-lock-preprocessor-face)
+
+                            (c-put-font-lock-face beg-close
+                                                  (match-end 0)
+                                                  'font-lock-preprocessor-face)
+
+                            ;; fontify within the directive
+                            (while (re-search-forward
+                                    ,(concat
+                                      "\\("
+                                      (c-lang-const c-symbol-key)
+                                      "\\)"
+                                      "=?"
+                                      )
+                                    beg-close t)
+
+                            (c-put-font-lock-face (match-beginning 1)
+                                                  (match-end 1)
+                                                  'font-lock-keyword-face)
+                            (c-skip-comments-and-strings beg-close))
+                            ))
+                        (goto-char (match-end 0)))))
+                nil))
+
+
 ;;            ;; Case 5: #if
 ;;            ,@(when t
 ;;                `((,(byte-compile
@@ -2137,18 +2255,8 @@ The return value is meaningless, and is ignored by 
cc-mode.
 ;; ==================================================================
 
 
-;; There's never a need to check for C-style macro definitions in
-;; a C# buffer.
-(defadvice c-beginning-of-macro (around
-                                 csharp-mode-advice-1
-                                 compile activate)
-  (if (c-major-mode-is 'csharp-mode)
-      nil
-    ad-do-it)
-  )
-
 
-;; There's never a need to move over an Obj-C directive in csharp mode
+;; 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)
@@ -2556,8 +2664,9 @@ support C#.
 The hook `c-mode-common-hook' is run with no args at mode
 initialization, then `csharp-mode-hook'.
 
-This mode will automatically add a regexp to the 
`compilation-error-regexp-alist'
-for Csc.exe error and warning messages.
+This mode will automatically add a symbol and regexp to the
+`compilation-error-regexp-alist' and `compilation-error-regexp-alist-alist'
+respectively, for Csc.exe error and warning messages.
 
 Key bindings:
 \\{csharp-mode-map}"
@@ -2608,12 +2717,9 @@ Key bindings:
   ;; to allow next-error to work with csc.exe:
   (setq compilation-scroll-output t)
 
-  ;; allow fill-paragraph to work on xml code doc
-  (set (make-local-variable 'paragraph-separate)
-       "[ \t]*\\(//+\\|\\**\\)\\([ \t]+\\|[ \t]+<.+?>\\)$\\|^\f")
-
 
-  (c-run-mode-hooks 'c-mode-common-hook 'csharp-mode-hook)
+  (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
@@ -2628,8 +2734,20 @@ Key bindings:
   ;; scan the entire buffer for verblit strings
   (csharp-scan-for-verbatim-literals-and-set-props nil nil)
 
-  (local-set-key (kbd "/") 'csharp-maybe-insert-codedoc)
-  (local-set-key (kbd "{") 'csharp-insert-open-brace)
+  (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")
+
+  ;;(message "C#: set paragraph-separate")
+
+  ;; 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]