Skip to content

Commit 87f765b

Browse files
authored
Merge pull request #3261 from Jack251970/multiple_keywords
Support Multiple keywords for Plugins
2 parents 5252d3e + ba0d412 commit 87f765b

File tree

15 files changed

+85
-40
lines changed

15 files changed

+85
-40
lines changed

Flow.Launcher.Core/Plugin/PluginManager.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ public static ICollection<PluginPair> ValidPluginsForQuery(Query query)
231231
if (!NonGlobalPlugins.ContainsKey(query.ActionKeyword))
232232
return GlobalPlugins;
233233

234-
235234
var plugin = NonGlobalPlugins[query.ActionKeyword];
236235
return new List<PluginPair>
237236
{
@@ -367,7 +366,16 @@ public static void AddActionKeyword(string id, string newActionKeyword)
367366
NonGlobalPlugins[newActionKeyword] = plugin;
368367
}
369368

369+
// Update action keywords and action keyword in plugin metadata
370370
plugin.Metadata.ActionKeywords.Add(newActionKeyword);
371+
if (plugin.Metadata.ActionKeywords.Count > 0)
372+
{
373+
plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0];
374+
}
375+
else
376+
{
377+
plugin.Metadata.ActionKeyword = string.Empty;
378+
}
371379
}
372380

373381
/// <summary>
@@ -388,16 +396,15 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword)
388396
if (oldActionkeyword != Query.GlobalPluginWildcardSign)
389397
NonGlobalPlugins.Remove(oldActionkeyword);
390398

391-
399+
// Update action keywords and action keyword in plugin metadata
392400
plugin.Metadata.ActionKeywords.Remove(oldActionkeyword);
393-
}
394-
395-
public static void ReplaceActionKeyword(string id, string oldActionKeyword, string newActionKeyword)
396-
{
397-
if (oldActionKeyword != newActionKeyword)
401+
if (plugin.Metadata.ActionKeywords.Count > 0)
402+
{
403+
plugin.Metadata.ActionKeyword = plugin.Metadata.ActionKeywords[0];
404+
}
405+
else
398406
{
399-
AddActionKeyword(id, newActionKeyword);
400-
RemoveActionKeyword(id, oldActionKeyword);
407+
plugin.Metadata.ActionKeyword = string.Empty;
401408
}
402409
}
403410

Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ public interface IPublicAPI
152152
/// <param name="callback"></param>
153153
public void RemoveGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback);
154154

155-
156155
/// <summary>
157156
/// Fuzzy Search the string with the given query. This is the core search mechanism Flow uses
158157
/// </summary>
@@ -191,14 +190,15 @@ public interface IPublicAPI
191190
Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath, Action<double> reportProgress = null, CancellationToken token = default);
192191

193192
/// <summary>
194-
/// Add ActionKeyword for specific plugin
193+
/// Add ActionKeyword and update action keyword metadata for specific plugin
194+
/// Before adding, please check if action keyword is already assigned by <see cref="ActionKeywordAssigned"/>
195195
/// </summary>
196196
/// <param name="pluginId">ID for plugin that needs to add action keyword</param>
197197
/// <param name="newActionKeyword">The actionkeyword that is supposed to be added</param>
198198
void AddActionKeyword(string pluginId, string newActionKeyword);
199199

200200
/// <summary>
201-
/// Remove ActionKeyword for specific plugin
201+
/// Remove ActionKeyword and update action keyword metadata for specific plugin
202202
/// </summary>
203203
/// <param name="pluginId">ID for plugin that needs to remove action keyword</param>
204204
/// <param name="oldActionKeyword">The actionkeyword that is supposed to be removed</param>

Flow.Launcher.Plugin/PluginMetadata.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ internal set
3434

3535
public List<string> ActionKeywords { get; set; }
3636

37+
public bool HideActionKeywordPanel { get; set; }
38+
3739
public string IcoPath { get; set;}
3840

3941
public override string ToString()

Flow.Launcher.Plugin/Query.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ public Query() { }
3939
public const string TermSeparator = " ";
4040

