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/Search/SearchManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchManager.cs
index d7b0690828a..463d39be1c3 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,41 @@ public int GetHashCode(Result obj)
internal async Task> SearchAsync(Query query, CancellationToken token)
{
var results = new HashSet(PathEqualityComparator.Instance);
+ var keywordStr = query.ActionKeyword.Length == 0 ? Query.GlobalPluginWildcardSign : query.ActionKeyword;
+ bool isPathSearch = query.Search.IsLocationPathString()
+ || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search)
+ || EnvironmentVariables.HasEnvironmentVar(query.Search);
- // 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 activeActionKeyword = Settings.GetActiveActionKeyword(keywordStr);
+
+ if (activeActionKeyword == null && !isPathSearch)
{
- if (string.IsNullOrEmpty(query.Search) && ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword))
- return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks);
+ MergeQuickAccessInResultsIfQueryMatch(results, query);
+ return results.ToList();
}
- else
+
+ 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)
+ && activeActionKeyword!.Equals(ActionKeyword.QuickAccessActionKeyword))
{
- // No action keyword matched- plugin should not handle this query, return empty results.
- return new List();
+ return QuickAccess.AccessLinkListAll(query, Settings.QuickAccessLinks);
}
IAsyncEnumerable searchResults;
- bool isPathSearch = query.Search.IsLocationPathString()
- || EnvironmentVariables.IsEnvironmentVariableSearch(query.Search)
- || EnvironmentVariables.HasEnvironmentVar(query.Search);
-
string engineName;
- switch (isPathSearch)
+ switch (activeActionKeyword!.Equals(ActionKeyword.PathSearchActionKeyword))
{
- 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 activeActionKeyword.Equals(ActionKeyword.FileContentSearchActionKeyword):
if (Settings.ContentIndexProvider is EverythingSearchManager && !Settings.EnableEverythingContentSearch)
return EverythingContentSearchResult(query);
@@ -93,33 +93,30 @@ 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):
+ case false
+ when activeActionKeyword.Equals(ActionKeyword.QuickAccessActionKeyword):
+ return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks);
+
+ default:
searchResults = Settings.IndexProvider.SearchAsync(query.Search, token);
engineName = Enum.GetName(Settings.IndexSearchEngine);
break;
-
- case true or false
- when ActionKeywordMatch(query, Settings.ActionKeyword.QuickAccessActionKeyword):
- return QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks);
-
- default:
- return results.ToList();
}
// Merge Quick Access Link results for non-path searches.
- results.UnionWith(QuickAccess.AccessLinkListMatched(query, Settings.QuickAccessLinks));
-
+ MergeQuickAccessInResultsIfQueryMatch(results, query);
try
{
await foreach (var search in searchResults.WithCancellation(token).ConfigureAwait(false))
- if (search.Type == ResultType.File && IsExcludedFile(search)) {
+ {
+ if (ShouldSkip(activeActionKeyword!.Value, search))
+ {
continue;
- } else {
- results.Add(ResultManager.CreateResult(query, search));
}
+ results.Add(ResultManager.CreateResult(query, search));
+
+ }
}
catch (OperationCanceledException)
{
@@ -140,25 +137,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 +258,32 @@ private bool IsExcludedFile(SearchResult result)
return excludedFileTypes.Contains(fileExtension, StringComparer.OrdinalIgnoreCase);
}
+
+ private bool ShouldSkip(ActionKeyword actionKeywordActive, SearchResult search)
+ {
+ if (search.Type == ResultType.File && IsExcludedFile(search))
+ return true;
+
+ if (actionKeywordActive.Equals(ActionKeyword.FolderSearchActionKeyword)
+ && search.Type != ResultType.Folder)
+ {
+ return true;
+ }
+
+ if (actionKeywordActive.Equals(ActionKeyword.FileSearchActionKeyword)
+ && search.Type != ResultType.File)
+ {
+ return true;
+ }
+
+ 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 8d62531cd62..0b02c374bc5 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
{
@@ -58,6 +59,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;
@@ -154,13 +164,16 @@ public enum ContentIndexSearchEngineOption
#endregion
- internal enum ActionKeyword
+ public enum ActionKeyword
{
SearchActionKeyword,
PathSearchActionKeyword,
FileContentSearchActionKeyword,
IndexSearchActionKeyword,
- QuickAccessActionKeyword
+ QuickAccessActionKeyword,
+ FolderSearchActionKeyword,
+ FileSearchActionKeyword,
+
}
internal string GetActionKeyword(ActionKeyword actionKeyword) => actionKeyword switch
@@ -170,6 +183,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")
};
@@ -180,6 +195,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")
};
@@ -190,6 +207,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")
};
@@ -200,7 +219,23 @@ 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")
};
+
+ public ActionKeyword? 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;
+ var isEnabled = GetActionKeywordEnabled(action);
+ if (keywordStr == actionKeywordStr && isEnabled) return action;
+ }
+ return null;
+ }
+
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ViewModels/SettingsViewModel.cs
index 2d46c6307cc..c4ca3f85310 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")
};
}
@@ -465,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)
{