我该如何修复csharp-mode.el?

时间:2009-11-25 18:56:43

标签: c# emacs

我修复了此处描述的所有问题(以及另外一个),并在emacswiki上发布了the modified
csharp-mode.el (v0.7.1)


csharp-mode I use 几乎非常好。

它适用于大多数事情,但有一些问题:

  • #if / #endif标签打破缩进,但仅限于方法范围内。

  • 应用于结构中字段的属性,中断缩进。 (有时,参见示例)

  • 在实现接口的类中,缩进被破坏。从那时起。

  • 文字字符串(以@为前缀)不能正确显示,实际上如果文字字符串中的最后一个字符是斜线,则会在源文件中从该点向前突破fontification。

  • 我认为还有其他一些问题。

我不是模特作家。

有没有人对这种模式有所改进?
有人想自愿修理这些东西吗?


示例代码

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's 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");
        }
    }

}

1 个答案:

答案 0 :(得分:3)

这段建议似乎解决了缩进问题#1的前半部分。我希望它不会在其他地方引起问题。它只是查找导致错误缩进的条件(语法statement-cont#if#endif(嗯,只是#)))并返回从之前的推断出的语法。对我来说很好,但我不是这里的法官。

(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))))))))))))

紧密的大括号仍然缩进不正确。我认为维护缩进代码的人会知道如何进行更改。这超出了我的理解范围。由cc引擎管理的缩进有104种不同的“案例”......

(与问题2和3的缩进相同,它们都被认为是'statement-cont语法的一部分)。要查看cc引擎认为当前点下的语法是什么,请执行: C-c C-s

关于问题4,文字字符串,上面似乎正确地缩进文字字符串,但是fontification仍然被打破。