[PowerToys Run] Plugin manager (#9872)

This commit is contained in:
Mykhailo Pylyp
2021-02-26 13:21:58 +02:00
committed by GitHub
parent f839a408de
commit 4a9e920a1c
66 changed files with 749 additions and 276 deletions

View File

@@ -15,7 +15,7 @@ using Wox.Plugin;
namespace Microsoft.Plugin.Folder
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IContextMenu, IDisposable
public class Main : IPlugin, IPluginI18n, ISavable, IContextMenu, IDisposable
{
public const string FolderImagePath = "Images\\folder.dark.png";
public const string FileImagePath = "Images\\file.dark.png";
@@ -38,6 +38,10 @@ namespace Microsoft.Plugin.Folder
private IContextMenu _contextMenuLoader;
private bool _disposed;
public string Name => Properties.Resources.wox_plugin_folder_plugin_name;
public string Description => Properties.Resources.wox_plugin_folder_plugin_description;
public void Save()
{
_storage.Save();
@@ -119,10 +123,6 @@ namespace Microsoft.Plugin.Folder
return _contextMenuLoader.LoadContextMenus(selectedResult);
}
public void UpdateSettings(PowerLauncherSettings settings)
{
}
public void Dispose()
{
Dispose(disposing: true);

View File

@@ -124,7 +124,7 @@ namespace Microsoft.Plugin.Folder.Properties {
}
/// <summary>
/// Looks up a localized string similar to Open favorite folder from PowerToys Run directly.
/// Looks up a localized string similar to Navigates folders starting from a drive letter &apos;C:\&apos; or from the user home &apos;~&apos;..
/// </summary>
public static string wox_plugin_folder_plugin_description {
get {

View File

@@ -121,7 +121,7 @@
<value>Folder</value>
</data>
<data name="wox_plugin_folder_plugin_description" xml:space="preserve">
<value>Open favorite folder from PowerToys Run directly</value>
<value>Navigates folders starting from a drive letter 'C:\' or from the user home '~'.</value>
</data>
<data name="Microsoft_plugin_folder_copy_path" xml:space="preserve">
<value>Copy path (Ctrl+C)</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "",
"IsGlobal": true,
"Name": "Folder",
"Description": "Search and open folders",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -23,6 +23,7 @@ namespace Microsoft.Plugin.Indexer
{
internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin
{
private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);
private static readonly IFileSystem _fileSystem = new FileSystem();
// This variable contains metadata about the Plugin
@@ -46,6 +47,20 @@ namespace Microsoft.Plugin.Indexer
private string WarningIconPath { get; set; }
public string Name => Properties.Resources.Microsoft_plugin_indexer_plugin_name;
public string Description => Properties.Resources.Microsoft_plugin_indexer_plugin_description;
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()
{
new PluginAdditionalOption()
{
Key = DisableDriveDetectionWarning,
DisplayLabel = Properties.Resources.disable_drive_detection_warning,
Value = false,
},
};
private IContextMenu _contextMenuLoader;
private bool disposedValue;
@@ -210,9 +225,10 @@ namespace Microsoft.Plugin.Indexer
return _contextMenuLoader.LoadContextMenus(selectedResult);
}
public void UpdateSettings(PowerLauncherSettings settings)
public void UpdateSettings(PowerLauncherPluginSettings settings)
{
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = settings.Properties.DisableDriveDetectionWarning;
var option = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);
_driveDetection.IsDriveDetectionWarningCheckBoxSelected = option == null ? false : option.Value;
}
public Control CreateSettingPanel()

View File

@@ -60,6 +60,15 @@ namespace Microsoft.Plugin.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Disable drive detection warning.
/// </summary>
public static string disable_drive_detection_warning {
get {
return ResourceManager.GetString("disable_drive_detection_warning", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Fail to set text in clipboard.
/// </summary>
@@ -151,7 +160,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
}
/// <summary>
/// Looks up a localized string similar to Returns files and folders.
/// Looks up a localized string similar to Searches files and folders..
/// </summary>
public static string Microsoft_plugin_indexer_plugin_description {
get {
@@ -160,7 +169,7 @@ namespace Microsoft.Plugin.Indexer.Properties {
}
/// <summary>
/// Looks up a localized string similar to Windows Indexer.
/// Looks up a localized string similar to Windows Search.
/// </summary>
public static string Microsoft_plugin_indexer_plugin_name {
get {

View File

@@ -151,12 +151,15 @@
<value>Fail to open folder at</value>
</data>
<data name="Microsoft_plugin_indexer_plugin_description" xml:space="preserve">
<value>Returns files and folders</value>
<value>Searches files and folders.</value>
</data>
<data name="Microsoft_plugin_indexer_plugin_name" xml:space="preserve">
<value>Windows Indexer</value>
<value>Windows Search</value>
</data>
<data name="Microsoft_plugin_indexer_subtitle_header" xml:space="preserve">
<value>Search</value>
</data>
<data name="disable_drive_detection_warning" xml:space="preserve">
<value>Disable drive detection warning</value>
</data>
</root>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "?",
"IsGlobal": true,
"Name": "Windows Indexer",
"Description": "Search for files and folders",
"Author": "Microsoft",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -32,10 +32,7 @@ namespace Microsoft.Plugin.Program.UnitTests.ProgramArgumentParser
new NoArgumentsArgumentParser(),
};
// basic version of the Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but did not want to create a project reference
var splittedSearchString = inputQuery?.Split(Query.TermSeparator, System.StringSplitOptions.RemoveEmptyEntries);
var cleanQuery = string.Join(Query.TermSeparator, splittedSearchString);
var query = new Query(cleanQuery, cleanQuery, new ReadOnlyCollection<string>(splittedSearchString), string.Empty);
var query = new Query(inputQuery);
// Act
string program = null, programArguments = null;

View File

@@ -32,6 +32,10 @@ namespace Microsoft.Plugin.Program
internal static ProgramPluginSettings Settings { get; set; }
public string Name => Properties.Resources.wox_plugin_program_plugin_name;
public string Description => Properties.Resources.wox_plugin_program_plugin_description;
private static PluginInitContext _context;
private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;
private bool _disposed;

View File

@@ -178,7 +178,7 @@ namespace Microsoft.Plugin.Program.Properties {
}
/// <summary>
/// Looks up a localized string similar to Search programs in PowerToys Run.
/// Looks up a localized string similar to Searches programs..
/// </summary>
public static string wox_plugin_program_plugin_description {
get {

View File

@@ -130,7 +130,7 @@
<value>Program</value>
</data>
<data name="wox_plugin_program_plugin_description" xml:space="preserve">
<value>Search programs in PowerToys Run</value>
<value>Searches programs.</value>
</data>
<data name="powertoys_run_plugin_program_win32_application" xml:space="preserve">
<value>Application</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": ".",
"IsGlobal": true,
"Name": "Program",
"Description": "Search for programs",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -22,7 +22,7 @@ using Control = System.Windows.Controls.Control;
namespace Microsoft.Plugin.Shell
{
public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavable
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable
{
private static readonly IFileSystem FileSystem = new FileSystem();
private static readonly IPath Path = FileSystem.Path;
@@ -34,6 +34,10 @@ namespace Microsoft.Plugin.Shell
private string IconPath { get; set; }
public string Name => Properties.Resources.wox_plugin_cmd_plugin_name;
public string Description => Properties.Resources.wox_plugin_cmd_plugin_description;
private PluginInitContext _context;
public Main()
@@ -331,9 +335,5 @@ namespace Microsoft.Plugin.Shell
return resultlist;
}
public void UpdateSettings(PowerLauncherSettings settings)
{
}
}
}

View File

@@ -97,7 +97,7 @@ namespace Microsoft.Plugin.Shell.Properties {
}
/// <summary>
/// Looks up a localized string similar to Allows to execute system commands from PowerToys Run. Commands should start with &gt;.
/// Looks up a localized string similar to Executes commands (e.g &apos;ping&apos;, &apos;cmd&apos;)..
/// </summary>
public static string wox_plugin_cmd_plugin_description {
get {

View File

@@ -121,7 +121,7 @@
<value>Shell</value>
</data>
<data name="wox_plugin_cmd_plugin_description" xml:space="preserve">
<value>Allows to execute system commands from PowerToys Run. Commands should start with &gt;</value>
<value>Executes commands (e.g 'ping', 'cmd').</value>
</data>
<data name="wox_plugin_cmd_cmd_has_been_executed_times" xml:space="preserve">
<value>this command has been executed {0} times</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": ">",
"IsGlobal": false,
"Name": "Shell",
"Description": "Provide executing commands. Commands should start with >",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -43,6 +43,10 @@ namespace Microsoft.Plugin.Uri
public PluginInitContext Context { get; protected set; }
public string Name => Properties.Resources.Microsoft_plugin_uri_plugin_name;
public string Description => Properties.Resources.Microsoft_plugin_uri_plugin_description;
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return new List<ContextMenuResult>(0);

View File

@@ -70,7 +70,7 @@ namespace Microsoft.Plugin.Uri.Properties {
}
/// <summary>
/// Looks up a localized string similar to Handles urls.
/// Looks up a localized string similar to Opens URLs and UNC network shares..
/// </summary>
public static string Microsoft_plugin_uri_plugin_description {
get {
@@ -79,7 +79,7 @@ namespace Microsoft.Plugin.Uri.Properties {
}
/// <summary>
/// Looks up a localized string similar to Url Handler.
/// Looks up a localized string similar to URI Handler.
/// </summary>
public static string Microsoft_plugin_uri_plugin_name {
get {

View File

@@ -121,10 +121,10 @@
<value>Failed to open URL</value>
</data>
<data name="Microsoft_plugin_uri_plugin_description" xml:space="preserve">
<value>Handles urls</value>
<value>Opens URLs and UNC network shares.</value>
</data>
<data name="Microsoft_plugin_uri_plugin_name" xml:space="preserve">
<value>Url Handler</value>
<value>URI Handler</value>
</data>
<data name="Microsoft_plugin_uri_website" xml:space="preserve">
<value>Open in browser</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "//",
"IsGlobal": true,
"Name": "Windows Uri Handler",
"Description": "Handles urls",
"Author": "Microsoft",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -19,6 +19,10 @@ namespace Microsoft.Plugin.WindowWalker
private PluginInitContext Context { get; set; }
public string Name => Properties.Resources.wox_plugin_windowwalker_plugin_name;
public string Description => Properties.Resources.wox_plugin_windowwalker_plugin_description;
static Main()
{
SearchController.Instance.OnSearchResultUpdateEventHandler += SearchResultUpdated;

View File

@@ -61,7 +61,7 @@ namespace Microsoft.Plugin.WindowWalker.Properties {
}
/// <summary>
/// Looks up a localized string similar to Alt-Tab alternative enabling searching through your windows..
/// Looks up a localized string similar to Switches between open windows..
/// </summary>
public static string wox_plugin_windowwalker_plugin_description {
get {

View File

@@ -121,7 +121,7 @@
<value>Window Walker</value>
</data>
<data name="wox_plugin_windowwalker_plugin_description" xml:space="preserve">
<value>Alt-Tab alternative enabling searching through your windows.</value>
<value>Switches between open windows.</value>
</data>
<data name="wox_plugin_windowwalker_running" xml:space="preserve">
<value>Running</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "<",
"IsGlobal": true,
"Name": "Window Walker",
"Description": "Alt-Tab alternative enabling searching through your windows.",
"Author": "betadele",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -19,6 +19,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator
private string IconPath { get; set; }
public string Name => Properties.Resources.wox_plugin_calculator_plugin_name;
public string Description => Properties.Resources.wox_plugin_calculator_plugin_description;
private bool _disposed;
public List<Result> Query(Query query)

View File

@@ -9,6 +9,9 @@
//------------------------------------------------------------------------------
namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@@ -20,15 +23,15 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
@@ -42,7 +45,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
@@ -56,7 +59,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Copy failed, please try later.
/// </summary>
@@ -65,7 +68,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_copy_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy this number to the clipboard.
/// </summary>
@@ -74,7 +77,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_copy_number_to_clipboard", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Expression wrong or incomplete (Did you forget some parentheses?).
/// </summary>
@@ -83,7 +86,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_expression_not_complete", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Not a number (NaN).
/// </summary>
@@ -92,16 +95,16 @@ namespace Microsoft.PowerToys.Run.Plugin.Calculator.Properties {
return ResourceManager.GetString("wox_plugin_calculator_not_a_number", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Allows you to do mathematical calculations. (Try 5*3-2 in PowerToys Run).
/// Looks up a localized string similar to Does mathematical calculations (e.g. 5*3-2)..
/// </summary>
public static string wox_plugin_calculator_plugin_description {
get {
return ResourceManager.GetString("wox_plugin_calculator_plugin_description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Calculator.
/// </summary>

View File

@@ -121,7 +121,7 @@
<value>Calculator</value>
</data>
<data name="wox_plugin_calculator_plugin_description" xml:space="preserve">
<value>Allows you to do mathematical calculations. (Try 5*3-2 in PowerToys Run)</value>
<value>Does mathematical calculations (e.g. 5*3-2).</value>
</data>
<data name="wox_plugin_calculator_not_a_number" xml:space="preserve">
<value>Not a number (NaN)</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "=",
"IsGlobal": true,
"Name": "Calculator",
"Description": "Provide mathematical calculations.(Try 5*3-2 in PowerToys)",
"Author": "cxfksword",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -42,6 +42,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry
/// </summary>
private bool _disposed;
public string Name => Resources.PluginTitle;
public string Description => Resources.PluginDescription;
/// <summary>
/// Initializes a new instance of the <see cref="Main"/> class.
/// </summary>

View File

@@ -133,7 +133,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Registry.Properties {
}
/// <summary>
/// Looks up a localized string similar to Search inside the Windows Registry.
/// Looks up a localized string similar to Navigates inside the Windows Registry..
/// </summary>
internal static string PluginDescription {
get {

View File

@@ -121,7 +121,7 @@
<value>Registry Plugin</value>
</data>
<data name="PluginDescription" xml:space="preserve">
<value>Search inside the Windows Registry</value>
<value>Navigates inside the Windows Registry.</value>
<comment>"this built into Windows the OS. translate accordingly, https://docs.microsoft.com/de-de/troubleshoot/windows-server/performance/windows-registry-advanced-users is an example of it translated in German"</comment>
</data>
<data name="CopyKeyNamePath" xml:space="preserve">

View File

@@ -3,7 +3,6 @@
"ActionKeyword": ":",
"IsGlobal": false,
"Name": "Registry",
"Description": "Search inside the Windows Registry",
"Author": "TobiasSekan",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -19,6 +19,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Service
private PluginInitContext _context;
private string _icoPath;
public string Name => Resources.wox_plugin_service_plugin_name;
public string Description => Resources.wox_plugin_service_plugin_description;
public void Init(PluginInitContext context)
{
_context = context;

View File

@@ -97,7 +97,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties {
}
/// <summary>
/// Looks up a localized string similar to Manages Windows services.
/// Looks up a localized string similar to Manages Windows services..
/// </summary>
internal static string wox_plugin_service_plugin_description {
get {

View File

@@ -130,7 +130,7 @@
<value>Pausing</value>
</data>
<data name="wox_plugin_service_plugin_description" xml:space="preserve">
<value>Manages Windows services</value>
<value>Manages Windows services.</value>
</data>
<data name="wox_plugin_service_plugin_name" xml:space="preserve">
<value>Service</value>

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "!",
"IsGlobal": false,
"Name": "Service",
"Description": "Manages Windows services",
"Author": "davidegiacometti",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -32,8 +32,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
// Setup
Mock<Main> main = new Mock<Main>();
main.Object.IconTheme = "dark";
string[] terms = { typedString };
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
Query expectedQuery = new Query(typedString);
// Act
var result = main.Object.Query(expectedQuery).FirstOrDefault().IcoPath;
@@ -54,8 +53,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
// Setup
Mock<Main> main = new Mock<Main>();
main.Object.IconTheme = "light";
string[] terms = { typedString };
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
Query expectedQuery = new Query(typedString);
// Act
var result = main.Object.Query(expectedQuery).FirstOrDefault().IcoPath;

View File

@@ -30,8 +30,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.UnitTests
{
// Setup
Mock<Main> main = new Mock<Main>();
string[] terms = { typedString };
Query expectedQuery = new Query(typedString, typedString, new ReadOnlyCollection<string>(terms), string.Empty);
Query expectedQuery = new Query(typedString);
// Act
var result = main.Object.Query(expectedQuery).FirstOrDefault().SubTitle;

View File

@@ -26,6 +26,10 @@ namespace Microsoft.PowerToys.Run.Plugin.System
public string IconTheme { get; set; }
public string Name => Properties.Resources.Microsoft_plugin_sys_plugin_name;
public string Description => Properties.Resources.Microsoft_plugin_sys_plugin_description;
public void Init(PluginInitContext context)
{
this._context = context;

View File

@@ -115,7 +115,7 @@ namespace Microsoft.PowerToys.Run.Plugin.System.Properties {
}
/// <summary>
/// Looks up a localized string similar to Provides Windows related commands, shutdown, lock, sleep .....
/// Looks up a localized string similar to Executes system commands (e.g. &apos;shutdown&apos;, &apos;lock&apos;, &apos;sleep&apos;)..
/// </summary>
internal static string Microsoft_plugin_sys_plugin_description {
get {

View File

@@ -142,7 +142,7 @@
<comment>This should align to the action in Windows of a locking your computer.</comment>
</data>
<data name="Microsoft_plugin_sys_plugin_description" xml:space="preserve">
<value>Provides Windows related commands, shutdown, lock, sleep ....</value>
<value>Executes system commands (e.g. 'shutdown', 'lock', 'sleep').</value>
<comment>This should align to the actions in Windows relating to shutting down, signing out, locking, sleeping, restarting, emptying the recycle bin, and hibernating your computer. </comment>
</data>
<data name="Microsoft_plugin_sys_plugin_name" xml:space="preserve">

View File

@@ -3,7 +3,6 @@
"ActionKeyword": "",
"IsGlobal": true,
"Name": "System Commands",
"Description": "Provide System related commands. e.g. shutdown,lock,setting etc.",
"Author": "Wox",
"Version": "1.0.0",
"Language": "csharp",

View File

@@ -12,7 +12,6 @@ using System.Reflection;
using System.Threading.Tasks;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.UserSettings;
using Wox.Plugin;
using Wox.Plugin.Logger;
@@ -62,15 +61,11 @@ namespace PowerLauncher.Plugin
}
}
public static Dictionary<string, PluginPair> NonGlobalPlugins
public static IEnumerable<PluginPair> NonGlobalPlugins
{
get
{
return AllPlugins
.Where(x => !string.IsNullOrWhiteSpace(x.Metadata.ActionKeyword))
.GroupBy(x => x.Metadata.ActionKeyword)
.Select(x => x.First())
.ToDictionary(x => x.Metadata.ActionKeyword);
return AllPlugins.Where(x => !string.IsNullOrWhiteSpace(x.Metadata.ActionKeyword));
}
}

View File

@@ -4,66 +4,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Collections.Generic;
using Wox.Plugin;
namespace PowerLauncher.Plugin
{
public static class QueryBuilder
{
public static Dictionary<PluginPair, Query> Build(ref string text)
public static Dictionary<PluginPair, Query> Build(string text)
{
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
// replace multiple white spaces with one white space
var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
if (terms.Length == 0)
{ // nothing was typed
return null;
}
text = text.Trim();
// This Dictionary contains the corresponding query for each plugin
Dictionary<PluginPair, Query> pluginQueryPair = new Dictionary<PluginPair, Query>();
var rawQuery = string.Join(Query.TermSeparator, terms);
// This is the query on removing extra spaces which would be executed by global Plugins
text = rawQuery;
string possibleActionKeyword = terms[0];
foreach (string pluginActionKeyword in PluginManager.NonGlobalPlugins.Keys)
foreach (var plugin in PluginManager.NonGlobalPlugins)
{
// Using Ordinal since this is used internally
if (possibleActionKeyword.StartsWith(pluginActionKeyword, StringComparison.Ordinal))
var pluginActionKeyword = plugin.Metadata.ActionKeyword;
if (plugin.Metadata.Disabled || !text.StartsWith(pluginActionKeyword, StringComparison.Ordinal))
{
if (PluginManager.NonGlobalPlugins.TryGetValue(pluginActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
{
// The search string is the raw query excluding the action keyword
string search = rawQuery.Substring(pluginActionKeyword.Length).Trim();
// To set the terms of the query after removing the action keyword
if (possibleActionKeyword.Length > pluginActionKeyword.Length)
{
// If the first term contains the action keyword, then set the remaining string to be the first term
terms[0] = possibleActionKeyword.Substring(pluginActionKeyword.Length);
}
else
{
// If the first term is the action keyword, then skip it.
terms = terms.Skip(1).ToArray();
}
// A new query is constructed for each plugin as they have different action keywords
var query = new Query(rawQuery, search, new ReadOnlyCollection<string>(terms), pluginActionKeyword);
pluginQueryPair.TryAdd(pluginPair, query);
}
continue;
}
// A new query is constructed for each plugin
var query = new Query(text, pluginActionKeyword);
pluginQueryPair.TryAdd(plugin, query);
}
// If the user has specified a matching action keyword, then do not
@@ -72,9 +40,9 @@ namespace PowerLauncher.Plugin
{
foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins)
{
if (!pluginQueryPair.ContainsKey(globalPlugin))
if (!globalPlugin.Metadata.Disabled && !pluginQueryPair.ContainsKey(globalPlugin))
{
var query = new Query(rawQuery, rawQuery, new ReadOnlyCollection<string>(terms), string.Empty);
var query = new Query(text);
pluginQueryPair.Add(globalPlugin, query);
}
}

View File

@@ -56,7 +56,7 @@ namespace PowerLauncher
Log.Info("PT Run settings.json was missing, creating a new one", GetType());
var defaultSettings = new PowerLauncherSettings();
defaultSettings.Plugins = GetPluginsSettings();
defaultSettings.Plugins = GetDefaultPluginsSettings();
defaultSettings.Save(_settingsUtils);
}
}
@@ -78,7 +78,7 @@ namespace PowerLauncher
if (overloadSettings.Plugins == null || !overloadSettings.Plugins.Any())
{
// Needed to be consistent with old settings
overloadSettings.Plugins = GetPluginsSettings();
overloadSettings.Plugins = GetDefaultPluginsSettings();
_settingsUtils.SaveSettings(overloadSettings.ToJsonString(), PowerLauncherSettings.ModuleName);
}
else
@@ -91,6 +91,10 @@ namespace PowerLauncher
plugin.Metadata.Disabled = setting.Disabled;
plugin.Metadata.ActionKeyword = setting.ActionKeyword;
plugin.Metadata.IsGlobal = setting.IsGlobal;
if (plugin.Plugin is ISettingProvider)
{
(plugin.Plugin as ISettingProvider).UpdateSettings(setting);
}
}
}
}
@@ -101,13 +105,6 @@ namespace PowerLauncher
_settings.Hotkey = openPowerlauncher;
}
var shell = PluginManager.AllPlugins.Find(pp => pp.Metadata.Name == "Shell");
if (shell != null)
{
var shellSettings = shell.Plugin as ISettingProvider;
shellSettings.UpdateSettings(overloadSettings);
}
if (_settings.MaxResultsToShow != overloadSettings.Properties.MaximumNumberOfResults)
{
_settings.MaxResultsToShow = overloadSettings.Properties.MaximumNumberOfResults;
@@ -118,14 +115,6 @@ namespace PowerLauncher
_settings.IgnoreHotkeysOnFullscreen = overloadSettings.Properties.IgnoreHotkeysInFullscreen;
}
// Using OrdinalIgnoreCase since this is internal
var indexer = PluginManager.AllPlugins.Find(p => p.Metadata.Name.Equals("Windows Indexer", StringComparison.OrdinalIgnoreCase));
if (indexer != null)
{
var indexerSettings = indexer.Plugin as ISettingProvider;
indexerSettings.UpdateSettings(overloadSettings);
}
if (_settings.ClearInputOnLaunch != overloadSettings.Properties.ClearInputOnLaunch)
{
_settings.ClearInputOnLaunch = overloadSettings.Properties.ClearInputOnLaunch;
@@ -184,19 +173,20 @@ namespace PowerLauncher
return model.ToString();
}
private static IEnumerable<PowerLauncherPluginSettings> GetPluginsSettings()
private static IEnumerable<PowerLauncherPluginSettings> GetDefaultPluginsSettings()
{
return PluginManager.AllPlugins.Select(x => x.Metadata).Select(x => new PowerLauncherPluginSettings
return PluginManager.AllPlugins.Select(x => new PowerLauncherPluginSettings()
{
Id = x.ID,
Name = x.Name,
Description = x.Description,
Author = x.Author,
Disabled = x.Disabled,
IsGlobal = x.IsGlobal,
ActionKeyword = x.ActionKeyword,
IconPathDark = x.IcoPathDark,
IconPathLight = x.IcoPathLight,
Id = x.Metadata.ID,
Name = x.Plugin.Name,
Description = x.Plugin.Description,
Author = x.Metadata.Author,
Disabled = x.Metadata.Disabled,
IsGlobal = x.Metadata.IsGlobal,
ActionKeyword = x.Metadata.ActionKeyword,
IconPathDark = x.Metadata.IcoPathDark,
IconPathLight = x.Metadata.IcoPathLight,
AdditionalOptions = x.Plugin is ISettingProvider ? (x.Plugin as ISettingProvider).AdditionalOptions : new List<PluginAdditionalOption>(),
});
}
}

View File

@@ -493,7 +493,7 @@ namespace PowerLauncher.ViewModel
Title = string.Format(CultureInfo.InvariantCulture, title, h.Query),
SubTitle = string.Format(CultureInfo.InvariantCulture, time, h.ExecutedDateTime),
IcoPath = "Images\\history.png",
OriginQuery = new Query { RawQuery = h.Query },
OriginQuery = new Query(h.Query),
Action = _ =>
{
SelectedResults = Results;
@@ -531,9 +531,10 @@ namespace PowerLauncher.ViewModel
_updateToken = currentCancellationToken;
var queryText = QueryText.Trim();
var pluginQueryPairs = QueryBuilder.Build(ref queryText);
var pluginQueryPairs = QueryBuilder.Build(queryText);
if (pluginQueryPairs != null && pluginQueryPairs.Count > 0)
{
queryText = pluginQueryPairs.Values.First().RawQuery;
_currentQuery = queryText;
Task.Run(
() =>
@@ -557,13 +558,9 @@ namespace PowerLauncher.ViewModel
{
var plugin = pluginQueryItem.Key;
var query = pluginQueryItem.Value;
if (!plugin.Metadata.Disabled)
{
var results = PluginManager.QueryForPlugin(plugin, query);
resultPluginPair.Add((results, plugin.Metadata));
currentCancellationToken.ThrowIfCancellationRequested();
}
var results = PluginManager.QueryForPlugin(plugin, query);
resultPluginPair.Add((results, plugin.Metadata));
currentCancellationToken.ThrowIfCancellationRequested();
}
lock (_addResultsLock)
@@ -595,39 +592,36 @@ namespace PowerLauncher.ViewModel
{
try
{
if (!plugin.Metadata.Disabled)
Query query;
pluginQueryPairs.TryGetValue(plugin, out query);
var results = PluginManager.QueryForPlugin(plugin, query, true);
currentCancellationToken.ThrowIfCancellationRequested();
if ((results?.Count ?? 0) != 0)
{
Query query;
pluginQueryPairs.TryGetValue(plugin, out query);
var results = PluginManager.QueryForPlugin(plugin, query, true);
currentCancellationToken.ThrowIfCancellationRequested();
if ((results?.Count ?? 0) != 0)
lock (_addResultsLock)
{
lock (_addResultsLock)
// Using CurrentCultureIgnoreCase since this is user facing
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
// Using CurrentCultureIgnoreCase since this is user facing
if (queryText.Equals(_currentQuery, StringComparison.CurrentCultureIgnoreCase))
{
currentCancellationToken.ThrowIfCancellationRequested();
currentCancellationToken.ThrowIfCancellationRequested();
// Remove the original results from the plugin
Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID);
currentCancellationToken.ThrowIfCancellationRequested();
// Remove the original results from the plugin
Results.Results.RemoveAll(r => r.Result.PluginID == plugin.Metadata.ID);
currentCancellationToken.ThrowIfCancellationRequested();
// Add the new results from the plugin
UpdateResultView(results, queryText, currentCancellationToken);
// Add the new results from the plugin
UpdateResultView(results, queryText, currentCancellationToken);
currentCancellationToken.ThrowIfCancellationRequested();
numResults = Results.Results.Count;
Results.Sort();
Results.SelectedItem = Results.Results.FirstOrDefault();
}
currentCancellationToken.ThrowIfCancellationRequested();
numResults = Results.Results.Count;
Results.Sort();
Results.SelectedItem = Results.Results.FirstOrDefault();
}
currentCancellationToken.ThrowIfCancellationRequested();
UpdateResultsListViewAfterQuery(queryText, true);
}
currentCancellationToken.ThrowIfCancellationRequested();
UpdateResultsListViewAfterQuery(queryText, true);
}
}
catch (OperationCanceledException)
@@ -875,9 +869,8 @@ namespace PowerLauncher.ViewModel
Results.Clear();
MainWindowVisibility = System.Windows.Visibility.Collapsed;
// Fix Cold start for plugins
string s = "m";
var pluginQueryPairs = QueryBuilder.Build(ref s);
// Fix Cold start for plugins, "m" is just a random string needed to query results
var pluginQueryPairs = QueryBuilder.Build("m");
// To execute a query corresponding to each plugin
foreach (KeyValuePair<PluginPair, Query> pluginQueryItem in pluginQueryPairs)

View File

@@ -11,5 +11,11 @@ namespace Wox.Plugin
List<Result> Query(Query query);
void Init(PluginInitContext context);
// Localized name
string Name { get; }
// Localized description
string Description { get; }
}
}

View File

@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Windows.Controls;
using Microsoft.PowerToys.Settings.UI.Library;
@@ -11,6 +12,8 @@ namespace Wox.Plugin
{
Control CreateSettingPanel();
void UpdateSettings(PowerLauncherSettings settings);
void UpdateSettings(PowerLauncherPluginSettings settings);
IEnumerable<PluginAdditionalOption> AdditionalOptions { get; }
}
}

View File

@@ -32,8 +32,6 @@ namespace Wox.Plugin
public string Language { get; set; }
public string Description { get; set; }
public string Website { get; set; }
public bool Disabled { get; set; }

View File

@@ -19,19 +19,32 @@ namespace Wox.Plugin
/// Initializes a new instance of the <see cref="Query"/> class.
/// to allow unit tests for plug ins
/// </summary>
public Query(string rawQuery, string search, ReadOnlyCollection<string> terms, string actionKeyword = "")
public Query(string query, string actionKeyword = "")
{
Search = search;
RawQuery = rawQuery;
Terms = terms;
_query = query;
ActionKeyword = actionKeyword;
}
private string _rawQuery;
/// <summary>
/// Gets raw query, this includes action keyword if it has
/// We didn't recommend use this property directly. You should always use Search property.
/// </summary>
public string RawQuery { get; internal set; }
public string RawQuery
{
get
{
if (_rawQuery == null)
{
_rawQuery = string.Join(Query.TermSeparator, _query.Split(new[] { TermSeparator }, StringSplitOptions.RemoveEmptyEntries));
}
return _rawQuery;
}
}
private string _search;
/// <summary>
/// Gets search part of a query.
@@ -39,12 +52,41 @@ namespace Wox.Plugin
/// Since we allow user to switch a exclusive plugin to generic plugin,
/// so this property will always give you the "real" query part of the query
/// </summary>
public string Search { get; internal set; }
public string Search
{
get
{
if (_search == null)
{
_search = RawQuery.Substring(ActionKeyword.Length).Trim();
}
return _search;
}
}
private ReadOnlyCollection<string> _terms;
/// <summary>
/// Gets the raw query splited into a string array.
/// </summary>
public ReadOnlyCollection<string> Terms { get; private set; }
public ReadOnlyCollection<string> Terms
{
get
{
if (_terms == null)
{
var terms = _query
.Trim()
.Substring(ActionKeyword.Length)
.Split(new[] { TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
_terms = new ReadOnlyCollection<string>(terms);
}
return _terms;
}
}
/// <summary>
/// Query can be splited into multiple terms by whitespace
@@ -102,6 +144,8 @@ namespace Wox.Plugin
}
}
private string _query;
public override string ToString() => RawQuery;
[Obsolete("Use Search instead, this method will be removed in v1.3.0")]

View File

@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Collections.Generic;
using NUnit.Framework;
using PowerLauncher.Plugin;
@@ -36,25 +37,8 @@ namespace Wox.Test
string searchQuery = "> file.txt file2 file3";
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
// Assert
Assert.AreEqual("> file.txt file2 file3", searchQuery);
}
[Test]
public void QueryBuilderShouldRemoveExtraSpacesForDisabledNonGlobalPlugin()
{
// Arrange
PluginManager.SetAllPlugins(new List<PluginPair>()
{
new PluginPair { Metadata = new PluginMetadata() { Disabled = true, ActionKeyword = ">" } },
});
string searchQuery = "> file.txt file2 file3";
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
searchQuery = pluginQueryPairs.Values.First().RawQuery;
// Assert
Assert.AreEqual("> file.txt file2 file3", searchQuery);
@@ -65,9 +49,14 @@ namespace Wox.Test
{
// Arrange
string searchQuery = "file.txt file2 file3";
PluginManager.SetAllPlugins(new List<PluginPair>()
{
new PluginPair { Metadata = new PluginMetadata() { Disabled = false, IsGlobal = true } },
});
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
searchQuery = pluginQueryPairs.Values.First().RawQuery;
// Assert
Assert.AreEqual("file.txt file2 file3", searchQuery);
@@ -87,10 +76,10 @@ namespace Wox.Test
var secondQueryText = "a search";
// Act
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText);
var firstPluginQueryPair = QueryBuilder.Build(firstQueryText);
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText);
var secondPluginQueryPairs = QueryBuilder.Build(secondQueryText);
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
// Assert
@@ -113,14 +102,14 @@ namespace Wox.Test
});
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
// Assert
Assert.IsTrue(AreEqual(firstQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(firstPlugin.Metadata.ActionKeyword.Length), ActionKeyword = firstPlugin.Metadata.ActionKeyword } ));
Assert.IsTrue(AreEqual(secondQuery, new Query { RawQuery = searchQuery, Search = searchQuery.Substring(secondPlugin.Metadata.ActionKeyword.Length), ActionKeyword = secondPlugin.Metadata.ActionKeyword }));
Assert.IsTrue(AreEqual(firstQuery, new Query(searchQuery, firstPlugin.Metadata.ActionKeyword)));
Assert.IsTrue(AreEqual(secondQuery, new Query(searchQuery, secondPlugin.Metadata.ActionKeyword)));
}
[Test]
@@ -137,7 +126,7 @@ namespace Wox.Test
});
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
@@ -147,5 +136,25 @@ namespace Wox.Test
Assert.IsTrue(firstQuery.Terms[0].Equals("cd", StringComparison.Ordinal) && firstQuery.Terms[1].Equals("efgh", StringComparison.Ordinal) && firstQuery.Terms.Count == 2);
Assert.IsTrue(secondQuery.Terms[0].Equals("efgh", StringComparison.Ordinal) && secondQuery.Terms.Count == 1);
}
[Test]
public void QueryBuilderShouldReturnAllPluginsWithTheActionWord()
{
// Arrange
string searchQuery = "!efgh";
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "!", ID = "plugin1" } };
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "!", ID = "plugin2" } };
PluginManager.SetAllPlugins(new List<PluginPair>()
{
firstPlugin,
secondPlugin,
});
// Act
var pluginQueryPairs = QueryBuilder.Build(searchQuery);
// Assert
Assert.AreEqual(2, pluginQueryPairs.Count);
}
}
}