tweak plugin settings (#9522)

This commit is contained in:
Mykhailo Pylyp
2021-02-10 15:12:42 +02:00
committed by GitHub
parent ec6b9acad9
commit d92ff6d45d
24 changed files with 240 additions and 398 deletions

View File

@@ -1,12 +1,14 @@
{
"ID":"B4D3B69656E14D44865C8D818EAE47C4",
"ActionKeyword": "*",
"Name":"Folder",
"Description":"Searcn and open folders",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://aka.ms/powertoys",
"ExecuteFileName":"Microsoft.Plugin.Folder.dll",
"IcoPath":"Images\\folder.dark.png"
"ID": "B4D3B69656E14D44865C8D818EAE47C4",
"ActionKeyword": "",
"IsGlobal": true,
"Name": "Folder",
"Description": "Search and open folders",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.Plugin.Folder.dll",
"IcoPathDark": "Images\\folder.dark.png",
"IcoPathLight": "Images\\folder.light.png"
}

View File

@@ -1,6 +1,7 @@
{
"ID": "2140FC9819AD43A3A616E2735815C27C",
"ActionKeywords": [ "*", "?" ],
"ActionKeyword": "?",
"IsGlobal": true,
"Name": "Windows Indexer",
"Description": "Search for files and folders",
"Author": "Microsoft",
@@ -8,5 +9,6 @@
"Language": "csharp",
"Website": "https://aka.ms/PowerToys",
"ExecuteFileName": "Microsoft.Plugin.Indexer.dll",
"IcoPath": "Images\\indexer.dark.png"
"IcoPathDark": "Images\\indexer.dark.png",
"IcoPathLight": "Images\\indexer.light.png"
}

View File

@@ -1,12 +1,14 @@
{
"ID":"791FC278BA414111B8D1886DFE447410",
"ActionKeywords": [ "*", "."],
"Name":"Program",
"Description":"Search for programs",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://aka.ms/PowerToys",
"ExecuteFileName":"Microsoft.Plugin.Program.dll",
"IcoPath":"Images\\app.dark.png"
"ID": "791FC278BA414111B8D1886DFE447410",
"ActionKeyword": ".",
"IsGlobal": true,
"Name": "Program",
"Description": "Search for programs",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/PowerToys",
"ExecuteFileName": "Microsoft.Plugin.Program.dll",
"IcoPathDark": "Images\\app.dark.png",
"IcoPathLight": "Images\\app.light.png"
}

View File

@@ -1,12 +1,14 @@
{
"ID":"D409510CD0D2481F853690A07E6DC426",
"ActionKeyword":">",
"Name":"Shell",
"Description":"Provide executing commands. Commands should start with >",
"Author":"qianlifeng",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://aka.ms/powertoys",
"ExecuteFileName":"Microsoft.Plugin.Shell.dll",
"IcoPath":"Images\\shell.dark.png"
"ID": "D409510CD0D2481F853690A07E6DC426",
"ActionKeyword": ">",
"IsGlobal": false,
"Name": "Shell",
"Description": "Provide executing commands. Commands should start with >",
"Author": "qianlifeng",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.Plugin.Shell.dll",
"IcoPathDark": "Images\\shell.dark.png",
"IcoPathLight": "Images\\shell.light.png"
}

View File

@@ -1,6 +1,7 @@
{
"ID": "03276A39D4E9417C8FFD200B0EE5E871",
"ActionKeywords": [ "*", "//" ],
"ActionKeyword": "//",
"IsGlobal": true,
"Name": "Windows Uri Handler",
"Description": "Handles urls",
"Author": "Microsoft",
@@ -8,5 +9,6 @@
"Language": "csharp",
"Website": "http://aka.ms/PowerToys",
"ExecuteFileName": "Microsoft.Plugin.Uri.dll",
"IcoPath": "Images\\uri.dark.png"
"IcoPathDark": "Images\\uri.dark.png",
"IcoPathLight": "Images\\uri.light.png"
}

View File

@@ -1,12 +1,14 @@
{
"ID":"F737A9223560B3C6833B5FFB8CDF78E5",
"ActionKeywords": [ "*", "<"],
"Name":"Window Walker",
"Description":"Alt-Tab alternative enabling searching through your windows.",
"Author":"betadele",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://www.windowwalker.com/",
"ExecuteFileName":"Microsoft.Plugin.WindowWalker.dll",
"IcoPath":"Images\\windowwalker.dark.png"
"ID": "F737A9223560B3C6833B5FFB8CDF78E5",
"ActionKeyword": "<",
"IsGlobal": true,
"Name": "Window Walker",
"Description": "Alt-Tab alternative enabling searching through your windows.",
"Author": "betadele",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://www.windowwalker.com/",
"ExecuteFileName": "Microsoft.Plugin.WindowWalker.dll",
"IcoPathDark": "Images\\windowwalker.dark.png",
"IcoPathLight": "Images\\windowwalker.light.png"
}

View File

@@ -1,12 +1,14 @@
{
"ID":"CEA0FDFC6D3B4085823D60DC76F28855",
"ActionKeywords": [ "*", "=" ],
"Name":"Calculator",
"Description":"Provide mathematical calculations.(Try 5*3-2 in PowerToys)",
"Author":"cxfksword",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://aka.ms/powertoys",
"ExecuteFileName":"Microsoft.PowerToys.Run.Plugin.Calculator.dll",
"IcoPath":"Images\\calculator.dark.png"
"ID": "CEA0FDFC6D3B4085823D60DC76F28855",
"ActionKeyword": "=",
"IsGlobal": true,
"Name": "Calculator",
"Description": "Provide mathematical calculations.(Try 5*3-2 in PowerToys)",
"Author": "cxfksword",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.Calculator.dll",
"IcoPathDark": "Images\\calculator.dark.png",
"IcoPathLight": "Images\\calculator.light.png"
}

View File

@@ -1,6 +1,7 @@
{
"ID": "303417D927BF4C97BCFFC78A123BE0C8",
"ActionKeyword": ":",
"IsGlobal": false,
"Name": "Registry",
"Description": "Search inside the Windows Registry",
"Author": "TobiasSekan",
@@ -8,5 +9,6 @@
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.Registry.dll",
"IcoPath": "Images\\reg.dark.png"
"IcoPathDark": "Images\\reg.dark.png",
"IcoPathLight": "Images\\reg.light.png"
}

View File

@@ -1,6 +1,7 @@
{
"ID": "11A6C36E4E91439CA69F702CBD364EF7",
"ActionKeyword": "!",
"IsGlobal": false,
"Name": "Service",
"Description": "Manages Windows services",
"Author": "davidegiacometti",
@@ -8,5 +9,6 @@
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.Service.dll",
"IcoPath": "Images\\service.dark.png"
"IcoPathDark": "Images\\service.dark.png",
"IcoPathLight": "Images\\service.light.png"
}

View File

@@ -1,12 +1,14 @@
{
"ID":"CEA08895D2544B019B2E9C5009600DF4",
"ActionKeyword":"*",
"Name":"System Commands",
"Description":"Provide System related commands. e.g. shutdown,lock,setting etc.",
"Author":"Wox",
"Version":"1.0.0",
"Language":"csharp",
"Website":"https://aka.ms/powertoys",
"ExecuteFileName":"Microsoft.PowerToys.Run.Plugin.System.dll",
"IcoPath":"Images\\lock.png"
"ID": "CEA08895D2544B019B2E9C5009600DF4",
"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",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.System.dll",
"IcoPathDark": "Images\\lock.dark.png",
"IcoPathLight": "Images\\lock.light.png"
}

View File

@@ -100,7 +100,6 @@ namespace PowerLauncher
StringMatcher.Instance = _stringMatcher;
_stringMatcher.UserSettingSearchPrecision = _settings.QuerySearchPrecision;
PluginManager.LoadPlugins(_settings.PluginSettings);
_mainVM = new MainViewModel(_settings);
_mainWindow = new MainWindow(_settings, _mainVM);
API = new PublicAPIInstance(_settingsVM, _mainVM, _themeManager);

View File

@@ -81,12 +81,6 @@ namespace PowerLauncher.Plugin
{
metadata = JsonConvert.DeserializeObject<PluginMetadata>(File.ReadAllText(configPath));
metadata.PluginDirectory = pluginDirectory;
// for plugins which doesn't has ActionKeywords key
metadata.SetActionKeywords(metadata.GetActionKeywords() ?? new List<string> { metadata.ActionKeyword });
// for plugin still use old ActionKeyword
metadata.ActionKeyword = metadata.GetActionKeywords()?[0];
}
catch (Exception e)
{

View File

@@ -28,22 +28,54 @@ namespace PowerLauncher.Plugin
private static IEnumerable<PluginPair> _contextMenuPlugins = new List<PluginPair>();
private static List<PluginPair> _allPlugins;
// should be only used in tests
public static void SetAllPlugins(List<PluginPair> plugins)
{
_allPlugins = plugins;
}
/// <summary>
/// Gets directories that will hold Wox plugin directory
/// </summary>
public static List<PluginPair> AllPlugins { get; private set; } = new List<PluginPair>();
public static List<PluginPair> AllPlugins
{
get
{
if (_allPlugins == null)
{
_allPlugins = PluginsLoader.Plugins(PluginConfig.Parse(Directories));
}
return _allPlugins;
}
}
public static IPublicAPI API { get; private set; }
public static readonly List<PluginPair> GlobalPlugins = new List<PluginPair>();
public static readonly Dictionary<string, PluginPair> NonGlobalPlugins = new Dictionary<string, PluginPair>();
public static List<PluginPair> GlobalPlugins
{
get
{
return AllPlugins.Where(x => x.Metadata.IsGlobal).ToList();
}
}
public static Dictionary<string, 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);
}
}
private static readonly string[] Directories = { Constant.PreinstalledDirectory, Constant.PluginsDirectory };
// todo happlebao, this should not be public, the indicator function should be embedded
public static PluginSettings Settings { get; set; }
private static List<PluginMetadata> _metadatas;
private static void ValidateUserDirectory()
{
if (!Directory.Exists(Constant.PluginsDirectory))
@@ -75,19 +107,6 @@ namespace PowerLauncher.Plugin
ValidateUserDirectory();
}
/// <summary>
/// because InitializePlugins needs API, so LoadPlugins needs to be called first
/// todo happlebao The API should be removed
/// </summary>
/// <param name="settings">Plugin settings</param>
public static void LoadPlugins(PluginSettings settings)
{
_metadatas = PluginConfig.Parse(Directories);
Settings = settings ?? throw new ArgumentNullException(nameof(settings));
Settings.UpdatePluginSettings(_metadatas);
AllPlugins = PluginsLoader.Plugins(_metadatas);
}
/// <summary>
/// Call initialize for all plugins
/// </summary>
@@ -120,18 +139,6 @@ namespace PowerLauncher.Plugin
});
_contextMenuPlugins = GetPluginsForInterface<IContextMenu>();
foreach (var plugin in AllPlugins)
{
if (IsGlobalPlugin(plugin.Metadata))
{
GlobalPlugins.Add(plugin);
}
// Plugins may have multiple ActionKeywords, eg. WebSearch
plugin.Metadata.GetActionKeywords().Where(x => x != Query.GlobalPluginWildcardSign)
.ToList()
.ForEach(x => NonGlobalPlugins[x] = plugin);
}
if (failedPlugins.Any())
{
@@ -145,24 +152,6 @@ namespace PowerLauncher.Plugin
PluginInstaller.Install(path);
}
public static List<PluginPair> ValidPluginsForQuery(Query query)
{
if (query == null)
{
throw new ArgumentNullException(nameof(query));
}
if (NonGlobalPlugins.ContainsKey(query.ActionKeyword))
{
var plugin = NonGlobalPlugins[query.ActionKeyword];
return new List<PluginPair> { plugin };
}
else
{
return GlobalPlugins;
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Suppressing this to enable FxCop. We are logging the exception, and going forward general exceptions should not be caught")]
public static List<Result> QueryForPlugin(PluginPair pair, Query query, bool delayedExecution = false)
{
@@ -245,11 +234,6 @@ namespace PowerLauncher.Plugin
}
}
private static bool IsGlobalPlugin(PluginMetadata metadata)
{
return metadata.GetActionKeywords().Contains(Query.GlobalPluginWildcardSign);
}
/// <summary>
/// get specified plugin, return null if not found
/// </summary>
@@ -293,72 +277,6 @@ namespace PowerLauncher.Plugin
}
}
public static bool ActionKeywordRegistered(string actionKeyword)
{
if (actionKeyword != Query.GlobalPluginWildcardSign &&
NonGlobalPlugins.ContainsKey(actionKeyword))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// used to add action keyword for multiple action keyword plugin
/// e.g. web search
/// </summary>
public static void AddActionKeyword(string id, string newActionKeyword)
{
var plugin = GetPluginForId(id);
if (newActionKeyword == Query.GlobalPluginWildcardSign)
{
GlobalPlugins.Add(plugin);
}
else
{
NonGlobalPlugins[newActionKeyword] = plugin;
}
plugin.Metadata.GetActionKeywords().Add(newActionKeyword);
}
/// <summary>
/// used to add action keyword for multiple action keyword plugin
/// e.g. web search
/// </summary>
public static void RemoveActionKeyword(string id, string oldActionkeyword)
{
var plugin = GetPluginForId(id);
if (oldActionkeyword == Query.GlobalPluginWildcardSign
&& // Plugins may have multiple ActionKeywords that are global, eg. WebSearch
plugin.Metadata.GetActionKeywords()
.Where(x => x == Query.GlobalPluginWildcardSign)
.ToList()
.Count == 1)
{
GlobalPlugins.Remove(plugin);
}
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
{
NonGlobalPlugins.Remove(oldActionkeyword);
}
plugin.Metadata.GetActionKeywords().Remove(oldActionkeyword);
}
public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword)
{
if (oldActionKeyword != newActionKeyword)
{
AddActionKeyword(id, newActionKeyword);
RemoveActionKeyword(id, oldActionKeyword);
}
}
public static void Dispose()
{
foreach (var plugin in AllPlugins)

View File

@@ -12,18 +12,13 @@ namespace PowerLauncher.Plugin
{
public static class QueryBuilder
{
public static Dictionary<PluginPair, Query> Build(ref string text, Dictionary<string, PluginPair> nonGlobalPlugins)
public static Dictionary<PluginPair, Query> Build(ref string text)
{
if (text == null)
{
throw new ArgumentNullException(nameof(text));
}
if (nonGlobalPlugins == null)
{
throw new ArgumentNullException(nameof(nonGlobalPlugins));
}
// replace multiple white spaces with one white space
var terms = text.Split(new[] { Query.TermSeparator }, StringSplitOptions.RemoveEmptyEntries);
if (terms.Length == 0)
@@ -41,12 +36,12 @@ namespace PowerLauncher.Plugin
string possibleActionKeyword = terms[0];
foreach (string pluginActionKeyword in nonGlobalPlugins.Keys)
foreach (string pluginActionKeyword in PluginManager.NonGlobalPlugins.Keys)
{
// Using Ordinal since this is used internally
if (possibleActionKeyword.StartsWith(pluginActionKeyword, StringComparison.Ordinal))
{
if (nonGlobalPlugins.TryGetValue(pluginActionKeyword, out var pluginPair) && !pluginPair.Metadata.Disabled)
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();
@@ -75,8 +70,6 @@ namespace PowerLauncher.Plugin
// add the global plugins to the list.
if (pluginQueryPair.Count == 0)
{
var globalplugins = PluginManager.GlobalPlugins;
foreach (PluginPair globalPlugin in PluginManager.GlobalPlugins)
{
if (!pluginQueryPair.ContainsKey(globalPlugin))

View File

@@ -3,8 +3,10 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
using System.Threading;
using System.Windows.Input;
using Microsoft.PowerToys.Common.UI;
@@ -54,6 +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.Save(_settingsUtils);
}
}
@@ -72,6 +75,26 @@ namespace PowerLauncher
var overloadSettings = _settingsUtils.GetSettingsOrDefault<PowerLauncherSettings>(PowerLauncherSettings.ModuleName);
if (overloadSettings.Plugins == null || !overloadSettings.Plugins.Any())
{
// Needed to be consistent with old settings
overloadSettings.Plugins = GetPluginsSettings();
_settingsUtils.SaveSettings(overloadSettings.ToJsonString(), PowerLauncherSettings.ModuleName);
}
else
{
foreach (var setting in overloadSettings.Plugins)
{
var plugin = PluginManager.AllPlugins.FirstOrDefault(x => x.Metadata.ID == setting.Id);
if (plugin != null)
{
plugin.Metadata.Disabled = setting.Disabled;
plugin.Metadata.ActionKeyword = setting.ActionKeyword;
plugin.Metadata.IsGlobal = setting.IsGlobal;
}
}
}
var openPowerlauncher = ConvertHotkey(overloadSettings.Properties.OpenPowerLauncher);
if (_settings.Hotkey != openPowerlauncher)
{
@@ -160,5 +183,21 @@ namespace PowerLauncher
HotkeyModel model = new HotkeyModel(hotkey.Alt, hotkey.Shift, hotkey.Win, hotkey.Ctrl, key);
return model.ToString();
}
private static IEnumerable<PowerLauncherPluginSettings> GetPluginsSettings()
{
return PluginManager.AllPlugins.Select(x => x.Metadata).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,
});
}
}
}

View File

@@ -539,7 +539,7 @@ namespace PowerLauncher.ViewModel
_updateToken = currentCancellationToken;
var queryText = QueryText.Trim();
var pluginQueryPairs = QueryBuilder.Build(ref queryText, PluginManager.NonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref queryText);
if (pluginQueryPairs != null && pluginQueryPairs.Count > 0)
{
_currentQuery = queryText;
@@ -885,7 +885,7 @@ namespace PowerLauncher.ViewModel
// Fix Cold start for plugins
string s = "m";
var pluginQueryPairs = QueryBuilder.Build(ref s, PluginManager.NonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref s);
// To execute a query corresponding to each plugin
foreach (KeyValuePair<PluginPair, Query> pluginQueryItem in pluginQueryPairs)

View File

@@ -1,47 +0,0 @@
// Copyright (c) Microsoft Corporation
// 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;
using System.Collections.Generic;
using Wox.Plugin;
namespace Wox.Infrastructure.UserSettings
{
public class PluginSettings : BaseModel
{
public Dictionary<string, RunPlugin> Plugins { get; private set; } = new Dictionary<string, RunPlugin>();
public void UpdatePluginSettings(List<PluginMetadata> metadatas)
{
if (metadatas == null)
{
throw new ArgumentNullException(nameof(metadatas));
}
foreach (var metadata in metadatas)
{
if (Plugins.ContainsKey(metadata.ID))
{
var settings = Plugins[metadata.ID];
if (settings.GetActionKeywords()?.Count > 0)
{
metadata.SetActionKeywords(settings.GetActionKeywords());
metadata.ActionKeyword = settings.GetActionKeywords()[0];
}
metadata.Disabled = settings.Disabled;
}
else
{
Plugins[metadata.ID] = new RunPlugin(metadata.GetActionKeywords())
{
ID = metadata.ID,
Name = metadata.Name,
Disabled = metadata.Disabled,
};
}
}
}
}
}

View File

@@ -135,10 +135,6 @@ namespace Wox.Infrastructure.UserSettings
}
}
// Order defaults to 0 or -1, so 1 will let this property appear last
[JsonProperty(Order = 1)]
public PluginSettings PluginSettings { get; set; } = new PluginSettings();
public ObservableCollection<CustomPluginHotkey> CustomPluginHotkeys { get; } = new ObservableCollection<CustomPluginHotkey>();
public bool DontPromptUpdateMsg { get; set; }

View File

@@ -1,37 +0,0 @@
// Copyright (c) Microsoft Corporation
// 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;
namespace Wox.Infrastructure.UserSettings
{
public class RunPlugin
{
public string ID { get; set; }
public string Name { get; set; }
private List<string> _actionKeywords;
public RunPlugin(List<string> actionKeywords = null)
{
_actionKeywords = actionKeywords;
}
public List<string> GetActionKeywords()
{
return _actionKeywords;
}
public void SetActionKeywords(List<string> value)
{
_actionKeywords = value;
}
/// <summary>
/// Gets or sets a value indicating whether used only to save the state of the plugin in settings
/// </summary>
public bool Disabled { get; set; }
}
}

View File

@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using Newtonsoft.Json;
namespace Wox.Plugin
@@ -17,11 +18,8 @@ namespace Wox.Plugin
private string _pluginDirectory;
private List<string> _actionKeywords;
public PluginMetadata(List<string> actionKeywords = null)
public PluginMetadata()
{
_actionKeywords = actionKeywords;
}
public string ID { get; set; }
@@ -55,32 +53,24 @@ namespace Wox.Plugin
{
_pluginDirectory = value;
ExecuteFilePath = Path.Combine(value, ExecuteFileName);
IcoPath = Path.Combine(value, IcoPath);
IcoPathDark = Path.Combine(value, IcoPathDark);
IcoPathLight = Path.Combine(value, IcoPathLight);
}
}
public string ActionKeyword { get; set; }
public List<string> GetActionKeywords()
{
return _actionKeywords;
}
public bool IsGlobal { get; set; }
public void SetActionKeywords(List<string> value)
{
_actionKeywords = value;
}
public string IcoPathDark { get; set; }
public string IcoPath { get; set; }
public string IcoPathLight { get; set; }
public override string ToString()
{
return Name;
}
[Obsolete("Use IcoPath")]
public string FullIcoPath => IcoPath;
/// <summary>
/// Gets or sets init time include both plugin load time and init time
/// </summary>

