How can I fix csharp-mode.el?

I fixed all the problems described here (and one additional) and posted the modified csharp-mode.el (v0.7.1) in emacswiki


The csharp-mode I use is almost really good.

It works for most things, but has several problems:

  • # if / # endif tags break the indent, but only within the scope of the method.

  • attributes applied to fields within the structure, margins of separation. (sometimes, see example)

  • inside classes that implement interfaces, indentation is violated. from this point forward.

  • Literal lines (with the @ prefix) do not filter out correctly and actually break the font from that point forward in the source file if the last character in the literal line is a slash.

  • I think there are other problems.

I am not a regime writer.

Does anyone have improvements in this mode?
Does anyone want to voluntarily eliminate these few things?


code example

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Xml.Serialization;

namespace Cheeso.Says.TreyIsTheBest
{
    public class Class1
    {
        private void Method1()
        {
            // Problem 1: the following if / endif pair causes indenting to break.
            // This occurs only within the scope of a method. If the #if/#endif  is
            // outside of a method, then the indenting does not break.

            #if DIAGS

                // this first line of code within the conditional scope
                // is indented 
                String StringNumber1;

            // the second line of code within the conditional scope
            // is un-indented
            public String StringNumber2;

            #endif

                // The endif is where I expect it to be, I guess.
                // It in-line with the matched #if.  But the comments here
                // are weirdly indented still further. ??  

                }

        // The prior close-curly is indented 2 units more than I would expect.
    }
    // the close-curly for the class is indented correctly. 


    // ==================================================================
    // ------------------------------------------------------------------

    [StructLayout(LayoutKind.Sequential,
                  CharSet = CharSet.Unicode)]
    public struct Class2
    {
        // Problem 2: when there is an attribute applied to a field
        // within a struct, and the attribute include a newline, then
        // the field indents strangely.  See also "Note 1", and "Note 2"
        // below.
        [MarshalAs(UnmanagedType.ByValArray,
                   SizeConst = 128)]
            public int Value1;

        // Note 1: this indents fine.  
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
        public int Value2;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public class Class3
    {
        public short PrintNameLength;

        [MarshalAs(UnmanagedType.ByValArray,
                   SizeConst = 128)]
        // Note 2: this indents just fine
        public int Value1;
    }

    // ==================================================================
    // ------------------------------------------------------------------

    // Linq Syntax is not a problem as I had originally thought
    public class Class4
    {
        #region eee

        #endregion

        private void Method1()
        {
            var files = Directory.GetFiles("Something");

            var selection = from f in files
                where System.IO.Path.GetFileName(f).StartsWith("C")
                select f;

            foreach (var e in selection)
                Console.WriteLine(e);
        }
    }


    // ==================================================================
    // ------------------------------------------------------------------

    public interface IGuess { }

    public class Class5 : IGuess
    {
        // Problem 3: When a #region tag is used inside a class that
        // implements an interface (or derives from a class) the line
        // following the region tag gets indented one extra unit.

        #region utility

            private static System.Random rnd= new System.Random(); 

        private string FigureCategory()
        {
            return "unknown";
        }

        #endregion


            // You can also see artifacts of the same confusion in
            // methods that have multiple attributes.  Again, this only
            // occurs when the containing class implements a particular
            // interface or derives from a parent class.

        [System.Web.Services.WebMethodAttribute()]
            [return: System.Xml.Serialization.XmlElementAttribute("getContainerObjectsReturn")]
            public String Method1()
        {
            return "Hello.";
        }
    }


    // ==================================================================
    // ------------------------------------------------------------------

    public class Pippo
    {
        // Problem 4: when the final char in an "escaped" string literal is a
        // slash, indenting and fontification breaks.

        List<string> directories = new List<string> { 
            @"C:\Temp\sub1\",

                // The emacs parser thinks the string has not ended.
                // This comment is fontified and indented as if it is in
                // the middle of a string literal.

                @"C:\Temp\sub2\",

            // Because we have another \" at the end of a string,
            // emacs now thinks we're "out" of the string literal.
            // This comment is now indented and fontified correctly. 

            @"C:\Home\"

                // A third \", and now emacs thinks we're back inside the string literal.
                // The rest of the code will be treated as if it were inside the string literal.

            };

        protected void Page_Load(object sender, EventArgs e)
        {
            Console.WriteLine("Hello {0}", "world");
        }
    }

}

+5
source share
1 answer

This piece of advice seems to fix the first half of the indentation problem # 1. I hope this does not cause problems elsewhere. It just searches for a condition that causes bad indentation (syntax statement-contand #ifor #endif(well, only #)) at the beginning of this) and returns the syntax output to this point. It looks good, but I'm not a judge here.

(defvar csharp-mode-syntax-table-no-special-slash
  (let ((res (copy-syntax-table csharp-mode-syntax-table)))
    (modify-syntax-entry ?\\ "w" res)
    res)
  "same as regular csharp-mode-syntax-table, only \\ is not an escape char")

(defadvice c-guess-basic-syntax (after c-guess-basic-syntax-csharp-hack activate)
  "following an #if/#endif, indentation gets screwey, fix it"
  (let ((res ad-return-value))
    (save-excursion
      (save-match-data
        (cond ((and (eq major-mode 'csharp-mode)
                    (eq 'statement-cont (caar res))
                    (progn
                      (goto-char (cadar res))
                      (looking-at "#")))
               ;; when following a #if, try for a redo
               (goto-char (cadar res))
               (setq ad-return-value (c-guess-basic-syntax)))

              ((and (eq major-mode 'csharp-mode)
                    (eq 'string (caar res)))
               ;; inside a string
               ;; check to see if it is a literal
               ;; and if so, redo with modified syntax table
               (let ((p (point))
                     (extent (c-literal-limits)))
                 (when extent
                   (goto-char (- (car extent) 1))
                   (when (looking-at "@\"")
                     ;; yup, a string literal
                     (with-syntax-table csharp-mode-syntax-table-no-special-slash
                       (goto-char p)
                       (setq ad-return-value (c-guess-basic-syntax))))))))))))

- . , , , , . . 104 "" , cc-engine...

( 2 3, statement-cont. , cc , , do: C-c C-s.

4, , , , , .

+3

All Articles