From 14bb138b4b78d9ad1bdaa8020ae27b8462a94f39 Mon Sep 17 00:00:00 2001 From: Ahmadkhan02 Date: Sat, 20 Jul 2024 15:25:47 +0530 Subject: [PATCH] Trigger completion tool --- MultilineGreyText/Options/General.cs | 1 - .../RefactCompletionCommandHandler.cs | 14 +- MultilineGreyText/RefactExtension.csproj | 371 +++++++++--------- MultilineGreyText/RefactLanguageClient.cs | 9 +- MultilineGreyText/RefactPackage.cs | 8 +- MultilineGreyText/RefactPackage.vsct | 239 +++++------ .../Resources/TriggerCompletionCommand.png | Bin 0 -> 1172 bytes MultilineGreyText/TriggerCompletionCommand.cs | 102 ++++- 8 files changed, 414 insertions(+), 330 deletions(-) create mode 100644 MultilineGreyText/Resources/TriggerCompletionCommand.png diff --git a/MultilineGreyText/Options/General.cs b/MultilineGreyText/Options/General.cs index 8208f5c..eea0a54 100644 --- a/MultilineGreyText/Options/General.cs +++ b/MultilineGreyText/Options/General.cs @@ -73,7 +73,6 @@ public class General : BaseOptionModel{ // Event handler to be invoked when settings are saved private void OnSettingsSaved(General options) { - VS.StatusBar.ShowMessageAsync("Options Saved").FireAndForget(); OnSettingsChanged?.Invoke(this, EventArgs.Empty); } diff --git a/MultilineGreyText/RefactCompletionCommandHandler.cs b/MultilineGreyText/RefactCompletionCommandHandler.cs index 9215cb5..82441bd 100644 --- a/MultilineGreyText/RefactCompletionCommandHandler.cs +++ b/MultilineGreyText/RefactCompletionCommandHandler.cs @@ -137,8 +137,9 @@ public bool IsInline(int lineN){ } //gets recommendations from LSP - public async void GetLSPCompletions(){ - if (!General.Instance.PauseCompletion){ + public async void GetLSPCompletions() + { + if (!General.Instance.PauseCompletion){ SnapshotPoint? caretPoint = m_textView.Caret.Position.Point.GetPoint(textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); if (caretPoint.HasValue){ @@ -236,18 +237,11 @@ void CheckSuggestionUpdate(uint nCmdID){ //Key input handler public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut){ - //let the other handlers handle automation functions + //let the other handlers handle automation if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)){ return m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } - if (pguidCmdGroup == RefactPackage.CommandSet && nCmdID == TriggerCompletionCommand.CommandId) - { - GetLSPCompletions(); - return VSConstants.S_OK; - } - - //check for a commit character if (!hasCompletionUpdated && nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB){ diff --git a/MultilineGreyText/RefactExtension.csproj b/MultilineGreyText/RefactExtension.csproj index 8055abb..5ac1f14 100644 --- a/MultilineGreyText/RefactExtension.csproj +++ b/MultilineGreyText/RefactExtension.csproj @@ -1,192 +1,193 @@ - - - - 17.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - true - - - - - - - - Debug - AnyCPU - 2.0 - {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {EBB916BC-0F79-4EAB-82D7-C6B17817424E} - Library - Properties - OutlineRegionTest - OutlineRegionTest - v4.8 - true - true - true - false - false - true - true - Program - $(DevEnvDir)devenv.exe - /rootsuffix Exp - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - False - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - GeneralOptions.xaml - - - Component - - - - - - - - True - True - Resources.resx - - - True - True - Settings.settings - - - - - - - - - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - Designer - VsixManifestGenerator - - - - - - - - - - - - - - - - - - - - PreserveNewest - true - - - true - PreserveNewest - - - - - 17.0.507 - - - 1.0.507 - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - 16.0.29.6 - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - 17.2.8 - - - compile; build; native; contentfiles; analyzers; buildtransitive - - - - - - Menus.ctmenu - - - true - - - Always - true - - - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - - true - VSPackage - Designer - - - - - Designer - MSBuild:Compile - - - - - - - - + + + + 17.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + true + + + + + + + + Debug + AnyCPU + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {EBB916BC-0F79-4EAB-82D7-C6B17817424E} + Library + Properties + OutlineRegionTest + OutlineRegionTest + v4.8 + true + true + true + false + false + true + true + Program + $(DevEnvDir)devenv.exe + /rootsuffix Exp + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + False + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + GeneralOptions.xaml + + + Component + + + + + + + + True + True + Resources.resx + + + True + True + Settings.settings + + + + + + + + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + Designer + VsixManifestGenerator + + + + + + + + + + + + + + + + + + + + PreserveNewest + true + + + true + PreserveNewest + + + + + 17.0.507 + + + 1.0.507 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + 16.0.29.6 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + 17.2.8 + + + compile; build; native; contentfiles; analyzers; buildtransitive + + + + + + Menus.ctmenu + + + true + + + Always + true + + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + true + VSPackage + Designer + + + + + Designer + MSBuild:Compile + + + + + + + + + --> \ No newline at end of file diff --git a/MultilineGreyText/RefactLanguageClient.cs b/MultilineGreyText/RefactLanguageClient.cs index 4e9684c..461cce2 100644 --- a/MultilineGreyText/RefactLanguageClient.cs +++ b/MultilineGreyText/RefactLanguageClient.cs @@ -96,6 +96,7 @@ public RefactLanguageClient() Instance = this; files = new HashSet(); statusBar = new StatusBar(); + ShowDefaultStatusBar(); General.OnSettingsChanged += ReloadLanguageClient; } @@ -108,10 +109,10 @@ async void ReloadLanguageClient(object sender, EventArgs e) var connection = await ActivateAsync(CancellationToken.None); // Rpc = new JsonRpc(connection.Input, connection.Output); - VS.StatusBar.ShowMessageAsync("Restarting Refact").FireAndForget(); - await OnLoadedAsync(); + VS.StatusBar.ShowMessageAsync("Options Updated").FireAndForget(); + await OnLoadedAsync(); - VS.StatusBar.ShowMessageAsync("Options updated").FireAndForget(); + VS.StatusBar.ShowMessageAsync("Ready").FireAndForget(); } catch (Exception ex) { @@ -204,8 +205,6 @@ public async Task ActivateAsync(CancellationToken token) } throw new InvalidOperationException("Failed to start language server process."); - - return null; } // get extension version diff --git a/MultilineGreyText/RefactPackage.cs b/MultilineGreyText/RefactPackage.cs index 14c4a02..8ccbe5a 100644 --- a/MultilineGreyText/RefactPackage.cs +++ b/MultilineGreyText/RefactPackage.cs @@ -1,6 +1,7 @@ using Community.VisualStudio.Toolkit; using Microsoft.VisualStudio.Shell; using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Threading; @@ -36,7 +37,6 @@ public sealed class RefactPackage : ToolkitPackage{ /// VSPackage1 GUID string. /// public const string PackageGuidString = "6f370a16-644a-450c-8e52-e2b92644822b"; - public static readonly Guid CommandSet = new Guid("6f370a16-644a-450c-8e52-e2b92644822b"); /// /// Initializes a new instance of the class. @@ -58,9 +58,11 @@ public RefactPackage(){ /// A provider for progress updates. /// A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method. protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress progress){ + Debug.Write("Initialzing the extension!"); await this.RegisterCommandsAsync(); - await RefactAI.PauseRefactCommand.InitializeAsync(this); - await RefactAI.TriggerCompletionCommand.InitializeAsync(this); + + await PauseRefactCommand.InitializeAsync(this); + await TriggerCompletionCommand.InitializeAsync(this); } #endregion diff --git a/MultilineGreyText/RefactPackage.vsct b/MultilineGreyText/RefactPackage.vsct index 017d435..a3973d1 100644 --- a/MultilineGreyText/RefactPackage.vsct +++ b/MultilineGreyText/RefactPackage.vsct @@ -1,114 +1,125 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - re - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MultilineGreyText/Resources/TriggerCompletionCommand.png b/MultilineGreyText/Resources/TriggerCompletionCommand.png new file mode 100644 index 0000000000000000000000000000000000000000..b22d975cbf00eda60e37587614e0677d0bfb525d GIT binary patch literal 1172 zcmV;F1Z(?=P)AHIP00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L1Sv^GK~z{r&6rO} zR8bVhMO+m@n`n^>S1nuxLD3=*TeOfsmlen?+6F={#2~abZOoueAZTJ(h!8>v{t3;> za?E)|5DA$%%#4KTQ&4A9oX&T-XSj3Ub>17D7(e)!JLjHr)!%vdzW1y+tlHh(J<9H6 zC)uRE&VI~3rPB^9A}Xs7r5JEE`&%NBp!)jyJP!>G(f0N>8gX8yD`m6Unw_1U4t9(0 z`^R-SPl)q;AA1VsnwSfU>5DfL{NbJ}g%6z=Y!y2`Ha4b!&wZSu_228{Z}{|MX*t&j zZo(SpokR_TtlRpvN}qckDl^<=y9pd?++5B0pB~($m6=KGCJ#9-DB`AjX=;A-hyG_1 zN-BV`t*0W3!CXzHQVMc9m8MO9D`43PoZE#OT-5;IfBKm6Z09Y^y}%qG^SC?X#c8;% zmPW2zAT)v-cn0$>D6qi4bZ1++_WElMyK_xfRaTMM6*J>-K>W+fd8@3$k!07x#Wsa& zh6e@)sHdmL2_OEsyh5>94C^nU#%=(NtDNIFl9sXrroHe%Qf zR#RHk57Kf$F@4Ym6oL;2B#=yiGL}!B8j$3hx#l>m9^&~A$eWpY>x2()toyQ7R+pg( zF;^30j9tL+`*eCvE-0oC(tt4duu~>1a~uXx^37ax999qU{L_hv32JL=bHaz`K$0hxe2L3grw7Dy*V%vN z@pF89A^<;=&QMcR6D=$(V6A3ds#K@}eDzQ1v^=?>zyKfhChP(p#i(@(kW64QmQS4) zkXbK z3DUMSq1eYz6R-(fVy2zqKPCsu9LuLp3rKRrQR_M8gpZvtIXRj8-rL(t$z&3146={t za`hC1ryCPE8iCz_=YDAha^&$-WCO9ipLYNow%GtP4m$-%g{;#8a^T^2W)0ic`s=u3>eS(!53jy;Ap}TwK(!j{X4>h0jPj$#%z}oK71%7O)%j{Z2*9CjSurx-l4;Lit}qY m*JGpEo(&`nZYkjtQN=$$-bTw6(Xv|r0000 + /// Command handler + /// internal sealed class TriggerCompletionCommand { - public const int CommandId = 0x0100; + /// + /// Command ID. + /// + public const int CommandId = 256; + + /// + /// Command menu group (command set GUID). + /// public static readonly Guid CommandSet = new Guid("528a0c75-4c23-4946-8b7f-b28afb34defc"); + /// + /// VS Package that provides this command, not null. + /// private readonly AsyncPackage package; + /// + /// Initializes a new instance of the class. + /// Adds our command handlers for menu (commands must exist in the command table file) + /// + /// Owner package, not null. + /// Command service to add command to, not null. private TriggerCompletionCommand(AsyncPackage package, OleMenuCommandService commandService) { this.package = package ?? throw new ArgumentNullException(nameof(package)); + commandService = commandService ?? throw new ArgumentNullException(nameof(commandService)); var menuCommandID = new CommandID(CommandSet, CommandId); var menuItem = new MenuCommand(this.Execute, menuCommandID); commandService.AddCommand(menuItem); } - public static TriggerCompletionCommand Instance { get; private set; } + /// + /// Gets the instance of the command. + /// + public static TriggerCompletionCommand Instance + { + get; + private set; + } - private IAsyncServiceProvider ServiceProvider => this.package; + /// + /// Gets the service provider from the owner package. + /// + private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider + { + get + { + return this.package; + } + } + /// + /// Initializes the singleton instance of the command. + /// + /// Owner package, not null. public static async Task InitializeAsync(AsyncPackage package) { - OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService; + // Switch to the main thread - the call to AddCommand in TriggerCompletionCommand's constructor requires + // the UI thread. + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken); + + OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService; Instance = new TriggerCompletionCommand(package, commandService); } + /// + /// This function is the callback used to execute the command when the menu item is clicked. + /// See the constructor to see how the menu item is associated with this function using + /// OleMenuCommandService service and MenuCommand class. + /// + /// Event sender. + /// Event args. private void Execute(object sender, EventArgs e) + { + ThreadHelper.ThrowIfNotOnUIThread(); + string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName); + string title = "TriggerCompletionCommand"; + + // Show a message box to prove we were here + VsShellUtilities.ShowMessageBox( + this.package, + message, + title, + OLEMSGICON.OLEMSGICON_INFO, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + + // Trigger LSP completions + TriggerLSPCompletions(); + } + + private void TriggerLSPCompletions() { ThreadHelper.ThrowIfNotOnUIThread(); var componentModel = (IComponentModel)Package.GetGlobalService(typeof(SComponentModel)); - var completionBroker = componentModel.GetService(); - var textView = componentModel.GetService().GetWpfTextView(Package.GetGlobalService(typeof(SVsTextManager)) as IVsTextView); + var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager)); + var adapterService = componentModel.GetService(); + var completionHandlerProvider = componentModel.GetService(); + + IVsTextView textView; + textManager.GetActiveView(1, null, out textView); + var wpfTextView = adapterService.GetWpfTextView(textView); - if (textView != null) + if (wpfTextView != null) { - var caretPosition = textView.Caret.Position.BufferPosition; - completionBroker.TriggerCompletion(textView); + var commandHandler = wpfTextView.Properties.GetProperty(typeof(RefactCompletionCommandHandler)); + commandHandler?.GetLSPCompletions(); } } }