View File

@@ -32,7 +32,8 @@ namespace Wox.Test
var metadata = new PluginMetadata
{
ID = "dummyName",
IcoPath = "dummyIcoPath",
IcoPathDark = "dummyIcoPath",
IcoPathLight = "dummyIcoPath",
ExecuteFileName = "dummyExecuteFileName",
PluginDirectory = "dummyPluginDirectory",
};

View File

@@ -25,14 +25,18 @@ namespace Wox.Test
public void QueryBuilderShouldRemoveExtraSpacesForNonGlobalPlugin()
{
// Arrange
var nonGlobalPlugins = new Dictionary<string, PluginPair>
PluginManager.SetAllPlugins(new List<PluginPair>()
{
{ ">", new PluginPair { Metadata = new PluginMetadata(new List<string> { ">" } ) } },
};
new PluginPair
{
Metadata = new PluginMetadata() { ActionKeyword = ">" },
},
});
string searchQuery = "> file.txt file2 file3";
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
// Assert
Assert.AreEqual("> file.txt file2 file3", searchQuery);
@@ -42,14 +46,15 @@ namespace Wox.Test
public void QueryBuilderShouldRemoveExtraSpacesForDisabledNonGlobalPlugin()
{
// Arrange
var nonGlobalPlugins = new Dictionary<string, PluginPair>
PluginManager.SetAllPlugins(new List<PluginPair>()
{
{ ">", new PluginPair { Metadata = new PluginMetadata(new List<string> { ">" }) { Disabled = true } } },
};
new PluginPair { Metadata = new PluginMetadata() { Disabled = true, ActionKeyword = ">" } },
});
string searchQuery = "> file.txt file2 file3";
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
// Assert
Assert.AreEqual("> file.txt file2 file3", searchQuery);
@@ -62,88 +67,30 @@ namespace Wox.Test
string searchQuery = "file.txt file2 file3";
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, new Dictionary<string, PluginPair>());
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
// Assert
Assert.AreEqual("file.txt file2 file3", searchQuery);
}
[Test]
public void QueryBuilderShouldGenerateSameQueryIfEitherActionKeywordOrActionKeywordsListIsSet()
{
// Arrange
string searchQuery = "> query";
var firstPlugin = new PluginPair { Metadata = new PluginMetadata(new List<string> { ">" } ) };
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = ">" } };
var nonGlobalPluginWithActionKeywords = new Dictionary<string, PluginPair>
{
{ ">", firstPlugin },
};
var nonGlobalPluginWithActionKeyword = new Dictionary<string, PluginPair>
{
{ ">", secondPlugin },
};
string[] terms = { ">", "query" };
Query expectedQuery = new Query("> query", "query", new ReadOnlyCollection<string>(terms), ">");
// Act
var queriesForPluginsWithActionKeywords = QueryBuilder.Build(ref searchQuery, nonGlobalPluginWithActionKeywords);
var queriesForPluginsWithActionKeyword = QueryBuilder.Build(ref searchQuery, nonGlobalPluginWithActionKeyword);
var firstQuery = queriesForPluginsWithActionKeyword.GetValueOrDefault(firstPlugin);
var secondQuery = queriesForPluginsWithActionKeywords.GetValueOrDefault(secondPlugin);
// Assert
Assert.IsTrue(AreEqual(firstQuery, expectedQuery));
Assert.IsTrue(AreEqual(firstQuery, secondQuery));
}
[Test]
public void QueryBuilderShouldGenerateCorrectQueriesForPluginsWithMultipleActionKeywords()
{
// Arrange
var plugin = new PluginPair { Metadata = new PluginMetadata(new List<string> { "a", "b" } ) };
var nonGlobalPlugins = new Dictionary<string, PluginPair>
{
{ "a", plugin },
{ "b", plugin },
};
var firstQueryText = "asearch";
var secondQueryText = "bsearch";
// Act
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText, nonGlobalPlugins);
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText, nonGlobalPlugins);
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
// Assert
Assert.IsTrue(AreEqual(firstQuery, new Query { ActionKeyword = "a", RawQuery = "asearch", Search = "search" }));
Assert.IsTrue(AreEqual(secondQuery, new Query { ActionKeyword = "b", RawQuery = "bsearch", Search = "search" }));
}
[Test]
public void QueryBuildShouldGenerateSameSearchQueryWithOrWithoutSpaceAfterActionKeyword()
{
// Arrange
var plugin = new PluginPair { Metadata = new PluginMetadata(new List<string> { "a" } ) };
var nonGlobalPlugins = new Dictionary<string, PluginPair>
var plugin = new PluginPair { Metadata = new PluginMetadata() { ActionKeyword = "a" } };
PluginManager.SetAllPlugins(new List<PluginPair>()
{
{ "a", plugin },
};
plugin,
});
var firstQueryText = "asearch";
var secondQueryText = "a search";
// Act
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText, nonGlobalPlugins);
var firstPluginQueryPair = QueryBuilder.Build(ref firstQueryText);
var firstQuery = firstPluginQueryPair.GetValueOrDefault(plugin);
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText, nonGlobalPlugins);
var secondPluginQueryPairs = QueryBuilder.Build(ref secondQueryText);
var secondQuery = secondPluginQueryPairs.GetValueOrDefault(plugin);
// Assert
@@ -159,15 +106,14 @@ namespace Wox.Test
string searchQuery = "abcdefgh";
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "ab", ID = "plugin1" } };
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "abcd", ID = "plugin2" } };
var nonGlobalPlugins = new Dictionary<string, PluginPair>
PluginManager.SetAllPlugins(new List<PluginPair>()
{
{ "ab", firstPlugin },
{ "abcd", secondPlugin },
};
firstPlugin,
secondPlugin,
});
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);
@@ -184,15 +130,14 @@ namespace Wox.Test
string searchQuery = "abcd efgh";
var firstPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "ab", ID = "plugin1" } };
var secondPlugin = new PluginPair { Metadata = new PluginMetadata { ActionKeyword = "abcd", ID = "plugin2" } };
var nonGlobalPlugins = new Dictionary<string, PluginPair>
PluginManager.SetAllPlugins(new List<PluginPair>()
{
{ "ab", firstPlugin },
{ "abcd", secondPlugin },
};
firstPlugin,
secondPlugin,
});
// Act
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery, nonGlobalPlugins);
var pluginQueryPairs = QueryBuilder.Build(ref searchQuery);
var firstQuery = pluginQueryPairs.GetValueOrDefault(firstPlugin);
var secondQuery = pluginQueryPairs.GetValueOrDefault(secondPlugin);

View File

@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.PowerToys.Settings.UI.Library
{
public class PowerLauncherPluginSettings
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Author { get; set; }
public bool Disabled { get; set; }
public bool IsGlobal { get; set; }
public string ActionKeyword { get; set; }
public string IconPathDark { get; set; }
public string IconPathLight { get; set; }
}
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
@@ -16,6 +17,9 @@ namespace Microsoft.PowerToys.Settings.UI.Library
[JsonPropertyName("properties")]
public PowerLauncherProperties Properties { get; set; }
[JsonPropertyName("plugins")]
public IEnumerable<PowerLauncherPluginSettings> Plugins { get; set; }
public PowerLauncherSettings()
{
Properties = new PowerLauncherProperties();