I fixed all the problems described here (and one additional), and posted the modified
csharp-mode.el (v0.7.1) at emacswiki
The csharp-mode I use is almost really good.
It works for most things, but has a few problems:
#if / #endif tags break indentation, but only within the scope of a method.
attributes applied to fields within a struct, break indentation. (sometimes, see example)
within classes that implement interfaces, the indenting is broken. from that point forward.
Literal strings (prefixed with @) do not fontify correctly, and in fact break fontification from that point forward in the source file, if the last character in the literal string is a slash.
I think there are some other problems, too.
I'm not a mode writer.
Has anyone got improvements on that mode?
anyone want to volunteer to fix these few things?
example code
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");
}
}
}