From 9461f270f30809167ea31a695b52cec3cd62034b Mon Sep 17 00:00:00 2001 From: "QH-PC\\qiuhao" Date: Fri, 27 Mar 2020 20:39:34 +0800 Subject: [PATCH] Add Visual Studio Extension --- .../Controllers/LuceneController.cs | 2 +- .../CodeIndex.VisualStudioExtension.csproj | 146 ++++++++++ .../CodeIndex.VisualStudioExtensionPackage.cs | 56 ++++ .../CodeIndexSearchWindow.cs | 34 +++ .../CodeIndexSearchWindowCommand.cs | 99 +++++++ .../CodeIndexSearchWindowControl.xaml | 17 ++ .../CodeIndexSearchWindowControl.xaml.cs | 20 ++ .../Controls/CodeIndexSearchControl.xaml | 137 ++++++++++ .../Controls/CodeIndexSearchControl.xaml.cs | 28 ++ .../Models/BaseViewModel.cs | 27 ++ .../Models/CodeIndexSearchViewModel.cs | 257 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 34 +++ .../Properties/CodeIndexSettings.Designer.cs | 38 +++ .../Properties/CodeIndexSettings.settings | 9 + .../ProvideToolboxControlAttribute.cs | 83 ++++++ .../CodeIndexSearchWindowCommand.png | Bin 0 -> 1172 bytes .../Resources/Style.xaml | 3 + .../VisualStudioExtensionPackage.vsct | 92 +++++++ .../app.config | 15 + .../source.extension.vsixmanifest | 24 ++ src/CodeIndex.sln | 6 + 21 files changed, 1126 insertions(+), 1 deletion(-) create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml create mode 100644 src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml create mode 100644 src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Models/BaseViewModel.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Models/CodeIndexSearchViewModel.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Properties/AssemblyInfo.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.Designer.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Properties/CodeIndexSettings.settings create mode 100644 src/CodeIndex.VisualStudioExtension/ProvideToolboxControlAttribute.cs create mode 100644 src/CodeIndex.VisualStudioExtension/Resources/CodeIndexSearchWindowCommand.png create mode 100644 src/CodeIndex.VisualStudioExtension/Resources/Style.xaml create mode 100644 src/CodeIndex.VisualStudioExtension/VisualStudioExtensionPackage.vsct create mode 100644 src/CodeIndex.VisualStudioExtension/app.config create mode 100644 src/CodeIndex.VisualStudioExtension/source.extension.vsixmanifest diff --git a/src/CodeIndex.Server/Controllers/LuceneController.cs b/src/CodeIndex.Server/Controllers/LuceneController.cs index e89164d..2a10899 100644 --- a/src/CodeIndex.Server/Controllers/LuceneController.cs +++ b/src/CodeIndex.Server/Controllers/LuceneController.cs @@ -40,7 +40,7 @@ public FetchResult> GetCodeSources(string searchQuery, b { searchQuery.RequireNotNullOrEmpty(nameof(searchQuery)); - var showResultsValue = showResults.HasValue && showResults.Value <= 100 && showResults.Value > 0 ? showResults.Value : 100; + var showResultsValue = showResults.HasValue && showResults.Value <= 100 && showResults.Value > 0 ? showResults.Value : 1000; result = new FetchResult> { diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj new file mode 100644 index 0000000..2052cd7 --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtension.csproj @@ -0,0 +1,146 @@ + + + + 16.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + Debug + AnyCPU + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {ED1D3026-8695-4B9B-9FA9-2D68E28EE850} + Library + Properties + CodeIndex.VisualStudioExtension + CodeIndex.VisualStudioExtension + v4.8 + true + true + true + false + false + true + true + Program + $(DevEnvDir)devenv.exe + /rootsuffix Exp + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + Models\CodeSource.cs + + + Models\FetchResult.cs + + + Models\Status.cs + + + CodeIndexSearchControl.xaml + + + + + CodeIndexSearchWindowControl.xaml + + + + + + + True + True + CodeIndexSettings.settings + + + + + + + SettingsSingleFileGenerator + CodeIndexSettings.Designer.cs + + + Designer + + + + + + + + + + + + + + + + + + + + + + 5.2.7 + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + Menus.ctmenu + + + + + + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + + + + + \ No newline at end of file diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs new file mode 100644 index 0000000..53f4c7b --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndex.VisualStudioExtensionPackage.cs @@ -0,0 +1,56 @@ +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Microsoft.VisualStudio.Shell; +using Task = System.Threading.Tasks.Task; + +namespace CodeIndex.VisualStudioExtension +{ + /// + /// This is the class that implements the package exposed by this assembly. + /// + /// + /// + /// The minimum requirement for a class to be considered a valid package for Visual Studio + /// is to implement the IVsPackage interface and register itself with the shell. + /// This package uses the helper classes defined inside the Managed Package Framework (MPF) + /// to do it: it derives from the Package class that provides the implementation of the + /// IVsPackage interface and uses the registration attributes defined in the framework to + /// register itself and its components with the shell. These attributes tell the pkgdef creation + /// utility what data to put into .pkgdef file. + /// + /// + /// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ...> in .vsixmanifest file. + /// + /// + [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)] + [Guid(PackageGuidString)] + [ProvideMenuResource("Menus.ctmenu", 1)] + [ProvideToolWindow(typeof(CodeIndex.VisualStudioExtension.CodeIndexSearchWindow))] + public sealed class VisualStudioExtensionPackage : AsyncPackage + { + /// + /// CodeIndex.VisualStudioExtensionPackage GUID string. + /// + public const string PackageGuidString = "1eaddb39-c1f2-42e2-807d-234d73e8ef2a"; + + #region Package Members + + /// + /// Initialization of the package; this method is called right after the package is sited, so this is the place + /// where you can put all the initialization code that rely on services provided by VisualStudio. + /// + /// A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down. + /// 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) + { + // When initialized asynchronously, the current thread may be a background thread at this point. + // Do any initialization that requires the UI thread after switching to the UI thread. + await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + await CodeIndex.VisualStudioExtension.CodeIndexSearchWindowCommand.InitializeAsync(this); + } + + #endregion + } +} diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs new file mode 100644 index 0000000..edbd64d --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindow.cs @@ -0,0 +1,34 @@ +using System; +using System.Runtime.InteropServices; +using Microsoft.VisualStudio.Shell; + +namespace CodeIndex.VisualStudioExtension +{ + /// + /// This class implements the tool window exposed by this package and hosts a user control. + /// + /// + /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane, + /// usually implemented by the package implementer. + /// + /// This class derives from the ToolWindowPane class provided from the MPF in order to use its + /// implementation of the IVsUIElementPane interface. + /// + /// + [Guid("6d5fde57-9331-4f68-8c3e-2945d8049f40")] + public class CodeIndexSearchWindow : ToolWindowPane + { + /// + /// Initializes a new instance of the class. + /// + public CodeIndexSearchWindow() : base(null) + { + this.Caption = "Code Index Search"; + + // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable, + // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on + // the object returned by the Content property. + this.Content = new CodeIndexSearchWindowControl(); + } + } +} diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs new file mode 100644 index 0000000..9ddfb49 --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowCommand.cs @@ -0,0 +1,99 @@ +using System; +using System.ComponentModel.Design; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Task = System.Threading.Tasks.Task; + +namespace CodeIndex.VisualStudioExtension +{ + /// + /// Command handler + /// + internal sealed class CodeIndexSearchWindowCommand + { + /// + /// Command ID. + /// + public const int CommandId = 4129; + + /// + /// Command menu group (command set GUID). + /// + public static readonly Guid CommandSet = new Guid("c025b4ef-e6ed-42b4-9c22-2d6835421d25"); + + /// + /// 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 CodeIndexSearchWindowCommand(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); + } + + /// + /// Gets the instance of the command. + /// + public static CodeIndexSearchWindowCommand Instance + { + get; + private set; + } + + /// + /// 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) + { + // Switch to the main thread - the call to AddCommand in CodeIndexSearchWindowCommand's constructor requires + // the UI thread. + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken); + + OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService; + Instance = new CodeIndexSearchWindowCommand(package, commandService); + } + + /// + /// Shows the tool window when the menu item is clicked. + /// + /// The event sender. + /// The event args. + private void Execute(object sender, EventArgs e) + { + this.package.JoinableTaskFactory.RunAsync(async delegate + { + ToolWindowPane window = await this.package.ShowToolWindowAsync(typeof(CodeIndexSearchWindow), 0, true, this.package.DisposalToken); + if ((null == window) || (null == window.Frame)) + { + throw new NotSupportedException("Cannot create tool window"); + } + }); + } + } +} diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml new file mode 100644 index 0000000..2936f7f --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs new file mode 100644 index 0000000..01cc3f8 --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/CodeIndexSearchWindowControl.xaml.cs @@ -0,0 +1,20 @@ +using System.Windows.Controls; + +namespace CodeIndex.VisualStudioExtension +{ + /// + /// Interaction logic for CodeIndexSearchWindowControl. + /// + public partial class CodeIndexSearchWindowControl : UserControl + { + /// + /// Initializes a new instance of the class. + /// + public CodeIndexSearchWindowControl() + { + InitializeComponent(); + + SearchControl.DataContext = new CodeIndexSearchViewModel(); + } + } +} \ No newline at end of file diff --git a/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml new file mode 100644 index 0000000..d028be4 --- /dev/null +++ b/src/CodeIndex.VisualStudioExtension/Controls/CodeIndexSearchControl.xaml @@ -0,0 +1,137 @@ + + + + +