Posted 17 years ago
by Bob Puckett
I am working on a non-mergable SyntaxLangauge. I am using the sample code for PerformLexicalParse with some modifications. In PerformLexicalParse, when a space is added in the editor, I get called with the TextRange representing the space character. Example: if my text is
HelloWorld
and I edit it to
Hello World
the invalid token for the space gets created and PerformLexicalParse gets called. If I parse just the one token, the preceding and following tokens are not necessarily correct. I assume that I actually need to reparse both the preceding and the following token as well, so I set the beginning offset to be the front of the preceding and the edning offset to be the end of the following and then I reparse resulting in 3 tokens. I call parseTarget.OnTokenParsed on each one.
OnTokenParsed returns false after the second token becuase it thinks I don't need to go any farther, but I ignore that becuase I am convinced that I do. Here is the problem - the tokens are not changed in the document. The token representing the space still has a type of Invalid even after the next edit. I have verified that it had the correct type when OnTokenParsed is called, but it never gets reflected in the document.Please help me understand what is going on. Thanks.
HelloWorld
and I edit it to
Hello World
the invalid token for the space gets created and PerformLexicalParse gets called. If I parse just the one token, the preceding and following tokens are not necessarily correct. I assume that I actually need to reparse both the preceding and the following token as well, so I set the beginning offset to be the front of the preceding and the edning offset to be the end of the following and then I reparse resulting in 3 tokens. I call parseTarget.OnTokenParsed on each one.
OnTokenParsed returns false after the second token becuase it thinks I don't need to go any farther, but I ignore that becuase I am convinced that I do. Here is the problem - the tokens are not changed in the document. The token representing the space still has a type of Invalid even after the next edit. I have verified that it had the correct type when OnTokenParsed is called, but it never gets reflected in the document.
public override TextRange PerformLexicalParse(Document document, TextRange parseTextRange, ILexicalParseTarget parseTarget)
{
// Get the offset at which to start and end parsing
// TODO: Implement this differently by backing up a certain number of tokens or document lines
// for the start and moving forward a certain number of tokens or lines for the end
int parseStartOffset = parseTextRange.StartOffset;
int parseThroughOffset = parseTextRange.EndOffset;
LimeToken t = document.Tokens.GetTokenAtOffset(parseStartOffset - 1) as LimeToken;
parseStartOffset = t.StartOffset;
t = document.Tokens.GetTokenAtOffset(parseThroughOffset + 1) as LimeToken;
parseThroughOffset = t.EndOffset;
// Get the ID of the lexical state at the parse start offset
// TODO: Implement this differently by examining the existing token at the parse start offset
int lexicalStateID = 0;
// Initialize the modified start/end offsets
int modifiedStartOffset = parseStartOffset;
int modifiedEndOffset = parseThroughOffset;
// Create a text buffer reader
ITextBufferReader reader = new StringBuilderTextBufferReader(document.GetCoreTextBuffer(), 0, parseStartOffset);
// Notify the parse target that parsing is starting
parseTarget.OnPreParse(parseStartOffset);
// Loop and generate all the tokens... this is optimized for incremental parsing
LimeToken token;
while (!reader.IsAtEnd)
{
// Get the next token
token = myLexicalParser.GetNextToken(reader, lexicalStateID);
lexicalStateID = token.LexicalStateID;
// Update the parse target. OnTokenParsed will return false when it thinks parsing should be done
// but we want to go at least one token farther.
parseTarget.OnTokenParsed(token, reader.Offset - token.StartOffset);
if (token.StartOffset < modifiedStartOffset)
modifiedStartOffset = token.StartOffset;
if (reader.Offset > modifiedEndOffset)
modifiedEndOffset = reader.Offset;
// Quit the loop if we have already parsed all changes
if (reader.Offset >= parseThroughOffset)
break;
}
// Notify the parse target that parsing is ending
parseTarget.OnPostParse();
return new TextRange(modifiedStartOffset, modifiedEndOffset);
}