|
// 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.
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text.Editor;
using Roslyn.Utilities;
using VSCommanding = Microsoft.VisualStudio.Commanding;
namespace Microsoft.CodeAnalysis.Editor.Implementation.NavigationCommandHandlers
{
internal abstract class AbstractNavigationCommandHandler<TCommandArgs> :
VSCommanding.ICommandHandler<TCommandArgs> where TCommandArgs : Microsoft.VisualStudio.Text.Editor.Commanding.EditorCommandArgs
{
private readonly IEnumerable<Lazy<IStreamingFindUsagesPresenter>> _streamingPresenters;
//private readonly IAsynchronousOperationListener _asyncListener;
internal AbstractNavigationCommandHandler(
IEnumerable<Lazy<IStreamingFindUsagesPresenter>> streamingPresenters)
{
Contract.ThrowIfNull(streamingPresenters);
_streamingPresenters = streamingPresenters;
}
public VSCommanding.CommandState GetCommandState(TCommandArgs args)
{
return VSCommanding.CommandState.Available;
}
public bool ExecuteCommand(TCommandArgs args, CommandExecutionContext context)
{
var snapshotSpans = args.TextView.Selection?.GetSnapshotSpansOnBuffer(args.SubjectBuffer);
if (snapshotSpans == null)
return false;
if (snapshotSpans.Count == 1)
{
var selectedSpan = snapshotSpans[0];
var snapshot = args.SubjectBuffer.CurrentSnapshot;
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document != null)
{
// Do a find-refs at the *start* of the selection. That way if the
// user has selected a symbol that has another symbol touching it
// on the right (i.e. Goo++ ), then we'll do the find-refs on the
// symbol selected, not the symbol following.
if (TryExecuteCommand(selectedSpan.Start, document, context))
{
return true;
}
}
}
return false;
}
protected abstract bool TryExecuteCommand(int caretPosition, Document document, CommandExecutionContext context);
internal IStreamingFindUsagesPresenter GetStreamingPresenter()
{
try
{
return _streamingPresenters.FirstOrDefault()?.Value;
}
catch
{
return null;
}
}
public virtual string DisplayName => nameof(AbstractNavigationCommandHandler<TCommandArgs>);
}
}
|