4141
/// <summary>
42-
/// User can set multiple action keywords seperated by ';'
42+
/// User can set multiple action keywords seperated by whitespace
4343
/// </summary>
44-
public const string ActionKeywordSeparator = ";";
45-
44+
public const string ActionKeywordSeparator = TermSeparator;
4645

4746
/// <summary>
4847
/// Wildcard action keyword. Plugins using this value will be queried on every search.

Flow.Launcher/ActionKeywords.xaml.cs

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using Flow.Launcher.Plugin;
44
using Flow.Launcher.ViewModel;
55
using Flow.Launcher.Core;
6+
using System.Linq;
7+
using System.Collections.Generic;
68

79
namespace Flow.Launcher
810
{
@@ -32,20 +34,59 @@ private void BtnCancel_OnClick(object sender, RoutedEventArgs e)
3234

3335
private void btnDone_OnClick(object sender, RoutedEventArgs _)
3436
{
35-
var oldActionKeyword = plugin.Metadata.ActionKeywords[0];
36-
var newActionKeyword = tbAction.Text.Trim();
37-
newActionKeyword = newActionKeyword.Length > 0 ? newActionKeyword : "*";
38-
39-
if (!PluginViewModel.IsActionKeywordRegistered(newActionKeyword))
37+
var oldActionKeywords = plugin.Metadata.ActionKeywords;
38+
39+
var newActionKeywords = tbAction.Text.Split(Query.ActionKeywordSeparator).ToList();
40+
newActionKeywords.RemoveAll(string.IsNullOrEmpty);
41+
newActionKeywords = newActionKeywords.Distinct().ToList();
42+
43+
newActionKeywords = newActionKeywords.Count > 0 ? newActionKeywords : new() { Query.GlobalPluginWildcardSign };
44+
45+
var addedActionKeywords = newActionKeywords.Except(oldActionKeywords).ToList();
46+
var removedActionKeywords = oldActionKeywords.Except(newActionKeywords).ToList();
47+
if (!addedActionKeywords.Any(App.API.ActionKeywordAssigned))
4048
{
41-
pluginViewModel.ChangeActionKeyword(newActionKeyword, oldActionKeyword);
42-
Close();
49+
if (oldActionKeywords.Count != newActionKeywords.Count)
50+
{
51+
ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
52+
return;
53+
}
54+
55+
var sortedOldActionKeywords = oldActionKeywords.OrderBy(s => s).ToList();
56+
var sortedNewActionKeywords = newActionKeywords.OrderBy(s => s).ToList();
57+
58+
if (sortedOldActionKeywords.SequenceEqual(sortedNewActionKeywords))
59+
{
60+
// User just changes the sequence of action keywords
61+
var msg = translater.GetTranslation("newActionKeywordsSameAsOld");
62+
MessageBoxEx.Show(msg);
63+
}
64+
else
65+
{
66+
ReplaceActionKeyword(plugin.Metadata.ID, removedActionKeywords, addedActionKeywords);
67+
}
4368
}
4469
else
4570
{
4671
string msg = translater.GetTranslation("newActionKeywordsHasBeenAssigned");
4772
App.API.ShowMsgBox(msg);
4873
}
4974
}
75+
76+
private void ReplaceActionKeyword(string id, IReadOnlyList<string> removedActionKeywords, IReadOnlyList<string> addedActionKeywords)
77+
{
78+
foreach (var actionKeyword in removedActionKeywords)
79+
{
80+
App.API.RemoveActionKeyword(id, actionKeyword);
81+
}
82+
foreach (var actionKeyword in addedActionKeywords)
83+
{
84+
App.API.AddActionKeyword(id, actionKeyword);
85+
}
86+
87+
// Update action keywords text and close window
88+
pluginViewModel.OnActionKeywordsChanged();
89+
Close();
90+
}
5091
}
5192
}

