Hi All,
I will start with the conclusion because I suspect many would get lost along
that winding description below:
Regular Expression-based indentation rules are doomed. They are unmaintainable
for anything but the basic cases. Nobody can read them.
A far better approach would be one based on scopes alone:
- assign indents to certain scopes
- count all existing scopes at the beginning if a line
- subtract all scopes no longer existing at the end of that line
The result is the indent for that line. Period. Done. Really!
With some gentle grammar support, this would even allow to indent switch
statements etc. to everybody's liking.
Here is how I arrived at that conclusion:
In the last few days I embarked on a crusade to get nested Objective-C method
calls to format like I want them too, eg like so:
[[a b]
c:d
e:[f g]
h:[i
j:k
]
];
Indentation in ObjC is currently governed by the rules in C, but trying to add
on to those quickly leads to madness. Besides ObjC rules do not belong in the C
bundle.
So it occurred to me to use try indentation preferences scoped to the bracketed
scope.
So I created a preference scoped to "meta.bracketed.objc", containing:
{ decreaseIndentPattern = '(?=not)possible';
increaseIndentPattern = '\[';
indentNextLinePattern = '(?=not)possible';
unIndentedLinePattern = '(?=not)possible';
}
That looked promising. Since the decreaseIndentPattern will not work (as the
decrease has to happen outside the scope) I added a simple snippet:
Scope: R:(punctuation.section.scope.end.objc)
Key Equivalent: \n
Content: "\n\t$0\n"
Looking better. But this still fails to do nested scopes. To fix it gets really
complex in a hurry:
increaseIndentPattern = '(?x)
^ # Start of line
[^\[\]]* # non-bracket chars
(?<rel> # This block will skip over nested
square brackets
\[ #
(?: #
(?> [^\[\]]+ ) #
| #
\g<rel> #
)* #
\] #
)? # End skip block
[^\[\]]* # non-bracket chars
\[ # open bracket
[^\[\]]* # non-bracket chars
(?<rer> # This block will skip over nested
square brackets
\[ #
(?: #
(?> [^\[\]]+ ) #
| #
\g<rer> #
)* #
\] #
)? # End skip block
[^\[\]]* # non-bracket chars
$ # End of line
';
That works. But any brackets in strings or character constants will still break
this, not even mentioning comments.
I guess it could be done, though the size of the RE would probably rival the
size of the entire TM2 code.
Gerd
_______________________________________________
textmate-dev mailing list
[email protected]
http://lists.macromates.com/listinfo/textmate-dev