diff options
author | Aaron Bockover <abock@microsoft.com> | 2019-07-03 19:12:18 +0300 |
---|---|---|
committer | Aaron Bockover <abock@microsoft.com> | 2019-07-03 19:12:18 +0300 |
commit | c59f8388d157a4584c269631ab8cd49b482e4aab (patch) | |
tree | 4fa7b5f8ee26698e1612ac6ed92d42294ea7e104 /src | |
parent | 23d9a046163fa3103098376d0f5f8983a873d540 (diff) |
Sync with vs-editor-core@684befeb
Diffstat (limited to 'src')
24 files changed, 334 insertions, 19 deletions
diff --git a/src/Editor/Language/Def/Language/AsyncCompletion/IAsyncCompletionSessionOperations.cs b/src/Editor/Language/Def/Language/AsyncCompletion/IAsyncCompletionSessionOperations.cs index e34e945..6a307eb 100644 --- a/src/Editor/Language/Def/Language/AsyncCompletion/IAsyncCompletionSessionOperations.cs +++ b/src/Editor/Language/Def/Language/AsyncCompletion/IAsyncCompletionSessionOperations.cs @@ -57,4 +57,10 @@ namespace Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion /// </summary> void SelectPageUp(); } + + public interface IAsyncCompletionSessionOperations2 : IAsyncCompletionSessionOperations + { + bool CanToggleFilter(string accessKey); + void ToggleFilter(string accessKey); + } } diff --git a/src/Editor/Language/Impl/Language/AsyncCompletion/AsyncCompletionSession.cs b/src/Editor/Language/Impl/Language/AsyncCompletion/AsyncCompletionSession.cs index 094c67d..09662e7 100644 --- a/src/Editor/Language/Impl/Language/AsyncCompletion/AsyncCompletionSession.cs +++ b/src/Editor/Language/Impl/Language/AsyncCompletion/AsyncCompletionSession.cs @@ -19,7 +19,7 @@ namespace Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Implement /// Holds a state of the session /// and a reference to the UI element /// </summary> - internal class AsyncCompletionSession : IAsyncCompletionSession, IAsyncCompletionSessionOperations, IModelComputationCallbackHandler<CompletionModel> + internal class AsyncCompletionSession : IAsyncCompletionSession, IAsyncCompletionSessionOperations2, IModelComputationCallbackHandler<CompletionModel> { // Available data and services private readonly IList<(IAsyncCompletionSource Source, SnapshotPoint Point)> _completionSources; @@ -634,6 +634,39 @@ namespace Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Implement _computation.Enqueue((model, token) => UpdateFilters(model, args.Filters, taskId, token), updateUi: true); } + static bool CheckFilterAccessKey(CompletionFilterWithState filter, string accessKey) + => string.Equals( + filter.Filter.AccessKey, + accessKey, + StringComparison.OrdinalIgnoreCase); + + public bool CanToggleFilter(string accessKey) + => _computation + .RecentModel + .Filters + .Any(filter => CheckFilterAccessKey(filter, accessKey)); + + public void ToggleFilter(string accessKey) + { + var taskId = Interlocked.Increment(ref _lastFilteringTaskId); + _computation.Enqueue((model, token) => + { + var newFilters = model + .Filters + .Select(filter => + { + if (CheckFilterAccessKey(filter, accessKey)) + return filter.WithSelected(!filter.IsSelected); + + return filter; + }) + .ToImmutableArray(); + + return UpdateFilters(model, newFilters, taskId, token); + }, + updateUi: true); + } + /// <summary> /// Handler for GUI requesting commit, usually through double-clicking. /// There is no UI for cancellation, so use self-imposed expiration. diff --git a/src/Editor/Language/Impl/Language/AsyncCompletion/CompletionCommandHandlers.cs b/src/Editor/Language/Impl/Language/AsyncCompletion/CompletionCommandHandlers.cs index 19a582f..c3201c8 100644 --- a/src/Editor/Language/Impl/Language/AsyncCompletion/CompletionCommandHandlers.cs +++ b/src/Editor/Language/Impl/Language/AsyncCompletion/CompletionCommandHandlers.cs @@ -46,6 +46,7 @@ namespace Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Implement IChainedCommandHandler<TabKeyCommandArgs>, IDynamicCommandHandler<TabKeyCommandArgs>, ICommandHandler<ToggleCompletionModeCommandArgs>, + ICommandHandler<ToggleCompletionListFilterCommandArgs>, IChainedCommandHandler<TypeCharCommandArgs>, IDynamicCommandHandler<TypeCharCommandArgs>, ICommandHandler<UndoCommandArgs>, @@ -316,6 +317,32 @@ namespace Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion.Implement return false; } + CommandState ICommandHandler<ToggleCompletionListFilterCommandArgs>.GetCommandState( + ToggleCompletionListFilterCommandArgs args) + { + if (!Broker.IsCompletionActive(args.TextView)) + return CommandState.Unspecified; + + if (Broker.GetSession(args.TextView) is IAsyncCompletionSessionOperations2 sessionInternal && + sessionInternal.CanToggleFilter(args.AccessKey)) + return CommandState.Available; + + return CommandState.Unavailable; + } + + bool ICommandHandler<ToggleCompletionListFilterCommandArgs>.ExecuteCommand( + ToggleCompletionListFilterCommandArgs args, + CommandExecutionContext executionContext) + { + if (Broker.GetSession(args.TextView) is IAsyncCompletionSessionOperations2 sessionInternal) + { + sessionInternal.ToggleFilter(args.AccessKey); + return true; + } + + return false; + } + CommandState IChainedCommandHandler<DeleteKeyCommandArgs>.GetCommandState(DeleteKeyCommandArgs args, Func<CommandState> nextCommandHandler) => nextCommandHandler(); diff --git a/src/Editor/Text/Def/TextUI/Commanding/CommandExecutionContext.cs b/src/Editor/Text/Def/TextUI/Commanding/CommandExecutionContext.cs index 72efbf0..235e8d9 100644 --- a/src/Editor/Text/Def/TextUI/Commanding/CommandExecutionContext.cs +++ b/src/Editor/Text/Def/TextUI/Commanding/CommandExecutionContext.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.Commanding /// Represents a command execution context, which is set up by a command handler service /// and provided to each command handler. /// </summary> - public sealed class CommandExecutionContext + public sealed class CommandExecutionContext : IPropertyOwner { /// <summary> /// Creates new instance of the <see cref="CommandExecutionContext"/>. @@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.Commanding public CommandExecutionContext(IUIThreadOperationContext operationContext) { this.OperationContext = operationContext ?? throw new ArgumentNullException(nameof(operationContext)); + this.Properties = new PropertyCollection(); } /// <summary> @@ -22,6 +23,10 @@ namespace Microsoft.VisualStudio.Commanding /// enables two way shared cancellability and wait indication. /// </summary> public IUIThreadOperationContext OperationContext { get; } + + /// <summary> + /// A collection of properties. + /// </summary> + public PropertyCollection Properties { get; } } } - diff --git a/src/Editor/Text/Def/TextUI/Commanding/CommandState.cs b/src/Editor/Text/Def/TextUI/Commanding/CommandState.cs index a6de4a3..3a264aa 100644 --- a/src/Editor/Text/Def/TextUI/Commanding/CommandState.cs +++ b/src/Editor/Text/Def/TextUI/Commanding/CommandState.cs @@ -15,11 +15,22 @@ namespace Microsoft.VisualStudio.Commanding public bool IsUnspecified { get; } /// <summary> - /// If true, the command should be visible and enabled in the UI. + /// If true, the command should be available for execution. + /// <see cref="IsEnabled"/> and <see cref="IsVisible"/> properties control how the command should be represented in the UI. /// </summary> public bool IsAvailable { get; } /// <summary> + /// If true, the command should be enabled in the UI. + /// </summary> + public bool IsEnabled { get; } + + /// <summary> + /// If true, the command should be visible in the UI. + /// </summary> + public bool IsVisible { get; } + + /// <summary> /// If true, the command should appear as checked (i.e. toggled) in the UI. /// </summary> public bool IsChecked { get; } @@ -30,22 +41,39 @@ namespace Microsoft.VisualStudio.Commanding public string DisplayText { get; } public CommandState(bool isAvailable = false, bool isChecked = false, string displayText = null, bool isUnspecified = false) + : this(isAvailable: isAvailable, isUnspecified: isUnspecified, isChecked: isChecked, isEnabled: isAvailable, isVisible: isAvailable, displayText: displayText) { - if (isUnspecified && (isAvailable || isChecked || displayText != null)) - { - throw new ArgumentException("Unspecified command state cannot be combined with other states or command text."); - } + } + + public CommandState(bool isAvailable, bool isChecked, bool isEnabled, bool isVisible, string displayText = null) + : this(isAvailable: isAvailable, isUnspecified: false, isChecked: isChecked, isEnabled: isEnabled, isVisible: isVisible, displayText: displayText) + { + } + + public CommandState(bool isAvailable, bool isUnspecified, bool isChecked, bool isEnabled, bool isVisible, string displayText) + { + Validate(isAvailable, isChecked, isUnspecified, isEnabled, isVisible, displayText); this.IsAvailable = isAvailable; this.IsChecked = isChecked; this.IsUnspecified = isUnspecified; + this.IsEnabled = isEnabled; + this.IsVisible = isVisible; this.DisplayText = displayText; } + private static void Validate(bool isAvailable, bool isChecked, bool isUnspecified, bool isEnabled, bool isVisible, string displayText) + { + if (isUnspecified && (isAvailable || isChecked || isEnabled || isVisible || displayText != null)) + { + throw new ArgumentException("Unspecified command state cannot be combined with other states or command text."); + } + } + /// <summary> - /// A helper singleton representing an available command state. + /// A helper singleton representing an available (supported, enabled and visible) command state. /// </summary> - public static CommandState Available { get; } = new CommandState(isAvailable: true); + public static CommandState Available { get; } = new CommandState(isAvailable: true, isChecked: false, isEnabled: true, isVisible: true); /// <summary> /// A helper singleton representing an unavailable command state. diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/CollapseTagCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/CollapseTagCommandArgs.cs new file mode 100644 index 0000000..d6e130a --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/CollapseTagCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class CollapseTagCommandArgs : EditorCommandArgs + { + public CollapseTagCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/FormatAndValidationCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/FormatAndValidationCommandArgs.cs new file mode 100644 index 0000000..df7ba63 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/FormatAndValidationCommandArgs.cs @@ -0,0 +1,10 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class FormatAndValidationCommandArgs : EditorCommandArgs + { + public FormatAndValidationCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } + +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceCommandArgs.cs new file mode 100644 index 0000000..d8ff50e --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceCommandArgs.cs @@ -0,0 +1,10 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class GotoBraceCommandArgs : EditorCommandArgs + { + public GotoBraceCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } + +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceExtCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceExtCommandArgs.cs new file mode 100644 index 0000000..80d618e --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/GotoBraceExtCommandArgs.cs @@ -0,0 +1,10 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class GotoBraceExtCommandArgs : EditorCommandArgs + { + public GotoBraceExtCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } + +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/HelpCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/HelpCommandArgs.cs new file mode 100644 index 0000000..caf281d --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/HelpCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class HelpCommandArgs : EditorCommandArgs + { + public HelpCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineCollapseToDefinitionsCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineCollapseToDefinitionsCommandArgs.cs new file mode 100644 index 0000000..ac16bde --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineCollapseToDefinitionsCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineCollapseToDefinitionsCommandArgs : EditorCommandArgs + { + public OutlineCollapseToDefinitionsCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineHideSelectionCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineHideSelectionCommandArgs.cs new file mode 100644 index 0000000..188522e --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineHideSelectionCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineHideSelectionCommandArgs : EditorCommandArgs + { + public OutlineHideSelectionCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingAllCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingAllCommandArgs.cs new file mode 100644 index 0000000..a52ebe3 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingAllCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineStopHidingAllCommandArgs : EditorCommandArgs + { + public OutlineStopHidingAllCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingCurrentCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingCurrentCommandArgs.cs new file mode 100644 index 0000000..170a2b9 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineStopHidingCurrentCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineStopHidingCurrentCommandArgs : EditorCommandArgs + { + public OutlineStopHidingCurrentCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleAllCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleAllCommandArgs.cs new file mode 100644 index 0000000..11926f4 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleAllCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineToggleAllCommandArgs : EditorCommandArgs + { + public OutlineToggleAllCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleCurrentCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleCurrentCommandArgs.cs new file mode 100644 index 0000000..8bf39b0 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/OutlineToggleCurrentCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class OutlineToggleCurrentCommandArgs : EditorCommandArgs + { + public OutlineToggleCurrentCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/PasteAsHTMLCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/PasteAsHTMLCommandArgs.cs new file mode 100644 index 0000000..fc3377b --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/PasteAsHTMLCommandArgs.cs @@ -0,0 +1,10 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class PasteAsHTMLCommandArgs : EditorCommandArgs + { + public PasteAsHTMLCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } + +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/ShowContextMenuCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/ShowContextMenuCommandArgs.cs new file mode 100644 index 0000000..9ee198f --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/ShowContextMenuCommandArgs.cs @@ -0,0 +1,35 @@ +using Microsoft.VisualStudio.Commanding; + +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class ShowContextMenuCommandArgs : EditorCommandArgs + { + /// <summary> + /// X coordinate for the context menu, optionally provided by the caller of the command. + /// </summary> + public double? X { get; } + + /// <summary> + /// Y coordinate for the context menu, optionally provided by the caller of the command. + /// </summary> + public double? Y { get; } + + /// <summary> + /// Creates an empty instance of the <see cref="ShowContextMenuCommandArgs"/>, for the + /// purpose of passing to the <see cref="IChainedCommandHandler{T}.GetCommandState(T, System.Func{CommandState})"/> + /// to determine the state of the command. + /// </summary> + public ShowContextMenuCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + + /// <summary> + /// Creates an instance of the <see cref="ShowContextMenuCommandArgs"/> to execute the command. + /// </summary> + public ShowContextMenuCommandArgs(ITextView textView, ITextBuffer subjectBuffer, double x, double y) : base(textView, subjectBuffer) + { + X = x; + Y = y; + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/ToggleCompletionListFilterCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/ToggleCompletionListFilterCommandArgs.cs new file mode 100644 index 0000000..00509be --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/ToggleCompletionListFilterCommandArgs.cs @@ -0,0 +1,15 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class ToggleCompletionListFilterCommandArgs : EditorCommandArgs + { + public string AccessKey { get; } + + public ToggleCompletionListFilterCommandArgs( + ITextView textView, + ITextBuffer subjectBuffer, + string accessKey) : base(textView, subjectBuffer) + { + AccessKey = accessKey; + } + } +}
\ No newline at end of file diff --git a/src/Editor/Text/Def/TextUI/Commanding/Commands/UncollapseTagCommandArgs.cs b/src/Editor/Text/Def/TextUI/Commanding/Commands/UncollapseTagCommandArgs.cs new file mode 100644 index 0000000..674e8d7 --- /dev/null +++ b/src/Editor/Text/Def/TextUI/Commanding/Commands/UncollapseTagCommandArgs.cs @@ -0,0 +1,9 @@ +namespace Microsoft.VisualStudio.Text.Editor.Commanding.Commands +{ + public sealed class UncollapseTagCommandArgs : EditorCommandArgs + { + public UncollapseTagCommandArgs(ITextView textView, ITextBuffer subjectBuffer) : base(textView, subjectBuffer) + { + } + } +} diff --git a/src/Editor/Text/Def/TextUI/Commanding/IEditorCommandHandlerService.cs b/src/Editor/Text/Def/TextUI/Commanding/IEditorCommandHandlerService.cs index 2516bd7..f1601df 100644 --- a/src/Editor/Text/Def/TextUI/Commanding/IEditorCommandHandlerService.cs +++ b/src/Editor/Text/Def/TextUI/Commanding/IEditorCommandHandlerService.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.Text.Editor.Commanding /// A service to execute commands on a text view. /// </summary> /// <remarks> - /// Instance of this service are created by <see cref="IEditorCommandHandlerServiceFactory"/>. + /// Instances of this service are created by <see cref="IEditorCommandHandlerServiceFactory"/>. /// </remarks> public interface IEditorCommandHandlerService { @@ -15,9 +15,9 @@ namespace Microsoft.VisualStudio.Text.Editor.Commanding /// Get the <see cref="CommandState"/> for command handlers of a given command. /// </summary> /// <param name="argsFactory">A factory of <see cref="EditorCommandArgs"/> that specifies what kind of command is being queried.</param> - /// <param name="nextCommandHandler">A next command handler to be called if no command handlers were - /// able to determine a command state.</param> - /// <typeparam name="T">Tehe </typeparam> + /// <param name="nextCommandHandler">The next command handler to be called if no command handlers were + /// able to determine the command state.</param> + /// <typeparam name="T">The type of the command being queried.</typeparam> /// <returns>The command state of a given command.</returns> CommandState GetCommandState<T>(Func<ITextView, ITextBuffer, T> argsFactory, Func<CommandState> nextCommandHandler) where T : EditorCommandArgs; @@ -25,8 +25,9 @@ namespace Microsoft.VisualStudio.Text.Editor.Commanding /// Execute a given command on the <see cref="ITextView"/> associated with this <see cref="IEditorCommandHandlerService"/> instance. /// </summary> /// <param name="argsFactory">A factory of <see cref="EditorCommandArgs"/> that specifies what kind of command is being executed. - /// <paramref name="nextCommandHandler">>A next command handler to be called if no command handlers were - /// able to handle a command.</paramref> + /// <param name="nextCommandHandler">The next command handler to be called if no command handlers were + /// able to handle the command.</param> + /// <typeparam name="T">The type of the command being executed.</typeparam> void Execute<T>(Func<ITextView, ITextBuffer, T> argsFactory, Action nextCommandHandler) where T : EditorCommandArgs; - } + } } diff --git a/src/Editor/Text/Impl/Commanding/DefaultBufferResolver.cs b/src/Editor/Text/Impl/Commanding/DefaultBufferResolver.cs index 71c93d8..100773d 100644 --- a/src/Editor/Text/Impl/Commanding/DefaultBufferResolver.cs +++ b/src/Editor/Text/Impl/Commanding/DefaultBufferResolver.cs @@ -4,6 +4,8 @@ using System.ComponentModel.Composition; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Editor.Commanding; +using Microsoft.VisualStudio.Text.Projection; +using Microsoft.VisualStudio.Text.Utilities; using Microsoft.VisualStudio.Utilities; namespace Microsoft.VisualStudio.UI.Text.Commanding.Implementation @@ -29,8 +31,25 @@ namespace Microsoft.VisualStudio.UI.Text.Commanding.Implementation public IEnumerable<ITextBuffer> ResolveBuffersForCommand<TArgs>() where TArgs : EditorCommandArgs { - var mappingPoint = _textView.BufferGraph.CreateMappingPoint(_textView.Caret.Position.BufferPosition, PointTrackingMode.Negative); - return _textView.BufferGraph.GetTextBuffers((b) => mappingPoint.GetPoint(b, PositionAffinity.Successor) != null); + var sourceSnapshotPoints = new FrugalList<SnapshotPoint>(new[] { _textView.Caret.Position.BufferPosition }); + var resolvedBuffers = new FrugalList<ITextBuffer>(); + for (int i = 0; i < sourceSnapshotPoints.Count; i++) + { + SnapshotPoint curSnapshotPoint = sourceSnapshotPoints[i]; + if (curSnapshotPoint.Snapshot is IProjectionSnapshot curProjectionSnapshot) + { + sourceSnapshotPoints.AddRange(curProjectionSnapshot.MapToSourceSnapshots(curSnapshotPoint)); + } + + // As the set of buffers isn't likely to exceed 5, just use the list to determine whether we've seen it before + ITextBuffer curBuffer = curSnapshotPoint.Snapshot.TextBuffer; + if (!resolvedBuffers.Contains(curBuffer)) + { + resolvedBuffers.Add(curBuffer); + } + } + + return resolvedBuffers; } } } diff --git a/src/Editor/Text/Impl/Commanding/EditorCommandHandlerService.cs b/src/Editor/Text/Impl/Commanding/EditorCommandHandlerService.cs index caf42d1..60f6262 100644 --- a/src/Editor/Text/Impl/Commanding/EditorCommandHandlerService.cs +++ b/src/Editor/Text/Impl/Commanding/EditorCommandHandlerService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -175,6 +176,24 @@ namespace Microsoft.VisualStudio.UI.Text.Commanding.Implementation var commandExecutionContext = new CommandExecutionContext(uiThreadOperationContext); commandExecutionContext.OperationContext.UserCancellationToken.Register(OnExecutionCancellationRequested, state); state.ExecutionContext = commandExecutionContext; + + // Per internal convention hosts can add additional host specific input context properties into + // text view's property bag. We then surface it to command handlers (first item in case it's a list) via + // CommandExecutionContext properties using type name as a key. + if (_textView.Properties.TryGetProperty("Additional Command Execution Context", out object hostSpecificInputContext)) + { + if (hostSpecificInputContext != null) + { + if (hostSpecificInputContext is IList hostSpecificInputContextList && + hostSpecificInputContextList.Count > 0) + { + hostSpecificInputContext = hostSpecificInputContextList[0]; + } + + commandExecutionContext.Properties.AddProperty(hostSpecificInputContext.GetType(), hostSpecificInputContext); + } + } + return state; } diff --git a/src/FPF/WindowsBase/System.Windows.Threading/Dispatcher.cs b/src/FPF/WindowsBase/System.Windows.Threading/Dispatcher.cs index 56a796c..6a92f34 100644 --- a/src/FPF/WindowsBase/System.Windows.Threading/Dispatcher.cs +++ b/src/FPF/WindowsBase/System.Windows.Threading/Dispatcher.cs @@ -182,6 +182,12 @@ namespace System.Windows.Threading } } + public bool HasShutdownStarted => false; + public bool HasShutdownFinished => false; + + public event EventHandler ShutdownStarted { add { } remove { } } + public event EventHandler ShutdownFinished { add { } remove { } } + #endregion } }
\ No newline at end of file |