|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Linq;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Editor.Commanding;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename;
internal abstract partial class AbstractRenameCommandHandler :
ICommandHandler<WordDeleteToStartCommandArgs>,
ICommandHandler<WordDeleteToEndCommandArgs>
{
public CommandState GetCommandState(WordDeleteToStartCommandArgs args)
=> GetCommandState();
public CommandState GetCommandState(WordDeleteToEndCommandArgs args)
=> GetCommandState();
public bool ExecuteCommand(WordDeleteToStartCommandArgs args, CommandExecutionContext context)
=> HandleWordDeleteCommand(args, context, args.TextView, deleteToStart: true);
public bool ExecuteCommand(WordDeleteToEndCommandArgs args, CommandExecutionContext context)
=> HandleWordDeleteCommand(args, context, args.TextView, deleteToStart: false);
private bool HandleWordDeleteCommand(EditorCommandArgs args, CommandExecutionContext context, ITextView view, bool deleteToStart)
{
var subjectBuffer = args.SubjectBuffer;
if (renameService.ActiveSession == null)
{
return false;
}
if (renameService.ActiveSession.IsCommitInProgress)
{
// When rename commit is in progress, swallow the command so it won't change the workspace
return true;
}
var caretPoint = view.GetCaretPoint(subjectBuffer);
if (caretPoint.HasValue)
{
if (renameService.ActiveSession.TryGetContainingEditableSpan(caretPoint.Value, out var span))
{
int start = caretPoint.Value;
int end = caretPoint.Value;
if (!view.Selection.IsEmpty)
{
var selectedSpans = view.Selection.GetSnapshotSpansOnBuffer(subjectBuffer);
if (selectedSpans.Count == 1 && span.Contains(selectedSpans.Single().Span))
{
// We might want to delete past the caret's active position if there's a selection
start = selectedSpans.Single().Start;
end = selectedSpans.Single().End;
}
else
{
// we're outside of an editable span, so let this command go to the next handler
return false;
}
}
subjectBuffer.Delete(deleteToStart
? Span.FromBounds(span.Start, end)
: Span.FromBounds(start, span.End));
return true;
}
else
{
CommitIfSynchronousOrCancelIfAsynchronous(args, context.OperationContext, placeCaretAtTheEndOfIdentifier: true);
}
}
return false;
}
}
|