Flow.Launcher/Languages/en.xaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,10 @@
342342
<system:String x:Key="cannotFindSpecifiedPlugin">Can't find specified plugin</system:String>
343343
<system:String x:Key="newActionKeywordsCannotBeEmpty">New Action Keyword can't be empty</system:String>
344344
<system:String x:Key="newActionKeywordsHasBeenAssigned">This new Action Keyword is already assigned to another plugin, please choose a different one</system:String>
345+
<system:String x:Key="newActionKeywordsSameAsOld">This new Action Keyword is the same as old, please choose a different one</system:String>
345346
<system:String x:Key="success">Success</system:String>
346347
<system:String x:Key="completedSuccessfully">Completed successfully</system:String>
347-
<system:String x:Key="actionkeyword_tips">Enter the action keyword you like to use to start the plugin. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.</system:String>
348+
<system:String x:Key="actionkeyword_tips">Enter the action keywords you like to use to start the plugin and use whitespace to divide them. Use * if you don't want to specify any, and the plugin will be triggered without any action keywords.</system:String>
348349

349350
<!-- Custom Query Hotkey Dialog -->
350351
<system:String x:Key="customeQueryHotkeyTitle">Custom Query Hotkey</system:String>

Flow.Launcher/PublicAPIInstance.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,6 @@ public bool IsGameModeOn()
331331
return _mainVM.GameModeStatus;
332332
}
333333

334-
335334
private readonly List<Func<int, int, SpecialKeyState, bool>> _globalKeyboardHandlers = new();
336335

337336
public void RegisterGlobalKeyboardCallback(Func<int, int, SpecialKeyState, bool> callback) => _globalKeyboardHandlers.Add(callback);

Flow.Launcher/ViewModel/PluginViewModel.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ private string PluginManagerActionKeyword
4343
}
4444
}
4545

46-
4746
private async void LoadIconAsync()
4847
{
4948
Image = await ImageLoader.LoadAsync(PluginPair.Metadata.IcoPath);
@@ -100,7 +99,7 @@ public Control SettingControl
10099
: null;
101100
private ImageSource _image = ImageLoader.MissingImage;
102101

103-
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.ActionKeywords.Count == 1 ? Visibility.Visible : Visibility.Collapsed;
102+
public Visibility ActionKeywordsVisibility => PluginPair.Metadata.HideActionKeywordPanel ? Visibility.Collapsed : Visibility.Visible;
104103
public string InitilizaTime => PluginPair.Metadata.InitTime + "ms";
105104
public string QueryTime => PluginPair.Metadata.AvgQueryTime + "ms";
106105
public string Version => InternationalizationManager.Instance.GetTranslation("plugin_query_version") + " " + PluginPair.Metadata.Version;
@@ -109,9 +108,8 @@ public Control SettingControl
109108
public int Priority => PluginPair.Metadata.Priority;
110109
public Infrastructure.UserSettings.Plugin PluginSettingsObject { get; set; }
111110

112-
public void ChangeActionKeyword(string newActionKeyword, string oldActionKeyword)
111+
public void OnActionKeywordsChanged()
113112
{
114-
PluginManager.ReplaceActionKeyword(PluginPair.Metadata.ID, oldActionKeyword, newActionKeyword);
115113
OnPropertyChanged(nameof(ActionKeywordsText));
116114
}
117115

@@ -150,8 +148,6 @@ private void OpenDeletePluginWindow()
150148
App.API.ShowMainWindow();
151149
}
152150

153-
public static bool IsActionKeywordRegistered(string newActionKeyword) => PluginManager.ActionKeywordRegistered(newActionKeyword);
154-
155151
[RelayCommand]
156152
private void SetActionKeywords()
157153
{

Plugins/Flow.Launcher.Plugin.Calculator/Flow.Launcher.Plugin.Calculator.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
<ItemGroup>
4545
<ProjectReference Include="..\..\Flow.Launcher.Core\Flow.Launcher.Core.csproj" />
46+
<ProjectReference Include="..\..\Flow.Launcher.Plugin\Flow.Launcher.Plugin.csproj" />
4647
</ItemGroup>
4748

4849
<ItemGroup>

Plugins/Flow.Launcher.Plugin.Explorer/plugin.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"*",
88
"*"
99
],
10+
"HideActionKeywordPanel": true,
1011
"Name": "Explorer",
1112
"Description": "Find and manage files and folders via Windows Search or Everything",
1213
"Author": "Jeremy Wu",

0 commit comments

Comments
 (0)