private SnapshotSpan? CreateClassification(int sourceLine, string text, ITextSnapshot snapshot) { int descriptionStartPosition = snapshot.GetLineFromLineNumber(sourceLine).Start.Position; int lineNumber = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Count() + sourceLine; if (snapshot.LineCount <= lineNumber) return null; int descriptionEndPosition = snapshot.GetLineFromLineNumber(lineNumber).Start.Position; var descriptionSpan = new Span(descriptionStartPosition, descriptionEndPosition - descriptionStartPosition); return new SnapshotSpan(snapshot, descriptionSpan); }
public static SnapshotSpan CreateSpan(this IEnumerable<IGherkinFileBlock> changedBlocks, ITextSnapshot textSnapshot) { VisualStudioTracer.Assert(changedBlocks.Count() > 0, "there is no changed block"); int minLineNumber = changedBlocks.First().GetStartLine(); int maxLineNumber = changedBlocks.Last().GetEndLine(); var minLine = textSnapshot.GetLineFromLineNumber(minLineNumber); var maxLine = minLineNumber == maxLineNumber ? minLine : textSnapshot.GetLineFromLineNumber(maxLineNumber); return new SnapshotSpan(minLine.Start, maxLine.EndIncludingLineBreak); }
public List<MarkerLine> GetMarkerLinesForFile(ITextSnapshot textSnapshot) { var lines = new List<MarkerLine>(); if (_threadFixPlugin == null || _threadFixPlugin.MarkerLookUp == null) { return lines; } var filename = textSnapshot.TextBuffer.GetTextDocument().FilePath.ToLower(); var markers = new List<VulnerabilityMarker>(); if(_threadFixPlugin.MarkerLookUp.TryGetValue(filename, out markers) && !string.IsNullOrEmpty(filename)) { foreach (var marker in markers) { if (marker.LineNumber.HasValue && marker.LineNumber.Value > 0 && marker.LineNumber.Value < textSnapshot.LineCount) { lines.Add(new MarkerLine(textSnapshot.GetLineFromLineNumber(marker.LineNumber.Value - 1), marker.GenericVulnName)); } } } return lines; }
private async Task<Document> DetermineNewDocumentAsync(MemberInsertionCompletionItem completionItem, ITextSnapshot textSnapshot, CancellationToken cancellationToken) { // The span we're going to replace var line = textSnapshot.GetLineFromLineNumber(completionItem.Line); var sourceText = textSnapshot.AsText(); var document = sourceText.GetOpenDocumentInCurrentContextWithChanges(); Contract.ThrowIfNull(document); // Annotate the line we care about so we can find it after adding usings var tree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken); var token = GetToken(completionItem, tree, cancellationToken); var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation)); document = document.WithSyntaxRoot(annotatedRoot); var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false); var insertionRoot = PrepareTreeForMemberInsertion(memberContainingDocument, cancellationToken); var insertionText = GenerateInsertionText(memberContainingDocument, cancellationToken); var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText); var finalText = insertionRoot.GetText(sourceText.Encoding).Replace(destinationSpan, insertionText.Trim()); document = document.WithText(finalText); var newRoot = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken); var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End)); document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation))); return Formatter.FormatAsync(document, _annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); }
/// <summary> /// Asynchronously constructs a line map from a <paramref name="snapshot"/> and <paramref name="code"/>. /// </summary> /// <param name="snapshot">The current text snapshot.</param> /// <param name="code">The code to derive a line map from.</param> /// <param name="cancelToken">Cancellation token.</param> /// <returns> /// A <see cref="LineMap"/> if <paramref name="code"/> was parsed correctly, /// <c>null</c> if there was invalid code or it was canceled. /// </returns> internal static Task<LineMap> ConstructAsync(ITextSnapshot snapshot, string code, CancellationToken cancelToken) { if (snapshot == null) throw new ArgumentNullException ("snapshot"); if (code == null) throw new ArgumentNullException ("code"); return Task<LineMap>.Factory.StartNew (() => { try { var tree = SyntaxTree.Parse (code, cancellationToken: cancelToken); if (tree.Errors.Any (p => p.ErrorType == ErrorType.Error)) return null; var identifier = new IdentifyingVisitor(); tree.AcceptVisitor (identifier); var spans = new Dictionary<int, ITrackingSpan> (identifier.LineMap.Count); foreach (var kvp in identifier.LineMap) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber (kvp.Value - 1); ITrackingSpan span = snapshot.CreateTrackingSpan (line.Extent, SpanTrackingMode.EdgeExclusive); spans.Add (kvp.Key, span); } return (cancelToken.IsCancellationRequested) ? null : new LineMap (spans); } catch (OperationCanceledException) { return null; } }, cancelToken); }
private static Span SnapshotSpanToSpan(ITextSnapshot snapshot, TokenInfo token, int lineNumber) { var line = snapshot.GetLineFromLineNumber(lineNumber); var index = line.Start.Position + token.SourceSpan.Start.Column - 1; var tokenSpan = new Span(index, token.SourceSpan.Length); return(tokenSpan); }
public string GetLine(int lineNo) { if (lineNo > 0) { return(_snapshot.GetLineFromLineNumber(lineNo - 1).GetText()); } return(null); }
private void ColorizeSpan(GherkinBufferSpan span, IClassificationType classificationType) { if (span == null) { return; } var startLine = textSnapshot.GetLineFromLineNumber(span.StartPosition.Line); var endLine = span.StartPosition.Line == span.EndPosition.Line ? startLine : textSnapshot.GetLineFromLineNumber(span.EndPosition.Line); var startIndex = startLine.Start + span.StartPosition.LinePosition; var endLinePosition = span.EndPosition.LinePosition == endLine.Length ? endLine.LengthIncludingLineBreak : span.EndPosition.LinePosition; var length = endLine.Start + endLinePosition - startIndex; AddClassification(classificationType, startIndex, length); }
public override TextLine this[int index] { get { var line = _snapshot.GetLineFromLineNumber(index); return(new TextLine(_sourceText, line.Start, line.Length)); } }
public string GetLine(int lineNo) { try { return(_snapshot.GetLineFromLineNumber(lineNo - 1).GetText()); } catch (ArgumentOutOfRangeException) { return(string.Empty); } }
private static bool LineIsInclude(ITextSnapshot snapshot, int lineIndex) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineIndex); string lineText = line.GetText().Trim(); bool result = lineText.StartsWith("#include"); return(result); }
/// <summary> /// Rescans the part of the buffer affected by a change. /// Scans a contiguous sub-<paramref name="span"/> of a larger code span which starts at <paramref name="codeStartLine"/>. /// </summary> private void ApplyChange(Tokenizer tokenizer, ITextSnapshot snapshot, Span span, int codeStartLine, int codeStartLineOffset) { int firstLine = snapshot.GetLineNumberFromPosition(span.Start); int lastLine = snapshot.GetLineNumberFromPosition(span.Length > 0 ? span.End - 1 : span.End); Contract.Assert(codeStartLineOffset >= 0); Contract.Assert(firstLine >= codeStartLine); // find the closest line preceding firstLine for which we know categorizer state, stop at the codeStartLine: LineTokenization lineTokenization; firstLine = _tokenCache.IndexOfPreviousTokenization(firstLine, codeStartLine, out lineTokenization) + 1; object state = lineTokenization.State; int currentLine = firstLine; object previousState; while (currentLine < snapshot.LineCount) { previousState = _tokenCache.TryGetTokenization(currentLine, out lineTokenization) ? lineTokenization.State : null; _tokenCache[currentLine] = lineTokenization = TokenizeLine(tokenizer, snapshot, state, currentLine, (currentLine == codeStartLine) ? codeStartLineOffset : 0); state = lineTokenization.State; // stop if we visted all affected lines and the current line has no tokenization state or its previous state is the same as the new state: if (currentLine > lastLine && (previousState == null || previousState.Equals(state))) { break; } currentLine++; } // classification spans might have changed between the start of the first and end of the last visited line: int changeStart = snapshot.GetLineFromLineNumber(firstLine).Start; int changeEnd = (currentLine < snapshot.LineCount) ? snapshot.GetLineFromLineNumber(currentLine).End : snapshot.Length; if (changeStart < changeEnd) { var classificationChanged = ClassificationChanged; if (classificationChanged != null) { var args = new ClassificationChangedEventArgs(new SnapshotSpan(snapshot, new Span(changeStart, changeEnd - changeStart))); classificationChanged(this, args); } } }
internal static IEnumerable <TagSpan> ProcessCellTags(ITextSnapshot snapshot, CancellationToken cancel) { if (snapshot.LineCount == 0) { yield break; } // Walk lines and attempt to find code cell tags var line = snapshot.GetLineFromLineNumber(0); int previousCellStart = -1; while (line != null) { cancel.ThrowIfCancellationRequested(); var cellStart = CodeCellAnalysis.FindStartOfCell(line); if (cellStart == null || cellStart.LineNumber == previousCellStart) { if (line.LineNumber + 1 < snapshot.LineCount) { line = snapshot.GetLineFromLineNumber(line.LineNumber + 1); } else { break; } } else { previousCellStart = cellStart.LineNumber; var cellEnd = CodeCellAnalysis.FindEndOfCell(cellStart, line); if (cellEnd.LineNumber > cellStart.LineNumber) { yield return(GetTagSpan(snapshot, cellStart.Start, cellEnd.End)); } if (cellEnd.LineNumber + 1 < snapshot.LineCount) { line = snapshot.GetLineFromLineNumber(cellEnd.LineNumber + 1); } else { break; } } } }
public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) { yield break; } List <Region> currentRegions = this.regions; ITextSnapshot currentSnapshot = this.snapshot; SnapshotSpan entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive); int startLineNumber = entire.Start.GetContainingLine().LineNumber; int endLineNumber = entire.End.GetContainingLine().LineNumber; foreach (var region in currentRegions) { if (region.StartLine <= endLineNumber && region.EndLine >= startLineNumber) { var startLine = currentSnapshot.GetLineFromLineNumber(region.StartLine); var endLine = currentSnapshot.GetLineFromLineNumber(region.EndLine); StringBuilder sb = new StringBuilder(); for (int i = startLine.LineNumber; i <= endLine.LineNumber; i++) { string text = currentSnapshot.GetLineFromLineNumber(i).GetText(); if (text.Length > 80) { text = text.Substring(0, 77) + "..."; } sb.AppendLine(text); if (i > startLine.LineNumber + 5) { sb.AppendLine("..."); break; } } //the region starts at the beginning of the "{", and goes until the *end* of the line that contains the "}". yield return(new TagSpan <IOutliningRegionTag>( new SnapshotSpan(startLine.Start + region.StartOffset, endLine.End), new OutliningRegionTag(false, false, (region.Text ?? string.Empty) + ellipsis, sb.ToString()))); } } }
private void CreateTagSpans(ITextSnapshot snapshot) { int lineNumber = 0; ITextSnapshotLine line = snapshot.GetLineFromLineNumber(0); foreach (ParsedSpan span in Scanner.GetSpans(snapshot.GetText(), false)) { if (span.LineNumber > lineNumber) { lineNumber = span.LineNumber; line = snapshot.GetLineFromLineNumber(lineNumber); } IClassificationType type = _typeRegistry.GetClassificationType(TokenToClassification[span.Type]); CreateTag(line, span.Start, span.Text.Length, type); } }
/// <summary> /// Given a node and lineAboveText enable collapsing for line /// showing the line above text. /// </summary> /// <param name="node"></param> /// <param name="lineAboveText"></param> private void AddTagIfNecessaryShowLineAbove(Node node, string lineAboveText) { int line = _snapshot.GetLineNumberFromPosition(node.StartIndex); var startsWithElse = _snapshot.GetLineFromLineNumber(line).GetText().Trim().StartsWith(lineAboveText); if (startsWithElse) { // this line starts with the 'above' line, don't adjust line int startIndex = _snapshot.GetLineFromLineNumber(line).Start.Position; AddTagIfNecessary(startIndex, node.EndIndex); } else { // line is below the 'above' line int startIndex = _snapshot.GetLineFromLineNumber(line - 1).Start.Position; AddTagIfNecessary(startIndex, node.EndIndex); } }
public override int ValidateBreakpointLocation(IVsTextBuffer buffer, int line, int col, TextSpan[] pCodeSpan) { var componentModel = ServiceProvider.GetComponentModel(); var adapterFactoryService = componentModel.DefaultExportProvider.GetExport <IVsEditorAdaptersFactoryService>(); ITextBuffer textBuffer = adapterFactoryService.Value.GetDataBuffer(buffer); ITextSnapshot snapshot = textBuffer.CurrentSnapshot; ITextSnapshotLine snapshotLine = snapshot.GetLineFromLineNumber(line); string lineText = snapshotLine.GetText(); IList <IParseTree> statementTrees; IList <IToken> tokens; if (!LineStatementAnalyzer.TryGetLineStatements(textBuffer, line, out statementTrees, out tokens)) { return(VSConstants.E_FAIL); } IParseTree tree = null; for (int i = statementTrees.Count - 1; i >= 0; i--) { // want the last tree ending at or after col IParseTree current = statementTrees[i]; if (current.SourceInterval.Length == 0) { continue; } IToken token = tokens[current.SourceInterval.b]; if (token.Line - 1 < line) { break; } if (token.Line - 1 == line && (token.Column + token.StopIndex - token.StartIndex + 1) < col) { break; } tree = current; } if (tree == null) { return(VSConstants.E_FAIL); } IToken startToken = tokens[tree.SourceInterval.a]; IToken stopToken = tokens[tree.SourceInterval.b]; pCodeSpan[0].iStartLine = startToken.Line - 1; pCodeSpan[0].iStartIndex = startToken.Column; pCodeSpan[0].iEndLine = stopToken.Line - 1; pCodeSpan[0].iEndIndex = stopToken.Column + stopToken.StopIndex - stopToken.StartIndex + 1; return(VSConstants.S_OK); }
internal void Navigate(ITextSnapshot snapshot, int line, int column) { CheckDisposed(); var snapshotLine = snapshot.GetLineFromLineNumber(line); var snapshotPoint = snapshotLine.Start + column; NavigateTo(snapshotPoint); _wpfTextView.ToVsTextView()?.SendExplicitFocus(); }
public static void replaceWord(ITextSnapshot snapshot, int lineStart, string oldWord, string newWord) { var line = snapshot.GetLineFromLineNumber(lineStart); int position = line.Start.Position + line.GetText().IndexOf(oldWord); Span oldSpan = new Span(position, oldWord.Length); snapshot.TextBuffer.Replace(oldSpan, newWord); }
private string GetFormattedTableText(IHasRows hasRows, string indent, string newLine, TableCaretPosition caretPosition, ITextSnapshot textSnapshot, out int newCaretLinePosition) { var widths = GetWidths(hasRows); int nextLine = ((IHasLocation)hasRows).Location.Line; var result = new StringBuilder(); foreach (var row in hasRows.Rows) { while (row.Location.Line > nextLine) { var nonRowLine = textSnapshot.GetLineFromLineNumber(nextLine - 1); result.Append(nonRowLine.GetText()); result.Append(newLine); nextLine++; } result.Append(indent); result.Append("|"); foreach (var item in row.Cells.Select((c, i) => new { c, i })) { result.Append(new string(' ', PADDING_LENGHT)); result.Append(Escape(item.c.Value).PadRight(widths[item.i])); result.Append(new string(' ', PADDING_LENGHT)); result.Append('|'); } var lineText = textSnapshot.GetLineFromLineNumber(nextLine - 1).GetText(); var unfinishedCell = GetUnfinishedCell(lineText); if (unfinishedCell != null) { result.Append(' '); result.Append(unfinishedCell); } result.Append(newLine); nextLine++; } result.Remove(result.Length - newLine.Length, newLine.Length); newCaretLinePosition = CalculateNewCaretLinePosition(caretPosition, widths, indent); return(result.ToString()); }
public override bool Unindent() { if (_startPoint.LineNumber == _endPoint.LineNumber) { return(_startPoint.RemovePreviousIndent()); } using (ITextEdit edit = TextBuffer.AdvancedTextBuffer.CreateEdit()) { ITextSnapshot snapshot = TextBuffer.AdvancedTextBuffer.CurrentSnapshot; for (int i = _startPoint.LineNumber; i <= _endPoint.LineNumber; i++) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(i); if ((line.Length > 0) && (_endPoint.CurrentPosition != line.Start)) { if (snapshot[line.Start] == '\t') { if (!edit.Delete(new Span(line.Start, 1))) { return(false); } } else { int spacesToRemove = 0; for (; (line.Start + spacesToRemove < snapshot.Length) && (spacesToRemove < _editorOptions.GetTabSize()); spacesToRemove++) { if (snapshot[line.Start + spacesToRemove] != ' ') { break; } } if (spacesToRemove > 0) { if (!edit.Delete(new Span(line.Start, spacesToRemove))) { return(false); } } } } } edit.Apply(); if (edit.Canceled) { return(false); } } return(true); }
private void SetLineInfo_Performance( LineInfo[] lineInfo, ITextSnapshot snapshot, int firstLine, int lastLine, CancellationToken cancel ) { #endif var contentType = snapshot.ContentType != null ? snapshot.ContentType.TypeName : null; bool isCSharp = string.Equals(contentType, "csharp", StringComparison.OrdinalIgnoreCase); bool isCPlusPlus = string.Equals(contentType, "c/c++", StringComparison.OrdinalIgnoreCase); for (int lineNumber = firstLine; lineNumber <= lastLine; ++lineNumber) { cancel.ThrowIfCancellationRequested(); var line = snapshot.GetLineFromLineNumber(lineNumber); var curLine = lineInfo[lineNumber - firstLine]; curLine.Number = lineNumber; curLine.HasText = false; curLine.TextAt = 0; var text = line.GetText(); if (string.IsNullOrEmpty(text)) { lineInfo[lineNumber - firstLine] = curLine; continue; } var normalizedLength = text.ActualLength(TabSize); if (normalizedLength > LongestLine) { LongestLine = normalizedLength; } bool allWhitespace; int spaces = text.LeadingWhitespace(TabSize, out allWhitespace); curLine.HasText = !allWhitespace; curLine.TextAt = spaces; if (isCSharp || isCPlusPlus) { // Left-aligned pragmas don't reduce the indent to zero. if (spaces == 0 && text.StartsWith("#")) { curLine.SkipLine = true; } } lineInfo[lineNumber - firstLine] = curLine; } cancel.ThrowIfCancellationRequested(); }
internal static SnapshotSpan CreateSpan(this ITextSnapshot snapshot, int lineNumber, int columnStart, int columnEnd) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber); SnapshotSpan span = new SnapshotSpan( line.Start + columnStart, columnEnd - columnStart); return(span); }
/// <summary> /// Rollback modified text. /// </summary> /// <param name="diffChange">Information about a specific difference between two sequences.</param> private void RollbackChange(IDiffChange diffChange) { ITextEdit edit = _textView.TextBuffer.CreateEdit(); try { ITextSnapshot snapshot = edit.Snapshot; ITextSnapshotLine startLine = snapshot.GetLineFromLineNumber(diffChange.ModifiedStart); ITextSnapshotLine endLine = snapshot.GetLineFromLineNumber(diffChange.ModifiedEnd); int start; if (diffChange.ChangeType != DiffChangeType.Delete) { start = startLine.Start.Position; int length = endLine.EndIncludingLineBreak.Position - start; edit.Delete(start, length); } else { if (startLine.LineNumber == 0 && endLine.LineNumber == 0) { start = startLine.Start.Position; } else { start = startLine.EndIncludingLineBreak.Position; } } if (diffChange.ChangeType != DiffChangeType.Insert) { string text = _marginCore.GetOriginalText(diffChange, false); edit.Insert(start, text); } ApplyEdit(edit, "Rollback Modified Region"); } catch (Exception) { edit.Cancel(); throw; } }
public SnapshotSpan CalculateSpan(IAnalysisIssueLocation location, ITextSnapshot currentSnapshot) { if (location.StartLine > currentSnapshot.LineCount) { // Race condition: the line reported in the diagnostic is beyond the end of the file, so presumably // the file has been edited while the analysis was being executed return(EmptySpan); } // SonarLint issues line numbers are 1-based, spans lines are 0-based var startLine = currentSnapshot.GetLineFromLineNumber(location.StartLine - 1); if (IsLineHashDifferent(location, startLine)) { // Out of sync: the line reported in the diagnostic has been edited, so we can no longer calculate the span return(EmptySpan); } var maxLength = currentSnapshot.Length; var startPos = startLine.Start.Position + location.StartLineOffset; int endPos; if (location.EndLine == 0 || // Special case : EndLine = 0 means "select whole of the start line, ignoring the offset" startPos > maxLength) // Defensive : issue start position is beyond the end of the file. Just select the last line. { startPos = startLine.Start.Position; endPos = startLine.Start.Position + startLine.Length; } else { endPos = currentSnapshot.GetLineFromLineNumber(location.EndLine - 1).Start.Position + location.EndLineOffset; // Make sure the end position isn't beyond the end of the snapshot either endPos = Math.Min(maxLength, endPos); } var start = new SnapshotPoint(currentSnapshot, startPos); var end = new SnapshotPoint(currentSnapshot, endPos); return(new SnapshotSpan(start, end)); }
internal void EndorseTextBounds(int lineStart, int lineEnd, int charStart, int charEnd) { if (applied) { throw new InvalidOperationException("This adornment is already applied."); } ITextSnapshot textSnapshot = view.TextSnapshot; ITextSnapshotLine textViewStartLine = textSnapshot.GetLineFromLineNumber(lineStart); ITextSnapshotLine textViewEndLine = textSnapshot.GetLineFromLineNumber(lineEnd); SnapshotSpan span = new SnapshotSpan( view.TextSnapshot, Span.FromBounds( textViewStartLine.Start + charStart, textViewEndLine.Start + charEnd)); IWpfTextViewLineCollection textViewLines = view.TextViewLines; Geometry geometry = textViewLines.GetMarkerGeometry(span); if (geometry != null) { var drawing = new GeometryDrawing(brush, pen, geometry); drawing.Freeze(); var drawingImage = new DrawingImage(drawing); drawingImage.Freeze(); var image = new Image { Source = drawingImage, }; // Align the image with the top of the bounds of the text geometry Canvas.SetLeft(image, geometry.Bounds.Left); Canvas.SetTop(image, geometry.Bounds.Top); layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, this, image, null); } applied = true; }
private void OnTextBufferChanged(object sender, TextContentChangedEventArgs e) { ITextSnapshot snapshot = e.After; // First update _lineCache so its size matches snapshot.LineCount. foreach (ITextChange change in e.Changes) { if (change.LineCountDelta > 0) { int line = snapshot.GetLineFromPosition(change.NewPosition).LineNumber; State state = State.Default; // Copy the state of the line to continue multi-line comments and strings. If not, // we lose the state and it doesn't parse the spans correctly. if (line < _lineCache.Count) { state = _lineCache[line]; } _lineCache.InsertRange(line, Enumerable.Repeat(state, change.LineCountDelta)); } else if (change.LineCountDelta < 0) { int line = snapshot.GetLineFromPosition(change.NewPosition).LineNumber; _lineCache.RemoveRange(line, -change.LineCountDelta); } } // Now that _lineCache is the appropriate size we can safely start rescanning. // If we hadn't updated _lineCache, then rescanning could walk off the edge. List <SnapshotSpan> changedSpans = new List <SnapshotSpan>(); foreach (ITextChange change in e.Changes) { ITextSnapshotLine startLine = snapshot.GetLineFromPosition(change.NewPosition); ITextSnapshotLine endLine = snapshot.GetLineFromPosition(change.NewPosition); int lastUpdatedLine = RescanLines(snapshot, startLine.LineNumber, endLine.LineNumber); changedSpans.Add(new SnapshotSpan(startLine.Start, snapshot.GetLineFromLineNumber(lastUpdatedLine).End)); } _lineCacheSnapshot = snapshot; var tagsChanged = TagsChanged; if (tagsChanged != null) { foreach (SnapshotSpan span in changedSpans) { tagsChanged(this, new SnapshotSpanEventArgs(span)); } } }
private string Get_Hover_Text_String(int beginLineNumber, int endLineNumber, ITextSnapshot snapshot) { StringBuilder sb = new StringBuilder(); int numberOfLines = Math.Min(endLineNumber + 1 - beginLineNumber, 40); // do not show more than 40 lines for (int i = 0; i < numberOfLines; ++i) { sb.AppendLine(snapshot.GetLineFromLineNumber(beginLineNumber + i).GetText()); } return(sb.ToString().TrimEnd()); }
// Parse the document from the current position until we find the // matching closing tag private SnapshotSpan?FindClosingTag(ITextSnapshot snapshot, int searchStart, string searchFor) { String textToSearch = snapshot.GetText(searchStart, snapshot.Length - searchStart); using (SgmlReader reader = new SgmlReader()) { reader.InputStream = new StringReader(textToSearch); reader.WhitespaceHandling = WhitespaceHandling.All; try { reader.Read(); if (!reader.IsEmptyElement) { // skip all the internal nodes, until the end while (reader.Read()) { if (reader.NodeType == XmlNodeType.EndElement && reader.Depth == 1) { break; } } // calculate the new position based on the number of lines // read in the SgmlReader + the position within that line. // Note that if there is whitespace after the closing tag // we'll be positioned on it, so we need to keep track of that. var origLine = snapshot.GetLineFromPosition(searchStart); int startOffset = searchStart - origLine.Start.Position; int newStart = 0; // tag is on same position as the opening one if (reader.LineNumber == 1) { var line = snapshot.GetLineFromPosition(searchStart); newStart = line.Start.Position + startOffset + reader.LinePosition - 2; } else { int newLineNum = origLine.LineNumber + reader.LineNumber - 1; var newLine = snapshot.GetLineFromLineNumber(newLineNum); newStart = newLine.Start.Position + reader.LinePosition - 1; } newStart -= reader.Name.Length + 3; // </ + element + > SnapshotSpan?newSpan = new SnapshotSpan(snapshot, newStart, searchFor.Length); if (newSpan.Value.GetText() != searchFor) { Trace.WriteLine(String.Format("Searching for '{0}', but found '{1}'.", searchFor, newSpan.Value.GetText())); newSpan = null; } return(newSpan); } } catch (Exception ex) { Trace.WriteLine(String.Format("Exception while parsing document: {0}.", ex.ToString())); } } return(null); }
public IEnumerable <ITagSpan <LuaErrorTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0 || this.errorTokens.Count == 0) { yield break; } List <Irony.Parsing.Token> currentErrors = this.errorTokens; ITextSnapshot currentSnapshot = spans[0].Snapshot; SnapshotSpan entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive); int startLineNumber = entire.Start.GetContainingLine().LineNumber; int endLineNumber = entire.End.GetContainingLine().LineNumber; int count = 0; foreach (var error in currentErrors) { count++; if (error.Location.Line <= endLineNumber && error.Location.Line >= startLineNumber) { var line = currentSnapshot.GetLineFromLineNumber(error.Location.Line); var startPosition = error.Location.Position; int length = error.Length; if (length == 0) { length = 1; //startPosition -= 1; } else { length = Math.Min(length, 100); var len = currentSnapshot.Length - error.Location.Position - 1; if (len > 0) { length = Math.Min(len, length); } } var msg = error.ValueString; if (count == currentErrors.Count() && msgParse != "") { msg = msgParse; } if (currentSnapshot.Length >= startPosition + length) { yield return(new TagSpan <LuaErrorTag>( new SnapshotSpan(currentSnapshot, startPosition, length), new LuaErrorTag(msg))); } } } }
public IEnumerable <ITagSpan <IOutliningRegionTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count != 0) { List <OneSClassifier.Region> currentRegions = this.regions; ITextSnapshot currentSnapshot = this.snapshot; SnapshotSpan entire = new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End).TranslateTo(currentSnapshot, SpanTrackingMode.EdgeExclusive); int startLineNumber = entire.Start.GetContainingLine().LineNumber; int endLineNumber = entire.End.GetContainingLine().LineNumber; foreach (OneSClassifier.Region region in currentRegions) { if (region.StartLine <= endLineNumber && region.EndLine >= startLineNumber) { ITextSnapshotLine startLine = currentSnapshot.GetLineFromLineNumber(region.StartLine); ITextSnapshotLine endLine = currentSnapshot.GetLineFromLineNumber(region.EndLine); yield return((ITagSpan <IOutliningRegionTag>) new TagSpan <IOutliningRegionTag>(new SnapshotSpan(startLine.Start + region.StartOffset, endLine.End), (IOutliningRegionTag) new OutliningRegionTag(false, false, (object)this.ellipsis, (object)region.HoverText))); } } } }
/// <summary> /// Get a <see cref="SnapshotPoint"/> representing the specified (0-based) line and column in the <paramref name="snapshot"/>. /// </summary> /// <param name="snapshot"> /// The <see cref="ITextSnapshot"/>. /// </param> /// <param name="line"> /// The target line (0-based). /// </param> /// <param name="column"> /// The target column (0-based). /// </param> /// <returns> /// The <see cref="SnapshotPoint"/>. /// </returns> public static SnapshotPoint GetPoint(this ITextSnapshot snapshot, long line, long column) { if (snapshot == null) { throw new ArgumentNullException(nameof(snapshot)); } ITextSnapshotLine snapshotLine = snapshot.GetLineFromLineNumber((int)line); return(snapshotLine.Start.Add((int)column)); }
public void ExtractVariable() { string selection = view.Selection.SelectedSpans[0].GetText(); ITextSnapshot snapshot = view.TextBuffer.CurrentSnapshot; // Verify the selected text doesn't contain mismatched quotes or braces. if (!hasIntegrity(selection)) { throw new UnrecognisedExpressionException(); } // Check that what comes after is .,);} or operator char next = NextNonWhiteSpaceCharacter(snapshot); if (!permissableFollowing.Contains(next)) { throw new UnrecognisedExpressionException(); } // Check that what comes before is (,= or operator char prev = PreviousNonWhiteSpaceCharacter(snapshot); if (!permissablePreceding.Contains(prev)) { throw new UnrecognisedExpressionException(); } // Get a variable name from the supplied provider. string varName = nameProvider.GetName(); if (varName == null) { return; } int lineNumber = FindLineAfterWhichToInsertDeclaration(snapshot, view.Selection.SelectedSpans[0].Start.Position); if (lineNumber < 0) { throw new FailedInsertionPointException(); } // replace selection with variable name. ITextEdit edit = snapshot.TextBuffer.CreateEdit(); edit.Replace(view.Selection.SelectedSpans[0], varName); int indentSize = GetIndentOfNextNonBlankLine(snapshot, lineNumber); // Add declaration. edit.Insert(snapshot.GetLineFromLineNumber(lineNumber + 1).Start.Position, ("".PadLeft(indentSize) + "var " + varName + " = " + selection + ";\n")); edit.Apply(); }
internal static SnapshotPoint LineIndexToSnapshotPoint(int line, int index, ITextSnapshot snapshot) { if (line >= snapshot.LineCount) { return(new SnapshotPoint(snapshot, snapshot.Length)); } ITextSnapshotLine l = snapshot.GetLineFromLineNumber(line); return(l.Start + Math.Min(index, l.Length)); }
private void TextBufferChanged(object sender, TextContentChangedEventArgs e) { ITextSnapshot snapshot = _buffer.CurrentSnapshot;// e.After; // Add lines to and remove lines from line state list foreach (ITextChange change in e.Changes) { if (change.LineCountDelta > 0) { // Add new lines to line state list int line = snapshot.GetLineFromPosition(change.NewPosition).LineNumber; for (int i = 0; i < change.LineCountDelta; i++) { _lineStartState.Insert(line + 1, Lexer.newState); } } else if (change.LineCountDelta < 0) { // Remove lines from line state list int line = snapshot.GetLineFromPosition(change.NewPosition).LineNumber; _lineStartState.RemoveRange(line + 1, -change.LineCountDelta); } } // Now process any changed lines _maxLineProcessed = -1; List <SnapshotSpan> changedSpans = new List <SnapshotSpan>(); foreach (ITextChange change in e.Changes) { ITextSnapshotLine startLine = snapshot.GetLineFromPosition(change.NewPosition); ProcessLine(startLine.LineNumber); ITextSnapshotLine endLine = snapshot.GetLineFromLineNumber(_maxLineProcessed); changedSpans.Add(new SnapshotSpan(startLine.Start, endLine.End)); } _lineCacheSnapshot = snapshot; // Our tags may have changed, tell anyone interested lock (updateLock) { var tempEvent = TagsChanged; if (tempEvent != null) { foreach (SnapshotSpan span in changedSpans) { tempEvent(this, new SnapshotSpanEventArgs(span)); } } } }
private GherkinDialect GetGherkinDialect(ITextSnapshot textSnapshot) { try { return projectScope.GherkinDialectServices.GetGherkinDialect( lineNo => textSnapshot.GetLineFromLineNumber(lineNo).GetText()); } catch(Exception) { return null; } }
public SnapshotParser(ITextSnapshot snapshot, IClassifier classifier) { Snapshot = snapshot; Classifier = classifier; ClassificationSpans = Classifier.GetClassificationSpans(new SnapshotSpan(Snapshot, 0, snapshot.Length)); foreach (ClassificationSpan s in ClassificationSpans) SpanIndex.Add(s.Span.Start.Position, s); CurrentPoint = Snapshot.GetLineFromLineNumber(0).Start; if (SpanIndex.ContainsKey(0)) CurrentSpan = SpanIndex[0]; }
IEnumerable<ITextSnapshotLine> GetLinesToAlign(ITextSnapshot snapshot) { int start = snapshot.GetLineNumberFromPosition(m_view.Selection.Start.Position); int end = snapshot.GetLineNumberFromPosition(m_view.Selection.End.Position); if (start == end) { start = 0; end = snapshot.LineCount -1; } return start.UpTo(end).Select(x => snapshot.GetLineFromLineNumber(x)); }
private static Span? GetRoxygenBlockPosition(ITextSnapshot snapshot, int definitionStart) { var line = snapshot.GetLineFromPosition(definitionStart); for (int i = line.LineNumber - 1; i >= 0; i--) { var currentLine = snapshot.GetLineFromLineNumber(i); string lineText = currentLine.GetText().TrimStart(); if (lineText.Length > 0) { if (lineText.EqualsOrdinal("##")) { return new Span(currentLine.Start, currentLine.Length); } else if (lineText.EqualsOrdinal("#'")) { return null; } break; } } return new Span(line.Start, 0); }
/// <summary> /// Returns the line on which the word "function" or other function initializers appear. /// </summary> /// <param name="capture">The text snapshot.</param> /// <param name="lineNumber">The line that should contain the open curlybrace for the function if one exists /// in the context of the comment, or the first line of the function itself.</param> /// <returns>Returns the line of the function declaration. -1 if one is not found that corresponds to the given /// line number.</returns> public static int GetFunctionDeclarationLineNumber(ITextSnapshot capture, int lineNumber, bool isAboveFunction = false) { string lineText = capture.GetLineFromLineNumber(lineNumber).GetText(); string unCommentedLine = RemoveComments(lineText); //Ignore inline functions if this is an "inside-the-function" doc (i.e, vsdoc) if (!isAboveFunction && !unCommentedLine.Trim().EndsWith("{")) return -1; if (capture.ContentType.TypeName == "TypeScript") { return GetTypeScriptFunctionLine(capture, lineNumber, isAboveFunction, lineText); } else { return GetJavaScriptFunctionLine(capture, lineNumber, isAboveFunction, lineText); } }
public static ITextSnapshotLine GetNonEmptyPreviousLine(ITextSnapshot snapshot, ITextSnapshotLine currentLine) { do { var previousLine = snapshot.GetLineFromLineNumber(Math.Max(currentLine.LineNumber - 1, 0)); // first line in the file if (previousLine.LineNumber == currentLine.LineNumber) { return currentLine; } if (previousLine.IsEmptyOrWhitespace()) { // keep goes up until it find non empty previous line currentLine = previousLine; continue; } return previousLine; } while (true); }
internal LineTokenization TokenizeLine(ITextSnapshot snapshot, object previousLineState, int lineNo, int lineOffset) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNo); SnapshotSpan lineSpan = new SnapshotSpan(snapshot, line.Start + lineOffset, line.LengthIncludingLineBreak - lineOffset); var tcp = new SnapshotSpanTextContentProvider(lineSpan); var scriptSource = _engine.CreateScriptSource(tcp, null, SourceCodeKind.File); _categorizer.Initialize(previousLineState, scriptSource, new SourceLocation(lineOffset, lineNo + 1, lineOffset + 1)); var tokens = new List<TokenInfo>(_categorizer.ReadTokens(lineSpan.Length)).ToArray(); return new LineTokenization(tokens, _categorizer.CurrentState); }
private IList<LineCommentInfo> GetMatchingComments( ITextSnapshot snapshot, LineCommentInfo toMatch, int lineNumberStart, int lineNumberLimit) { var list = new List<LineCommentInfo>(); var up = lineNumberLimit >= lineNumberStart; var delta = up ? 1 : -1; for ( var lineNumber = lineNumberStart; up ? lineNumber < lineNumberLimit : lineNumber >= lineNumberLimit; lineNumber += delta) { var line = snapshot.GetLineFromLineNumber(lineNumber); var info = LineCommentInfo.FromLine(line, this.view.Options, this.classifier); // TODO: treat lines with code (non-comment) as non-matching so // that behavior is better? if (!toMatch.Matches(info)) { break; } list.Add(info); } if (!up) { list.Reverse(); } return list; }
void UpdateAdornments_Performance( ITextSnapshot snapshot, ITextViewModel viewModel, ITextViewLine firstVisibleLine, IEnumerable<LineSpan> analysisLines ) { #endif double spaceWidth = firstVisibleLine.VirtualSpaceWidth; if (spaceWidth <= 0.0) return; double horizontalOffset = firstVisibleLine.TextLeft; var unusedLines = new HashSet<LineSpan>(Lines.Keys); var caret = CaretHandlerBase.FromName(Theme.CaretHandler, View.Caret.Position.VirtualBufferPosition, Analysis.TabSize); object perfCookie = null; PerformanceLogger.Start(ref perfCookie); #if DEBUG var initialCount = Lines.Count; #endif foreach (var line in analysisLines.Concat(GetPageWidthLines())) { double top = View.ViewportTop; double bottom = View.ViewportBottom; double left = line.Indent * spaceWidth + horizontalOffset; Line adornment; unusedLines.Remove(line); if (line.Type == LineSpanType.PageWidthMarker) { line.Highlight = (Analysis.LongestLine > line.Indent); if (!Lines.TryGetValue(line, out adornment)) { Lines[line] = adornment = CreateGuide(Canvas); } UpdateGuide(line, adornment, left, top, bottom); continue; } if (Lines.TryGetValue(line, out adornment)) { adornment.Visibility = Visibility.Hidden; } caret.AddLine(line, willUpdateImmediately: true); if (line.FirstLine >= 0 && line.LastLine < int.MaxValue) { var firstLineNumber = line.FirstLine; var lastLineNumber = line.LastLine; ITextSnapshotLine firstLine, lastLine; try { firstLine = snapshot.GetLineFromLineNumber(firstLineNumber); lastLine = snapshot.GetLineFromLineNumber(lastLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); continue; } if (firstLine.Start > View.TextViewLines.LastVisibleLine.Start || lastLine.Start < View.TextViewLines.FirstVisibleLine.Start) { continue; } while ( !viewModel.IsPointInVisualBuffer(firstLine.Start, PositionAffinity.Successor) && ++firstLineNumber < lastLineNumber ) { try { firstLine = snapshot.GetLineFromLineNumber(firstLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); firstLine = null; break; } } while ( !viewModel.IsPointInVisualBuffer(lastLine.Start, PositionAffinity.Predecessor) && --lastLineNumber > firstLineNumber ) { try { lastLine = snapshot.GetLineFromLineNumber(lastLineNumber); } catch (Exception ex) { Trace.TraceError("In GetLineFromLineNumber:\n{0}", ex); lastLine = null; break; } } if (firstLine == null || lastLine == null || firstLineNumber > lastLineNumber) { continue; } IWpfTextViewLine firstView, lastView; try { firstView = View.GetTextViewLineContainingBufferPosition(firstLine.Start); lastView = View.GetTextViewLineContainingBufferPosition(lastLine.End); } catch (Exception ex) { Trace.TraceError("UpdateAdornments GetTextViewLineContainingBufferPosition failed\n{0}", ex); continue; } string extentText; if (!string.IsNullOrWhiteSpace((extentText = firstView.Extent.GetText())) && line.Indent > extentText.LeadingWhitespace(Analysis.TabSize) ) { continue; } if (firstView.VisibilityState != VisibilityState.Unattached) { top = firstView.Top; } if (lastView.VisibilityState != VisibilityState.Unattached) { bottom = lastView.Bottom; } } if (!Lines.TryGetValue(line, out adornment)) { Lines[line] = adornment = CreateGuide(Canvas); } UpdateGuide(line, adornment, left, top, bottom); } PerformanceLogger.End(perfCookie); #if DEBUG Debug.WriteLine("Added {0} guides", Lines.Count - initialCount); Debug.WriteLine("Removed {0} guides", unusedLines.Count); Debug.WriteLine("{0} guides active", Lines.Count - unusedLines.Count); Debug.WriteLine(""); #endif foreach (var line in unusedLines) { Line adornment; if (Lines.TryGetValue(line, out adornment)) { Canvas.Children.Remove(adornment); Lines.Remove(line); } } foreach (var line in caret.GetModified()) { Line adornment; if (Lines.TryGetValue(line, out adornment)) { UpdateGuide(line, adornment); } } }
private LineTokenization TokenizeLine(JSScanner JSScanner, ITextSnapshot snapshot, object previousLineState, int lineNo) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNo); SnapshotSpan lineSpan = new SnapshotSpan(snapshot, line.Start, line.LengthIncludingLineBreak); var tcp = new SnapshotSpanSourceCodeReader(lineSpan); JSScanner.Initialize( lineSpan.GetText(), previousLineState, new SourceLocation(0, lineNo + 1, 1) ); try { var tokens = JSScanner.ReadTokens(lineSpan.Length).Select(ToTokenKind).ToArray(); return new LineTokenization(tokens, JSScanner.CurrentState); } finally { JSScanner.Uninitialize(); } }
private LineTokenization TokenizeLine(Tokenizer tokenizer, ITextSnapshot snapshot, object previousLineState, int lineNo) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNo); SnapshotSpan lineSpan = new SnapshotSpan(snapshot, line.Start, line.LengthIncludingLineBreak); var tcp = new SnapshotSpanSourceCodeReader(lineSpan); tokenizer.Initialize(previousLineState, tcp, new SourceLocation(line.Start.Position, lineNo + 1, 1)); var tokens = tokenizer.ReadTokens(lineSpan.Length).ToArray(); return new LineTokenization(tokens, tokenizer.CurrentState); }
private static Span SnapshotSpanToSpan(ITextSnapshot snapshot, TokenInfo token, int lineNumber) { var line = snapshot.GetLineFromLineNumber(lineNumber); var index = line.Start.Position + token.SourceSpan.Start.Column - 1; var tokenSpan = new Span(index, token.SourceSpan.Length); return tokenSpan; }
/// <summary> /// Gets the number of tabs from the beginning of the line. /// </summary> /// <param name="lastSlashPosition"></param> /// <param name="capture">The snapshot to use as the context of the line.</param> /// <returns></returns> public static string GetIndention(int lastSlashPosition, ITextSnapshot capture, bool isAboveFunction = false) { int lineNum = capture.GetLineNumberFromPosition(lastSlashPosition); if (isAboveFunction) { lineNum++; } else { lineNum--; } lineNum = GetFunctionDeclarationLineNumber(capture, lineNum, isAboveFunction); string space = capture.GetLineFromLineNumber(lineNum).GetText(); int leadingSpace = space.Length - space.TrimStart().Length; space = space.Substring(0, leadingSpace); if (isAboveFunction) { return space; } return space + GetTab(); }
public static bool ShouldCreateReturnTag(int position, ITextSnapshot capture, bool isAboveFunction = false) { if (Options.ReturnGenerationOption == ReturnTagGenerationSetting.Always) return true; if (Options.ReturnGenerationOption == ReturnTagGenerationSetting.Never) return false; bool hasReturn = false; bool newFunction = false; bool functionClosed = false; bool hasComment = false; int lineNumber = capture.GetLineNumberFromPosition(position - 1); string lineText = capture.GetLineFromLineNumber(lineNumber).GetText(); if (isAboveFunction) { lineNumber++; } else { lineNumber--; } bool inFunction = GetFunctionDeclarationLineNumber(capture, lineNumber, isAboveFunction) >= 0; if (!inFunction) return false; if (isAboveFunction) { lineNumber = GetNextOpenCurlyBrace(lineNumber, capture); } if (lineNumber == -1) { return false; } int functionsOpen = 0; int openBracket = 0; for (int i = lineNumber; i < capture.LineCount; i++) { lineText = capture.GetLineFromLineNumber(i).GetText(); //HANDLE COMMENTS if (lineText.Contains("/*") && lineText.Contains("*/") && lineText.LastIndexOf("/*") > lineText.LastIndexOf("*/")) { hasComment = true; } else if (lineText.Contains("/*") && lineText.Contains("*/")) { hasComment = false; } else if (lineText.Contains("/*")) { hasComment = true; } if (hasComment && lineText.Contains("*/")) { if (!lineText.Contains("/*") || lineText.LastIndexOf("/*") <= lineText.LastIndexOf("*/")) hasComment = false; } else if (hasComment || String.IsNullOrEmpty(lineText.Trim())) { continue; } lineText = RemoveComments(lineText); //END COMMENT HANDLING //HANDLE BRACKETS - "{ }" if (javaScriptFnRegex.IsMatch(lineText) && lineText.Contains("{")) { //adds an open function and an open bracket. functionsOpen++; } else if (javaScriptFnRegex.IsMatch(lineText)) { //states that there is a new function open without an open bracket. newFunction = true; } else if (newFunction && lineText.Contains("{")) { //states that there is no longer a new function and adds an open //bracket and open function. newFunction = false; functionsOpen++; } if (lineText.Contains("{")) { //Adds an open bracket. openBracket++; } bool isInlineFunction = false; if (lineText.Contains("}")) { //If function is closed on same line as closing bracket if (functionsOpen == 1 && returnRegex.IsMatch(lineText)) { hasReturn = true; break; } else if (returnRegex.IsMatch(lineText)) { isInlineFunction = true; } //Decrements both the number of open brackets and functions if they are equal. //This means the number of open brackets are the same as the number of open functions. //Otherwise it just decrements the number of open brackets. if (openBracket == functionsOpen) { functionsOpen--; } openBracket--; } if (functionsOpen == 0) functionClosed = true; if (functionsOpen == 1 && returnRegex.IsMatch(lineText) && !isInlineFunction) { hasReturn = true; break; } else if (functionClosed) { break; } } return hasReturn; }
private static int GetJavaScriptFunctionLine(ITextSnapshot capture, int lineNumber, bool isAboveFunction, string lineText) { if (!isAboveFunction) { while (!IsJSFunctionLine(lineText)) { lineNumber--; lineText = capture.GetLineFromLineNumber(lineNumber).Extent.GetText(); //There is no function declaration associated with the curly brace. if (lineText.Contains("{")) return -1; } } else if (!IsJSFunctionLine(lineText)) { return -1; } return lineNumber; }
// Searches down the file for the next line with an open curly brace, including the given line number. // Returns the line number. private static int GetNextOpenCurlyBrace(int lineNumber, ITextSnapshot capture) { var found = false; while (lineNumber < capture.LineCount) { var text = capture.GetLineFromLineNumber(lineNumber).GetText(); if (text.Contains("{")) { found = true; break; } lineNumber++; } if (found == false) { return -1; } return lineNumber; }
private void NotifyChanges(ITextSnapshot textSnapshot, IEnumerable<GherkinParseEvent> newAndChanged) { var linesChanged = newAndChanged .Where(_ => _.Tokens.Any()) .Select(_ => _.Tokens[0].LineInFile.Line) .Distinct().ToArray(); int from = linesChanged.Min(); int to = linesChanged.Max(); var previousEvent = new GherkinParseEvent(GherkinTokenType.Feature, new Token("", new LineInFile(0))); for (int i = from; i <= to; i++) { ITextSnapshotLine line = textSnapshot.GetLineFromLineNumber(i); var s = new SnapshotSpan(textSnapshot, line.Start, line.Length); GherkinParseEvent evt = newAndChanged.FirstOrDefault(_ => _.Tokens.Any() && _.Tokens[0].LineInFile.Line == i) ?? new GherkinParseEvent(previousEvent.GherkinTokenType, new Token("", new LineInFile(i))); TokenParserEvent.Invoke(this, new TokenParserEventArgs(evt, s)); previousEvent = evt; } var lastLine = textSnapshot.GetLineFromLineNumber(to); TokenParserEvent.Invoke(this, new TokenParserEventArgs(new GherkinParseEvent(GherkinTokenType.Eof), new SnapshotSpan(textSnapshot, lastLine.Start, 0))); }
// This function could use some refinement as it will return some false positives, // but hopefully they are rare enough to not cause any major issues. I would much // rather return a couple false positives than false negatives. private static int GetTypeScriptFunctionLine(ITextSnapshot capture, int lineNumber, bool isAboveFunction, string lineText) { if (!isAboveFunction) { while (!lineText.Contains('(') && !typeScriptFnRegex.IsMatch(lineText)) { lineNumber--; lineText = capture.GetLineFromLineNumber(lineNumber).Extent.GetText(); //There is no function declaration associated with the curly brace. if (lineText.Contains('{')) return -1; } return lineNumber; } else { if (typeScriptFnRegex.IsMatch(lineText)) { return lineNumber; } var textToCloseParen = lineText; // Though we are looking for a ), we need to break the loop if we find either { or }, // because it could be the start of an object, class, or something else. var checkBreakLoop = new Regex(@"\)|\{|\}"); // At this point, we know the given lineNumber is what we want to return as long // as it starts on a valid function declaration, so we create a separate counter. var lineCounter = lineNumber; while (!checkBreakLoop.IsMatch(lineText)) { lineCounter++; lineText = capture.GetLineFromLineNumber(lineCounter).Extent.GetText(); textToCloseParen += lineText; } whitespace.Replace(textToCloseParen, ""); if (!hasMatchingParens.IsMatch(textToCloseParen) || keywordWithParen.IsMatch(textToCloseParen)) { return -1; } var textToOpenBracket = textToCloseParen.Substring(textToCloseParen.IndexOf(')') + 1); while (!lineText.Contains('{')) { lineCounter++; lineText = capture.GetLineFromLineNumber(lineCounter).Extent.GetText(); textToOpenBracket += lineText; } textToOpenBracket = textToOpenBracket.Substring(0, textToOpenBracket.LastIndexOf('{')); // If there is no text between the ) and {, then we know it is a valid function header. if (String.IsNullOrWhiteSpace(textToOpenBracket)) { return lineNumber; } // If there is text between ) {, check if it is a return type declaration. if (textToOpenBracket.Trim().StartsWith(":")) { return lineNumber; } return -1; } }
private static IList<SnapshotSpan> CreateSnapshotSpans(ITextSnapshot snapshot, LineSpan lineSpan) { var result = new List<SnapshotSpan>(); for (int i = lineSpan.Start; i < lineSpan.End; i++) { var line = snapshot.GetLineFromLineNumber(i); result.Add(line.Extent); } return result; }
public void ReportParseErrors(IParseResult parseResult, ITextSnapshot snapshot) { _errorListProvider.SuspendRefresh(); try { // remove any previously created errors to get a clean start ClearErrors(); var messages = (CompilerMessageList)parseResult.CompilerMessages; foreach (var error in messages.GetMessages()) { // creates the instance that will be added to the Error List var nSpan = error.Location.Span; var span = new Span(nSpan.StartPos, nSpan.Length); if (span.Start >= snapshot.Length) continue; ErrorTask task = new ErrorTask(); task.Category = TaskCategory.All; task.Priority = TaskPriority.Normal; task.Document = _textBuffer.Properties.GetProperty<ITextDocument>(typeof(ITextDocument)).FilePath; task.ErrorCategory = TranslateErrorCategory(error); task.Text = error.Text; task.Line = snapshot.GetLineNumberFromPosition(span.Start); task.Column = span.Start - snapshot.GetLineFromLineNumber(task.Line).Start; task.Navigate += OnTaskNavigate; _errorListProvider.Tasks.Add(task); _previousErrors.Add(task); var trackingSpan = snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeNegative); _squiggleTagger.CreateTagSpan(trackingSpan, new ErrorTag("syntax error", error.Text)); _previousSquiggles.Add(new TrackingTagSpan<IErrorTag>(trackingSpan, new ErrorTag("syntax error", error.Text))); } } finally { _errorListProvider.ResumeRefresh(); } }
private bool TryAsSwitchSection(SyntaxNode childnode, ITextSnapshot snapshot, ref BlockType type, ref int startPosition, ref int endPosition) { var child = childnode as SwitchSectionSyntax; if (child != null) { type = BlockType.Conditional; startPosition = child.Labels.FullSpan.End; ITextSnapshotLine line = snapshot.GetLineFromPosition(startPosition); if ((startPosition == line.Start.Position) && (line.LineNumber > 0)) { startPosition = snapshot.GetLineFromLineNumber(line.LineNumber - 1).End; } endPosition = child.Span.End; return true; } return false; }
/// <summary> /// Rescans the part of the buffer affected by a change. /// Scans a contiguous sub-<paramref name="span"/> of a larger code span which starts at <paramref name="codeStartLine"/>. /// </summary> private void ApplyChange(Tokenizer tokenizer, ITextSnapshot snapshot, Span span) { int firstLine = snapshot.GetLineNumberFromPosition(span.Start); int lastLine = snapshot.GetLineNumberFromPosition(span.Length > 0 ? span.End - 1 : span.End); Contract.Assert(firstLine >= 0); // find the closest line preceding firstLine for which we know categorizer state, stop at the codeStartLine: LineTokenization lineTokenization; firstLine = _tokenCache.IndexOfPreviousTokenization(firstLine, 0, out lineTokenization) + 1; object state = lineTokenization.State; int currentLine = firstLine; object previousState; while (currentLine < snapshot.LineCount) { previousState = _tokenCache.TryGetTokenization(currentLine, out lineTokenization) ? lineTokenization.State : null; _tokenCache[currentLine] = lineTokenization = TokenizeLine(tokenizer, snapshot, state, currentLine); state = lineTokenization.State; // stop if we visted all affected lines and the current line has no tokenization state or its previous state is the same as the new state: if (currentLine > lastLine && (previousState == null || previousState.Equals(state))) { break; } currentLine++; } // classification spans might have changed between the start of the first and end of the last visited line: int changeStart = snapshot.GetLineFromLineNumber(firstLine).Start; int changeEnd = (currentLine < snapshot.LineCount) ? snapshot.GetLineFromLineNumber(currentLine).End : snapshot.Length; if (changeStart < changeEnd) { var classificationChanged = ClassificationChanged; if (classificationChanged != null) { var args = new ClassificationChangedEventArgs(new SnapshotSpan(snapshot, new Span(changeStart, changeEnd - changeStart))); classificationChanged(this, args); } } }
private static ITextSnapshotLine GetLastLine(ITextSnapshot snapshot) { return snapshot.GetLineFromLineNumber(snapshot.LineCount - 1); }
private GherkinFileEditorInfo DoScan(string fileContent, ITextSnapshot textSnapshot, int lineOffset, I18n languageService, GherkinFileEditorParserListener gherkinListener, int errorRertyCount, out ScenarioEditorInfo firstUnchangedScenario) { const int MAX_ERROR_RETRY = 5; const int NO_ERROR_RETRY_FOR_LINES = 5; firstUnchangedScenario = null; try { Lexer lexer = languageService.lexer(gherkinListener); lexer.scan(fileContent, null, 0); } catch (PartialListeningDoneException partialListeningDoneException) { firstUnchangedScenario = partialListeningDoneException.FirstUnchangedScenario; } catch(LexingError lexingError) { int? errorLine = GetErrorLine(lexingError, lineOffset); if (errorLine != null && errorLine.Value < textSnapshot.LineCount - NO_ERROR_RETRY_FOR_LINES && errorRertyCount < MAX_ERROR_RETRY) { //add error classification & continue var restartLineNumber = errorLine.Value + 1; int restartPosition = textSnapshot.GetLineFromLineNumber(restartLineNumber).Start; string restartFileContent = textSnapshot.GetText(restartPosition, textSnapshot.Length - restartPosition); gherkinListener.LineOffset = restartLineNumber; return DoScan(restartFileContent, textSnapshot, restartLineNumber, languageService, gherkinListener, errorRertyCount + 1, out firstUnchangedScenario); } } // ReSharper disable EmptyGeneralCatchClause catch // ReSharper restore EmptyGeneralCatchClause { // unknown error } return gherkinListener.GetResult(); }
public static string[] GetFunctionParameters(int position, ITextSnapshot capture, bool isAboveFunction = false) { int openFunctionLine = capture.GetLineNumberFromPosition(position - 1); if (isAboveFunction) { openFunctionLine += 1; } else { openFunctionLine -= 1; } ITextSnapshotLine line = capture.GetLineFromLineNumber(openFunctionLine); string prevLine = line.Extent.GetText(); openFunctionLine = StubUtils.GetFunctionDeclarationLineNumber(capture, openFunctionLine, isAboveFunction); //Not immediately after a function declaration if (openFunctionLine == -1) return new string[0]; prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText(); int ftnIndex = StubUtils.javaScriptFnRegex.Match(prevLine).Index; int firstParenPosition = -1; if (prevLine.IndexOf('(', ftnIndex) > -1) { firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start + prevLine.IndexOf('(', ftnIndex) + 1; } else { do { openFunctionLine++; prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText(); } while (!prevLine.Contains("(")); firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start + prevLine.IndexOf('(') + 1; } int lastParenPosition = -1; if (prevLine.IndexOf(')') > 0) { lastParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start + prevLine.IndexOf(')', prevLine.IndexOf('(')); } else { do { openFunctionLine++; prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText(); } while (!prevLine.Contains(")")); lastParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start + prevLine.IndexOf(")"); } return StubUtils .RemoveComments(capture .GetText() .Substring(firstParenPosition, (lastParenPosition - firstParenPosition))) .Split(',') .Select(param => param.Trim()) .ToArray(); }