// Convert an Irony token to one that is independant of Irony. public Pie.Expressions.Token ConvertToken(Irony.Parsing.Token ironyToken) { var t = new Pie.Expressions.Token(); t.Column = ironyToken.Location.Column; t.Line = ironyToken.Location.Line; t.Position = ironyToken.Location.Position; return(t); }
/// <summary> /// Format selection block /// </summary> /// <param name="entry"></param> /// <param name="textView"></param> internal void FormatBlock(ITextView textView) { int startLine = textView.Selection.Start.Position.GetContainingLine().LineNumber; int endLine = textView.Selection.End.Position.GetContainingLine().LineNumber; ITextSnapshot snapshot = textView.TextSnapshot; int[] indentations; bool[] fixedLines; this.Model.RetrieveIndentationsFromSyntaxTree(out indentations, out fixedLines); //Get long-string and block-comment spans, which are not to be added or removed indentations //Need a new parser and scanner here Irony.Parsing.Parser parser = new Irony.Parsing.Parser(IronyParser.LuaGrammar.Instance); Irony.Parsing.Scanner scanner = parser.Scanner; //rule 1: insert space before and after binary operator if there not any //rule 2: insert space after comma, semicolon if there not any //rule 3: indentation increase inside block //rule 4: multiple spaces replaced by a single space using (var edit = textView.TextBuffer.CreateEdit()) { //IEnumerable<ITextSnapshotLine> lines = view.TextSnapshot.Lines; for (int lineNumber = startLine; lineNumber <= endLine; lineNumber++) { if (fixedLines[lineNumber]) { continue; } ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber); int lineOffset = line.Start.Position; string lineText = line.GetText(); scanner.VsSetSource(lineText, 0); int state = 0; Irony.Parsing.Token currentToken = scanner.VsReadToken(ref state); Irony.Parsing.Token lastToken = null; // add space before the first token if (currentToken != null) { Span editSpan = new Span(lineOffset, currentToken.Location.Position); string indentation = ""; for (int i = 0; i < indentations[lineNumber]; ++i) { indentation += "\t"; } edit.Replace(editSpan, indentation); } while (currentToken != null && currentToken.Terminal.Name != "SYNTAX_ERROR") { Irony.Parsing.Token nextToken = scanner.VsReadToken(ref state); if (currentToken.Text == "+" || currentToken.Text == "=" || currentToken.Text == "*" || currentToken.Text == "\\" || currentToken.Text == "-") { if (lastToken != null) { int spaceStart = lastToken.Location.Position + lastToken.Length; int spaceLength = currentToken.Location.Position - spaceStart; if (spaceLength != 1) { Span span = new Span(lineOffset + spaceStart, spaceLength); edit.Replace(span, " "); } } if (nextToken != null) { int spaceStart = currentToken.Location.Position + currentToken.Length; int spaceLength = nextToken.Location.Position - spaceStart; if (spaceLength != 1) { Span span = new Span(lineOffset + spaceStart, spaceLength); edit.Replace(span, " "); } } } else if (currentToken.Text == "," || currentToken.Text == ";") { if (nextToken != null) { int spaceStart = currentToken.Location.Position + currentToken.Length; int spaceLength = nextToken.Location.Position - spaceStart; if (spaceLength != 1) { Span span = new Span(lineOffset + spaceStart, spaceLength); edit.Replace(span, " "); } } } lastToken = currentToken; currentToken = nextToken; } } edit.Apply(); } }
public IEnumerable <ITagSpan <ClassificationTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { yield break; } var snapShot = spans[0].Snapshot; foreach (var span in spans) { var startLine = span.Start.GetContainingLine(); var endLine = span.End.GetContainingLine(); var startLineNumber = startLine.LineNumber; var endLineNumber = endLine.LineNumber; #region Tag for (int i = startLineNumber; i <= endLineNumber; i++) { var line = spans[0].Snapshot.GetLineFromLineNumber(i); _parser.Scanner.VsSetSource(line.GetText(), 0); int state = 0; _lineStates.TryGetValue(i, out state); Irony.Parsing.Token token = _parser.Scanner.VsReadToken(ref state); while (token != null) { if (token.Category == Irony.Parsing.TokenCategory.Content) { if (token.EditorInfo != null) { ClassificationTag tag; if (TryGetTag(token, out tag)) { if (line.Start.Position + token.Location.Position + token.Length <= line.End.Position) { var location = new SnapshotSpan(snapShot, line.Start.Position + token.Location.Position, token.Length); yield return(new TagSpan <ClassificationTag>(location, tag)); } } } } else if (token.Category == Irony.Parsing.TokenCategory.Comment) { if (line.Start.Position + token.Location.Position + token.Length <= line.End.Position) { var location = new SnapshotSpan(snapShot, line.Start.Position + token.Location.Position, token.Length); yield return(new TagSpan <ClassificationTag>(location, HighlightTag.GetTagWithTokenType(TokenType.Comment))); } } token = _parser.Scanner.VsReadToken(ref state); } int oldState = 0; _lineStates.TryGetValue(i + 1, out oldState); _lineStates[i + 1] = state; //We're going into overtime, process new tags and send the event that these spans need updating! if (oldState != state) { var lineNumber = endLineNumber; while (oldState != state && lineNumber < snapShot.LineCount) { lineNumber++; var dummyToken = _parser.Scanner.VsReadToken(ref state); while (dummyToken != null) { dummyToken = _parser.Scanner.VsReadToken(ref state); } _lineStates.TryGetValue(lineNumber + 1, out oldState); _lineStates[lineNumber + 1] = state; } if (lineNumber >= snapShot.LineCount) { lineNumber = snapShot.LineCount - 1; } var lastLine = snapShot.GetLineFromLineNumber(lineNumber); if (lastLine != null && this.TagsChanged != null) { int length = lastLine.End.Position - endLine.End.Position; var snapShotSpan = new SnapshotSpan(snapShot, endLine.End.Position, length); this.TagsChanged(this, new SnapshotSpanEventArgs(snapShotSpan)); } } } #endregion } }
private bool TryGetTag(Irony.Parsing.Token token, out ClassificationTag tag) { tag = HighlightTag.GetTag(token); return(tag != null); }