/// <summary> /// Creates an ElasticTabstopsFormatters for /// the provided configuration. /// </summary> public TextParagraphProperties Create(IFormattedLineSource formattedLineSource, TextFormattingRunProperties textProperties, IMappingSpan line, IMappingPoint lineStart, int lineSegment) { if (!AlwaysAlignedConfigurationService.Instance.GetConfiguration().Enabled) { return(new TextFormattingParagraphProperties(textProperties, formattedLineSource.ColumnWidth * formattedLineSource.TabSize)); } IWpfTextView textView = _textBufferToViewMapService.GetViewByFormattedLineSource(formattedLineSource); //View is not initialized yet if (textView == null) { return(new TextFormattingParagraphProperties(textProperties, formattedLineSource.ColumnWidth * formattedLineSource.TabSize)); } var manager = ElasticTabstopsSizeManager.Get(textView); ITextSnapshot textSnapshot = formattedLineSource.SourceTextSnapshot; ITextBuffer textBuffer = textSnapshot.TextBuffer; var normalizedspancoll = line.GetSpans(textBuffer); ITextSnapshotLine currentLine = textSnapshot.GetLineFromPosition(normalizedspancoll.First().Start.Position); //Get tab offset calculated by ElasticTabstopsSizeManager double[] tabOffsets = manager.GetTabOffsets(currentLine); return(new ElasticTabstopsFormatter(textProperties, formattedLineSource, tabOffsets)); }
// Map the mapping span to the visual snapshot. note that as a result of projection // topology, originally single span may be mapped into several spans. Visual adornments do // not make much sense on disjoint spans. We will not decorate spans that could not make it // in one piece. private bool TryMapToSingleSnapshotSpan(IMappingSpan mappingSpan, ITextSnapshot viewSnapshot, out SnapshotSpan span) { // IMappingSpan.GetSpans is a surprisingly expensive function that allocates multiple // lists and collection if the view buffer is same as anchor we could just map the // anchor to the viewSnapshot however, since the _anchor is not available, we have to // map start and end TODO: verify that affinity is correct. If it does not matter we // should use the cheapest. if (viewSnapshot != null && mappingSpan.AnchorBuffer == viewSnapshot.TextBuffer) { var mappedStart = mappingSpan.Start.GetPoint(viewSnapshot, PositionAffinity.Predecessor).Value; var mappedEnd = mappingSpan.End.GetPoint(viewSnapshot, PositionAffinity.Successor).Value; span = new SnapshotSpan(mappedStart, mappedEnd); return(true); } // TODO: actually adornments do not make much sense on "cropped" spans either - Consider line separator on "nd Su" // is it possible to cheaply detect cropping? var spans = mappingSpan.GetSpans(viewSnapshot); if (spans.Count != 1) { span = default; return(false); // span is unmapped or disjoint. } span = spans[0]; return(true); }
public IEnumerable <IMappingTagSpan <T> > GetTags(IMappingSpan span) { if (span == null) { throw new ArgumentNullException(nameof(span)); } return(GetTags(span.GetSpans(TextBuffer))); }
public IEnumerable <IMappingTagSpan <T> > GetTags(IMappingSpan span, CancellationToken cancellationToken) { if (span is null) { throw new ArgumentNullException(nameof(span)); } return(GetTags(span.GetSpans(TextBuffer), cancellationToken)); }
private void NotifyTagChanged(ITextSnapshot snapshot) { IMappingSpan t = tagsChanged.Dequeue(); NormalizedSnapshotSpanCollection sp = t.GetSpans(snapshot); if (TagsChanged != null) { TagsChanged.Invoke(this, new SnapshotSpanEventArgs(sp.First())); } }
private void UpdateSelection(ITextSelection sel) { List <Span> spanList = new List <Span>(); for (int s = 0; s < sel.SelectedSpans.Count; ++s) { SnapshotSpan selectedSpan = sel.SelectedSpans[s]; IMappingSpan m = this.textView.BufferGraph.CreateMappingSpan(selectedSpan, SpanTrackingMode.EdgeExclusive); // todo: this should be on ITextSelection! NormalizedSnapshotSpanCollection spans = m.GetSpans(this.textBuffer); // TODO: add NormalizedSpanCollection property to NormalizedSnapshotSpanCollection foreach (var sp in spans) { spanList.Add(sp.Span); } } this.SelectionCombo.ItemsSource = spanList; if (spanList.Count < 2) { if (!this.selectionLabelInstalled) { this.SelectionPanel.Children.Clear(); this.SelectionPanel.Children.Add(this.SelectionLabel); this.selectionLabelInstalled = true; } if (spanList.Count == 0) { this.SelectionLabel.Content = "-"; } else { this.SelectionLabel.Content = spanList[0]; } } else { if (this.selectionLabelInstalled) { this.SelectionPanel.Children.Clear(); this.SelectionPanel.Children.Add(this.SelectionCombo); this.selectionLabelInstalled = false; } this.SelectionCombo.Text = spanList[0].ToString(); } }
private SnapshotSpan MapTo(SnapshotSpan span, ITextSnapshot snapshot, SpanTrackingMode spanTrackingMode) { if (span.Snapshot.TextBuffer == snapshot.TextBuffer) { return(span.TranslateTo(snapshot, spanTrackingMode)); } IBufferGraph graph = _bufferGraphFactoryService.CreateBufferGraph(snapshot.TextBuffer); IMappingSpan mappingSpan = graph.CreateMappingSpan(span, spanTrackingMode); NormalizedSnapshotSpanCollection mapped = mappingSpan.GetSpans(snapshot); if (mapped.Count == 1) { return(mapped[0]); } return(new SnapshotSpan(mapped[0].Start, mapped[mapped.Count - 1].End)); }
private IEnumerable <IMappingTagSpan <T> > InternalGetTags(IMappingSpan mappingSpan, CancellationToken?cancel) { foreach (var bufferAndTaggers in taggers) { if (bufferAndTaggers.Value.Count > 0) { NormalizedSnapshotSpanCollection spans = mappingSpan.GetSpans(bufferAndTaggers.Key); if (spans.Count > 0) { foreach (var tagSpan in this.GetTagsForBuffer(bufferAndTaggers, spans, null, cancel)) { yield return(tagSpan); } } } } }
private IEnumerable <IMappingTagSpan <T> > InternalGetTags(IMappingSpan mappingSpan, CancellationToken?cancel) { foreach (var bufferAndState in bufferStates) { if (bufferAndState.Value.Taggers.Count > 0) { var spans = mappingSpan.GetSpans(bufferAndState.Key); if (spans.Count > 0) { foreach (var tag in this.GetTagsForBuffer(spans, bufferAndState.Value, null, cancel)) { yield return(tag); } if (cancel.HasValue && cancel.Value.IsCancellationRequested) { yield break; } } } } }
private String getKeywordAt(List <IMappingTagSpan <IClassificationTag> > tagList, int tagIndex) { string keyword = null; if (tagIndex < tagList.Count) { var buffer = _textView.TextBuffer; IClassificationTag currentTag = tagList[tagIndex].Tag; IMappingSpan currentSpan = tagList[tagIndex].Span; // if (currentTag.ClassificationType.IsOfType("keyword")) { var spans = currentSpan.GetSpans(buffer); if (spans.Count > 0) { SnapshotSpan kwSpan = spans[0]; keyword = kwSpan.GetText(); keyword = keyword.ToUpper(); } } } return(keyword); }
/// <summary> /// Get the first keyword in Line. The modifiers (Private, Protected, ... ) are ignored /// If the first Keyword is a Comment, "//" is returned /// </summary> /// <param name="line">The line to analyze</param> /// <param name="doSkipped">Bool value indicating if a "DO" keyword has been skipped</param> /// <param name="minIndent"></param> /// <returns></returns> private String getFirstKeywordInLine(ITextSnapshotLine line, out bool doSkipped, out int minIndent) { minIndent = -1; doSkipped = false; List <IMappingTagSpan <IClassificationTag> > tagList = GetTagsInLine(line); String keyword = ""; // if (tagList.Count > 0) { var buffer = this._textView.TextBuffer; IMappingSpan currentSpan = tagList[0].Span; /////////////////////////////////////////// //SnapshotPoint? snapPointFirst = currentSpan.Start.GetPoint(buffer, PositionAffinity.Predecessor); //// Extract the start of line //SnapshotSpan toIndent = new SnapshotSpan(line.Start, snapPointFirst.Value.Position - line.Start.Position); //String startOfLine = toIndent.GetText(); //// Convert Tabs to Spaces //startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); //// So, at least, to align to previous line, we will need... //minIndent = startOfLine.Length; //////////////////////////////////////////// String startOfLine = line.GetText(); startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); // So, at least, to align to previous line, we will need... minIndent = (startOfLine.Length - startOfLine.TrimStart(' ').Length); // int tagIndex = 0; while (tagIndex < tagList.Count) { IClassificationTag currentTag = tagList[tagIndex].Tag; currentSpan = tagList[tagIndex].Span; // if (currentTag.ClassificationType.IsOfType("keyword")) { var spans = currentSpan.GetSpans(buffer); if (spans.Count > 0) { SnapshotSpan kwSpan = spans[0]; keyword = kwSpan.GetText(); keyword = keyword.ToUpper(); // it could be modifier... switch (keyword) { case "PROTECTED": case "INTERNAL": case "HIDDEN": case "PRIVATE": case "EXPORT": case "PUBLIC": case "STATIC": case "SEALED": case "ABSTRACT": case "VIRTUAL": case "PARTIAL": tagIndex++; keyword = ""; continue; case "DO": tagIndex++; keyword = ""; doSkipped = true; continue; default: break; } } } else if (currentTag.ClassificationType.IsOfType("comment")) { // keyword = "//"; } // out please break; } ; } return(keyword); }
private int?alignToSpecificTokens(ITextSnapshotLine currentLine, String tokenList) { int indentValue = 0; bool found = false; Stack <String> context = new Stack <String>(); // try { String[] possibleTokens = tokenList.Split(','); // On what line are we ? int lineNumber = currentLine.LineNumber; // We need to analyze the Previous line lineNumber = lineNumber - 1; while (lineNumber > 0) { // We need to analyze the Previous line lineNumber = lineNumber - 1; ITextSnapshotLine line = currentLine.Snapshot.GetLineFromLineNumber(lineNumber); List <IMappingTagSpan <IClassificationTag> > tagList = GetTagsInLine(line); String currentKeyword = ""; // if (tagList.Count > 0) { var buffer = this._textView.TextBuffer; IMappingSpan currentSpan = tagList[0].Span; /* * SnapshotPoint? snapPointFirst = currentSpan.Start.GetPoint(buffer, PositionAffinity.Predecessor); * // Extract the start of line * SnapshotSpan toIndent = new SnapshotSpan(line.Start, snapPointFirst.Value.Position - line.Start.Position); * String startOfLine = toIndent.GetText(); * // Convert Tabs to Spaces * startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); * // So, at least, to align to previous line, we will need... * indentValue = startOfLine.Length; */ String startOfLine = line.GetText(); startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); // So, at least, to align to previous line, we will need... indentValue = (startOfLine.Length - startOfLine.TrimStart(' ').Length); // IClassificationTag currentTag = tagList[0].Tag; currentSpan = tagList[0].Span; // if (currentTag.ClassificationType.IsOfType("keyword")) { var spans = currentSpan.GetSpans(buffer); if (spans.Count > 0) { SnapshotSpan kwSpan = spans[0]; currentKeyword = kwSpan.GetText(); currentKeyword = currentKeyword.ToUpper(); if (possibleTokens.Contains <String>(currentKeyword)) { if (context.Count == 0) { found = true; break; } else { tokenList = context.Pop(); possibleTokens = tokenList.Split(','); } } // Here we should also check for nested construct or we might get false positive... string outdentToken; if ((outdentToken = this.searchSpecialOutdentKeyword(currentKeyword)) != null) { context.Push(tokenList); tokenList = outdentToken; possibleTokens = tokenList.Split(','); } } } // indentValue = 0; } } } finally { // } // if (found) { return(indentValue); } else { return(null); } }
private int?alignToSpecificToken_(ITextSnapshotLine currentLine, String token) { int indentValue = 0; bool found = false; try { // On what line are we ? int lineNumber = currentLine.LineNumber; // We need to analyze the Previous line lineNumber = lineNumber - 1; while (lineNumber > 0) { // We need to analyze the Previous line lineNumber = lineNumber - 1; ITextSnapshotLine line = currentLine.Snapshot.GetLineFromLineNumber(lineNumber); List <IMappingTagSpan <IClassificationTag> > tagList = GetTagsInLine(line); String keyword = ""; // if (tagList.Count > 0) { var buffer = this._textView.TextBuffer; IMappingSpan currentSpan = tagList[0].Span; /* * SnapshotPoint? snapPointFirst = currentSpan.Start.GetPoint(buffer, PositionAffinity.Predecessor); * // Extract the start of line * SnapshotSpan toIndent = new SnapshotSpan(line.Start, snapPointFirst.Value.Position - line.Start.Position); * String startOfLine = toIndent.GetText(); * // Convert Tabs to Spaces * startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); * // So, at least, to align to previous line, we will need... * indentValue = startOfLine.Length; */ String startOfLine = line.GetText(); startOfLine = startOfLine.Replace("\t", new String(' ', _tabSize)); // So, at least, to align to previous line, we will need... indentValue = (startOfLine.Length - startOfLine.TrimStart(' ').Length); // IClassificationTag currentTag = tagList[0].Tag; currentSpan = tagList[0].Span; // if (currentTag.ClassificationType.IsOfType("keyword")) { var spans = currentSpan.GetSpans(buffer); if (spans.Count > 0) { SnapshotSpan kwSpan = spans[0]; keyword = kwSpan.GetText(); keyword = keyword.ToUpper(); if (keyword == token) { found = true; break; } } } // indentValue = 0; } } } finally { // } // if (found) { return(indentValue); } else { return(null); } }