public void Start_DontResetSelection() { Create(VisualKind.Character, ""); var realView = CreateTextView("foo bar baz"); var selection = new Mock <ITextSelection>(MockBehavior.Strict); var snapshot = new Mock <ITextSnapshot>(MockBehavior.Strict); snapshot.SetupGet(x => x.Length).Returns(1); selection.SetupGet(x => x.IsEmpty).Returns(false).Verifiable(); var nonEmptySpan = new VirtualSnapshotSpan(new SnapshotSpan(snapshot.Object, new Span(0, 1))); selection.SetupGet(x => x.StreamSelectionSpan).Returns(nonEmptySpan).Verifiable(); selection.SetupGet(x => x.IsReversed).Returns(false).Verifiable(); selection.SetupGet(x => x.AnchorPoint).Returns(new VirtualSnapshotPoint(realView.TextSnapshot, 0)); selection.SetupGet(x => x.ActivePoint).Returns(new VirtualSnapshotPoint(realView.TextSnapshot, 1)); selection.SetupGet(x => x.End).Returns(new VirtualSnapshotPoint(realView.TextSnapshot, 1)); selection.SetupProperty(x => x.Mode); var view = new Mock <ITextView>(MockBehavior.Strict); view.SetupGet(x => x.TextBuffer).Returns(realView.TextBuffer); view.SetupGet(x => x.Caret).Returns(realView.Caret); view.SetupGet(x => x.TextSnapshot).Returns(realView.TextSnapshot); view.SetupGet(x => x.Selection).Returns(selection.Object); var vimTextBuffer = new Mock <IVimTextBuffer>(MockBehavior.Strict); vimTextBuffer.SetupGet(x => x.LocalSettings).Returns(new LocalSettings(_globalSettings)); vimTextBuffer.SetupGet(x => x.UseVirtualSpace).Returns(false); vimTextBuffer.SetupSet(x => x.LastVisualSelection = It.IsAny <Microsoft.FSharp.Core.FSharpOption <VisualSelection> >()); var vimBufferData = MockObjectFactory.CreateVimBufferData(vimTextBuffer.Object, view.Object); var tracker = new SelectionTracker(vimBufferData, _commonOperations, _incrementalSearch.Object, VisualKind.Character); tracker.Start(); selection.Verify(); }
/// <summary> /// Constructor /// </summary> /// <param name="location">Location</param> /// <param name="span">Text view span</param> public DbgTextViewBreakpointLocationResult(DbgCodeLocation location, VirtualSnapshotSpan span) { if (span.Snapshot == null) { throw new ArgumentException(); } Locations = new[] { location ?? throw new ArgumentNullException(nameof(location)) };
/// <summary> /// Comment out the code in a single <see cref="VirtualSnapshotSpan"/>. /// </summary> /// <remarks> /// <para>The default implementation uses line comments if <see cref="UseLineComments"/> is /// <see langword="true"/> and one of the following is true.</para> /// <list type="number"> /// <item>There is no selected text.</item> /// <item> /// On the line where the selection starts, there is only whitespace up to the selection start point, /// <strong>and</strong> one of the following is true. /// <list type="bullet"> /// <item>On the line where the selection ends, there is only whitespace up to the selection end point, /// <strong>or</strong></item> /// <item>There is only whitespace from the selection end point to the end of the line.</item> /// </list> /// </item> /// </list> /// /// <para>The default implementation uses block comments if <em>all</em> of the following are true.</para> /// <list type="bullet"> /// <item>We are not using line comments.</item> /// <item><see cref="PreferredBlockFormat"/> is not <see langword="null"/>.</item> /// </list> /// </remarks> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to apply the changes to.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> protected virtual VirtualSnapshotSpan CommentSpan(VirtualSnapshotSpan span, ITextEdit edit) { Contract.Requires <ArgumentNullException>(edit != null, "edit"); span = span.TranslateTo(edit.Snapshot, SpanTrackingMode.EdgeExclusive); var startContainingLine = span.Start.Position.GetContainingLine(); var endContainingLine = span.End.Position.GetContainingLine(); if (UseLineComments && (span.IsEmpty || (string.IsNullOrWhiteSpace(startContainingLine.GetText().Substring(0, span.Start.Position - startContainingLine.Start)) && (string.IsNullOrWhiteSpace(endContainingLine.GetText().Substring(0, span.End.Position - endContainingLine.Start)) || string.IsNullOrWhiteSpace(endContainingLine.GetText().Substring(span.End.Position - endContainingLine.Start))) ))) { span = CommentLines(span, edit, PreferredLineFormat); } else if (PreferredBlockFormat != null) { span = CommentBlock(span, edit, PreferredBlockFormat); } return(span); }
void ReplaceNext() { if (!CanReplaceNext) return; string expandedReplacePattern; var res = ReplaceFindNextCore(out expandedReplacePattern); if (res == null) return; var vres = new VirtualSnapshotSpan(res.Value); if (!wpfTextView.Selection.IsEmpty && wpfTextView.Selection.StreamSelectionSpan == vres) { if (CanReplaceSpan(res.Value, expandedReplacePattern)) { using (var ed = wpfTextView.TextBuffer.CreateEdit()) { if (ed.Replace(res.Value.Span, expandedReplacePattern)) ed.Apply(); } } wpfTextView.Selection.Clear(); var newPos = res.Value.End.TranslateTo(wpfTextView.TextSnapshot, PointTrackingMode.Positive); wpfTextView.Caret.MoveTo(newPos); res = ReplaceFindNextCore(out expandedReplacePattern); if (res == null) return; ShowSearchResult(res.Value); } else ShowSearchResult(res.Value); }
private void OnSelectionChanged(object sender, object e) { _selectedText = _view.Selection.StreamSelectionSpan.GetText(); _selectedWord = _view.Selection.StreamSelectionSpan; _layer.RemoveAllAdornments(); SnapShotsToColor.Clear(); if (string.IsNullOrEmpty(_selectedText) || string.IsNullOrWhiteSpace(_selectedText)) { return; } var length = _selectedText.Length; var position = _view.Selection.StreamSelectionSpan.Start.Position.Position; var num = position + length; if (position - 1 >= 0 && char.IsLetterOrDigit(_view.TextSnapshot[position - 1])) { return; } if (num < _view.TextSnapshot.GetText().Length&& char.IsLetterOrDigit(_view.TextSnapshot[num])) { return; } var text = _selectedText; if (text.Any(c => !char.IsLetterOrDigit(c) && c != '_')) { return; } //FindWordsInDocument(); Dispatcher.CurrentDispatcher.BeginInvoke(new Action(FindWordsInDocument), DispatcherPriority.ApplicationIdle, null); }
private void OnSelectionChanged(object sender, object e) { this.selectedText = this._view.Selection.StreamSelectionSpan.GetText(); this.selectedWord = this._view.Selection.StreamSelectionSpan; this._layer.RemoveAllAdornments(); this.SnapShotsToColor.Clear(); if (!string.IsNullOrEmpty(this.selectedText) && !string.IsNullOrWhiteSpace(this.selectedText)) { int length = this.selectedText.Length; int position = this._view.Selection.StreamSelectionSpan.Start.Position.Position; int num = position + length; if (position - 1 >= 0 && char.IsLetterOrDigit(this._view.TextSnapshot[position - 1])) { return; } if (num < this._view.TextSnapshot.GetText().Length&& char.IsLetterOrDigit(this._view.TextSnapshot[num])) { return; } foreach (char c in this.selectedText) { if (!char.IsLetterOrDigit(c) && c != '_') { return; } } //在文档中查找选中单词 this.FindWordsInDocument(); //set color this.ColorWords(); } //选区长度状态栏显示异步事件 SelectionLenght(sender); }
/// <summary> /// Comment out a span of text using the specified block comment format. If the <paramref name="span"/> is /// empty, the entire line containing the span's start point is commented. /// </summary> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to use for applying changes.</param> /// <param name="format">The block comment format.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="format"/> is <see langword="null"/>.</para> /// </exception> protected virtual VirtualSnapshotSpan CommentBlock(VirtualSnapshotSpan span, ITextEdit edit, BlockCommentFormat format) { if (edit == null) { throw new ArgumentNullException(nameof(edit)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } //special case no selection if (span.IsEmpty) { VirtualSnapshotPoint start = new VirtualSnapshotPoint(span.Start.Position.GetContainingLine().Start + ScanToNonWhitespaceChar(span.Start.Position.GetContainingLine())); VirtualSnapshotPoint end = span.IsInVirtualSpace ? span.End : new VirtualSnapshotPoint(span.End.Position.GetContainingLine().End); span = new VirtualSnapshotSpan(start, end); } // add start comment edit.Insert(span.Start.Position, format.StartText); // add end comment edit.Insert(span.End.Position, format.EndText); return(span); }
/// <summary> /// Uncomment the span of text. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the uncommented code.</returns> /// <exception cref="ArgumentNullException">If <paramref name="edit"/> is <see langword="null"/>.</exception> protected virtual VirtualSnapshotSpan UncommentSpan(VirtualSnapshotSpan span, ITextEdit edit) { Contract.Requires <ArgumentNullException>(edit != null, "edit"); span = span.TranslateTo(edit.Snapshot, SpanTrackingMode.EdgeExclusive); bool useLineComments = true; var startContainingLine = span.Start.Position.GetContainingLine(); var endContainingLine = span.End.Position.GetContainingLine(); // special case: empty span if (span.IsEmpty) { if (useLineComments) { TryUncommentLines(span, edit, LineFormats, out span); } } else { VirtualSnapshotSpan resultSpan; if (TryUncommentBlock(span, edit, BlockFormats, out resultSpan)) { return(resultSpan); } if (useLineComments) { TryUncommentLines(span, edit, LineFormats, out span); } } return(span); }
/// <summary> /// Comment out a span using a particular line comment format. If the <paramref name="span"/> is empty, the /// entire line containing the span's start point is commented. /// </summary> /// <remarks> /// <para>The default algorithm for line comments is designed to meet the following conditions.</para> /// <list type="bullet"> /// <item>Make sure line comments are indented as far as possible, skipping empty lines as necessary.</item> /// <item>Don't comment <em>N</em>+1 lines when only <em>N</em> lines were selected by clicking in the left /// margin.</item> /// </list> /// </remarks> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to apply the changes to.</param> /// <param name="format">The line comment format to use for commenting the code.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="format"/> is <see langword="null"/>.</para> /// </exception> protected virtual VirtualSnapshotSpan CommentLines(VirtualSnapshotSpan span, ITextEdit edit, LineCommentFormat format) { Contract.Requires <ArgumentNullException>(edit != null, "edit"); Contract.Requires <ArgumentNullException>(format != null, "format"); if (span.End.Position.GetContainingLine().LineNumber > span.Start.Position.GetContainingLine().LineNumber&& span.End.Position.GetContainingLine().Start == span.End.Position) { VirtualSnapshotPoint start = span.Start; VirtualSnapshotPoint end = new VirtualSnapshotPoint(span.Snapshot.GetLineFromLineNumber(span.End.Position.GetContainingLine().LineNumber - 1).Start); if (end < start) { start = end; } span = new VirtualSnapshotSpan(start, end); } int minindex = (from i in Enumerable.Range(span.Start.Position.GetContainingLine().LineNumber, span.End.Position.GetContainingLine().LineNumber - span.Start.Position.GetContainingLine().LineNumber + 1) where span.Snapshot.GetLineFromLineNumber(i).GetText().Trim().Length > 0 select ScanToNonWhitespaceChar(span.Snapshot.GetLineFromLineNumber(i))) .Min(); //comment each line for (int line = span.Start.Position.GetContainingLine().LineNumber; line <= span.End.Position.GetContainingLine().LineNumber; line++) { if (span.Snapshot.GetLineFromLineNumber(line).GetText().Trim().Length > 0) { edit.Insert(span.Snapshot.GetLineFromLineNumber(line).Start + minindex, format.StartText); } } span = new VirtualSnapshotSpan(new SnapshotSpan(span.Start.Position.GetContainingLine().Start, span.End.Position.GetContainingLine().End)); return(span); }
public static bool TryGetSurfaceBufferSpan( this ITextView textView, VirtualSnapshotSpan virtualSnapshotSpan, out VirtualSnapshotSpan surfaceBufferSpan) { // If we are already on the surface buffer, then there's no reason to attempt mappings // as we'll lose virtualness if (virtualSnapshotSpan.Snapshot.TextBuffer == textView.TextBuffer) { surfaceBufferSpan = virtualSnapshotSpan; return(true); } // We have to map. We'll lose virtualness in this process because // mapping virtual points through projections is poorly defined. var targetSpan = textView.BufferGraph.MapUpToSnapshot( virtualSnapshotSpan.SnapshotSpan, SpanTrackingMode.EdgeExclusive, textView.TextSnapshot).FirstOrNullable(); if (targetSpan.HasValue) { surfaceBufferSpan = new VirtualSnapshotSpan(targetSpan.Value); return(true); } surfaceBufferSpan = default(VirtualSnapshotSpan); return(false); }
public MouseLeftDownInfo(VirtualSnapshotSpan span, Point point, int clicks, ITextVersion version) { Span = span; Point = point; Clicks = clicks; Version = version; }
public static void MakeSelection( this Mock <ITextSelection> selection, VirtualSnapshotSpan span) { selection.Setup(x => x.Mode).Returns(TextSelectionMode.Stream); selection.Setup(x => x.StreamSelectionSpan).Returns(span); }
public async Task <INavigableLocation?> GetLocationForSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken) { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); if (workspace is not InteractiveWindowWorkspace interactiveWorkspace) { Debug.Fail("InteractiveDocumentNavigationService called with incorrect workspace!"); return(null); } if (interactiveWorkspace.Window is null) { Debug.Fail("We are trying to navigate with a workspace that doesn't have a window!"); return(null); } var textView = interactiveWorkspace.Window.TextView; var document = interactiveWorkspace.CurrentSolution.GetDocument(documentId); if (document is null) { return(null); } var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var textSnapshot = text.FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { return(null); } var snapshotSpan = new SnapshotSpan(textSnapshot, textSpan.Start, textSpan.Length); var virtualSnapshotSpan = new VirtualSnapshotSpan(snapshotSpan); if (!textView.TryGetSurfaceBufferSpan(virtualSnapshotSpan, out var surfaceBufferSpan)) { return(null); } return(new NavigableLocation(async(options, cancellationToken) => { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); textView.Selection.Select(surfaceBufferSpan.Start, surfaceBufferSpan.End); textView.ViewScroller.EnsureSpanVisible(surfaceBufferSpan.SnapshotSpan, EnsureSpanVisibleOptions.AlwaysCenter); // Moving the caret must be the last operation involving surfaceBufferSpan because // it might update the version number of textView.TextSnapshot (VB does line commit // when the caret leaves a line which might cause pretty listing), which must be // equal to surfaceBufferSpan.SnapshotSpan.Snapshot's version number. textView.Caret.MoveTo(surfaceBufferSpan.Start); textView.VisualElement.Focus(); return true; })); }
public static Geometry?CreateGeometry(IWpfTextView textView, VirtualSnapshotSpan span, bool isMultiLine, bool clipToViewport = false) { var padding = isMultiLine ? LineMarkerPadding : TextMarkerPadding; var pos = span.Start; PathGeometry?geo = null; bool createOutlinedPath = false; while (pos <= span.End) { var line = textView.GetTextViewLineContainingBufferPosition(pos.Position); bool useVspaces = line.IsLastDocumentLine(); var lineExtent = new VirtualSnapshotSpan(new VirtualSnapshotPoint(line.Start), new VirtualSnapshotPoint(line.EndIncludingLineBreak, useVspaces ? span.End.VirtualSpaces : 0)); var extentTmp = lineExtent.Intersection(new VirtualSnapshotSpan(pos, span.End)); Debug2.Assert(!(extentTmp is null)); if (line.VisibilityState != VisibilityState.Unattached && !(extentTmp is null) && extentTmp.Value.Length != 0) { var extent = extentTmp.Value; Collection <TextBounds> textBounds; if (extent.Start.IsInVirtualSpace) { var leading = line.TextRight + extent.Start.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; double width = line.EndOfLineWidth; int vspaces = span.End.VirtualSpaces - span.Start.VirtualSpaces; if (vspaces > 0) { width = vspaces * textView.FormattedLineSource.ColumnWidth; } textBounds = new Collection <TextBounds>(); textBounds.Add(new TextBounds(leading, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else if (extent.End.IsInVirtualSpace) { textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); double width = extent.End.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; textBounds.Add(new TextBounds(line.TextRight, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else { textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); } AddGeometries(textView, textBounds, isMultiLine, clipToViewport, padding, SystemParameters.CaretWidth, ref geo, ref createOutlinedPath); } if (line.IsLastDocumentLine()) { break; } pos = new VirtualSnapshotPoint(line.GetPointAfterLineBreak()); } if (createOutlinedPath) { geo = geo !.GetOutlinedPathGeometry(); } if (!(geo is null) && geo.CanFreeze) { geo.Freeze(); } return(geo); }
private static Selection InsertDiscoveredMatchRegion(IMultiSelectionBroker broker, Selection primaryRegion, SnapshotSpan found) { var newSpan = new VirtualSnapshotSpan(found); var newSelection = new Selection(newSpan, primaryRegion.IsReversed); broker.AddSelection(newSelection); return(newSelection); }
public void EnsureSpanVisible(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { if (span.Snapshot != textView.TextSnapshot) { throw new ArgumentException(); } throw new NotImplementedException(); //TODO: }
/// <summary> /// Constructor /// </summary> /// <param name="location">Location</param> /// <param name="span">Text view span</param> public TextViewBookmarkLocationResult(BookmarkLocation location, VirtualSnapshotSpan span) { if (span.Snapshot is null) { throw new ArgumentException(); } Location = location ?? throw new ArgumentNullException(nameof(location)); Span = span; }
public void EnsureSpanVisible(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { if (span.Snapshot != textView.TextSnapshot) throw new ArgumentException(); if ((textView.TextViewLines?.Count ?? 0) == 0) return; EnsureSpanVisibleY(span, options); EnsureSpanVisibleX(span, options); }
private void SelectSpan(ITextView wpfTextView, SnapshotSpan snapshotSpan) { var virtualSnapshotSpan = new VirtualSnapshotSpan(snapshotSpan); var editorOperations = editorOperationsFactory.GetEditorOperations(wpfTextView); editorOperations.SelectAndMoveCaret( virtualSnapshotSpan.Start, virtualSnapshotSpan.End, TextSelectionMode.Stream, EnsureSpanVisibleOptions.AlwaysCenter); }
public void NavigateTo(IWpfTextView textView, Span span, bool selectSpan, bool deferNavigationWithOutlining) { Validate.IsNotNull(textView, nameof(textView)); Debug.Assert(span.End <= textView.TextSnapshot.Length, string.Format("span.End ({0}) > textView.TextSnapshot.Length ({1})", span.End, textView.TextSnapshot.Length)); IEditorOperations editorOperations = this.singletons.EditorOperationsFactory.GetEditorOperations(textView); SnapshotSpan snapshotSpan = EditorUtilities.CreateSnapshotSpan(textView.TextSnapshot, span.Start, span.Length); VirtualSnapshotSpan virtualSnapshotSpan = new VirtualSnapshotSpan(snapshotSpan); Navigate(editorOperations, virtualSnapshotSpan, selectSpan); }
public void Virtual(string line1) { Create(line1, ""); var point1 = _textBuffer.GetVirtualPointInLine(0, 0); var point2 = _textBuffer.GetVirtualPointInLine(0, 4); var span = new VirtualSnapshotSpan(point1, point2); var visualSpan = VisualSpan.CreateForVirtualSelectionPoints(VisualKind.Character, point1, point2, _vimBuffer.LocalSettings.TabStop, true); Assert.Equal(point1, visualSpan.AsCharacter().CharacterSpan.VirtualStart); Assert.Equal(point2, visualSpan.AsCharacter().CharacterSpan.VirtualEnd); Assert.Equal(span.Length, visualSpan.AsCharacter().CharacterSpan.VirtualLength); }
public static Geometry CreateBoxGeometry(IWpfTextView textView, IList <VirtualSnapshotSpan> spans, bool isMultiLine, bool clipToViewport = false) { var padding = isMultiLine ? LineMarkerPadding : TextMarkerPadding; PathGeometry geo = null; bool createOutlinedPath = false; foreach (var span in spans) { var line = textView.GetTextViewLineContainingBufferPosition(span.SnapshotSpan.Start); Debug.Assert(span.SnapshotSpan.End <= line.EndIncludingLineBreak); var lineExtent = new VirtualSnapshotSpan(new VirtualSnapshotPoint(line.Start), new VirtualSnapshotPoint(line.EndIncludingLineBreak, span.End.VirtualSpaces)); var extentTmp = lineExtent.Intersection(span); Debug.Assert(extentTmp != null); if (line.VisibilityState != VisibilityState.Unattached && extentTmp != null) { var extent = extentTmp.Value; Collection <TextBounds> textBounds; if (extent.Start.IsInVirtualSpace) { var leading = line.TextRight + extent.Start.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; double width = line.EndOfLineWidth; int vspaces = span.End.VirtualSpaces - span.Start.VirtualSpaces; if (vspaces > 0) { width = vspaces * textView.FormattedLineSource.ColumnWidth; } textBounds = new Collection <TextBounds>(); textBounds.Add(new TextBounds(leading, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else if (extent.End.IsInVirtualSpace) { textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); double width = extent.End.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; textBounds.Add(new TextBounds(line.TextRight, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else { textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); } AddGeometries(textView, textBounds, isMultiLine, clipToViewport, padding, SystemParameters.CaretWidth, ref geo, ref createOutlinedPath); } } if (createOutlinedPath) { geo = geo.GetOutlinedPathGeometry(); } if (geo != null && geo.CanFreeze) { geo.Freeze(); } return(geo); }
public StreamMarkerSpanCollection(ITextView textView, VirtualSnapshotSpan span) { if (textView == null) { throw new ArgumentNullException(nameof(textView)); } if (span.Snapshot == null) { throw new ArgumentException(); } this.textView = textView; this.span = span; }
public bool TryNavigateToSpan( Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet options, bool allowInvalidSpan, CancellationToken cancellationToken ) { if (workspace is not InteractiveWindowWorkspace interactiveWorkspace) { Debug.Fail("InteractiveDocumentNavigationService called with incorrect workspace!"); return(false); } var textView = interactiveWorkspace.Window.TextView; var document = interactiveWorkspace.CurrentSolution.GetDocument(documentId); var textSnapshot = document .GetTextSynchronously(cancellationToken) .FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { return(false); } var snapshotSpan = new SnapshotSpan(textSnapshot, textSpan.Start, textSpan.Length); var virtualSnapshotSpan = new VirtualSnapshotSpan(snapshotSpan); if (!textView.TryGetSurfaceBufferSpan(virtualSnapshotSpan, out var surfaceBufferSpan)) { return(false); } textView.Selection.Select(surfaceBufferSpan.Start, surfaceBufferSpan.End); textView.ViewScroller.EnsureSpanVisible( surfaceBufferSpan.SnapshotSpan, EnsureSpanVisibleOptions.AlwaysCenter ); // Moving the caret must be the last operation involving surfaceBufferSpan because // it might update the version number of textView.TextSnapshot (VB does line commit // when the caret leaves a line which might cause pretty listing), which must be // equal to surfaceBufferSpan.SnapshotSpan.Snapshot's version number. textView.Caret.MoveTo(surfaceBufferSpan.Start); textView.VisualElement.Focus(); return(true); }
/// <summary> /// Attempt to uncomment a span of text using a particular block comment format. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <param name="format">The block comment format to use for uncommenting the code.</param> /// <param name="result">Upon return, a <see cref="VirtualSnapshotSpan"/> containing the uncommented /// code.</param> /// <returns> /// <para><see langword="true"/> if the span of text was uncommented using the specified block comment /// <paramref name="format"/>.</para> /// <para>-or-</para> /// <para>false if the span of text was not a complete block comment with the specified /// <paramref name="format"/>.</para> /// </returns> /// <exception cref="ArgumentNullException">If <paramref name="edit"/> is <see langword="null"/>.</exception> protected virtual bool TryUncommentBlock(VirtualSnapshotSpan span, ITextEdit edit, BlockCommentFormat format, out VirtualSnapshotSpan result) { if (edit == null) { throw new ArgumentNullException(nameof(edit)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } string blockStart = format.StartText; string blockEnd = format.EndText; int startLen = span.Start.Position.GetContainingLine().Length; int endLen = span.End.Position.GetContainingLine().Length; TrimSpan(ref span); //special case no selection, try and uncomment the current line. if (span.IsEmpty) { VirtualSnapshotPoint start = new VirtualSnapshotPoint(span.Start.Position.GetContainingLine().Start + ScanToNonWhitespaceChar(span.Start.Position.GetContainingLine())); VirtualSnapshotPoint end = span.IsInVirtualSpace ? span.End : new VirtualSnapshotPoint(span.End.Position.GetContainingLine().End); span = new VirtualSnapshotSpan(start, end); } // Check that comment start and end blocks are possible. if ((span.Start.Position - span.Start.Position.GetContainingLine().Start) + blockStart.Length <= startLen && (span.End.Position - span.End.Position.GetContainingLine().Start) - blockStart.Length >= 0) { string startText = span.Snapshot.GetText(span.Start.Position, blockStart.Length); if (startText.Equals(blockStart, StringComparison.Ordinal)) { SnapshotSpan linespan = span.SnapshotSpan; linespan = new SnapshotSpan(span.End.Position - blockEnd.Length, span.End.Position); string endText = linespan.GetText(); if (endText.Equals(blockEnd, StringComparison.Ordinal)) { //yes, block comment selected; remove it edit.Delete(linespan); edit.Delete(span.Start.Position, blockStart.Length); result = new VirtualSnapshotSpan(span.SnapshotSpan); return(true); } } } result = default(VirtualSnapshotSpan); return(false); }
public void Virtual(string line1) { Create(line1, ""); var point1 = _textBuffer.GetVirtualPointInLine(0, 0); var point2 = _textBuffer.GetVirtualPointInLine(0, 4); var span = new VirtualSnapshotSpan(point1, point2); var characterSpan = new CharacterSpan(span, true); var visualSpan = VisualSpan.NewCharacter(characterSpan); visualSpan.Select(_textView, SearchPath.Forward); DoEvents(); Assert.Equal(point1, _textView.Selection.Start); Assert.Equal(point2, _textView.Selection.End); }
internal void SetSelection(VirtualSnapshotSpan newSpan, ITextSnapshot snapshot) { Start = snapshot.CreateTrackingPoint( newSpan.Start.Position.Position > newSpan.End.Position.Position ? newSpan.End.Position.Position : newSpan.Start.Position.Position ); End = snapshot.CreateTrackingPoint( newSpan.Start.Position.Position > newSpan.End.Position.Position ? newSpan.Start.Position.Position : newSpan.End.Position.Position ); }
public readonly bool AtBottom; // ... Bottom. public SelectionData(VirtualSnapshotSpan span, double adornmentLeft, double adornmentRight, double leftClip, double rightClip, bool atTop, bool atBottom) { this.Span = span; //Everything on this adornment between leftClip and rightClip has been rendered correctly (and if the adornment doesn't //extend to leftClip then it is rendered "correctly" all the way to double.MinVal & the equivalent for right edge). //If the adornment is being clipped, then it is only correctly rendered up to a little bit inside the clip bounds (since there could //aliasing artifacts from the edge of the rectangles). this.LeftEdgeOfCorrectlyRenderedAdornment = (adornmentLeft < leftClip) ? (leftClip + BrushSelectionPainter.EdgeWidth) : double.MinValue; this.RightEdgeOfCorrectlyRenderedAdornment = (adornmentRight > rightClip) ? (rightClip - BrushSelectionPainter.EdgeWidth) : double.MaxValue; this.AtTop = atTop; this.AtBottom = atBottom; }
public void EnsureSpanVisible(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { if (span.Snapshot != textView.TextSnapshot) { throw new ArgumentException(); } if ((textView.TextViewLines?.Count ?? 0) == 0) { return; } EnsureSpanVisibleY(span, options); EnsureSpanVisibleX(span, options); }
public void Virtual(string line1) { Create(line1, ""); var point1 = _textBuffer.GetVirtualPointInLine(0, 0); var point2 = _textBuffer.GetVirtualPointInLine(0, 4); var span = new VirtualSnapshotSpan(point1, point2); _textView.Selection.Select(point1, point2); DoEvents(); var visualSpan = VisualSpan.CreateForVirtualSelection(_textView, VisualKind.Character, tabStop: 4, useVirtualSpace: true); Assert.Equal(point1, visualSpan.AsCharacter().CharacterSpan.VirtualStart); Assert.Equal(point2, visualSpan.AsCharacter().CharacterSpan.VirtualEnd); Assert.Equal(span.Length, visualSpan.AsCharacter().CharacterSpan.VirtualLength); }
private SnapshotSpan GetSpan(ITextView textview) { VirtualSnapshotSpan sel = textview.Selection.StreamSelectionSpan; ITextSnapshotLine startLine = new SnapshotPoint(textview.TextSnapshot, sel.Start.Position).GetContainingLine(); ITextSnapshotLine endLine = new SnapshotPoint(textview.TextSnapshot, sel.End.Position).GetContainingLine(); if (textview.Selection.IsEmpty || startLine.LineNumber != endLine.LineNumber) { return(new SnapshotSpan(startLine.Start, endLine.End)); } else { return(new SnapshotSpan(sel.Start.Position, sel.Length)); } }
public static Geometry CreateGeometry(IWpfTextView textView, VirtualSnapshotSpan span, bool isMultiLine, bool clipToViewport = false) { var padding = isMultiLine ? LineMarkerPadding : TextMarkerPadding; var pos = span.Start; PathGeometry geo = null; bool createOutlinedPath = false; while (pos <= span.End) { var line = textView.GetTextViewLineContainingBufferPosition(pos.Position); bool useVspaces = line.IsLastDocumentLine(); var lineExtent = new VirtualSnapshotSpan(new VirtualSnapshotPoint(line.Start), new VirtualSnapshotPoint(line.EndIncludingLineBreak, useVspaces ? span.End.VirtualSpaces : 0)); var extentTmp = lineExtent.Intersection(new VirtualSnapshotSpan(pos, span.End)); Debug.Assert(extentTmp != null); if (line.VisibilityState != VisibilityState.Unattached && extentTmp != null && extentTmp.Value.Length != 0) { var extent = extentTmp.Value; Collection<TextBounds> textBounds; if (extent.Start.IsInVirtualSpace) { var leading = line.TextRight + extent.Start.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; double width = line.EndOfLineWidth; int vspaces = span.End.VirtualSpaces - span.Start.VirtualSpaces; if (vspaces > 0) width = vspaces * textView.FormattedLineSource.ColumnWidth; textBounds = new Collection<TextBounds>(); textBounds.Add(new TextBounds(leading, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else if (extent.End.IsInVirtualSpace) { textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); double width = extent.End.VirtualSpaces * textView.FormattedLineSource.ColumnWidth; textBounds.Add(new TextBounds(line.TextRight, line.Top, width, line.Height, line.TextTop, line.TextHeight)); } else textBounds = line.GetNormalizedTextBounds(extent.SnapshotSpan); AddGeometries(textView, textBounds, isMultiLine, clipToViewport, padding, SystemParameters.CaretWidth, ref geo, ref createOutlinedPath); } if (line.IsLastDocumentLine()) break; pos = new VirtualSnapshotPoint(line.GetPointAfterLineBreak()); } if (createOutlinedPath) geo = geo.GetOutlinedPathGeometry(); if (geo != null && geo.CanFreeze) geo.Freeze(); return geo; }
public bool TryNavigateToSpan(Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet options) { var interactiveWorkspace = workspace as InteractiveWorkspace; if (interactiveWorkspace == null) { Debug.Fail("InteractiveDocumentNavigationService called with incorrect workspace!"); return false; } var textView = interactiveWorkspace.Window.TextView; var document = interactiveWorkspace.CurrentSolution.GetDocument(documentId); var textSnapshot = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None).FindCorrespondingEditorTextSnapshot(); if (textSnapshot == null) { return false; } var snapshotSpan = new SnapshotSpan(textSnapshot, textSpan.Start, textSpan.Length); var virtualSnapshotSpan = new VirtualSnapshotSpan(snapshotSpan); VirtualSnapshotSpan surfaceBufferSpan; if (!textView.TryGetSurfaceBufferSpan(virtualSnapshotSpan, out surfaceBufferSpan)) { return false; } textView.Selection.Select(surfaceBufferSpan.Start, surfaceBufferSpan.End); textView.ViewScroller.EnsureSpanVisible(surfaceBufferSpan.SnapshotSpan, EnsureSpanVisibleOptions.AlwaysCenter); // Moving the caret must be the last operation involving surfaceBufferSpan because // it might update the version number of textView.TextSnapshot (VB does line commit // when the caret leaves a line which might cause pretty listing), which must be // equal to surfaceBufferSpan.SnapshotSpan.Snapshot's version number. textView.Caret.MoveTo(surfaceBufferSpan.Start); textView.VisualElement.Focus(); return true; }
private void SelectSpan(ITextView textView, SnapshotSpan snapshotSpan) { var source = textView.BufferGraph.MapUpToSnapshot(snapshotSpan, SpanTrackingMode.EdgeExclusive, textView.TextSnapshot); var span = source.First<SnapshotSpan>(); if (_outliningManagerService != null) { var outliningManager = _outliningManagerService.GetOutliningManager(textView); if (outliningManager != null) { outliningManager.ExpandAll(span, (_) => true); } } var virtualSnapshotSpan = new VirtualSnapshotSpan(span); _editorOperationsFactory.GetEditorOperations(textView).SelectAndMoveCaret( virtualSnapshotSpan.Start, virtualSnapshotSpan.End, TextSelectionMode.Stream, EnsureSpanVisibleOptions.AlwaysCenter); }
public bool DeleteWordToRight() { if (Selection.ActivePoint < Selection.AnchorPoint) { DeleteSelection(); return true; } var selSpan = GetSelectionOrCaretIfNoSelection(); var wordPoint = GetPointOfRightWord(selSpan.End); var oldSelection = new SavedCaretSelection(this); var newSelSpan = new VirtualSnapshotSpan(selSpan.Start, new VirtualSnapshotPoint(wordPoint)); if (Selection.IsEmpty || Selection.Mode != TextSelectionMode.Box) TextBuffer.Delete(newSelSpan.SnapshotSpan.Span); else { var line = Snapshot.GetLineFromPosition(wordPoint.Position); int column = wordPoint - line.Start; using (var ed = TextBuffer.CreateEdit()) { foreach (var span in Selection.SelectedSpans) { line = Snapshot.GetLineFromPosition(span.Start.Position); var end = line.Start + Math.Min(line.Length, column); if (span.Start < end) { var newSpan = new SnapshotSpan(span.Start, end); ed.Delete(newSpan); } } ed.Apply(); } } oldSelection.UpdatePositions(); return true; }
/// <summary> /// Comment out a span using a particular line comment format. If the <paramref name="span"/> is empty, the /// entire line containing the span's start point is commented. /// </summary> /// <remarks> /// <para>The default algorithm for line comments is designed to meet the following conditions.</para> /// <list type="bullet"> /// <item>Make sure line comments are indented as far as possible, skipping empty lines as necessary.</item> /// <item>Don't comment <em>N</em>+1 lines when only <em>N</em> lines were selected by clicking in the left /// margin.</item> /// </list> /// </remarks> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to apply the changes to.</param> /// <param name="format">The line comment format to use for commenting the code.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="format"/> is <see langword="null"/>.</para> /// </exception> protected virtual VirtualSnapshotSpan CommentLines(VirtualSnapshotSpan span, ITextEdit edit, LineCommentFormat format) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); Contract.Requires<ArgumentNullException>(format != null, "format"); if (span.End.Position.GetContainingLine().LineNumber > span.Start.Position.GetContainingLine().LineNumber && span.End.Position.GetContainingLine().Start == span.End.Position) { VirtualSnapshotPoint start = span.Start; VirtualSnapshotPoint end = new VirtualSnapshotPoint(span.Snapshot.GetLineFromLineNumber(span.End.Position.GetContainingLine().LineNumber - 1).Start); if (end < start) start = end; span = new VirtualSnapshotSpan(start, end); } int minindex = (from i in Enumerable.Range(span.Start.Position.GetContainingLine().LineNumber, span.End.Position.GetContainingLine().LineNumber - span.Start.Position.GetContainingLine().LineNumber + 1) where span.Snapshot.GetLineFromLineNumber(i).GetText().Trim().Length > 0 select ScanToNonWhitespaceChar(span.Snapshot.GetLineFromLineNumber(i))) .Min(); //comment each line for (int line = span.Start.Position.GetContainingLine().LineNumber; line <= span.End.Position.GetContainingLine().LineNumber; line++) { if (span.Snapshot.GetLineFromLineNumber(line).GetText().Trim().Length > 0) edit.Insert(span.Snapshot.GetLineFromLineNumber(line).Start + minindex, format.StartText); } span = new VirtualSnapshotSpan(new SnapshotSpan(span.Start.Position.GetContainingLine().Start, span.End.Position.GetContainingLine().End)); return span; }
/// <summary> /// Attempt to uncomment a span of text using a particular block comment format. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <param name="format">The block comment format to use for uncommenting the code.</param> /// <param name="result">Upon return, a <see cref="VirtualSnapshotSpan"/> containing the uncommented /// code.</param> /// <returns> /// <para><see langword="true"/> if the span of text was uncommented using the specified block comment /// <paramref name="format"/>.</para> /// <para>-or-</para> /// <para>false if the span of text was not a complete block comment with the specified /// <paramref name="format"/>.</para> /// </returns> /// <exception cref="ArgumentNullException">If <paramref name="edit"/> is <see langword="null"/>.</exception> protected virtual bool TryUncommentBlock(VirtualSnapshotSpan span, ITextEdit edit, BlockCommentFormat format, out VirtualSnapshotSpan result) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); Contract.Requires<ArgumentNullException>(format != null, "format"); string blockStart = format.StartText; string blockEnd = format.EndText; int startLen = span.Start.Position.GetContainingLine().Length; int endLen = span.End.Position.GetContainingLine().Length; TrimSpan(ref span); //special case no selection, try and uncomment the current line. if (span.IsEmpty) { VirtualSnapshotPoint start = new VirtualSnapshotPoint(span.Start.Position.GetContainingLine().Start + ScanToNonWhitespaceChar(span.Start.Position.GetContainingLine())); VirtualSnapshotPoint end = span.IsInVirtualSpace ? span.End : new VirtualSnapshotPoint(span.End.Position.GetContainingLine().End); span = new VirtualSnapshotSpan(start, end); } // Check that comment start and end blocks are possible. if ((span.Start.Position - span.Start.Position.GetContainingLine().Start) + blockStart.Length <= startLen && (span.End.Position - span.End.Position.GetContainingLine().Start) - blockStart.Length >= 0) { string startText = span.Snapshot.GetText(span.Start.Position, blockStart.Length); if (startText.Equals(blockStart, StringComparison.Ordinal)) { SnapshotSpan linespan = span.SnapshotSpan; linespan = new SnapshotSpan(span.End.Position - blockEnd.Length, span.End.Position); string endText = linespan.GetText(); if (endText.Equals(blockEnd, StringComparison.Ordinal)) { //yes, block comment selected; remove it edit.Delete(linespan); edit.Delete(span.Start.Position, blockStart.Length); result = new VirtualSnapshotSpan(span.SnapshotSpan); return true; } } } result = default(VirtualSnapshotSpan); return false; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || quickInfoContent == null) return; if (session.TextView.TextBuffer == this.TextBuffer) { ITextSnapshot currentSnapshot = this.TextBuffer.CurrentSnapshot; SnapshotPoint? triggerPoint = session.GetTriggerPoint(currentSnapshot); if (!triggerPoint.HasValue) return; #region experimental /* use the experimental model to locate and process the expression */ Stopwatch stopwatch = Stopwatch.StartNew(); // lex the entire document var input = new SnapshotCharStream(currentSnapshot, new Span(0, currentSnapshot.Length)); var lexer = new GoLexer(input); var tokenSource = new GoSemicolonInsertionTokenSource(lexer); var tokens = new CommonTokenStream(tokenSource); tokens.Fill(); // locate the last token before the trigger point while (true) { IToken nextToken = tokens.LT(1); if (nextToken.Type == CharStreamConstants.EndOfFile) break; if (nextToken.StartIndex > triggerPoint.Value.Position) break; tokens.Consume(); } switch (tokens.LA(-1)) { case GoLexer.IDENTIFIER: //case GoLexer.KW_THIS: //case GoLexer.KW_UNIV: //case GoLexer.KW_IDEN: //case GoLexer.KW_INT2: //case GoLexer.KW_SEQINT: break; default: return; } Network network = NetworkBuilder<GoSimplifiedAtnBuilder>.GetOrBuildNetwork(); RuleBinding memberSelectRule = network.GetRule(GoSimplifiedAtnBuilder.RuleNames.PrimaryExpr); #if false HashSet<Transition> memberSelectTransitions = new HashSet<Transition>(); GetReachableTransitions(memberSelectRule, memberSelectTransitions); #endif NetworkInterpreter interpreter = new NetworkInterpreter(network, tokens); interpreter.BoundaryRules.Add(memberSelectRule); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.Label)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.TypeSwitchGuard)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.FieldName)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.Receiver)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.FunctionDecl)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.BaseTypeName)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.TypeSpec)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.IdentifierList)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.MethodName)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.ParameterDecl)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.FieldIdentifierList)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.PackageName)); interpreter.BoundaryRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.TypeName)); interpreter.ExcludedStartRules.Add(network.GetRule(GoSimplifiedAtnBuilder.RuleNames.Block)); while (interpreter.TryStepBackward()) { if (interpreter.Contexts.Count == 0) break; /* we want all traces to start outside the binOpExpr18 rule, which means all * traces with a transition reachable from binOpExpr18 should contain a push * transition with binOpExpr18's start state as its target. */ if (interpreter.Contexts.All(context => context.BoundedStart)) { break; } } interpreter.CombineBoundedStartContexts(); IOutputWindowPane pane = Provider.OutputWindowService.TryGetPane(PredefinedOutputWindowPanes.TvlIntellisense); if (pane != null) { pane.WriteLine(string.Format("Located {0} QuickInfo expression(s) in {1}ms.", interpreter.Contexts.Count, stopwatch.ElapsedMilliseconds)); } HashSet<string> finalResult = new HashSet<string>(); SnapshotSpan? contextSpan = null; foreach (var context in interpreter.Contexts) { Span? span = null; //List<string> results = AnalyzeInterpreterTrace(context, memberSelectRule, out span); foreach (var transition in context.Transitions) { if (!transition.Transition.IsMatch) continue; IToken token = transition.Token; Span tokenSpan = new Span(token.StartIndex, token.StopIndex - token.StartIndex + 1); if (span == null) span = tokenSpan; else span = Span.FromBounds(Math.Min(span.Value.Start, tokenSpan.Start), Math.Max(span.Value.End, tokenSpan.End)); } if (span.HasValue && !span.Value.IsEmpty) contextSpan = new SnapshotSpan(currentSnapshot, span.Value); //if (results.Count > 0) //{ // finalResult.UnionWith(results); // applicableToSpan = currentSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); //} } foreach (var result in finalResult) { quickInfoContent.Add(result); } #endregion #if false var selection = session.TextView.Selection.StreamSelectionSpan; if (selection.IsEmpty || !selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) { SnapshotSpan? expressionSpan = Provider.IntellisenseCache.GetExpressionSpan(triggerPoint.Value); if (expressionSpan.HasValue) selection = new VirtualSnapshotSpan(expressionSpan.Value); } #endif VirtualSnapshotSpan selection = new VirtualSnapshotSpan(); if (contextSpan.HasValue) selection = new VirtualSnapshotSpan(contextSpan.Value); if (!selection.IsEmpty && selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) { applicableToSpan = selection.Snapshot.CreateTrackingSpan(selection.SnapshotSpan, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(selection.GetText()); //try //{ // Expression currentExpression = Provider.IntellisenseCache.ParseExpression(selection); // if (currentExpression != null) // { // SnapshotSpan? span = currentExpression.Span; // if (span.HasValue) // applicableToSpan = span.Value.Snapshot.CreateTrackingSpan(span.Value, SpanTrackingMode.EdgeExclusive); // quickInfoContent.Add(currentExpression.ToString()); // } // else // { // quickInfoContent.Add("Could not parse expression."); // } //} //catch (Exception ex) //{ // if (ErrorHandler.IsCriticalException(ex)) // throw; // quickInfoContent.Add(ex.Message); //} } } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> quickInfoContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || quickInfoContent == null) return; if (session.TextView.TextBuffer == this.TextBuffer) { ITextSnapshot currentSnapshot = this.TextBuffer.CurrentSnapshot; SnapshotPoint? triggerPoint = session.GetTriggerPoint(currentSnapshot); if (!triggerPoint.HasValue) return; #region experimental /* use the experimental model to locate and process the expression */ Stopwatch stopwatch = Stopwatch.StartNew(); // lex the entire document var input = new SnapshotCharStream(currentSnapshot, new Span(0, currentSnapshot.Length)); var lexer = new AlloyLexer(input); var tokens = new CommonTokenStream(lexer); tokens.Fill(); // locate the last token before the trigger point while (true) { IToken nextToken = tokens.LT(1); if (nextToken.Type == CharStreamConstants.EndOfFile) break; if (nextToken.StartIndex > triggerPoint.Value.Position) break; tokens.Consume(); } switch (tokens.LA(-1)) { case AlloyLexer.IDENTIFIER: case AlloyLexer.KW_THIS: case AlloyLexer.KW_UNIV: case AlloyLexer.KW_IDEN: case AlloyLexer.KW_INT2: case AlloyLexer.KW_SEQINT: case AlloyLexer.INTEGER: break; default: return; } Network network = NetworkBuilder<AlloySimplifiedAtnBuilder>.GetOrBuildNetwork(); RuleBinding memberSelectRule = network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.BinOpExpr18); #if DEBUG && false HashSet<Transition> memberSelectTransitions = new HashSet<Transition>(ObjectReferenceEqualityComparer<Transition>.Default); GetReachableTransitions(memberSelectRule, memberSelectTransitions); #endif NetworkInterpreter interpreter = new NetworkInterpreter(network, tokens); interpreter.BoundaryRules.Add(memberSelectRule); //interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.UnaryExpression)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.LetDecl)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.NameListName)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.Ref)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.Module)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.Open)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.FactDecl)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.AssertDecl)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.FunctionName)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.CmdDecl)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.Typescope)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.EnumDecl)); interpreter.BoundaryRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.ElseClause)); interpreter.ExcludedStartRules.Add(network.GetRule(AlloySimplifiedAtnBuilder.RuleNames.CallArguments)); while (interpreter.TryStepBackward()) { if (interpreter.Contexts.Count == 0) break; /* we want all traces to start outside the binOpExpr18 rule, which means all * traces with a transition reachable from binOpExpr18 should contain a push * transition with binOpExpr18's start state as its target. */ if (interpreter.Contexts.All(context => context.BoundedStart)) { break; } } HashSet<InterpretTrace> contexts = new HashSet<InterpretTrace>(BoundedStartInterpretTraceEqualityComparer.Default); if (interpreter.Contexts.Count > 0) { contexts.UnionWith(interpreter.Contexts); } else { contexts.UnionWith(interpreter.BoundedStartContexts); } IOutputWindowPane pane = Provider.OutputWindowService.TryGetPane(PredefinedOutputWindowPanes.TvlIntellisense); if (pane != null) { pane.WriteLine(string.Format("Located {0} QuickInfo expression(s) in {1}ms.", contexts.Count, stopwatch.ElapsedMilliseconds)); } HashSet<Span> spans = new HashSet<Span>(); foreach (var context in contexts) { Span? span = null; foreach (var transition in context.Transitions) { if (!transition.Transition.IsMatch) continue; IToken token = transition.Token; Span tokenSpan = new Span(token.StartIndex, token.StopIndex - token.StartIndex + 1); if (span == null) span = tokenSpan; else span = Span.FromBounds(Math.Min(span.Value.Start, tokenSpan.Start), Math.Max(span.Value.End, tokenSpan.End)); } if (span.HasValue) spans.Add(span.Value); } //List<Expression> expressions = new List<Expression>(); //HashSet<string> finalResult = new HashSet<string>(); //SnapshotSpan? contextSpan = null; bool foundInfo = false; foreach (var span in spans) { if (!span.IsEmpty) { VirtualSnapshotSpan selection = new VirtualSnapshotSpan(new SnapshotSpan(currentSnapshot, span)); if (!selection.IsEmpty && selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) { try { Expression currentExpression = Provider.IntellisenseCache.ParseExpression(selection); if (currentExpression != null && currentExpression.Span.HasValue && currentExpression.Span.Value.Contains(triggerPoint.Value)) { applicableToSpan = currentExpression.Span.Value.Snapshot.CreateTrackingSpan(currentExpression.Span.Value, SpanTrackingMode.EdgeExclusive); quickInfoContent.Add(currentExpression.ToString()); foundInfo = true; } } catch (Exception ex) { if (ErrorHandler.IsCriticalException(ex)) throw; quickInfoContent.Add(ex.Message); } } //try //{ // SnapshotSpan contextSpan = new SnapshotSpan(currentSnapshot, span.Value); // Expression expression = Provider.IntellisenseCache.ParseExpression(contextSpan); // if (expression != null) // expressions.Add(expression); //} //catch (Exception e) //{ // if (ErrorHandler.IsCriticalException(e)) // throw; //} } //if (results.Count > 0) //{ // finalResult.UnionWith(results); // applicableToSpan = currentSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeExclusive); //} } if (!foundInfo && spans.Count > 0) { foreach (var span in spans) { if (!span.IsEmpty) { VirtualSnapshotSpan selection = new VirtualSnapshotSpan(new SnapshotSpan(currentSnapshot, span)); if (!selection.IsEmpty && selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) { applicableToSpan = selection.Snapshot.CreateTrackingSpan(selection.SnapshotSpan, SpanTrackingMode.EdgeExclusive); break; } } } quickInfoContent.Add("Could not parse expression."); } //foreach (var result in finalResult) //{ // quickInfoContent.Add(result); //} #endregion #if false var selection = session.TextView.Selection.StreamSelectionSpan; if (selection.IsEmpty || !selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) { SnapshotSpan? expressionSpan = Provider.IntellisenseCache.GetExpressionSpan(triggerPoint.Value); if (expressionSpan.HasValue) selection = new VirtualSnapshotSpan(expressionSpan.Value); } #endif //VirtualSnapshotSpan selection = new VirtualSnapshotSpan(); //if (contextSpan.HasValue) // selection = new VirtualSnapshotSpan(contextSpan.Value); //if (!selection.IsEmpty && selection.Contains(new VirtualSnapshotPoint(triggerPoint.Value))) //{ // applicableToSpan = selection.Snapshot.CreateTrackingSpan(selection.SnapshotSpan, SpanTrackingMode.EdgeExclusive); // try // { // Expression currentExpression = Provider.IntellisenseCache.ParseExpression(selection); // if (currentExpression != null) // { // SnapshotSpan? span = currentExpression.Span; // if (span.HasValue) // applicableToSpan = span.Value.Snapshot.CreateTrackingSpan(span.Value, SpanTrackingMode.EdgeExclusive); // quickInfoContent.Add(currentExpression.ToString()); // } // else // { // quickInfoContent.Add("Could not parse expression."); // } // } // catch (Exception ex) // { // if (ErrorHandler.IsCriticalException(ex)) // throw; // quickInfoContent.Add(ex.Message); // } //} } }
void EnsureSpanVisibleX(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { if ((textView.Options.WordWrapStyle() & WordWrapStyles.WordWrap) != 0) return; if (textView.ViewportWidth == 0) return; var lines = textView.TextViewLines.GetTextViewLinesIntersectingSpan(span.SnapshotSpan); if (lines.Count == 0) return; var ispan = span.Intersection(new VirtualSnapshotSpan(textView.TextViewLines.FormattedSpan)); if (ispan == null) return; span = ispan.Value; double left = double.PositiveInfinity, right = double.NegativeInfinity; for (int i = 0; i < lines.Count; i++) { var line = lines[i]; var lineSpan = line.ExtentIncludingLineBreak.Intersection(span.SnapshotSpan); if (lineSpan == null) continue; var startPoint = new VirtualSnapshotPoint(lineSpan.Value.Start); var endPoint = new VirtualSnapshotPoint(lineSpan.Value.End); if (startPoint.Position == span.Start.Position) startPoint = span.Start; if (endPoint.Position == span.End.Position) endPoint = span.End; var startBounds = line.GetExtendedCharacterBounds(startPoint); var endBounds = line.GetExtendedCharacterBounds(endPoint); if (left > startBounds.Left) left = startBounds.Left; if (right < startBounds.Right) right = startBounds.Right; if (left > endBounds.Left) left = endBounds.Left; if (right < endBounds.Right) right = endBounds.Right; } if (double.IsInfinity(left) || double.IsInfinity(right)) return; Debug.Assert(left <= right); if (left > right) right = left; double width = right - left; double availWidth = Math.Max(0, textView.ViewportWidth - width); double extraScroll; const double EXTRA_WIDTH = 4; if (availWidth >= EXTRA_WIDTH) extraScroll = EXTRA_WIDTH; else extraScroll = availWidth / 2; if (textView.ViewportLeft <= right && right <= textView.ViewportRight) { } else if (right > textView.ViewportRight) textView.ViewportLeft = right + extraScroll - textView.ViewportWidth; else { var newLeft = left - extraScroll; if (newLeft + textView.ViewportWidth < right) newLeft = right - textView.ViewportWidth; textView.ViewportLeft = newLeft; } }
public void EnsureSpanVisible(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { throw new NotImplementedException(); }
/// <summary> /// Attempt to uncomment a span of text using any of a collection of line comment formats. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <param name="formats">The line comment formats to use for attempting to uncomment the code.</param> /// <param name="result">Upon return, a <see cref="VirtualSnapshotSpan"/> containing the uncommented /// code.</param> /// <returns> /// <para><see langword="true"/> if one or more lines of the span of text were successfully uncommented using /// one of the specified line comment <paramref name="formats"/>.</para> /// <para>-or-</para> /// <para><see langword="false"/> if none of the lines in the span of text could be uncommented using any of the /// specified <paramref name="formats"/>.</para> /// </returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="formats"/> is <see langword="null"/>.</para> /// </exception> /// <exception cref="ArgumentException">If <paramref name="formats"/> contains any <see langword="null"/> /// values.</exception> protected virtual bool TryUncommentLines(VirtualSnapshotSpan span, ITextEdit edit, ReadOnlyCollection<LineCommentFormat> formats, out VirtualSnapshotSpan result) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); Contract.Requires<ArgumentNullException>(formats != null, "formats"); Contract.Requires(Contract.ForAll(formats, i => i != null)); if (span.End.Position.GetContainingLine().LineNumber > span.Start.Position.GetContainingLine().LineNumber && span.End.Position == span.End.Position.GetContainingLine().Start) { VirtualSnapshotPoint start = span.Start; VirtualSnapshotPoint end = new VirtualSnapshotPoint(span.Snapshot.GetLineFromLineNumber(span.End.Position.GetContainingLine().LineNumber - 1).Start); if (end < start) start = end; span = new VirtualSnapshotSpan(start, end); } // Remove line comments bool containedComments = false; for (int line = span.Start.Position.GetContainingLine().LineNumber; line <= span.End.Position.GetContainingLine().LineNumber; line++) { int i = ScanToNonWhitespaceChar(span.Snapshot.GetLineFromLineNumber(line)); string text = span.Snapshot.GetLineFromLineNumber(line).GetText(); foreach (var format in formats) { int clen = format.StartText.Length; if ((text.Length > i + clen) && text.Substring(i, clen).Equals(format.StartText, StringComparison.Ordinal)) { // remove line comment. edit.Delete(span.Snapshot.GetLineFromLineNumber(line).Start.Position + i, clen); containedComments = true; break; } } } span = new VirtualSnapshotSpan(new SnapshotSpan(span.Start.Position.GetContainingLine().Start, span.End.Position.GetContainingLine().End)); result = span; return containedComments; }
private void OnSelectionChanged(object sender, object e) { this.selectedText = this._view.Selection.StreamSelectionSpan.GetText(); this.selectedWord = this._view.Selection.StreamSelectionSpan; this._layer.RemoveAllAdornments(); this.SnapShotsToColor.Clear(); if (string.IsNullOrEmpty(this.selectedText) || string.IsNullOrWhiteSpace(this.selectedText)) return; int length = this.selectedText.Length; int position = this._view.Selection.StreamSelectionSpan.Start.Position.Position; int index = position + length; //if (position - 1 >= 0 && char.IsLetterOrDigit(this._view.TextSnapshot[position - 1]) || index < this._view.TextSnapshot.GetText().Length && char.IsLetterOrDigit(this._view.TextSnapshot[index])) // return; //foreach (char c in this.selectedText) //{ // if (!char.IsLetterOrDigit(c) && (int)c != 95) // return; //} this.FindWordsInDocument(); this.ColorWords(); }
/// <summary> /// Comment out the code in a single <see cref="VirtualSnapshotSpan"/>. /// </summary> /// <remarks> /// <para>The default implementation uses line comments if <see cref="UseLineComments"/> is /// <see langword="true"/> and one of the following is true.</para> /// <list type="number"> /// <item>There is no selected text.</item> /// <item> /// On the line where the selection starts, there is only whitespace up to the selection start point, /// <strong>and</strong> one of the following is true. /// <list type="bullet"> /// <item>On the line where the selection ends, there is only whitespace up to the selection end point, /// <strong>or</strong></item> /// <item>There is only whitespace from the selection end point to the end of the line.</item> /// </list> /// </item> /// </list> /// /// <para>The default implementation uses block comments if <em>all</em> of the following are true.</para> /// <list type="bullet"> /// <item>We are not using line comments.</item> /// <item><see cref="PreferredBlockFormat"/> is not <see langword="null"/>.</item> /// </list> /// </remarks> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to apply the changes to.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> protected virtual VirtualSnapshotSpan CommentSpan(VirtualSnapshotSpan span, ITextEdit edit) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); span = span.TranslateTo(edit.Snapshot, SpanTrackingMode.EdgeExclusive); var startContainingLine = span.Start.Position.GetContainingLine(); var endContainingLine = span.End.Position.GetContainingLine(); if (UseLineComments && (span.IsEmpty || (string.IsNullOrWhiteSpace(startContainingLine.GetText().Substring(0, span.Start.Position - startContainingLine.Start)) && (string.IsNullOrWhiteSpace(endContainingLine.GetText().Substring(0, span.End.Position - endContainingLine.Start)) || string.IsNullOrWhiteSpace(endContainingLine.GetText().Substring(span.End.Position - endContainingLine.Start))) ))) { span = CommentLines(span, edit, PreferredLineFormat); } else if (PreferredBlockFormat != null) { span = CommentBlock(span, edit, PreferredBlockFormat); } return span; }
private static void Navigate(IEditorOperations editorOperations, VirtualSnapshotSpan virtualSnapshotSpan, bool selectSpan) { VirtualSnapshotPoint selectionEnd = selectSpan ? virtualSnapshotSpan.End : virtualSnapshotSpan.Start; editorOperations.SelectAndMoveCaret(virtualSnapshotSpan.Start, selectionEnd, TextSelectionMode.Stream, EnsureSpanVisibleOptions.AlwaysCenter); }
/// <summary> /// Attempt to uncomment a span of text using any of a collection of block comment formats. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <param name="formats">The block comment formats to use for attempting to uncomment the code.</param> /// <param name="result">Upon return, a <see cref="VirtualSnapshotSpan"/> containing the uncommented /// code.</param> /// <returns> /// <para><see langword="true"/> if the span of text was successfully uncommented using one of the specified /// block comment <paramref name="formats"/>.</para> /// <para>-or-</para> /// <para><see langword="false"/> if the span of text was not a complete block comment using any of the /// specified <paramref name="formats"/>.</para> /// </returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="formats"/> is <see langword="null"/>.</para> /// </exception> /// <exception cref="ArgumentException">If <paramref name="formats"/> contains any <see langword="null"/> /// values.</exception> protected virtual bool TryUncommentBlock(VirtualSnapshotSpan span, ITextEdit edit, ReadOnlyCollection<BlockCommentFormat> formats, out VirtualSnapshotSpan result) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); Contract.Requires<ArgumentNullException>(formats != null, "formats"); Contract.Requires(Contract.ForAll(formats, i => i != null)); foreach (var format in formats) { if (TryUncommentBlock(span, edit, format, out result)) return true; } result = default(VirtualSnapshotSpan); return false; }
/// <summary> /// Uncomment the span of text. /// </summary> /// <param name="span">The span of text to uncomment.</param> /// <param name="edit">The <see cref="ITextEdit"/> instance to use for applying changes.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the uncommented code.</returns> /// <exception cref="ArgumentNullException">If <paramref name="edit"/> is <see langword="null"/>.</exception> protected virtual VirtualSnapshotSpan UncommentSpan(VirtualSnapshotSpan span, ITextEdit edit) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); span = span.TranslateTo(edit.Snapshot, SpanTrackingMode.EdgeExclusive); bool useLineComments = true; var startContainingLine = span.Start.Position.GetContainingLine(); var endContainingLine = span.End.Position.GetContainingLine(); // special case: empty span if (span.IsEmpty) { if (useLineComments) TryUncommentLines(span, edit, LineFormats, out span); } else { VirtualSnapshotSpan resultSpan; if (TryUncommentBlock(span, edit, BlockFormats, out resultSpan)) return resultSpan; if (useLineComments) { TryUncommentLines(span, edit, LineFormats, out span); } } return span; }
void EnsureSpanVisibleY(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options) { bool showStart = (options & EnsureSpanVisibleOptions.ShowStart) != 0; bool minimumScroll = (options & EnsureSpanVisibleOptions.MinimumScroll) != 0; bool alwaysCenter = (options & EnsureSpanVisibleOptions.AlwaysCenter) != 0; var bufferSpan = span.SnapshotSpan; var visibleSpan = VisibleSpan; bool spanIsInView = bufferSpan.Start >= visibleSpan.Start && bufferSpan.End <= visibleSpan.End; if (!spanIsInView) { ShowSpan(bufferSpan, options); alwaysCenter = true; visibleSpan = VisibleSpan; spanIsInView = bufferSpan.Start >= visibleSpan.Start && bufferSpan.End <= visibleSpan.End; } if (spanIsInView) { var lines = textView.TextViewLines.GetTextViewLinesIntersectingSpan(bufferSpan); Debug.Assert(lines.Count > 0); if (lines.Count == 0) return; var first = lines[0]; var last = lines[lines.Count - 1]; var firstSpan = first.ExtentIncludingLineBreak; var lastSpan = last.ExtentIncludingLineBreak; bool allLinesFullyVisible = first.VisibilityState == VisibilityState.FullyVisible && last.VisibilityState == VisibilityState.FullyVisible; if (alwaysCenter || (!allLinesFullyVisible && !minimumScroll)) { double height = last.Bottom - first.Top; double verticalDistance = (textView.ViewportHeight - height) / 2; textView.DisplayTextLineContainingBufferPosition(first.Start, verticalDistance, ViewRelativePosition.Top); return; } if (first.VisibilityState != VisibilityState.FullyVisible) { if (first != last || !minimumScroll || first.VisibilityState != VisibilityState.PartiallyVisible) textView.DisplayTextLineContainingBufferPosition(first.Start, 0, ViewRelativePosition.Top); else if (first.Bottom > textView.ViewportBottom) textView.DisplayTextLineContainingBufferPosition(first.Start, 0, ViewRelativePosition.Bottom); else textView.DisplayTextLineContainingBufferPosition(first.Start, 0, ViewRelativePosition.Top); } else if (last.VisibilityState != VisibilityState.FullyVisible) textView.DisplayTextLineContainingBufferPosition(last.Start, 0, ViewRelativePosition.Bottom); if (showStart) { var line = textView.TextViewLines.GetTextViewLineContainingBufferPosition(firstSpan.Start); if (line == null || line.VisibilityState != VisibilityState.FullyVisible) ShowSpan(bufferSpan, options); } else { var line = textView.TextViewLines.GetTextViewLineContainingBufferPosition(lastSpan.Start); if (line == null || line.VisibilityState != VisibilityState.FullyVisible) ShowSpan(bufferSpan, options); } } }
/// <summary> /// Update the specified <paramref name="span"/> to not include any leading or trailing whitespace characters. /// </summary> /// <param name="span">The span to trim.</param> protected static void TrimSpan(ref VirtualSnapshotSpan span) { string text = span.GetText(); int length = text.Trim().Length; int offset = 0; while (offset < text.Length && char.IsWhiteSpace(text[offset])) offset++; if (offset > 0 || length != text.Length) { VirtualSnapshotPoint start = offset > 0 ? new VirtualSnapshotPoint(span.Start.Position + offset) : span.Start; bool removedSpacesFromEnd = length < text.Length - offset; VirtualSnapshotPoint end = removedSpacesFromEnd ? new VirtualSnapshotPoint(start.Position + length) : span.End; span = new VirtualSnapshotSpan(start, end); } }
bool IndentMultipleLines(ITextEdit ed, VirtualSnapshotSpan vspan) { var currPos = vspan.Start.Position; while (currPos <= vspan.End.Position) { if (vspan.Length != 0 && currPos == vspan.End.Position) break; var line = currPos.GetContainingLine(); var lineString = line.Extent.GetText(); int index = TryGetIndexOfFirstNonWhitespace(lineString); if (index >= 0) { var vpos = new VirtualSnapshotPoint(line.Start + index); if (!IndentLine(ed, line, lineString, vpos, onlyAddIndentSize: true, isOverwrite: false)) return false; } if (line.LineNumber + 1 == line.Snapshot.LineCount) break; line = line.Snapshot.GetLineFromLineNumber(line.LineNumber + 1); currPos = line.Start; } return true; }
/// <summary> /// Comment out a span of text using the specified block comment format. If the <paramref name="span"/> is /// empty, the entire line containing the span's start point is commented. /// </summary> /// <param name="span">The span of text to comment.</param> /// <param name="edit">The <see cref="ITextEdit"/> to use for applying changes.</param> /// <param name="format">The block comment format.</param> /// <returns>A <see cref="VirtualSnapshotSpan"/> containing the commented code.</returns> /// <exception cref="ArgumentNullException"> /// <para>If <paramref name="edit"/> is <see langword="null"/>.</para> /// <para>-or-</para> /// <para>If <paramref name="format"/> is <see langword="null"/>.</para> /// </exception> protected virtual VirtualSnapshotSpan CommentBlock(VirtualSnapshotSpan span, ITextEdit edit, BlockCommentFormat format) { Contract.Requires<ArgumentNullException>(edit != null, "edit"); Contract.Requires<ArgumentNullException>(format != null, "format"); //special case no selection if (span.IsEmpty) { VirtualSnapshotPoint start = new VirtualSnapshotPoint(span.Start.Position.GetContainingLine().Start + ScanToNonWhitespaceChar(span.Start.Position.GetContainingLine())); VirtualSnapshotPoint end = span.IsInVirtualSpace ? span.End : new VirtualSnapshotPoint(span.End.Position.GetContainingLine().End); span = new VirtualSnapshotSpan(start, end); } // add start comment edit.Insert(span.Start.Position, format.StartText); // add end comment edit.Insert(span.End.Position, format.EndText); return span; }
private void TestSimpleLineComment(string initialText, string finalText, int caretPosition) { ITextBuffer textBuffer = TextBufferFactoryService.CreateTextBuffer(initialText, ContentTypeRegistryService.GetContentType(TestContentType)); LineCommentFormat lineCommentFormat = new LineCommentFormat("//"); FormatCommenter commenter = new FormatCommenter(textBuffer, lineCommentFormat); VirtualSnapshotPoint caret = new VirtualSnapshotPoint(textBuffer.CurrentSnapshot.Lines.First(), caretPosition); VirtualSnapshotSpan caretSpan = new VirtualSnapshotSpan(caret, caret); ReadOnlyCollection<VirtualSnapshotSpan> commentSpans = commenter.CommentSpans(new ReadOnlyCollection<VirtualSnapshotSpan>(new[] { caretSpan })); Assert.AreEqual(finalText, textBuffer.CurrentSnapshot.GetText()); Assert.AreEqual(1, commentSpans.Count); Assert.AreEqual(0, commentSpans[0].Start.Position); Assert.AreEqual(initialText.Length + lineCommentFormat.StartText.Length, commentSpans[0].End.Position); }