From cfd705ca68e56c4d75016ed6ed3793ae5feabe56 Mon Sep 17 00:00:00 2001
From: VictoriousRaptor <10308169+VictoriousRaptor@users.noreply.github.com>
Date: Fri, 2 Jan 2026 23:33:45 +0800
Subject: [PATCH 1/8] Use Highlight matches from Everything
To solve inaccurate highlight when facing Chinese Pinyin searches
---
.../Search/Everything/EverythingAPI.cs | 53 ++++++++++++++++++-
.../Everything/EverythingApiDllImport.cs | 2 +-
.../Search/ResultManager.cs | 13 ++---
.../Search/SearchResult.cs | 7 +++
4 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
index a4e959dd9..4dee3fdbd 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
@@ -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 = (int)EverythingApiDllImport.Everything_GetResultRunCount( (uint)idx),
+ HighlightData = EverythingHightlightStringToHighlightList(EverythingApiDllImport.Everything_GetResultHighlightedFileName((uint)idx))
};
yield return result;
@@ -208,5 +209,55 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
}
finally { _semaphore.Release(); }
}
+
+ ///
+ /// Convert the highlighted string from Everything API to a list of highlight indexes for our Result.
+ ///
+ /// 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.
+ ///
+ public static List EverythingHightlightStringToHighlightList(string highlightString)
+ {
+ var highlightData = new List();
+
+ 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;
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs
index c952a980c..f010f4dfe 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingApiDllImport.cs
@@ -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)]
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 18eb168b9..8b4004eb9 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -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 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 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(() => new PreviewPanel(Settings, filePath, ResultType.File)),
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
index 3cd97df82..148072931 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
@@ -1,11 +1,18 @@
+using System.Collections.Generic;
+
namespace Flow.Launcher.Plugin.Explorer.Search
{
public record struct SearchResult
{
+ public SearchResult()
+ {
+ }
+
public string FullPath { get; init; }
public ResultType Type { get; init; }
public int Score { get; init; }
public bool WindowsIndexed { get; init; }
+ public List HighlightData { get; init; } = null;
}
}
From 79bdd3c691a05884ce61b066c383c0ffcabaa008 Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 Jan 2026 20:29:12 +0800
Subject: [PATCH 2/8] Fix typos
---
.../Search/Everything/EverythingAPI.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
index 4dee3fdbd..7225f61d6 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
@@ -158,7 +158,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
EverythingApiDllImport.Everything_IsFileResult(idx) ? ResultType.File :
ResultType.Volume,
Score = (int)EverythingApiDllImport.Everything_GetResultRunCount( (uint)idx),
- HighlightData = EverythingHightlightStringToHighlightList(EverythingApiDllImport.Everything_GetResultHighlightedFileName((uint)idx))
+ HighlightData = EverythingHighlightStringToHighlightList(EverythingApiDllImport.Everything_GetResultHighlightedFileName((uint)idx))
};
yield return result;
@@ -215,7 +215,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
///
/// 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.
///
- public static List EverythingHightlightStringToHighlightList(string highlightString)
+ public static List EverythingHighlightStringToHighlightList(string highlightString)
{
var highlightData = new List();
From 3129bddd24cf4e7377bf255e960b3e92db366b02 Mon Sep 17 00:00:00 2001
From: Jack Ye
Date: Sat, 3 Jan 2026 20:34:05 +0800
Subject: [PATCH 3/8] Update comments
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../Search/Everything/EverythingAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
index 7225f61d6..0d42dbb8e 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
@@ -214,7 +214,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search.Everything
/// Convert the highlighted string from Everything API to a list of highlight indexes for our Result.
///
/// 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.
- ///
+ /// A list of zero-based character indices that should be highlighted.
public static List EverythingHighlightStringToHighlightList(string highlightString)
{
var highlightData = new List();
From 7e9dc186761d33a29faf9ea160822b096dbe7f5a Mon Sep 17 00:00:00 2001
From: Jack Ye
Date: Sat, 3 Jan 2026 20:34:51 +0800
Subject: [PATCH 4/8] Remove unnecessary constructor
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs | 4 ----
1 file changed, 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
index 148072931..39e4119bf 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
@@ -4,10 +4,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
public record struct SearchResult
{
- public SearchResult()
- {
- }
-
public string FullPath { get; init; }
public ResultType Type { get; init; }
public int Score { get; init; }
From 047d4ddc34b071ef3ff6002301648fbde5fbaa0f Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Sat, 3 Jan 2026 20:36:01 +0800
Subject: [PATCH 5/8] Use camel case for parameters
---
.../Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
index 8b4004eb9..60073ce5f 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
@@ -93,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, List HighlightData = null)
+ internal static Result CreateFolderResult(string title, string subtitle, string path, Query query, int score = 0, bool windowsIndexed = false, List highlightData = null)
{
return new Result
{
@@ -101,7 +101,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
IcoPath = path,
SubTitle = subtitle,
AutoCompleteText = GetAutoCompleteText(title, query, path, ResultType.Folder),
- TitleHighlightData = HighlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
+ TitleHighlightData = highlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
CopyText = path,
Preview = new Result.PreviewInfo
{
@@ -283,7 +283,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
};
}
- internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false, List HighlightData = null)
+ internal static Result CreateFileResult(string filePath, Query query, int score = 0, bool windowsIndexed = false, List highlightData = null)
{
var isMedia = IsMedia(Path.GetExtension(filePath));
var title = Path.GetFileName(filePath) ?? string.Empty;
@@ -303,7 +303,7 @@ namespace Flow.Launcher.Plugin.Explorer.Search
FilePath = filePath,
},
AutoCompleteText = GetAutoCompleteText(title, query, filePath, ResultType.File),
- TitleHighlightData = HighlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
+ TitleHighlightData = highlightData ?? Context.API.FuzzySearch(query.Search, title).MatchData,
Score = score,
CopyText = filePath,
PreviewPanel = new Lazy(() => new PreviewPanel(Settings, filePath, ResultType.File)),
From 43df5e174482e445c3874057d02c04ee9d31f7e3 Mon Sep 17 00:00:00 2001
From: Jack Ye
Date: Sat, 3 Jan 2026 20:37:16 +0800
Subject: [PATCH 6/8] Use ToInt32 instead of explicit converting
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../Search/Everything/EverythingAPI.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
index 0d42dbb8e..a78628469 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Everything/EverythingAPI.cs
@@ -157,7 +157,7 @@ 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))
};
From 10f160d9a2b07aa392a921a2a37f709fc07fa8fe Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 Jan 2026 09:43:48 +0800
Subject: [PATCH 7/8] Revert "Remove unnecessary constructor"
This reverts commit 7e9dc186761d33a29faf9ea160822b096dbe7f5a.
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
index 39e4119bf..148072931 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
@@ -4,6 +4,10 @@ namespace Flow.Launcher.Plugin.Explorer.Search
{
public record struct SearchResult
{
+ public SearchResult()
+ {
+ }
+
public string FullPath { get; init; }
public ResultType Type { get; init; }
public int Score { get; init; }
From 43d3963e3dd09b67324b45f51e46c92e2570ecdb Mon Sep 17 00:00:00 2001
From: Jack251970 <1160210343@qq.com>
Date: Mon, 5 Jan 2026 09:45:32 +0800
Subject: [PATCH 8/8] Make SearchResult readonly and init HighlightData to
empty list
Changed SearchResult to a readonly record struct for better immutability and performance. Updated HighlightData to initialize as an empty list using a collection expression instead of null. Retained the default constructor with a clarifying comment.
---
Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
index 148072931..e2ff216ca 100644
--- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
+++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/SearchResult.cs
@@ -2,8 +2,9 @@
namespace Flow.Launcher.Plugin.Explorer.Search
{
- public record struct SearchResult
+ public readonly record struct SearchResult
{
+ // Constructor is necesssary for record struct
public SearchResult()
{
}
@@ -13,6 +14,6 @@ namespace Flow.Launcher.Plugin.Explorer.Search
public int Score { get; init; }
public bool WindowsIndexed { get; init; }
- public List HighlightData { get; init; } = null;
+ public List HighlightData { get; init; } = [];
}
}