/// <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> /// 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); }
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); }