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
textmate-dev@lists.macromates.com
http://lists.macromates.com/listinfo/textmate-dev

Reply via email to