提交 83d1a5dc 编写于 作者: D David Barbet

Add toggle block comment command handler + refactor existing comment

selection handler.
上级 36d6458c
......@@ -118,7 +118,7 @@ private static void UncommentSelection(string markup, string expected)
workspace.ExportProvider.GetExportedValue<IEditorOperationsFactoryService>());
var textView = doc.GetTextView();
var textBuffer = doc.GetTextBuffer();
commandHandler.ExecuteCommand(textView, textBuffer, CommentUncommentSelectionCommandHandler.Operation.Uncomment, TestCommandExecutionContext.Create());
commandHandler.ExecuteCommand(textView, textBuffer, Operation.Uncomment, TestCommandExecutionContext.Create());
Assert.Equal(expected, doc.TextBuffer.CurrentSnapshot.GetText());
}
......
......@@ -1890,6 +1890,24 @@ internal class EditorFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Toggle Block Comment.
/// </summary>
internal static string Toggle_Block_Comment {
get {
return ResourceManager.GetString("Toggle_Block_Comment", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Toggling block comment on selection....
/// </summary>
internal static string Toggling_block_comment_on_selection {
get {
return ResourceManager.GetString("Toggling_block_comment_on_selection", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Type Parts.
/// </summary>
......
......@@ -889,4 +889,10 @@ Do you want to proceed?</value>
<data name="Operation_is_not_ready_for_0_yet_see_task_center_for_more_detail" xml:space="preserve">
<value>Operation is not ready for "{0}" yet. See bottom left corner for more details.</value>
</data>
<data name="Toggle_Block_Comment" xml:space="preserve">
<value>Toggle Block Comment</value>
</data>
<data name="Toggling_block_comment_on_selection" xml:space="preserve">
<value>Toggling block comment on selection...</value>
</data>
</root>
\ No newline at end of file
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CommentSelection;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Roslyn.Utilities;
using VSCommanding = Microsoft.VisualStudio.Commanding;
namespace Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection
{
internal enum Operation { Comment, Uncomment, Toggle }
abstract class AbstractCommentSelectionCommandHandler
{
protected readonly ITextUndoHistoryRegistry _undoHistoryRegistry;
protected readonly IEditorOperationsFactoryService _editorOperationsFactoryService;
internal AbstractCommentSelectionCommandHandler(
ITextUndoHistoryRegistry undoHistoryRegistry,
IEditorOperationsFactoryService editorOperationsFactoryService)
{
Contract.ThrowIfNull(undoHistoryRegistry);
Contract.ThrowIfNull(editorOperationsFactoryService);
_undoHistoryRegistry = undoHistoryRegistry;
_editorOperationsFactoryService = editorOperationsFactoryService;
}
protected static VSCommanding.CommandState GetCommandState(ITextBuffer buffer)
{
if (!buffer.CanApplyChangeDocumentToWorkspace())
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
}
protected static void Format(ICommentSelectionService service, ITextSnapshot snapshot, IEnumerable<CommentTrackingSpan> changes, CancellationToken cancellationToken)
{
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return;
}
// Only format uncomment actions.
var textSpans = changes
.Where(change => change.Operation == Operation.Uncomment)
.Select(uncommentChange => uncommentChange.ToSnapshotSpan(snapshot).Span.ToTextSpan())
.ToImmutableArray();
var newDocument = service.FormatAsync(document, textSpans, cancellationToken).WaitAndGetResult(cancellationToken);
newDocument.Project.Solution.Workspace.ApplyDocumentChanges(newDocument, cancellationToken);
}
private static ICommentSelectionService GetService(Document document)
{
// First, try to get the new service for comment selection.
var service = document.GetLanguageService<ICommentSelectionService>();
if (service != null)
{
return service;
}
// If we couldn't find one, fallback to the legacy service.
#pragma warning disable CS0618 // Type or member is obsolete
var legacyService = document.GetLanguageService<ICommentUncommentService>();
#pragma warning restore CS0618 // Type or member is obsolete
if (legacyService != null)
{
return new CommentSelectionServiceProxy(legacyService);
}
return null;
}
internal bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, Operation operation, CommandExecutionContext context)
{
var title = GetTitle(operation);
var message = GetMessage(operation);
using (context.OperationContext.AddScope(allowCancellation: false, message))
{
var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return true;
}
var service = GetService(document);
if (service == null)
{
return true;
}
var trackingSpans = new List<CommentTrackingSpan>();
var textChanges = new List<TextChange>();
CollectEdits(
document, service, textView.Selection.GetSnapshotSpansOnBuffer(subjectBuffer),
textChanges, trackingSpans, operation, CancellationToken.None);
using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService))
{
document.Project.Solution.Workspace.ApplyTextChanges(document.Id, textChanges.Distinct(), CancellationToken.None);
transaction.Complete();
}
using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService))
{
Format(service, subjectBuffer.CurrentSnapshot, trackingSpans, CancellationToken.None);
transaction.Complete();
}
if (trackingSpans.Any())
{
SetTrackingSpans(textView, subjectBuffer, trackingSpans);
}
}
return true;
}
public abstract string DisplayName { get; }
internal abstract string GetTitle(Operation operation);
internal abstract string GetMessage(Operation operation);
internal abstract void CollectEdits(
Document document, ICommentSelectionService service, NormalizedSnapshotSpanCollection selectedSpans,
List<TextChange> textChanges, List<CommentTrackingSpan> trackingSpans, Operation operation, CancellationToken cancellationToken);
internal abstract void SetTrackingSpans(ITextView textView, ITextBuffer buffer, List<CommentTrackingSpan> trackingSpans);
}
}
using Microsoft.VisualStudio.Text;
namespace Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection
{
/// <summary>
/// Wrapper around an ITrackingSpan that holds extra data used to format and modify span.
/// </summary>
internal struct CommentTrackingSpan
{
public Operation Operation { get; }
private readonly ITrackingSpan _trackingSpan;
// In some cases, the tracking span needs to be adjusted by a specific amount after the changes have been applied.
// These fields store the amount to adjust the span by after edits have been applied.
private readonly int _amountToAddToStart;
private readonly int _amountToAddToEnd;
public CommentTrackingSpan(ITrackingSpan trackingSpan, Operation operation)
{
Operation = operation;
_trackingSpan = trackingSpan;
_amountToAddToStart = 0;
_amountToAddToEnd = 0;
}
public CommentTrackingSpan(ITrackingSpan trackingSpan, Operation operation, int amountToAddToStart, int amountToAddToEnd)
{
Operation = operation;
_trackingSpan = trackingSpan;
_amountToAddToStart = amountToAddToStart;
_amountToAddToEnd = amountToAddToEnd;
}
public Selection ToSelection(ITextBuffer buffer)
{
return new Selection(ToSnapshotSpan(buffer.CurrentSnapshot));
}
public SnapshotSpan ToSnapshotSpan(ITextSnapshot snapshot)
{
var snapshotSpan = _trackingSpan.GetSpan(snapshot);
if (_amountToAddToStart != 0 || _amountToAddToEnd != 0)
{
var spanExpandedByAmount = Span.FromBounds(snapshotSpan.Start.Position + _amountToAddToStart, snapshotSpan.End.Position + _amountToAddToEnd);
snapshotSpan = new SnapshotSpan(snapshot, spanExpandedByAmount);
}
return snapshotSpan;
}
}
}
......@@ -8,7 +8,6 @@
using System.Threading;
using Microsoft.CodeAnalysis.CommentSelection;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
......@@ -17,45 +16,24 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
using VSCommanding = Microsoft.VisualStudio.Commanding;
namespace Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection
{
[Export(typeof(VSCommanding.ICommandHandler))]
[ContentType(ContentTypeNames.RoslynContentType)]
[Name(PredefinedCommandHandlerNames.CommentSelection)]
//[Export(typeof(VSCommanding.ICommandHandler))]
//[ContentType(ContentTypeNames.RoslynContentType)]
//[Name(PredefinedCommandHandlerNames.CommentSelection)]
internal class CommentUncommentSelectionCommandHandler :
AbstractCommentSelectionCommandHandler,
VSCommanding.ICommandHandler<CommentSelectionCommandArgs>,
VSCommanding.ICommandHandler<UncommentSelectionCommandArgs>
{
private readonly ITextUndoHistoryRegistry _undoHistoryRegistry;
private readonly IEditorOperationsFactoryService _editorOperationsFactoryService;
[ImportingConstructor]
internal CommentUncommentSelectionCommandHandler(
ITextUndoHistoryRegistry undoHistoryRegistry,
IEditorOperationsFactoryService editorOperationsFactoryService)
{
Contract.ThrowIfNull(undoHistoryRegistry);
Contract.ThrowIfNull(editorOperationsFactoryService);
_undoHistoryRegistry = undoHistoryRegistry;
_editorOperationsFactoryService = editorOperationsFactoryService;
}
public string DisplayName => EditorFeaturesResources.Comment_Uncomment_Selection;
private static VSCommanding.CommandState GetCommandState(ITextBuffer buffer)
{
if (!buffer.CanApplyChangeDocumentToWorkspace())
{
return VSCommanding.CommandState.Unspecified;
}
return VSCommanding.CommandState.Available;
}
IEditorOperationsFactoryService editorOperationsFactoryService) : base(undoHistoryRegistry, editorOperationsFactoryService)
{ }
public VSCommanding.CommandState GetCommandState(CommentSelectionCommandArgs args)
{
......@@ -83,107 +61,51 @@ public bool ExecuteCommand(UncommentSelectionCommandArgs args, CommandExecutionC
return this.ExecuteCommand(args.TextView, args.SubjectBuffer, Operation.Uncomment, context);
}
internal bool ExecuteCommand(ITextView textView, ITextBuffer subjectBuffer, Operation operation, CommandExecutionContext context)
{
var title = operation == Operation.Comment ? EditorFeaturesResources.Comment_Selection
: EditorFeaturesResources.Uncomment_Selection;
var message = operation == Operation.Comment ? EditorFeaturesResources.Commenting_currently_selected_text
: EditorFeaturesResources.Uncommenting_currently_selected_text;
using (context.OperationContext.AddScope(allowCancellation: false, message))
{
var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return true;
}
var service = GetService(document);
if (service == null)
{
return true;
}
var trackingSpans = new List<ITrackingSpan>();
var textChanges = new List<TextChange>();
CollectEdits(
document, service, textView.Selection.GetSnapshotSpansOnBuffer(subjectBuffer),
textChanges, trackingSpans, operation, CancellationToken.None);
public override string DisplayName => EditorFeaturesResources.Comment_Uncomment_Selection;
using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService))
{
document.Project.Solution.Workspace.ApplyTextChanges(document.Id, textChanges, CancellationToken.None);
transaction.Complete();
}
if (operation == Operation.Uncomment)
{
using (var transaction = new CaretPreservingEditTransaction(title, textView, _undoHistoryRegistry, _editorOperationsFactoryService))
{
Format(service, subjectBuffer.CurrentSnapshot, trackingSpans, CancellationToken.None);
transaction.Complete();
}
}
if (trackingSpans.Any())
{
// TODO, this doesn't currently handle block selection
textView.SetSelection(trackingSpans.First().GetSpan(subjectBuffer.CurrentSnapshot));
}
}
return true;
internal override string GetTitle(Operation operation)
{
return operation == Operation.Comment ? EditorFeaturesResources.Comment_Selection
: EditorFeaturesResources.Uncomment_Selection;
}
private ICommentSelectionService GetService(Document document)
internal override string GetMessage(Operation operation)
{
// First, try to get the new service for comment selection.
var service = document.GetLanguageService<ICommentSelectionService>();
if (service != null)
{
return service;
}
return null;
return operation == Operation.Comment ? EditorFeaturesResources.Commenting_currently_selected_text
: EditorFeaturesResources.Uncommenting_currently_selected_text;
}
private void Format(ICommentSelectionService service, ITextSnapshot snapshot, IEnumerable<ITrackingSpan> changes, CancellationToken cancellationToken)
internal override void SetTrackingSpans(ITextView textView, ITextBuffer buffer, List<CommentTrackingSpan> trackingSpans)
{
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return;
}
var textSpans = changes.Select(s => s.GetSpan(snapshot).Span.ToTextSpan()).ToImmutableArray();
var newDocument = service.FormatAsync(document, textSpans, cancellationToken).WaitAndGetResult(cancellationToken);
newDocument.Project.Solution.Workspace.ApplyDocumentChanges(newDocument, cancellationToken);
// TODO, this doesn't currently handle block selection
textView.SetSelection(trackingSpans.First().ToSnapshotSpan(buffer.CurrentSnapshot));
}
internal enum Operation { Comment, Uncomment }
/// <summary>
/// Add the necessary edits to the given spans. Also collect tracking spans over each span.
///
/// Internal so that it can be called by unit tests.
/// </summary>
internal void CollectEdits(
internal override void CollectEdits(
Document document, ICommentSelectionService service, NormalizedSnapshotSpanCollection selectedSpans,
List<TextChange> textChanges, List<ITrackingSpan> trackingSpans, Operation operation, CancellationToken cancellationToken)
List<TextChange> textChanges, List<CommentTrackingSpan> trackingSpans, Operation operation, CancellationToken cancellationToken)
{
var spanTrackingList = new List<ITrackingSpan>();
foreach (var span in selectedSpans)
{
if (operation == Operation.Comment)
{
CommentSpan(document, service, span, textChanges, trackingSpans, cancellationToken);
CommentSpan(document, service, span, textChanges, spanTrackingList, cancellationToken);
}
else
{
UncommentSpan(document, service, span, textChanges, trackingSpans, cancellationToken);
UncommentSpan(document, service, span, textChanges, spanTrackingList, cancellationToken);
}
}
foreach (var internalTrackingSpan in spanTrackingList)
{
trackingSpans.Add(new CommentTrackingSpan(internalTrackingSpan, operation));
}
}
/// <summary>
......
......@@ -1284,6 +1284,16 @@ Chcete pokračovat?</target>
<target state="translated">Inteligentní formátování tokenů</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Möchten Sie fortfahren?</target>
<target state="translated">Intelligente Tokenformatierung</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">Formateador de token inteligente</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Voulez-vous continuer ?</target>
<target state="translated">Formateur de jeton intelligent</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Continuare?</target>
<target state="translated">Formattatore di token intelligente</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">スマート トークン フォーマッタ</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">스마트 토큰 포맷터</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Czy chcesz kontynuować?</target>
<target state="translated">Inteligentny element formatujący tokeny</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Deseja continuar?</target>
<target state="translated">Formatador de Token Inteligente</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">Средство форматирования смарт-токена</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Devam etmek istiyor musunuz?</target>
<target state="translated">Akıllı Belirteç Biçimlendirici</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">智能令牌格式化程序</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1284,6 +1284,16 @@ Do you want to proceed?</source>
<target state="translated">智慧權杖格式器</target>
<note />
</trans-unit>
<trans-unit id="Toggling_block_comment_on_selection">
<source>Toggling block comment on selection...</source>
<target state="new">Toggling block comment on selection...</target>
<note />
</trans-unit>
<trans-unit id="Toggle_Block_Comment">
<source>Toggle Block Comment</source>
<target state="new">Toggle Block Comment</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -717,27 +717,27 @@ class A
private static void UncommentSelection(string code, IEnumerable<TextChange> expectedChanges, Span expectedSelectedSpan, bool supportBlockComments)
{
CommentOrUncommentSelection(code, expectedChanges, new[] { expectedSelectedSpan }, supportBlockComments, CommentUncommentSelectionCommandHandler.Operation.Uncomment);
CommentOrUncommentSelection(code, expectedChanges, new[] { expectedSelectedSpan }, supportBlockComments, Operation.Uncomment);
}
private static void UncommentSelection(string code, IEnumerable<TextChange> expectedChanges, IEnumerable<Span> expectedSelectedSpans, bool supportBlockComments)
{
CommentOrUncommentSelection(code, expectedChanges, expectedSelectedSpans, supportBlockComments, CommentUncommentSelectionCommandHandler.Operation.Uncomment);
CommentOrUncommentSelection(code, expectedChanges, expectedSelectedSpans, supportBlockComments, Operation.Uncomment);
}
private static void CommentSelection(string code, IEnumerable<TextChange> expectedChanges, bool supportBlockComments)
{
CommentOrUncommentSelection(code, expectedChanges, null /*expectedSelectedSpans*/, supportBlockComments, CommentUncommentSelectionCommandHandler.Operation.Comment);
CommentOrUncommentSelection(code, expectedChanges, null /*expectedSelectedSpans*/, supportBlockComments, Operation.Comment);
}
private static void CommentSelection(string code, IEnumerable<TextChange> expectedChanges, IEnumerable<Span> expectedSelectedSpans, bool supportBlockComments)
{
CommentOrUncommentSelection(code, expectedChanges, expectedSelectedSpans, supportBlockComments, CommentUncommentSelectionCommandHandler.Operation.Comment);
CommentOrUncommentSelection(code, expectedChanges, expectedSelectedSpans, supportBlockComments, Operation.Comment);
}
private static void CommentSelection(ITextView textView, IEnumerable<TextChange> expectedChanges, IEnumerable<Span> expectedSelectedSpans, bool supportBlockComments)
{
CommentOrUncommentSelection(textView, expectedChanges, expectedSelectedSpans, supportBlockComments, CommentUncommentSelectionCommandHandler.Operation.Comment);
CommentOrUncommentSelection(textView, expectedChanges, expectedSelectedSpans, supportBlockComments, Operation.Comment);
}
private static void CommentOrUncommentSelection(
......@@ -745,7 +745,7 @@ private static void CommentSelection(ITextView textView, IEnumerable<TextChange>
IEnumerable<TextChange> expectedChanges,
IEnumerable<Span> expectedSelectedSpans,
bool supportBlockComments,
CommentUncommentSelectionCommandHandler.Operation operation)
Operation operation)
{
using (var disposableView = EditorFactory.CreateView(TestExportProvider.ExportProviderWithCSharpAndVisualBasic, code))
{
......@@ -760,14 +760,14 @@ private static void CommentSelection(ITextView textView, IEnumerable<TextChange>
IEnumerable<TextChange> expectedChanges,
IEnumerable<Span> expectedSelectedSpans,
bool supportBlockComments,
CommentUncommentSelectionCommandHandler.Operation operation)
Operation operation)
{
var textUndoHistoryRegistry = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue<ITextUndoHistoryRegistry>();
var editorOperationsFactory = TestExportProvider.ExportProviderWithCSharpAndVisualBasic.GetExportedValue<IEditorOperationsFactoryService>();
var commandHandler = new CommentUncommentSelectionCommandHandler(textUndoHistoryRegistry, editorOperationsFactory);
var service = new MockCommentSelectionService(supportBlockComments);
var trackingSpans = new List<ITrackingSpan>();
var trackingSpans = new List<CommentTrackingSpan>();
var textChanges = new List<TextChange>();
commandHandler.CollectEdits(
......@@ -786,7 +786,7 @@ private static void CommentSelection(ITextView textView, IEnumerable<TextChange>
if (trackingSpans.Any())
{
textView.SetSelection(trackingSpans.First().GetSpan(textView.TextSnapshot));
textView.SetSelection(trackingSpans.First().ToSnapshotSpan(textView.TextBuffer.CurrentSnapshot));
}
if (expectedSelectedSpans != null)
......
......@@ -29,7 +29,7 @@ End Module</code>
'End Sub
End Module</code>
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, CommentUncommentSelectionCommandHandler.Operation.Comment)
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, Operation.Comment)
End Sub
......@@ -47,7 +47,7 @@ End Module</code>
End Sub
End Module</code>
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, CommentUncommentSelectionCommandHandler.Operation.Uncomment)
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, Operation.Uncomment)
End Sub
<WpfFact, Trait(Traits.Feature, Traits.Features.CommentSelection)>
......@@ -64,10 +64,10 @@ End Module</code>
End Sub
End Module</code>
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, CommentUncommentSelectionCommandHandler.Operation.Uncomment)
InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code.Value, expected.Value, Operation.Uncomment)
End Sub
Private Shared Sub InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code As String, expected As String, operation As CommentUncommentSelectionCommandHandler.Operation)
Private Shared Sub InvokeCommentOperationOnSelectionAfterReplacingLfToCrLf(code As String, expected As String, operation As Operation)
' do this since xml value put only vbLf
code = code.Replace(vbLf, vbCrLf)
expected = expected.Replace(vbLf, vbCrLf)
......
......@@ -247,6 +247,7 @@ public static class Features
public const string SuggestionTags = nameof(SuggestionTags);
public const string TextStructureNavigator = nameof(TextStructureNavigator);
public const string TodoComments = nameof(TodoComments);
public const string ToggleBlockComment = nameof(ToggleBlockComment);
public const string TypeInferenceService = nameof(TypeInferenceService);
public const string Venus = nameof(Venus);
public const string ValidateFormatString = nameof(ValidateFormatString);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册