From 1efb97aff887c3d6c5ef9a55e213a1789b306540 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 26 Aug 2015 15:38:39 -0700 Subject: [PATCH] Properly support indentation within text of XML doc comment on ENTER --- .../DocumentationCommentTests.cs | 150 ++++++++++++++++++ ...tractDocumentationCommentCommandHandler.cs | 34 +++- .../DocumentationCommentTests.vb | 125 +++++++++++++++ 3 files changed, 302 insertions(+), 7 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs b/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs index 5bf13ee2f62..3965936842a 100644 --- a/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs +++ b/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs @@ -1114,6 +1114,156 @@ void M() VerifyPressingEnter(code, expected); } + [WorkItem(2108, "https://github.com/dotnet/roslyn/issues/2108")] + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] + public void PressingEnter_Indentation1() + { + const string code = +@"class C +{ + /// + /// hello world$$ + /// + void M() + { + } +}"; + + const string expected = +@"class C +{ + /// + /// hello world + /// $$ + /// + void M() + { + } +}"; + + VerifyPressingEnter(code, expected); + } + + [WorkItem(2108, "https://github.com/dotnet/roslyn/issues/2108")] + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] + public void PressingEnter_Indentation2() + { + const string code = +@"class C +{ + /// + /// hello $$world + /// + void M() + { + } +}"; + + const string expected = +@"class C +{ + /// + /// hello + /// $$world + /// + void M() + { + } +}"; + + VerifyPressingEnter(code, expected); + } + + [WorkItem(2108, "https://github.com/dotnet/roslyn/issues/2108")] + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] + public void PressingEnter_Indentation3() + { + const string code = +@"class C +{ + /// + /// hello$$ world + /// + void M() + { + } +}"; + + const string expected = +@"class C +{ + /// + /// hello + /// $$world + /// + void M() + { + } +}"; + + VerifyPressingEnter(code, expected); + } + + [WorkItem(2108, "https://github.com/dotnet/roslyn/issues/2108")] + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] + public void PressingEnter_Indentation4() + { + const string code = +@"class C +{ + /// + /// $$hello world + /// + void M() + { + } +}"; + + const string expected = +@"class C +{ + /// + /// + /// $$hello world + /// + void M() + { + } +}"; + + VerifyPressingEnter(code, expected); + } + + [WorkItem(2108, "https://github.com/dotnet/roslyn/issues/2108")] + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] + public void PressingEnter_Indentation5_UseTabs() + { + const string code = +@"class C +{ + /// + /// hello world$$ + /// + void M() + { + } +}"; + + const string expected = +@"class C +{ + /// + /// hello world + /// $$ + /// + void M() + { + } +}"; + + VerifyPressingEnter(code, expected, useTabs: true); + } + [Fact, Trait(Traits.Feature, Traits.Features.DocumentationComments)] public void Command_Class() { diff --git a/src/EditorFeatures/Core/Implementation/DocumentationComments/AbstractDocumentationCommentCommandHandler.cs b/src/EditorFeatures/Core/Implementation/DocumentationComments/AbstractDocumentationCommentCommandHandler.cs index 9ce78b54fcd..58aed62a599 100644 --- a/src/EditorFeatures/Core/Implementation/DocumentationComments/AbstractDocumentationCommentCommandHandler.cs +++ b/src/EditorFeatures/Core/Implementation/DocumentationComments/AbstractDocumentationCommentCommandHandler.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Threading; using Microsoft.CodeAnalysis.Editor.Commands; using Microsoft.CodeAnalysis.Editor.Host; @@ -657,20 +658,39 @@ private void InsertExteriorTriviaIfNeeded(ITextView view, ITextBuffer subjectBuf private void InsertExteriorTrivia(ITextView view, ITextBuffer subjectBuffer, TextLine currentLine, TextLine previousLine) { - var useTabs = subjectBuffer.GetOption(FormattingOptions.UseTabs); - var tabSize = subjectBuffer.GetOption(FormattingOptions.TabSize); - - var firstNonWhitespaceColumn = previousLine.GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(tabSize); - var indentText = firstNonWhitespaceColumn.CreateIndentationString(useTabs, tabSize) + ExteriorTriviaText + " "; + var insertionText = CreateInsertionTextFromPreviousLine(previousLine, subjectBuffer); var firstNonWhitespaceOffset = currentLine.GetFirstNonWhitespaceOffset(); var replaceSpan = firstNonWhitespaceOffset != null ? TextSpan.FromBounds(currentLine.Start, currentLine.Start + firstNonWhitespaceOffset.Value) : currentLine.Span; - subjectBuffer.Replace(replaceSpan.ToSpan(), indentText); + subjectBuffer.Replace(replaceSpan.ToSpan(), insertionText); + + view.TryMoveCaretToAndEnsureVisible(subjectBuffer.CurrentSnapshot.GetPoint(replaceSpan.Start + insertionText.Length)); + } + + private string CreateInsertionTextFromPreviousLine(TextLine previousLine, ITextBuffer subjectBuffer) + { + var useTabs = subjectBuffer.GetOption(FormattingOptions.UseTabs); + var tabSize = subjectBuffer.GetOption(FormattingOptions.TabSize); + + var previousLineText = previousLine.ToString(); + var firstNonWhitespaceColumn = previousLineText.GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(tabSize); + + var trimmedPreviousLine = previousLineText.Trim(); + Debug.Assert(trimmedPreviousLine.StartsWith(ExteriorTriviaText), "Unexpected: previous line does not begin with doc comment exterior trivia."); + + // skip exterior trivia. + trimmedPreviousLine = trimmedPreviousLine.Substring(3); + + var firstNonWhitespaceOffsetInPreviousXmlText = trimmedPreviousLine.GetFirstNonWhitespaceOffset(); + + var extraIndent = firstNonWhitespaceOffsetInPreviousXmlText != null + ? trimmedPreviousLine.Substring(0, firstNonWhitespaceOffsetInPreviousXmlText.Value) + : " "; - view.TryMoveCaretToAndEnsureVisible(subjectBuffer.CurrentSnapshot.GetPoint(replaceSpan.Start + indentText.Length)); + return firstNonWhitespaceColumn.CreateIndentationString(useTabs, tabSize) + ExteriorTriviaText + extraIndent; } private bool CurrentLineStartsWithExteriorTrivia(ITextBuffer subjectBuffer, int position) diff --git a/src/EditorFeatures/VisualBasicTest/DocumentationComments/DocumentationCommentTests.vb b/src/EditorFeatures/VisualBasicTest/DocumentationComments/DocumentationCommentTests.vb index 6d626371d95..8d131cccfa3 100644 --- a/src/EditorFeatures/VisualBasicTest/DocumentationComments/DocumentationCommentTests.vb +++ b/src/EditorFeatures/VisualBasicTest/DocumentationComments/DocumentationCommentTests.vb @@ -611,6 +611,131 @@ End Class VerifyPressingEnter(code, expected) End Sub + + + Public Sub PressingEnter_Indentation1() + Const code = " +Class C + ''' + ''' hello world$$ + ''' + Sub M() + End Sub +End Class +" + Const expected = " +Class C + ''' + ''' hello world + ''' $$ + ''' + Sub M() + End Sub +End Class +" + VerifyPressingEnter(code, expected) + End Sub + + + + Public Sub PressingEnter_Indentation2() + Const code = " +Class C + ''' + ''' hello $$world + ''' + Sub M() + End Sub +End Class +" + Const expected = " +Class C + ''' + ''' hello + ''' $$world + ''' + Sub M() + End Sub +End Class +" + VerifyPressingEnter(code, expected) + End Sub + + + + Public Sub PressingEnter_Indentation3() + Const code = " +Class C + ''' + ''' hello$$ world + ''' + Sub M() + End Sub +End Class +" + Const expected = " +Class C + ''' + ''' hello + ''' $$world + ''' + Sub M() + End Sub +End Class +" + VerifyPressingEnter(code, expected) + End Sub + + + + Public Sub PressingEnter_Indentation4() + Const code = " +Class C + ''' + ''' $$hello world + ''' + Sub M() + End Sub +End Class +" + Const expected = " +Class C + ''' + ''' + ''' $$hello world + ''' + Sub M() + End Sub +End Class +" + VerifyPressingEnter(code, expected) + End Sub + + + + Public Sub PressingEnter_Indentation5_UseTabs() + Const code = " +Class C + ''' + ''' hello world$$ + ''' + Sub M() + End Sub +End Class +" + Const expected = " +Class C + ''' + ''' hello world + ''' $$ + ''' + Sub M() + End Sub +End Class +" + VerifyPressingEnter(code, expected, useTabs:=True) + End Sub + Public Sub Command_Class() Const code = " -- GitLab