How to implement SmartEdit in custom parser?

I understand that a parser indicates its ability to perform SmartEdit by including that in the ResetOptions() method. What I’d like to understand is how the editor interacts with the parser when a user hits return and where the parser needs to implement custom logic. My custom parser needs to know about the previous line so it can compute where exactly to put the indent but I’m not sure where to do that, or how. Any advice appreciated!

Hi Bob,

When user hits Enter, the following code is executed by TextSource:

        private string GetAutoIndent(int line)
        {
            if ((indentOptions & IndentOptions.AutoIndent) != 0)
            {
                if (((indentOptions & IndentOptions.SmartIndent) != 0) && NeedFormatText())
                {
                    var parser = lexer as ISyntaxParser;
                    parser.Prepare(fileName, Lines, null, false, PrepareReason.Indentation);
                    string indentStr = parser.GetSmartIndentString(line, true, lines.UseSpaces, lines.GetTabStop(0));

                    if (indentStr == null)
                    {
                        int indent = Math.Max(parser.GetSmartIndent(line, true), 0);
                        indentStr = lines.GetIndentString(GetTabIndent(indent), 0);
                    }

                    return indentStr;
                }

…
}

Parser has to set option SmartIndent, and implement one of the following methods:
GetSmartIndentString or GetSmartIndent

GetSmartIndent works for the advanced-parsers, by looking for the nodes in the SyntaxTree which have Indentation option set.
The most simple example is our XML Parser, which increases indent level inside every xml tag.

GetSmartIndentString is implemented by new-generation parsers such as Roslyn/TypeScript by calling appropriate APIs.

Let me know if it helps or if you need more detailed examples.

Regards,
Dmitry

Yes, some more examples, please. I’m still not 100% sure I understand what I have to return when I implement those methods in my parser. In the case of GetSmartIndentString, is it just a string with as many spaces as I need for the next line? Is it the whole line, including the spaces? In the case of GetSmartIndent, one overload of which returns boolean, what does true mean? what does false mean? There are several overloads of GetSmartIndent, some are protected… so, the dizzying array of choices require some design explanation for those of us who… didn’t implement it. :wink:

But thanks for the example … at least some of the fog is lifting. I see more or less how the public methods are used. I guess I’m just unclear what the implications of the old vs new style parsers (which apparently go different routes in terms of which internal/protected methods they call) are.

Hi Bob,

GetSmartIndentString should return a string containing just white spaces that are used as indentation for the line (spaces or tabs or both)

I believe you mean the method (that returns boolean) :
protected virtual bool GetSmartIndent(ISyntaxNode node, int index, ref int indent)

This one normally should not be overriden.

New-style parsers do not rely on building SyntaxTree, instead they employ external APIs, that’s why we had to introduce a different GetSmartIndent function.

Regards,
Dmitry