|
| 1 | +using Cody.Core.Agent.Protocol; |
| 2 | +using Microsoft.VisualStudio; |
| 3 | +using Microsoft.VisualStudio.Shell; |
| 4 | +using Microsoft.VisualStudio.Shell.Interop; |
| 5 | +using System; |
| 6 | +using System.Collections.Generic; |
| 7 | +using System.ComponentModel.Design; |
| 8 | +using System.Linq; |
| 9 | +using System.Text; |
| 10 | +using System.Threading.Tasks; |
| 11 | + |
| 12 | +namespace Cody.VisualStudio |
| 13 | +{ |
| 14 | + public partial class CodyPackage |
| 15 | + { |
| 16 | + private readonly Dictionary<int, CodyCommand> codyCommands = new Dictionary<int, CodyCommand>(); |
| 17 | + |
| 18 | + private void InitOleMenu() |
| 19 | + { |
| 20 | + AddCommand(CommandIds.CodyToolWindow, null, ShowToolWindow, true); |
| 21 | + AddCommand(CommandIds.DocumentCodeCommandId, "cody.command.document-code", InvokeCodyCommand, false); |
| 22 | + AddCommand(CommandIds.GenerateUnitTestsCommandId, "cody.command.unit-tests", InvokeCodyCommand, false); |
| 23 | + AddCommand(CommandIds.ExplainCodeCommandId, "cody.command.explain-code", InvokeCodyCommand, false); |
| 24 | + AddCommand(CommandIds.FindCodeSmellsCommandId, "cody.command.smell-code", InvokeCodyCommand, false); |
| 25 | + } |
| 26 | + |
| 27 | + private void AddCommand(int commandId, string commandName, EventHandler handler, bool enabled) |
| 28 | + { |
| 29 | + try |
| 30 | + { |
| 31 | + var command = new CommandID(Guids.CodyPackageCommandSet, commandId); |
| 32 | + var menuCommand = new MenuCommand(handler, command); |
| 33 | + menuCommand.Enabled = enabled; |
| 34 | + |
| 35 | + codyCommands[commandId] = new CodyCommand { MenuCommand = menuCommand, CommandName = commandName }; |
| 36 | + |
| 37 | + OleMenuService.AddCommand(menuCommand); |
| 38 | + } |
| 39 | + catch (Exception ex) |
| 40 | + { |
| 41 | + Logger.Error($"Failed to add command {commandName}", ex); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + public void EnableContextMenu(bool enabled) |
| 46 | + { |
| 47 | + codyCommands |
| 48 | + .Where(x => x.Value.CommandName != null) |
| 49 | + .ToList() |
| 50 | + .ForEach(x => x.Value.MenuCommand.Enabled = enabled); |
| 51 | + } |
| 52 | + |
| 53 | + public async void InvokeCodyCommand(object sender, EventArgs eventArgs) |
| 54 | + { |
| 55 | + try |
| 56 | + { |
| 57 | + var menuCommand = sender as MenuCommand; |
| 58 | + if (menuCommand == null) |
| 59 | + { |
| 60 | + Logger.Error("Cannot get MenuCommand instance"); |
| 61 | + return; |
| 62 | + } |
| 63 | + |
| 64 | + var commandId = menuCommand.CommandID.ID; |
| 65 | + |
| 66 | + if (codyCommands.TryGetValue(commandId, out var command)) |
| 67 | + { |
| 68 | + if (commandId == CommandIds.ExplainCodeCommandId || |
| 69 | + commandId == CommandIds.FindCodeSmellsCommandId || |
| 70 | + commandId == CommandIds.GenerateUnitTestsCommandId) |
| 71 | + { |
| 72 | + Logger.Debug($"Showing the chat window for the {command} command"); |
| 73 | + await ShowToolWindowAsync(); |
| 74 | + } |
| 75 | + else |
| 76 | + { |
| 77 | + StatusbarService?.StartProgressAnimation(); |
| 78 | + } |
| 79 | + |
| 80 | + if (AgentClient != null) |
| 81 | + { |
| 82 | + Logger.Info($"Invoking command: {command}"); |
| 83 | + await AgentService.CommandExecute(new ExecuteCommandParams |
| 84 | + { |
| 85 | + Command = command.CommandName |
| 86 | + }); |
| 87 | + } |
| 88 | + else Logger.Warn($"AgentClient not jet initialized. Can't invoke command: {command}"); |
| 89 | + } |
| 90 | + else Logger.Error($"Cant find command for id: {commandId}"); |
| 91 | + } |
| 92 | + catch (Exception ex) |
| 93 | + { |
| 94 | + Logger.Error($"Failed to invoke command", ex); |
| 95 | + } |
| 96 | + |
| 97 | + } |
| 98 | + |
| 99 | + public async void ShowToolWindow(object sender, EventArgs eventArgs) => await ShowToolWindowAsync(); |
| 100 | + |
| 101 | + public async Task ShowToolWindowAsync() |
| 102 | + { |
| 103 | + try |
| 104 | + { |
| 105 | + Logger.Debug("Showing Tool Window ..."); |
| 106 | + var window = await ShowToolWindowAsync(typeof(CodyToolWindow), 0, true, DisposalToken); |
| 107 | + if (window?.Frame is IVsWindowFrame windowFrame) |
| 108 | + { |
| 109 | + bool isVisible = windowFrame.IsVisible() == 0; |
| 110 | + bool isOnScreen = windowFrame.IsOnScreen(out int screenTmp) == 0 && screenTmp == 1; |
| 111 | + |
| 112 | + Logger.Debug($"IsVisible:{isVisible} IsOnScreen:{isOnScreen}"); |
| 113 | + |
| 114 | + if (!isVisible || !isOnScreen) |
| 115 | + { |
| 116 | + ErrorHandler.ThrowOnFailure(windowFrame.Show()); |
| 117 | + Logger.Debug("Shown."); |
| 118 | + |
| 119 | + } |
| 120 | + } |
| 121 | + } |
| 122 | + catch (Exception ex) |
| 123 | + { |
| 124 | + Logger.Error("Cannot toggle Tool Window.", ex); |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + public class CodyCommand |
| 129 | + { |
| 130 | + public MenuCommand MenuCommand { get; set; } |
| 131 | + public string CommandName { get; set; } |
| 132 | + } |
| 133 | + } |
| 134 | +} |
0 commit comments