Sublime modes configure their automatic indentation via certain plist files, documented here. The problem is that the way in which this is done is by denoting lines which signal indent/dedent/ignore with the option of indenting just the next line or all subsequent lines. There is no way to denote a line which signals multiple indents/dedents, and this is a serious limitation for several languages. A quick and obvious example:
{
{
}}
stuff
Imagine a C-like language. While this is poor style, and you can argue about the correct indentation of the third line, the fourth line is clearly correctly indented. More generally:
{{
}}
stuff
Ditto again.
Here’s an example from Scala (you can recreate this example pretty easily in C++ or Java as well, using the switch
/case
construct):
x match {
case Foo =>
things
case Bar =>
more things
}
This is the correct indentation. The trick is on the final line. The }
denotes the closing of two scopes: the pattern match block, and the second match itself. Thus, it should be dedented twice. As far as I can find, there is no way to indicate this in the mode metadata. All I can do is have it dedent a single time.
There’s more tricky things going on here with the second case
line, which must both dedent and indent while the first case
must only indent, but that can be resolved through clever meta scoping.
Anyway, is there anything I’m missing here? As far as I can tell, Sublime just can’t handle this kind of auto-indentation.
My proposal to fix this (again, assuming I’m not missing anything) would be to leverage meta scoping and give a special meta scope (say, meta.indent.increase.1
, where the final sub-scope indicates the number of increases/decreases to apply) to the relevant tokens in the syntax mode. We have more than enough context to do this with extreme precision, and it would allow for very robust auto-indentation. This alternate auto indent/dedent encoding would need to be opted into by modes in their metadata, so that we don’t break old modes which might not correctly apply the scoping.