mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 19:27:56 +01:00
tweak plugin settings (#9522)
This commit is contained in:
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace Wox.Test
|
||||
var metadata = new PluginMetadata
|
||||
{
|
||||
ID = "dummyName",
|
||||
IcoPath = "dummyIcoPath",
|
||||
IcoPathDark = "dummyIcoPath",
|
||||
IcoPathLight = "dummyIcoPath",
|
||||
ExecuteFileName = "dummyExecuteFileName",
|
||||
PluginDirectory = "dummyPluginDirectory",
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user