From c979609de7db53ac987156e05e206f3df826a932 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Wed, 29 Oct 2025 20:39:44 -0300 Subject: [PATCH 01/10] new keywords in settings --- Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 8d62531cd62..8c787796055 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -58,6 +58,15 @@ public class Settings public bool QuickAccessKeywordEnabled { get; set; } + + public string FolderSearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign; + + public bool FolderSearchKeywordEnabled { get; set; } + + public string FileSearchActionKeyword { get; set; } = Query.GlobalPluginWildcardSign; + + public bool FileSearchKeywordEnabled { get; set; } + public bool WarnWindowsSearchServiceOff { get; set; } = true; public bool ShowFileSizeInPreviewPanel { get; set; } = true; @@ -160,7 +169,10 @@ internal enum ActionKeyword PathSearchActionKeyword, FileContentSearchActionKeyword, IndexSearchActionKeyword, - QuickAccessActionKeyword + QuickAccessActionKeyword, + FolderSearchActionKeyword, + FileSearchActionKeyword, + } internal string GetActionKeyword(ActionKeyword actionKeyword) => actionKeyword switch From 531e8c70715157b7c942fc899d87be2d88d5c30b Mon Sep 17 00:00:00 2001 From: 01Dri Date: Wed, 29 Oct 2025 20:50:59 -0300 Subject: [PATCH 02/10] settings keywords --- Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml | 2 ++ Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs | 8 ++++++++ .../ViewModels/SettingsViewModel.cs | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml index c40040df5be..45c0d72acd9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Languages/en.xaml @@ -58,6 +58,8 @@ File Content Search: Index Search: Quick Access: + Folder Search: + File Search: Current Action Keyword Done Enabled diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 8c787796055..b5ea760dc20 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -182,6 +182,8 @@ internal enum ActionKeyword ActionKeyword.FileContentSearchActionKeyword => FileContentSearchActionKeyword, ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword, ActionKeyword.QuickAccessActionKeyword => QuickAccessActionKeyword, + ActionKeyword.FolderSearchActionKeyword => FolderSearchActionKeyword, + ActionKeyword.FileSearchActionKeyword => FileSearchActionKeyword, _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyWord property not found") }; @@ -192,6 +194,8 @@ internal enum ActionKeyword ActionKeyword.FileContentSearchActionKeyword => FileContentSearchActionKeyword = keyword, ActionKeyword.IndexSearchActionKeyword => IndexSearchActionKeyword = keyword, ActionKeyword.QuickAccessActionKeyword => QuickAccessActionKeyword = keyword, + ActionKeyword.FolderSearchActionKeyword => FolderSearchActionKeyword = keyword, + ActionKeyword.FileSearchActionKeyword => FileSearchActionKeyword = keyword, _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyWord property not found") }; @@ -202,6 +206,8 @@ internal enum ActionKeyword ActionKeyword.IndexSearchActionKeyword => IndexSearchKeywordEnabled, ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled, ActionKeyword.QuickAccessActionKeyword => QuickAccessKeywordEnabled, + ActionKeyword.FolderSearchActionKeyword => FolderSearchKeywordEnabled, + ActionKeyword.FileSearchActionKeyword => FileSearchKeywordEnabled, _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; @@ -212,6 +218,8 @@ internal enum ActionKeyword ActionKeyword.IndexSearchActionKeyword => IndexSearchKeywordEnabled = enable, ActionKeyword.FileContentSearchActionKeyword => FileContentSearchKeywordEnabled = enable, ActionKeyword.QuickAccessActionKeyword => QuickAccessKeywordEnabled = enable, + ActionKeyword.FolderSearchActionKeyword => FolderSearchKeywordEnabled = enable, + ActionKeyword.FileSearchActionKeyword => FileSearchKeywordEnabled = enable, _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 2d46c6307cc..956c84db2c6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -279,7 +279,11 @@ private void InitializeActionKeywordModels() new(Settings.ActionKeyword.IndexSearchActionKeyword, "plugin_explorer_actionkeywordview_indexsearch"), new(Settings.ActionKeyword.QuickAccessActionKeyword, - "plugin_explorer_actionkeywordview_quickaccess") + "plugin_explorer_actionkeywordview_quickaccess"), + new(Settings.ActionKeyword.FolderSearchActionKeyword, + "plugin_explorer_actionkeywordview_foldersearch"), + new(Settings.ActionKeyword.FileSearchActionKeyword, + "plugin_explorer_actionkeywordview_filesearch") }; } From dbe7d520cd5329706f57c65cb339aec5532750d8 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Thu, 30 Oct 2025 00:16:25 -0300 Subject: [PATCH 03/10] ActionKeywordConfiguration --- .../Search/ActionKeywordConfiguration.cs | 25 +++ .../Search/SearchManager.cs | 170 ++++++++++++------ .../Flow.Launcher.Plugin.Explorer/Settings.cs | 2 +- 3 files changed, 140 insertions(+), 57 deletions(-) create mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs new file mode 100644 index 00000000000..926a7c01870 --- /dev/null +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Flow.Launcher.Plugin.Explorer.Search; +public class ActionKeywordConfiguration +{ + public string Keyword { get; } + + public Settings.ActionKeyword Type { get; } + + public bool Enable { get; } + + public ActionKeywordConfiguration(string keyword, Settings.ActionKeyword type, bool enable) + { + Keyword = keyword; + Type = type; + Enable = enable; + } + + public bool IsActive(Settings.ActionKeyword type) + => Type == type && Enable; +} diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index d7b0690828a..c5a30ccde93 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -1,13 +1,16 @@ -using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo; -using Flow.Launcher.Plugin.Explorer.Search.Everything; -using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; -using Flow.Launcher.Plugin.SharedCommands; -using System; +using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Windows; using Flow.Launcher.Plugin.Explorer.Exceptions; +using Flow.Launcher.Plugin.Explorer.Search.DirectoryInfo; +using Flow.Launcher.Plugin.Explorer.Search.Everything; +using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; +using Flow.Launcher.Plugin.SharedCommands; +using static Flow.Launcher.Plugin.Explorer.Settings; using Path = System.IO.Path; namespace Flow.Launcher.Plugin.Explorer.Search @@ -24,6 +27,7 @@ public SearchManager(Settings settings, PluginInitContext context) Settings = settings; } + /// /// Note: A path that ends with "\" and one that doesn't will not be regarded as equal. /// @@ -47,45 +51,46 @@ public int GetHashCode(Result obj) internal async Task> SearchAsync(Query query, CancellationToken token) { var results = new HashSet(PathEqualityComparator.Instance); - - // This allows the user to type the below action keywords and see/search the list of quick folder links - if (ActionKeywordMatch(query, Settings.ActionKeyword.SearchActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.PathSearchActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.IndexSearchActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.FileContentSearchActionKeyword)) + var actionKeywordConfigurations = GetActionKeywordConfigurations(); + var keywordStr = query.ActionKeyword.Length == 0 ? Query.GlobalPluginWildcardSign : query.ActionKeyword; + if (string.IsNullOrEmpty(keywordStr)) { - if (string.IsNullOrEmpty(query.Search) && ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword)) - return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); + return new List(); } - else + bool isPathSearch = query.Search.IsLocationPathString() + || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) + || EnvironmentVariables.HasEnvironmentVar(query.Search); + + var actionKeywordConfiguration = actionKeywordConfigurations.FirstOrDefault(x => x.Keyword == keywordStr && x.Enable); + if (actionKeywordConfiguration == null && !isPathSearch) { - // No action keyword matched- plugin should not handle this query, return empty results. return new List(); } - IAsyncEnumerable searchResults; + if (actionKeywordConfiguration == null && isPathSearch) + { + actionKeywordConfiguration = + new ActionKeywordConfiguration(keywordStr, ActionKeyword.PathSearchActionKeyword, true); + } - bool isPathSearch = query.Search.IsLocationPathString() - || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) - || EnvironmentVariables.HasEnvironmentVar(query.Search); + if (string.IsNullOrEmpty(query.Search) + && actionKeywordConfiguration!.IsActive(ActionKeyword.QuickAccessActionKeyword)) + { + return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); + } + + IAsyncEnumerable searchResults; string engineName; - switch (isPathSearch) + switch (actionKeywordConfiguration!.IsActive(ActionKeyword.PathSearchActionKeyword) + || actionKeywordConfiguration.IsActive(ActionKeyword.SearchActionKeyword)) { - case true - when ActionKeywordMatch(query, Settings.ActionKeyword.PathSearchActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.SearchActionKeyword): - + case true: results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); - return results.ToList(); - case false - when ActionKeywordMatch(query, Settings.ActionKeyword.FileContentSearchActionKeyword): - - // Intentionally require enabling of Everything's content search due to its slowness + when actionKeywordConfiguration.IsActive(ActionKeyword.FileContentSearchActionKeyword): if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch) return EverythingContentSearchResult(query); @@ -93,18 +98,22 @@ when ActionKeywordMatch(query, Settings.ActionKeyword.FileContentSearchActionKey engineName = Enum.GetName(Settings.ContentSearchEngine); break; + case false - when ActionKeywordMatch(query, Settings.ActionKeyword.IndexSearchActionKeyword) - || ActionKeywordMatch(query, Settings.ActionKeyword.SearchActionKeyword): + when actionKeywordConfiguration.IsActive(ActionKeyword.IndexSearchActionKeyword) + || actionKeywordConfiguration.IsActive(ActionKeyword.SearchActionKeyword) + || actionKeywordConfiguration.IsActive(ActionKeyword.FolderSearchActionKeyword) + || actionKeywordConfiguration.IsActive(ActionKeyword.FileSearchActionKeyword): searchResults = Settings.IndexProvider.SearchAsync(query.Search, token); engineName = Enum.GetName(Settings.IndexSearchEngine); break; - case true or false - when ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword): + case false + when actionKeywordConfiguration.IsActive(ActionKeyword.QuickAccessActionKeyword): return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); + default: return results.ToList(); } @@ -115,11 +124,14 @@ when ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword): try { await foreach (var search in searchResults.WithCancellation(token).ConfigureAwait(false)) - if (search.Type == ResultType.File && IsExcludedFile(search)) { + { + if (ShouldSkip(actionKeywordConfiguration, search)) + { continue; - } else { - results.Add(ResultManager.CreateResult(query, search)); } + results.Add(ResultManager.CreateResult(query, search)); + + } } catch (OperationCanceledException) { @@ -140,25 +152,6 @@ when ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword): return results.ToList(); } - private bool ActionKeywordMatch(Query query, Settings.ActionKeyword allowedActionKeyword) - { - var keyword = query.ActionKeyword.Length == 0 ? Query.GlobalPluginWildcardSign : query.ActionKeyword; - - return allowedActionKeyword switch - { - Settings.ActionKeyword.SearchActionKeyword => Settings.SearchActionKeywordEnabled && - keyword == Settings.SearchActionKeyword, - Settings.ActionKeyword.PathSearchActionKeyword => Settings.PathSearchKeywordEnabled && - keyword == Settings.PathSearchActionKeyword, - Settings.ActionKeyword.FileContentSearchActionKeyword => Settings.FileContentSearchKeywordEnabled && - keyword == Settings.FileContentSearchActionKeyword, - Settings.ActionKeyword.IndexSearchActionKeyword => Settings.IndexSearchKeywordEnabled && - keyword == Settings.IndexSearchActionKeyword, - Settings.ActionKeyword.QuickAccessActionKeyword => Settings.QuickAccessKeywordEnabled && - keyword == Settings.QuickAccessActionKeyword, - _ => throw new ArgumentOutOfRangeException(nameof(allowedActionKeyword), allowedActionKeyword, "actionKeyword out of range") - }; - } private List EverythingContentSearchResult(Query query) { @@ -280,5 +273,70 @@ private bool IsExcludedFile(SearchResult result) return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase); } + + private bool ShouldSkip(ActionKeywordConfiguration actionKeywordConfiguration, SearchResult search) + { + if (search.Type == ResultType.File && IsExcludedFile(search)) + return true; + + if (actionKeywordConfiguration.IsActive(ActionKeyword.FolderSearchActionKeyword) + && search.Type != ResultType.Folder) + { + return true; + } + + if (actionKeywordConfiguration.IsActive(ActionKeyword.FileSearchActionKeyword) + && search.Type != ResultType.File) + { + return true; + } + + return false; + } + + + private List GetActionKeywordConfigurations() + { + return new List() + { + new( + Settings.FolderSearchActionKeyword, + ActionKeyword.FolderSearchActionKeyword, + Settings.FolderSearchKeywordEnabled + ), + new( + Settings.FileSearchActionKeyword, + ActionKeyword.FileSearchActionKeyword, + Settings.FileSearchKeywordEnabled + ), + new( + Settings.PathSearchActionKeyword, + ActionKeyword.PathSearchActionKeyword, + Settings.PathSearchKeywordEnabled + ), + new( + Settings.SearchActionKeyword, + ActionKeyword.SearchActionKeyword, + Settings.SearchActionKeywordEnabled + ), + new( + Settings.QuickAccessActionKeyword, + ActionKeyword.QuickAccessActionKeyword, + Settings.QuickAccessKeywordEnabled + ), + new( + Settings.IndexSearchActionKeyword, + ActionKeyword.IndexSearchActionKeyword, + Settings.IndexSearchKeywordEnabled + ), + new( + Settings.FileContentSearchActionKeyword, + ActionKeyword.FileContentSearchActionKeyword, + Settings.FileContentSearchKeywordEnabled + ), + }; + } + } + } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index b5ea760dc20..0e31d23c0ac 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -163,7 +163,7 @@ public enum ContentIndexSearchEngineOption #endregion - internal enum ActionKeyword + public enum ActionKeyword { SearchActionKeyword, PathSearchActionKeyword, From e0a99c5099993e28dcab2c9457f3a1a4d72a5c13 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sat, 1 Nov 2025 20:55:55 -0300 Subject: [PATCH 04/10] adjust --- .../Search/SearchManager.cs | 50 ++----------------- .../Flow.Launcher.Plugin.Explorer/Settings.cs | 27 ++++++++-- 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index c5a30ccde93..2917f93093f 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -51,7 +51,6 @@ public int GetHashCode(Result obj) internal async Task> SearchAsync(Query query, CancellationToken token) { var results = new HashSet(PathEqualityComparator.Instance); - var actionKeywordConfigurations = GetActionKeywordConfigurations(); var keywordStr = query.ActionKeyword.Length == 0 ? Query.GlobalPluginWildcardSign : query.ActionKeyword; if (string.IsNullOrEmpty(keywordStr)) { @@ -60,8 +59,8 @@ internal async Task> SearchAsync(Query query, CancellationToken tok bool isPathSearch = query.Search.IsLocationPathString() || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) || EnvironmentVariables.HasEnvironmentVar(query.Search); + var actionKeywordConfiguration = Settings.GetActionKeywordConfiguration(keywordStr); - var actionKeywordConfiguration = actionKeywordConfigurations.FirstOrDefault(x => x.Keyword == keywordStr && x.Enable); if (actionKeywordConfiguration == null && !isPathSearch) { return new List(); @@ -72,6 +71,7 @@ internal async Task> SearchAsync(Query query, CancellationToken tok actionKeywordConfiguration = new ActionKeywordConfiguration(keywordStr, ActionKeyword.PathSearchActionKeyword, true); } + // This allows the user to type the below action keywords and see/search the list of quick folder links if (string.IsNullOrEmpty(query.Search) && actionKeywordConfiguration!.IsActive(ActionKeyword.QuickAccessActionKeyword)) @@ -90,6 +90,7 @@ internal async Task> SearchAsync(Query query, CancellationToken tok results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); return results.ToList(); case false + // Intentionally require enabling of Everything's content search due to its slowness when actionKeywordConfiguration.IsActive(ActionKeyword.FileContentSearchActionKeyword): if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch) return EverythingContentSearchResult(query); @@ -109,7 +110,7 @@ when actionKeywordConfiguration.IsActive(ActionKeyword.IndexSearchActionKeyword) engineName = Enum.GetName(Settings.IndexSearchEngine); break; - case false + case false when actionKeywordConfiguration.IsActive(ActionKeyword.QuickAccessActionKeyword): return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); @@ -294,49 +295,6 @@ private bool ShouldSkip(ActionKeywordConfiguration actionKeywordConfiguration, S return false; } - - private List GetActionKeywordConfigurations() - { - return new List() - { - new( - Settings.FolderSearchActionKeyword, - ActionKeyword.FolderSearchActionKeyword, - Settings.FolderSearchKeywordEnabled - ), - new( - Settings.FileSearchActionKeyword, - ActionKeyword.FileSearchActionKeyword, - Settings.FileSearchKeywordEnabled - ), - new( - Settings.PathSearchActionKeyword, - ActionKeyword.PathSearchActionKeyword, - Settings.PathSearchKeywordEnabled - ), - new( - Settings.SearchActionKeyword, - ActionKeyword.SearchActionKeyword, - Settings.SearchActionKeywordEnabled - ), - new( - Settings.QuickAccessActionKeyword, - ActionKeyword.QuickAccessActionKeyword, - Settings.QuickAccessKeywordEnabled - ), - new( - Settings.IndexSearchActionKeyword, - ActionKeyword.IndexSearchActionKeyword, - Settings.IndexSearchKeywordEnabled - ), - new( - Settings.FileContentSearchActionKeyword, - ActionKeyword.FileContentSearchActionKeyword, - Settings.FileContentSearchKeywordEnabled - ), - }; - } - } } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 0e31d23c0ac..dbd74ca42d3 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -1,12 +1,13 @@ -using Flow.Launcher.Plugin.Explorer.Search; -using Flow.Launcher.Plugin.Explorer.Search.Everything; -using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; -using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex; -using System; +using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Text.Json.Serialization; +using Flow.Launcher.Plugin.Explorer.Search; +using Flow.Launcher.Plugin.Explorer.Search.Everything; using Flow.Launcher.Plugin.Explorer.Search.IProvider; +using Flow.Launcher.Plugin.Explorer.Search.QuickAccessLinks; +using Flow.Launcher.Plugin.Explorer.Search.WindowsIndex; namespace Flow.Launcher.Plugin.Explorer { @@ -222,5 +223,21 @@ public enum ActionKeyword ActionKeyword.FileSearchActionKeyword => FileSearchKeywordEnabled = enable, _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; + + public ActionKeywordConfiguration GetActionKeywordConfiguration(string actionKeywordStr) + { + if (string.IsNullOrEmpty(actionKeywordStr)) return null; + foreach (ActionKeyword action in Enum.GetValues(typeof(ActionKeyword))) + { + var keywordStr = GetActionKeyword(action); + if (string.IsNullOrEmpty(keywordStr)) continue; + if (keywordStr == actionKeywordStr) + { + return new ActionKeywordConfiguration(keywordStr, action, GetActionKeywordEnabled(action)); + } + } + return null; + } + } } From 9209b93a5e7766165300f5db3d3a9e85b0c12cd7 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 00:35:42 -0300 Subject: [PATCH 05/10] up --- .../Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index 2917f93093f..6e5c7615462 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -52,13 +52,11 @@ internal async Task> SearchAsync(Query query, CancellationToken tok { var results = new HashSet(PathEqualityComparator.Instance); var keywordStr = query.ActionKeyword.Length == 0 ? Query.GlobalPluginWildcardSign : query.ActionKeyword; - if (string.IsNullOrEmpty(keywordStr)) - { - return new List(); - } bool isPathSearch = query.Search.IsLocationPathString() || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) || EnvironmentVariables.HasEnvironmentVar(query.Search); + + var actionKeywordConfiguration = Settings.GetActionKeywordConfiguration(keywordStr); if (actionKeywordConfiguration == null && !isPathSearch) From d2dd16bcfb72c39a67ca15a4ae9dd9da656f79b3 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 03:38:39 -0300 Subject: [PATCH 06/10] up --- .../Search/SearchManager.cs | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index 6e5c7615462..bc2112aa5c8 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -56,7 +56,6 @@ internal async Task> SearchAsync(Query query, CancellationToken tok || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) || EnvironmentVariables.HasEnvironmentVar(query.Search); - var actionKeywordConfiguration = Settings.GetActionKeywordConfiguration(keywordStr); if (actionKeywordConfiguration == null && !isPathSearch) @@ -97,31 +96,21 @@ when actionKeywordConfiguration.IsActive(ActionKeyword.FileContentSearchActionKe engineName = Enum.GetName(Settings.ContentSearchEngine); break; - - case false - when actionKeywordConfiguration.IsActive(ActionKeyword.IndexSearchActionKeyword) - || actionKeywordConfiguration.IsActive(ActionKeyword.SearchActionKeyword) - || actionKeywordConfiguration.IsActive(ActionKeyword.FolderSearchActionKeyword) - || actionKeywordConfiguration.IsActive(ActionKeyword.FileSearchActionKeyword): - - searchResults = Settings.IndexProvider.SearchAsync(query.Search, token); - engineName = Enum.GetName(Settings.IndexSearchEngine); - break; - - case false + case false when actionKeywordConfiguration.IsActive(ActionKeyword.QuickAccessActionKeyword): return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); default: - return results.ToList(); + searchResults = Settings.IndexProvider.SearchAsync(query.Search, token); + engineName = Enum.GetName(Settings.IndexSearchEngine); + break; } - // Merge Quick Access Link results for non-path searches. - results.UnionWith(QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks)); - try { + results.UnionWith(QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks)); + await foreach (var search in searchResults.WithCancellation(token).ConfigureAwait(false)) { if (ShouldSkip(actionKeywordConfiguration, search)) From fbb26e9932741bd11a000c98f0114eec2f4f823a Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 03:46:19 -0300 Subject: [PATCH 07/10] switch case adjust --- Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index bc2112aa5c8..73cb04574f1 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -80,8 +80,7 @@ internal async Task> SearchAsync(Query query, CancellationToken tok string engineName; - switch (actionKeywordConfiguration!.IsActive(ActionKeyword.PathSearchActionKeyword) - || actionKeywordConfiguration.IsActive(ActionKeyword.SearchActionKeyword)) + switch (actionKeywordConfiguration!.IsActive(ActionKeyword.PathSearchActionKeyword)) { case true: results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); From c90de6fa8a5589d93c5bf8700a7d5efb2073b950 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 16:30:29 -0300 Subject: [PATCH 08/10] code quality --- ...onfiguration.cs => ActionKeywordActive.cs} | 14 +++--- .../Search/SearchManager.cs | 43 ++++++++++++------- .../Flow.Launcher.Plugin.Explorer/Settings.cs | 7 +-- .../ViewModels/SettingsViewModel.cs | 2 +- 4 files changed, 40 insertions(+), 26 deletions(-) rename Plugins/Flow.Launcher.Plugin.Explorer/Search/{ActionKeywordConfiguration.cs => ActionKeywordActive.cs} (52%) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs similarity index 52% rename from Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs rename to Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs index 926a7c01870..1fb5ee13987 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordConfiguration.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs @@ -3,23 +3,25 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using static Flow.Launcher.Plugin.Explorer.Settings; namespace Flow.Launcher.Plugin.Explorer.Search; -public class ActionKeywordConfiguration +public class ActionKeywordActive { public string Keyword { get; } public Settings.ActionKeyword Type { get; } - public bool Enable { get; } - public ActionKeywordConfiguration(string keyword, Settings.ActionKeyword type, bool enable) + public ActionKeywordActive(string keyword, Settings.ActionKeyword type) { Keyword = keyword; Type = type; - Enable = enable; } - public bool IsActive(Settings.ActionKeyword type) - => Type == type && Enable; + public bool Equals(ActionKeyword type) + { + return Type == type; + } + } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index 73cb04574f1..f922a781ab5 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -56,22 +56,23 @@ internal async Task> SearchAsync(Query query, CancellationToken tok || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search) || EnvironmentVariables.HasEnvironmentVar(query.Search); - var actionKeywordConfiguration = Settings.GetActionKeywordConfiguration(keywordStr); + var activeActionKeyword = Settings.GetActiveActionKeyword(keywordStr); - if (actionKeywordConfiguration == null && !isPathSearch) + if (activeActionKeyword == null && !isPathSearch) { - return new List(); + MergeQuickAccessInResultsIfQueryMatch(results, query); + return results.ToList(); } - if (actionKeywordConfiguration == null && isPathSearch) + if (activeActionKeyword == null && isPathSearch) { - actionKeywordConfiguration = - new ActionKeywordConfiguration(keywordStr, ActionKeyword.PathSearchActionKeyword, true); + activeActionKeyword = + new ActionKeywordActive(keywordStr, ActionKeyword.PathSearchActionKeyword); } // This allows the user to type the below action keywords and see/search the list of quick folder links if (string.IsNullOrEmpty(query.Search) - && actionKeywordConfiguration!.IsActive(ActionKeyword.QuickAccessActionKeyword)) + && activeActionKeyword!.Equals(ActionKeyword.QuickAccessActionKeyword)) { return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks); } @@ -80,14 +81,14 @@ internal async Task> SearchAsync(Query query, CancellationToken tok string engineName; - switch (actionKeywordConfiguration!.IsActive(ActionKeyword.PathSearchActionKeyword)) + switch (activeActionKeyword!.Equals(ActionKeyword.PathSearchActionKeyword)) { case true: results.UnionWith(await PathSearchAsync(query, token).ConfigureAwait(false)); return results.ToList(); case false // Intentionally require enabling of Everything's content search due to its slowness - when actionKeywordConfiguration.IsActive(ActionKeyword.FileContentSearchActionKeyword): + when activeActionKeyword.Equals(ActionKeyword.FileContentSearchActionKeyword): if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch) return EverythingContentSearchResult(query); @@ -96,7 +97,7 @@ when actionKeywordConfiguration.IsActive(ActionKeyword.FileContentSearchActionKe break; case false - when actionKeywordConfiguration.IsActive(ActionKeyword.QuickAccessActionKeyword): + when activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword): return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); @@ -106,13 +107,13 @@ when actionKeywordConfiguration.IsActive(ActionKeyword.QuickAccessActionKeyword) break; } + // Merge Quick Access Link results for non-path searches. + MergeQuickAccessInResultsIfQueryMatch(results, query); try { - results.UnionWith(QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks)); - await foreach (var search in searchResults.WithCancellation(token).ConfigureAwait(false)) { - if (ShouldSkip(actionKeywordConfiguration, search)) + if (ShouldSkip(activeActionKeyword, search)) { continue; } @@ -261,18 +262,18 @@ private bool IsExcludedFile(SearchResult result) return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase); } - private bool ShouldSkip(ActionKeywordConfiguration actionKeywordConfiguration, SearchResult search) + private bool ShouldSkip(ActionKeywordActive actionKeywordActive, SearchResult search) { if (search.Type == ResultType.File && IsExcludedFile(search)) return true; - if (actionKeywordConfiguration.IsActive(ActionKeyword.FolderSearchActionKeyword) + if (actionKeywordActive.Equals(ActionKeyword.FolderSearchActionKeyword) && search.Type != ResultType.Folder) { return true; } - if (actionKeywordConfiguration.IsActive(ActionKeyword.FileSearchActionKeyword) + if (actionKeywordActive.Equals(ActionKeyword.FileSearchActionKeyword) && search.Type != ResultType.File) { return true; @@ -281,6 +282,16 @@ private bool ShouldSkip(ActionKeywordConfiguration actionKeywordConfiguration, S return false; } + private void MergeQuickAccessInResultsIfQueryMatch(HashSet results, Query query) + { + var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); + if (quickAccessMatched != null && quickAccessMatched.Any()) + { + results.UnionWith(quickAccessMatched); + } + + } + } } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index dbd74ca42d3..8da51b41ae3 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -224,16 +224,17 @@ public enum ActionKeyword _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; - public ActionKeywordConfiguration GetActionKeywordConfiguration(string actionKeywordStr) + public ActionKeywordActive GetActiveActionKeyword(string actionKeywordStr) { if (string.IsNullOrEmpty(actionKeywordStr)) return null; foreach (ActionKeyword action in Enum.GetValues(typeof(ActionKeyword))) { var keywordStr = GetActionKeyword(action); if (string.IsNullOrEmpty(keywordStr)) continue; - if (keywordStr == actionKeywordStr) + var isEnabled = GetActionKeywordEnabled(action); + if (keywordStr == actionKeywordStr && isEnabled) { - return new ActionKeywordConfiguration(keywordStr, action, GetActionKeywordEnabled(action)); + return new ActionKeywordActive(keywordStr, action); } } return null; diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs index 956c84db2c6..c4ca3f85310 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs @@ -469,7 +469,7 @@ private void ShowUnselectedMessage() private static string? PromptUserSelectPath(ResultType type, string? initialDirectory = null) { - string? path = null; + string? path = null; if (type is ResultType.Folder) { From 20959dc0dac387767f2675322647339d1eae8b37 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 17:10:24 -0300 Subject: [PATCH 09/10] code quality --- .../Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index f922a781ab5..926b60c735c 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -285,13 +285,8 @@ private bool ShouldSkip(ActionKeywordActive actionKeywordActive, SearchResult se private void MergeQuickAccessInResultsIfQueryMatch(HashSet results, Query query) { var quickAccessMatched = QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks); - if (quickAccessMatched != null && quickAccessMatched.Any()) - { - results.UnionWith(quickAccessMatched); - } - + if (quickAccessMatched != null && quickAccessMatched.Any()) results.UnionWith(quickAccessMatched); } - } } From 4107b87aeb41143b0c7f589018295400d5cc5379 Mon Sep 17 00:00:00 2001 From: 01Dri Date: Sun, 2 Nov 2025 23:40:39 -0300 Subject: [PATCH 10/10] code quality --- .../Search/ActionKeywordActive.cs | 27 ------------------- .../Search/SearchManager.cs | 11 +++----- .../Flow.Launcher.Plugin.Explorer/Settings.cs | 7 ++--- 3 files changed, 6 insertions(+), 39 deletions(-) delete mode 100644 Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs deleted file mode 100644 index 1fb5ee13987..00000000000 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ActionKeywordActive.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Flow.Launcher.Plugin.Explorer.Settings; - -namespace Flow.Launcher.Plugin.Explorer.Search; -public class ActionKeywordActive -{ - public string Keyword { get; } - - public Settings.ActionKeyword Type { get; } - - - public ActionKeywordActive(string keyword, Settings.ActionKeyword type) - { - Keyword = keyword; - Type = type; - } - - public bool Equals(ActionKeyword type) - { - return Type == type; - } - -} diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs index 926b60c735c..463d39be1c3 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs @@ -64,11 +64,8 @@ internal async Task> SearchAsync(Query query, CancellationToken tok return results.ToList(); } - if (activeActionKeyword == null && isPathSearch) - { - activeActionKeyword = - new ActionKeywordActive(keywordStr, ActionKeyword.PathSearchActionKeyword); - } + if (activeActionKeyword == null && isPathSearch) activeActionKeyword = ActionKeyword.PathSearchActionKeyword; + // This allows the user to type the below action keywords and see/search the list of quick folder links if (string.IsNullOrEmpty(query.Search) @@ -113,7 +110,7 @@ when activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword): { await foreach (var search in searchResults.WithCancellation(token).ConfigureAwait(false)) { - if (ShouldSkip(activeActionKeyword, search)) + if (ShouldSkip(activeActionKeyword!.Value, search)) { continue; } @@ -262,7 +259,7 @@ private bool IsExcludedFile(SearchResult result) return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase); } - private bool ShouldSkip(ActionKeywordActive actionKeywordActive, SearchResult search) + private bool ShouldSkip(ActionKeyword actionKeywordActive, SearchResult search) { if (search.Type == ResultType.File && IsExcludedFile(search)) return true; diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs index 8da51b41ae3..0b02c374bc5 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Settings.cs @@ -224,7 +224,7 @@ public enum ActionKeyword _ => throw new ArgumentOutOfRangeException(nameof(actionKeyword), actionKeyword, "ActionKeyword enabled status not defined") }; - public ActionKeywordActive GetActiveActionKeyword(string actionKeywordStr) + public ActionKeyword? GetActiveActionKeyword(string actionKeywordStr) { if (string.IsNullOrEmpty(actionKeywordStr)) return null; foreach (ActionKeyword action in Enum.GetValues(typeof(ActionKeyword))) @@ -232,10 +232,7 @@ public ActionKeywordActive GetActiveActionKeyword(string actionKeywordStr) var keywordStr = GetActionKeyword(action); if (string.IsNullOrEmpty(keywordStr)) continue; var isEnabled = GetActionKeywordEnabled(action); - if (keywordStr == actionKeywordStr && isEnabled) - { - return new ActionKeywordActive(keywordStr, action); - } + if (keywordStr == actionKeywordStr && isEnabled) return action; } return null; }