mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Let index provider filter result type
This commit is contained in:
parent
8092a440f4
commit
6fa719dde3
4 changed files with 65 additions and 6 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -72,14 +73,16 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async IAsyncEnumerable<SearchResult> SearchAsync(string search, [EnumeratorCancellation] CancellationToken token)
|
public async IAsyncEnumerable<SearchResult> SearchAsync(string search, [EnumeratorCancellation] CancellationToken token, IEnumerable<ResultType> allowedResultTypes = null)
|
||||||
{
|
{
|
||||||
await ThrowIfEverythingNotAvailableAsync(token);
|
await ThrowIfEverythingNotAvailableAsync(token);
|
||||||
|
|
||||||
if (token.IsCancellationRequested)
|
if (token.IsCancellationRequested)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
var option = new EverythingSearchOption(search,
|
var searchKeyword = BuildSearchKeywordWithTypeFilter(search, allowedResultTypes);
|
||||||
|
|
||||||
|
var option = new EverythingSearchOption(searchKeyword,
|
||||||
Settings.SortOption,
|
Settings.SortOption,
|
||||||
MaxCount: Settings.MaxResult,
|
MaxCount: Settings.MaxResult,
|
||||||
IsFullPathSearch: Settings.EverythingSearchFullPath,
|
IsFullPathSearch: Settings.EverythingSearchFullPath,
|
||||||
|
|
@ -89,6 +92,33 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
|
||||||
yield return result;
|
yield return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string BuildSearchKeywordWithTypeFilter(string search, IEnumerable<ResultType> allowedResultTypes)
|
||||||
|
{
|
||||||
|
if (allowedResultTypes == null)
|
||||||
|
return search;
|
||||||
|
|
||||||
|
var typesList = allowedResultTypes as IList<ResultType> ?? allowedResultTypes.ToList();
|
||||||
|
if (typesList.Count == 0 || typesList.Count == 3)
|
||||||
|
return search; // No filtering needed
|
||||||
|
|
||||||
|
var hasFile = typesList.Contains(ResultType.File);
|
||||||
|
var hasFolder = typesList.Contains(ResultType.Folder);
|
||||||
|
var hasVolume = typesList.Contains(ResultType.Volume);
|
||||||
|
|
||||||
|
var filter = (hasFile, hasFolder, hasVolume) switch
|
||||||
|
{
|
||||||
|
(true, false, false) => "file:",
|
||||||
|
(false, true, false) => "folder:",
|
||||||
|
(false, false, true) => "volume:",
|
||||||
|
(true, true, false) => "<file:|folder:>",
|
||||||
|
(true, false, true) => "<file:|volume:>",
|
||||||
|
(false, true, true) => "<folder:|volume:>",
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
|
||||||
|
return filter == null ? search : $"{filter} {search}";
|
||||||
|
}
|
||||||
|
|
||||||
public async IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch, string contentSearch,
|
public async IAsyncEnumerable<SearchResult> ContentSearchAsync(string plainSearch, string contentSearch,
|
||||||
[EnumeratorCancellation] CancellationToken token)
|
[EnumeratorCancellation] CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,18 @@ using System.Threading;
|
||||||
|
|
||||||
namespace Flow.Launcher.Plugin.Explorer.Search.IProvider
|
namespace Flow.Launcher.Plugin.Explorer.Search.IProvider
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functionality for searching indexed items.
|
||||||
|
/// </summary>
|
||||||
public interface IIndexProvider
|
public interface IIndexProvider
|
||||||
{
|
{
|
||||||
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token);
|
/// <summary>
|
||||||
|
/// Asynchronously searches for items matching the specified search criteria.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="search">The search query string.</param>
|
||||||
|
/// <param name="token">The cancellation token to cancel the search operation.</param>
|
||||||
|
/// <param name="allowedResultTypes">Optional collection of result types to filter the search results. If null, all result types are included.</param>
|
||||||
|
/// <returns>An asynchronous enumerable of <see cref="SearchResult"/> objects matching the search criteria.</returns>
|
||||||
|
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token, IEnumerable<ResultType> allowedResultTypes = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
|
|
||||||
case false
|
case false
|
||||||
when CanUseIndexSearchByActionKeywords(activeActionKeywords):
|
when CanUseIndexSearchByActionKeywords(activeActionKeywords):
|
||||||
searchResults = Settings.IndexProvider.SearchAsync(query.Search, token);
|
searchResults = Settings.IndexProvider.SearchAsync(query.Search, token, GetAllowedResultTypeByUsedActionKeyword(activeActionKeywords));
|
||||||
engineName = Enum.GetName(Settings.IndexSearchEngine);
|
engineName = Enum.GetName(Settings.IndexSearchEngine);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -150,7 +150,11 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
{
|
{
|
||||||
if (search.Type == ResultType.File && IsExcludedFile(search))
|
if (search.Type == ResultType.File && IsExcludedFile(search))
|
||||||
continue;
|
continue;
|
||||||
|
// TODO: Optimize filtering by action keyword at the provider level to reduce unnecessary searches.
|
||||||
|
// 1. Path search and content search may not need filtering as they are specific enough.
|
||||||
|
// 2. Index search can be optimized by passing allowed result types to the provider to limit the search scope.
|
||||||
|
// 3. Quick access link filtering is already handled separately.
|
||||||
|
//
|
||||||
if (IsResultTypeFilteredByActionKeyword(search.Type, actions))
|
if (IsResultTypeFilteredByActionKeyword(search.Type, actions))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -329,6 +333,20 @@ namespace Flow.Launcher.Plugin.Explorer.Search
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ResultType> GetAllowedResultTypeByUsedActionKeyword(Dictionary<ActionKeyword, string> activeActionKeywords)
|
||||||
|
{
|
||||||
|
List<ActionKeyword> activeKeywords = activeActionKeywords.Keys.ToList();
|
||||||
|
var allowedResultTypes = new List<ResultType>();
|
||||||
|
foreach (var actionKeyword in activeKeywords)
|
||||||
|
{
|
||||||
|
if (_allowedTypesByActionKeyword.TryGetValue(actionKeyword, out var resultTypes))
|
||||||
|
{
|
||||||
|
allowedResultTypes.AddRange(resultTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allowedResultTypes.Distinct().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
private bool CanUseIndexSearchByActionKeywords(Dictionary<ActionKeyword, string> actions)
|
private bool CanUseIndexSearchByActionKeywords(Dictionary<ActionKeyword, string> actions)
|
||||||
{
|
{
|
||||||
var keysToUseIndexSearch = new[]
|
var keysToUseIndexSearch = new[]
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search.WindowsIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token)
|
public IAsyncEnumerable<SearchResult> SearchAsync(string search, CancellationToken token, IEnumerable<ResultType> allowedResultTypes = null)
|
||||||
{
|
{
|
||||||
|
// TODO: result type filter
|
||||||
return WindowsIndexFilesAndFoldersSearchAsync(search, token: token);
|
return WindowsIndexFilesAndFoldersSearchAsync(search, token: token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue