diff --git a/BrowserSearch/Main.cs b/BrowserSearch/Main.cs index f75b21c..c511b73 100644 --- a/BrowserSearch/Main.cs +++ b/BrowserSearch/Main.cs @@ -267,17 +267,40 @@ public List Query(Query query) private int CalculateScore(string query, string title, string url) { // Since PT Run's FuzzySearch is too slow, and the history usually has a lot of entries, - // lets calculate the scores manually using a faster (but less accurate) method - float titleScore = title.Contains(query, StringComparison.InvariantCultureIgnoreCase) - ? (query.Length / (float)title.Length * 100f) - : 0; - float urlScore = url.Contains(query, StringComparison.InvariantCultureIgnoreCase) - ? (query.Length / (float)url.Length * 100f) - : 0; + // lets calculate the scores manually using a faster (but less accurate) method. + // Multi-token: every whitespace-separated token must appear in title or url (AND). + string[] tokens = query.Split(' ', StringSplitOptions.RemoveEmptyEntries); + if (tokens.Length == 0) + { + return 0; + } - float score = new[] { titleScore, urlScore }.Max(); - score += _defaultBrowser!.CalculateExtraScore(query, title, url); + float score = 0; + foreach (string token in tokens) + { + bool inTitle = title.Contains(token, StringComparison.InvariantCultureIgnoreCase); + bool inUrl = url.Contains(token, StringComparison.InvariantCultureIgnoreCase); + if (!inTitle && !inUrl) + { + return 0; + } + + float titleContrib = inTitle ? token.Length / (float)title.Length * 100f : 0f; + float urlContrib = inUrl ? token.Length / (float)url.Length * 100f : 0f; + score += Math.Max(titleContrib, urlContrib); + } + // Bonus when the whole query appears contiguously, so phrase matches still outrank scattered tokens + if (title.Contains(query, StringComparison.InvariantCultureIgnoreCase)) + { + score += query.Length / (float)title.Length * 100f; + } + else if (url.Contains(query, StringComparison.InvariantCultureIgnoreCase)) + { + score += query.Length / (float)url.Length * 100f; + } + + score += _defaultBrowser!.CalculateExtraScore(query, title, url); return (int)score; } }