This commit is contained in:
VictoriousRaptor 2026-03-10 11:56:38 +08:00 committed by GitHub
commit 01f584227d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 69 additions and 9 deletions

View file

@ -157,7 +157,8 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
Type = EverythingApiDllImport.Everything_IsFolderResult(idx) ? ResultType.Folder :
EverythingApiDllImport.Everything_IsFileResult(idx) ? ResultType.File :
ResultType.Volume,
Score = (int)EverythingApiDllImport.Everything_GetResultRunCount( (uint)idx)
Score = Convert.ToInt32(EverythingApiDllImport.Everything_GetResultRunCount((uint)idx)),
HighlightData = EverythingHighlightStringToHighlightList(EverythingApiDllImport.Everything_GetResultHighlightedFileName((uint)idx))
};
yield return result;
@ -208,5 +209,55 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
}
finally { _semaphore.Release(); }
}
/// <summary>
/// Convert the highlighted string from Everything API to a list of highlight indexes for our Result.
/// </summary>
/// <param name="highlightString">Text inside a * quote is highlighted, two consecutive *'s is a single literal *. For example, in the highlighted text: abc*123* the 123 part is highlighted.</param>
/// <returns>A list of zero-based character indices that should be highlighted.</returns>
public static List<int> EverythingHighlightStringToHighlightList(string highlightString)
{
var highlightData = new List<int>();
if (string.IsNullOrEmpty(highlightString))
return highlightData;
var isHighlighted = false;
var actualIndex = 0; // Index in the actual string (without * markers)
var length = highlightString.Length;
for (var i = 0; i < length; i++)
{
if (highlightString[i] == '*')
{
// Check if it's a literal * (two consecutive *)
if (i + 1 < length && highlightString[i + 1] == '*')
{
// Two consecutive *'s represent a single literal *
if (isHighlighted)
{
highlightData.Add(actualIndex);
}
actualIndex++;
i++; // Skip the next *
}
else
{
isHighlighted = !isHighlighted;
}
}
else
{
// Regular character
if (isHighlighted)
{
highlightData.Add(actualIndex);
}
actualIndex++;
}
}
return highlightData;
}
}
}

View file

@ -147,7 +147,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
[DllImport(DLL)]
public static extern bool Everything_GetResultDateRecentlyChanged(uint nIndex, out long lpFileTime);
[DllImport(DLL, CharSet = CharSet.Unicode)]
public static extern IntPtr Everything_GetResultHighlightedFileName(uint nIndex);
public static extern string Everything_GetResultHighlightedFileName(uint nIndex);
[DllImport(DLL, CharSet = CharSet.Unicode)]
public static extern IntPtr Everything_GetResultHighlightedPath(uint nIndex);
[DllImport(DLL, CharSet = CharSet.Unicode)]

View file

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
@ -64,9 +65,9 @@ namespace Flow.Launcher.Plugin.Explorer.Search
return result.Type switch
{
ResultType.Folder or ResultType.Volume =>
CreateFolderResult(Path.GetFileName(result.FullPath), result.FullPath, result.FullPath, query, result.Score, result.WindowsIndexed),
CreateFolderResult(Path.GetFileName(result.FullPath), result.FullPath, result.FullPath, query, result.Score, result.WindowsIndexed, result.HighlightData),
ResultType.File =>
CreateFileResult(result.FullPath, query, result.Score, result.WindowsIndexed),
CreateFileResult(result.FullPath, query, result.Score, result.WindowsIndexed, result.HighlightData),
_ => throw new ArgumentOutOfRangeException(null)
};
}
@ -92,7 +93,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
}
}
internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, int score = 0, bool windowsIndexed = false)
internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, int score = 0, bool windowsIndexed = false, List<int> highlightData = null)
{
return new Result
{
@ -100,7 +101,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
IcoPath = path,
SubTitle = subtitle,
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
TitleHighlightData = highlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
CopyText = path,
Preview = new Result.PreviewInfo
{
@ -282,7 +283,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false)
internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false, List<int> highlightData = null)
{
var isMedia = IsMedia(Path.GetExtension(filePath));
var title = Path.GetFileName(filePath) ?? string.Empty;
@ -302,7 +303,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
FilePath = filePath,
},
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
TitleHighlightData = Context.API.FuzzySearch(query.Search, title).MatchData,
TitleHighlightData = highlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
PreviewPanel = new Lazy<UserControl>(() => new PreviewPanel(Settings, filePath, ResultType.File)),

View file

@ -1,11 +1,19 @@
using System.Collections.Generic;
namespace Flow.Launcher.Plugin.Explorer.Search
{
public record struct SearchResult
public readonly record struct SearchResult
{
// Constructor is necesssary for record struct
public SearchResult()
{
}
public string FullPath { get; init; }
public ResultType Type { get; init; }
public int Score { get; init; }
public bool WindowsIndexed { get; init; }
public List<int> HighlightData { get; init; } = [];
}
}