diff --git a/CodeiumVS/CodeiumVSPackage.cs b/CodeiumVS/CodeiumVSPackage.cs index e5acc01..a321712 100644 --- a/CodeiumVS/CodeiumVSPackage.cs +++ b/CodeiumVS/CodeiumVSPackage.cs @@ -44,14 +44,33 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke Instance = this; await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - //await this.SatisfyImportsOnceAsync(); - LanguageServer = new LanguageServer(); - OutputWindow = new OutputWindow(); - SettingsPage = (SettingsPage)GetDialogPage(typeof(SettingsPage)); + LanguageServer = new LanguageServer(); + OutputWindow = new OutputWindow(); NotificationAuth = new NotificationInfoBar(); - await this.RegisterCommandsAsync(); + try + { + SettingsPage = GetDialogPage(typeof(SettingsPage)) as SettingsPage; + } + catch (Exception) { } + + if (SettingsPage == null) + { + await LogAsync($"CodeiumVSPackage.InitializeAsync: Failed to get settings page, using the default settings"); + SettingsPage = new SettingsPage(); + } + + try + { + await this.RegisterCommandsAsync(); + } + catch (Exception ex) + { + await LogAsync($"CodeiumVSPackage.InitializeAsync: Failed to register commands; Exception {ex}"); + await VS.MessageBox.ShowErrorAsync("Codeium: Failed to register commands.", "Codeium might not work correctly. Please check the output window for more details."); + } + await LanguageServer.InitializeAsync(); await LogAsync("Codeium Extension for Visual Studio"); } @@ -87,10 +106,17 @@ public async Task UpdateSignedInStateAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - OleMenuCommandService obj = (await GetServiceAsync(typeof(IMenuCommandService))) as OleMenuCommandService; - obj.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.SignIn)).Visible = !IsSignedIn(); - obj.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.SignOut)).Visible = IsSignedIn(); - obj.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.EnterAuthToken)).Visible = !IsSignedIn(); + + if ((await GetServiceAsync(typeof(IMenuCommandService))) is OleMenuCommandService cmdService) + { + MenuCommand? commandSignIn = cmdService.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.SignIn)); + MenuCommand? commandSignOut = cmdService.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.SignOut)); + MenuCommand? commandEnterToken = cmdService.FindCommand(new CommandID(PackageGuids.CodeiumVS, PackageIds.EnterAuthToken)); + + if (commandSignIn != null) commandSignIn.Visible = !IsSignedIn(); + if (commandSignOut != null) commandSignOut.Visible = IsSignedIn(); + if (commandEnterToken != null) commandEnterToken.Visible = !IsSignedIn(); + } // notify the user they need to sign in if (!IsSignedIn()) diff --git a/CodeiumVS/InlineDiff/InlineDiffAdornment.cs b/CodeiumVS/InlineDiff/InlineDiffAdornment.cs index 8829e4b..5a65e8a 100644 --- a/CodeiumVS/InlineDiff/InlineDiffAdornment.cs +++ b/CodeiumVS/InlineDiff/InlineDiffAdornment.cs @@ -471,8 +471,8 @@ private void Adornment_OnAccepted() // format it try { - DTE2 dte = (DTE2)ServiceProvider.GlobalProvider.GetService(typeof(DTE)); - dte.ExecuteCommand("Edit.FormatSelection"); + DTE2? dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE2; + dte?.ExecuteCommand("Edit.FormatSelection"); // this doesn't work //var guid = VSConstants.CMDSETID.StandardCommandSet2K_guid; diff --git a/CodeiumVS/InlineDiff/InlineDiffView.cs b/CodeiumVS/InlineDiff/InlineDiffView.cs index a543c20..7f0596a 100644 --- a/CodeiumVS/InlineDiff/InlineDiffView.cs +++ b/CodeiumVS/InlineDiff/InlineDiffView.cs @@ -458,18 +458,18 @@ private void DiffView_OnClosed(object sender, EventArgs e) private void LeftView_OnClosed(object sender, EventArgs e) { - LeftView.VisualElement.GotFocus -= LeftView_OnGotFocus; - LeftView.VisualElement.LostFocus -= LeftView_OnLostFocus; - LeftView.Caret.PositionChanged -= LeftView_OnCaretPositionChanged; - LeftView.Closed -= LeftView_OnClosed; + LeftView.VisualElement.GotFocus -= LeftView_OnGotFocus; + LeftView.VisualElement.LostFocus -= LeftView_OnLostFocus; + LeftView.Caret.PositionChanged -= LeftView_OnCaretPositionChanged; + LeftView.Closed -= LeftView_OnClosed; } private void RightView_OnClosed(object sender, EventArgs e) { - RightView.VisualElement.GotFocus -= RightView_OnGotFocus; - RightView.VisualElement.LostFocus -= RightView_OnLostFocus; - RightView.Caret.PositionChanged -= RightView_OnCaretPositionChanged; - RightView.Closed -= RightView_OnClosed; + RightView.VisualElement.GotFocus -= RightView_OnGotFocus; + RightView.VisualElement.LostFocus -= RightView_OnLostFocus; + RightView.Caret.PositionChanged -= RightView_OnCaretPositionChanged; + RightView.Closed -= RightView_OnClosed; } /// @@ -481,6 +481,9 @@ private void DifferenceViewer_OnClosed(object sender, EventArgs e) { _diffBuffer.SnapshotDifferenceChanged -= DiffBuffer_SnapshotDifferenceChanged; _viewer.Closed -= DifferenceViewer_OnClosed; + + // restore the selected line highlight for the host view + ShowSelectedLineForView(_hostView); } /// diff --git a/CodeiumVS/LanguageServer/LanguageServer.cs b/CodeiumVS/LanguageServer/LanguageServer.cs index ab2a626..bc09702 100644 --- a/CodeiumVS/LanguageServer/LanguageServer.cs +++ b/CodeiumVS/LanguageServer/LanguageServer.cs @@ -1,4 +1,5 @@ using CodeiumVS.Packets; +using EnvDTE80; using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; @@ -45,15 +46,24 @@ public LanguageServer() public async Task InitializeAsync() { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + + string ideVersion = "17.0", locale = "en-US"; + + try + { + locale = CultureInfo.CurrentUICulture.Name; + Version? version = await VS.Shell.GetVsVersionAsync(); + if (version != null) ideVersion = version.ToString(); + } + catch (Exception) { } - EnvDTE.DTE VSDTE = (EnvDTE.DTE)Marshal.GetActiveObject("VisualStudio.DTE"); Metadata.request_id = 0; Metadata.ide_name = "visual_studio"; - Metadata.ide_version = VSDTE.Version; + Metadata.ide_version = ideVersion; Metadata.extension_name = Vsix.Name; Metadata.extension_version = Version; Metadata.session_id = Guid.NewGuid().ToString(); - Metadata.locale = new CultureInfo(VSDTE.LocaleID).Name; + Metadata.locale = locale; Metadata.disable_telemetry = false; await PrepareAsync(); @@ -167,9 +177,6 @@ public async Task SignOutAsync() // Download the language server (if not already) and start it public async Task PrepareAsync() { - string langServerFolder = Package.GetLanguageServerFolder(); - Directory.CreateDirectory(langServerFolder); - string binaryPath = Package.GetLanguageServerPath(); if (File.Exists(binaryPath)) @@ -195,9 +202,13 @@ public async Task PrepareAsync() // until VS is closing, not sure how we can fix that without spawning a separate thread void ThreadDownloadLanguageServer() { + string langServerFolder = Package.GetLanguageServerFolder(); + string downloadDest = Path.Combine(langServerFolder, "language-server.gz"); + + Directory.CreateDirectory(langServerFolder); + if (File.Exists(downloadDest)) File.Delete(downloadDest); + Uri url = new($"https://github.com/Exafunction/codeium/releases/download/language-server-v{Version}/language_server_windows_x64.exe.gz"); - string downloadDest = Path.Combine(Package.GetLanguageServerFolder(), "language-server.gz"); - File.Delete(downloadDest); WebClient webClient = new(); @@ -280,8 +291,20 @@ private async Task StartAsync() string managerDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); string databaseDir = Package.GetDatabaseDirectory(); - Directory.CreateDirectory(managerDir); - Directory.CreateDirectory(databaseDir); + try + { + Directory.CreateDirectory(managerDir); + Directory.CreateDirectory(databaseDir); + } + catch (Exception ex) + { + await Package.LogAsync($"LanguageServer.StartAsync: Failed to create directories; Exception: {ex}"); + await VS.MessageBox.ShowErrorAsync( + "Codeium: Failed to create language server directories.", + "Please check the output window for more details." + ); + return; + } process = new(); process.StartInfo.FileName = Package.GetLanguageServerPath(); @@ -301,10 +324,21 @@ private async Task StartAsync() process.Exited += LSP_OnExited; await Package.LogAsync("Starting language server"); - process.Start(); - process.BeginErrorReadLine(); - Utilities.ProcessExtensions.MakeProcessExitOnParentExit(process); + try + { + process.Start(); + process.BeginErrorReadLine(); + Utilities.ProcessExtensions.MakeProcessExitOnParentExit(process); + } + catch (Exception ex) + { + await Package.LogAsync($"LanguageServer.StartAsync: Failed to start the language server; Exception: {ex}"); + await VS.MessageBox.ShowErrorAsync( + "Codeium: Failed to start the language server.", + "Please check the output window for more details." + ); + } string apiKeyFilePath = Package.GetAPIKeyPath(); if (File.Exists(apiKeyFilePath)) diff --git a/CodeiumVS/NotificationBar.cs b/CodeiumVS/NotificationBar.cs index d40cee9..a3c595c 100644 --- a/CodeiumVS/NotificationBar.cs +++ b/CodeiumVS/NotificationBar.cs @@ -31,22 +31,30 @@ public void Show(string text, ImageMoniker? icon = null, bool canClose = true, A ThreadHelper.ThrowIfNotOnUIThread("Show"); if (view != null) return; - IVsShell vsShell = ServiceProvider.GlobalProvider.GetService(); - IVsInfoBarUIFactory vsInfoBarFactory = ServiceProvider.GlobalProvider.GetService(); - if (vsShell == null || vsInfoBarFactory == null) return; - - if (vsInfoBarFactory != null && ErrorHandler.Succeeded(vsShell.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out var pvar)) && pvar is IVsInfoBarHost vsInfoBarHost) + try { - InfoBarModel infoBar = new(text, GetActionsItems(actions), icon ?? KnownMonikers.StatusInformation, canClose); + IVsShell vsShell = ServiceProvider.GlobalProvider.GetService(); + IVsInfoBarUIFactory vsInfoBarFactory = ServiceProvider.GlobalProvider.GetService(); + if (vsShell == null || vsInfoBarFactory == null) return; + + if (vsInfoBarFactory != null && ErrorHandler.Succeeded(vsShell.GetProperty((int)__VSSPROPID7.VSSPROPID_MainWindowInfoBarHost, out var pvar)) && pvar is IVsInfoBarHost vsInfoBarHost) + { + InfoBarModel infoBar = new(text, GetActionsItems(actions), icon ?? KnownMonikers.StatusInformation, canClose); - view = vsInfoBarFactory.CreateInfoBar(infoBar); - view.Advise(this, out infoBarEventsCookie); + view = vsInfoBarFactory.CreateInfoBar(infoBar); + view.Advise(this, out infoBarEventsCookie); - this.vsInfoBarHost = vsInfoBarHost; - this.vsInfoBarHost.AddInfoBar(view); + this.vsInfoBarHost = vsInfoBarHost; + this.vsInfoBarHost.AddInfoBar(view); - IsShown = true; - OnCloseCallback = onCloseCallback; + IsShown = true; + OnCloseCallback = onCloseCallback; + } + } + catch (Exception ex) + { + CodeiumVSPackage.Instance?.Log($"NotificationInfoBar.Show: Failed to show notificaiton; Exception: {ex}"); + return; } }