Skip to content

Commit 4230c40

Browse files
Merge pull request #410 from reduckted/feature/unregister-command-interceptor
Allow command interceptors to be unregistered [release]
2 parents a37ebbb + c864ff4 commit 4230c40

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

src/toolkit/Community.VisualStudio.Toolkit.Shared/Commands/Commands.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Microsoft.VisualStudio.OLE.Interop;
66
using Microsoft.VisualStudio.Shell;
77
using Microsoft.VisualStudio.Shell.Interop;
8-
using Task = System.Threading.Tasks.Task;
98

109
namespace Community.VisualStudio.Toolkit
1110
{
@@ -93,32 +92,38 @@ public Task<bool> ExecuteAsync(CommandID cmd, string argument = "")
9392
/// <summary>
9493
/// Intercept any command before it is being handled by other command handlers.
9594
/// </summary>
96-
public Task InterceptAsync(VSConstants.VSStd97CmdID command, Func<CommandProgression> func)
95+
/// <returns>Returns an <see cref="IDisposable"/> that will remove the command interceptor when disposed.</returns>
96+
public Task<IDisposable> InterceptAsync(VSConstants.VSStd97CmdID command, Func<CommandProgression> func)
9797
=> InterceptAsync(typeof(VSConstants.VSStd97CmdID).GUID, (int)command, func);
9898

9999
/// <summary>
100100
/// Intercept any command before it is being handled by other command handlers.
101101
/// </summary>
102-
public Task InterceptAsync(VSConstants.VSStd2KCmdID command, Func<CommandProgression> func)
102+
/// <returns>Returns an <see cref="IDisposable"/> that will remove the command interceptor when disposed.</returns>
103+
public Task<IDisposable> InterceptAsync(VSConstants.VSStd2KCmdID command, Func<CommandProgression> func)
103104
=> InterceptAsync(typeof(VSConstants.VSStd2KCmdID).GUID, (int)command, func);
104105

105106
/// <summary>
106107
/// Intercept any command before it is being handled by other command handlers.
107108
/// </summary>
108-
public Task InterceptAsync(Guid menuGroup, int commandId, Func<CommandProgression> func)
109+
/// <returns>Returns an <see cref="IDisposable"/> that will remove the command interceptor when disposed.</returns>
110+
public Task<IDisposable> InterceptAsync(Guid menuGroup, int commandId, Func<CommandProgression> func)
109111
=> InterceptAsync(new CommandID(menuGroup, commandId), func);
110112

111113
/// <summary>
112114
/// Intercept any command before it is being handled by other command handlers.
113115
/// </summary>
114-
public async Task InterceptAsync(CommandID cmd, Func<CommandProgression> func)
116+
/// <returns>Returns an <see cref="IDisposable"/> that will remove the command interceptor when disposed.</returns>
117+
public async Task<IDisposable> InterceptAsync(CommandID cmd, Func<CommandProgression> func)
115118
{
116119
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
117120

118121
IVsRegisterPriorityCommandTarget? priority = await VS.Services.GetPriorityCommandTargetAsync();
119122
CommandInterceptor interceptor = new(cmd, func);
120123

121-
ErrorHandler.ThrowOnFailure(priority.RegisterPriorityCommandTarget(0, interceptor, out _));
124+
ErrorHandler.ThrowOnFailure(priority.RegisterPriorityCommandTarget(0, interceptor, out uint cookie));
125+
126+
return new Disposable(() => priority.UnregisterPriorityCommandTarget(cookie));
122127
}
123128
}
124129

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace Community.VisualStudio.Toolkit
4+
{
5+
internal sealed class Disposable : IDisposable
6+
{
7+
private readonly Action _action;
8+
private bool _disposed;
9+
10+
public Disposable(Action action)
11+
{
12+
_action = action;
13+
}
14+
15+
public void Dispose()
16+
{
17+
if (!_disposed)
18+
{
19+
_disposed = true;
20+
_action();
21+
}
22+
}
23+
}
24+
}

src/toolkit/Community.VisualStudio.Toolkit.Shared/VSSDK.Helpers.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
</PropertyGroup>
1111
<ItemGroup>
1212
<Compile Include="$(MSBuildThisFileDirectory)Debugger\Debugger.cs" />
13+
<Compile Include="$(MSBuildThisFileDirectory)Helpers\Disposable.cs" />
1314
<Compile Include="$(MSBuildThisFileDirectory)Windows\IToolWindowPaneAware.cs" />
1415
<Compile Include="$(MSBuildThisFileDirectory)Windows\ToolkitToolWindowPane.cs" />
1516
<Compile Include="$(MSBuildThisFileDirectory)\Attributes\ProvideBraceCompletionAttribute.cs" />

0 commit comments

Comments
 (0)