diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index 2a4270fb4..300404b9e 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -1,3 +1,4 @@ +using Flow.Launcher.Plugin.SharedModel; using System; using System.Collections.Generic; using System.ComponentModel; @@ -239,75 +240,9 @@ namespace Flow.Launcher.Infrastructure return score; } - - public enum SearchPrecisionScore - { - Regular = 50, - Low = 20, - None = 0 - } } - public class MatchResult - { - public MatchResult(bool success, SearchPrecisionScore searchPrecision) - { - Success = success; - SearchPrecision = searchPrecision; - } - - public MatchResult(bool success, SearchPrecisionScore searchPrecision, List matchData, int rawScore) - { - Success = success; - SearchPrecision = searchPrecision; - MatchData = matchData; - RawScore = rawScore; - } - - public bool Success { get; set; } - - /// - /// The final score of the match result with search precision filters applied. - /// - public int Score { get; private set; } - - /// - /// The raw calculated search score without any search precision filtering applied. - /// - private int _rawScore; - - public int RawScore - { - get { return _rawScore; } - set - { - _rawScore = value; - Score = ScoreAfterSearchPrecisionFilter(_rawScore); - } - } - - /// - /// Matched data to highlight. - /// - public List MatchData { get; set; } - - public SearchPrecisionScore SearchPrecision { get; set; } - - public bool IsSearchPrecisionScoreMet() - { - return IsSearchPrecisionScoreMet(_rawScore); - } - - private bool IsSearchPrecisionScoreMet(int rawScore) - { - return rawScore >= (int)SearchPrecision; - } - - private int ScoreAfterSearchPrecisionFilter(int rawScore) - { - return IsSearchPrecisionScoreMet(rawScore) ? rawScore : 0; - } - } + public class MatchOption { diff --git a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs index 837fe3b71..891ce7924 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -4,6 +4,7 @@ using System.Drawing; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModel; namespace Flow.Launcher.Infrastructure.UserSettings { @@ -30,7 +31,7 @@ namespace Flow.Launcher.Infrastructure.UserSettings /// public bool ShouldUsePinyin { get; set; } = false; - internal StringMatcher.SearchPrecisionScore QuerySearchPrecision { get; private set; } = StringMatcher.SearchPrecisionScore.Regular; + internal SearchPrecisionScore QuerySearchPrecision { get; private set; } = SearchPrecisionScore.Regular; [JsonIgnore] public string QuerySearchPrecisionString @@ -40,8 +41,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings { try { - var precisionScore = (StringMatcher.SearchPrecisionScore)Enum - .Parse(typeof(StringMatcher.SearchPrecisionScore), value); + var precisionScore = (SearchPrecisionScore)Enum + .Parse(typeof(SearchPrecisionScore), value); QuerySearchPrecision = precisionScore; StringMatcher.Instance.UserSettingSearchPrecision = precisionScore; @@ -50,8 +51,8 @@ namespace Flow.Launcher.Infrastructure.UserSettings { Logger.Log.Exception(nameof(Settings), "Failed to load QuerySearchPrecisionString value from Settings file", e); - QuerySearchPrecision = StringMatcher.SearchPrecisionScore.Regular; - StringMatcher.Instance.UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular; + QuerySearchPrecision = SearchPrecisionScore.Regular; + StringMatcher.Instance.UserSettingSearchPrecision = SearchPrecisionScore.Regular; throw; } diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index 0f6450d18..cefbfb1c8 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 diff --git a/Flow.Launcher.Plugin/IPublicAPI.cs b/Flow.Launcher.Plugin/IPublicAPI.cs index b6f3f0680..ae554044e 100644 --- a/Flow.Launcher.Plugin/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/IPublicAPI.cs @@ -1,4 +1,5 @@ -using System; +using Flow.Launcher.Plugin.SharedModel; +using System; using System.Collections.Generic; namespace Flow.Launcher.Plugin @@ -89,6 +90,6 @@ namespace Flow.Launcher.Plugin /// event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent; - public (List MatchedData, int Score, bool Success) MatchString(string query, string stringToCompare); + public MatchResult FuzzySearch(string query, string stringToCompare); } } diff --git a/Flow.Launcher.Plugin/SharedModel/MatchResult.cs b/Flow.Launcher.Plugin/SharedModel/MatchResult.cs new file mode 100644 index 000000000..26fc09cb9 --- /dev/null +++ b/Flow.Launcher.Plugin/SharedModel/MatchResult.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Flow.Launcher.Plugin.SharedModel +{ + public class MatchResult + { + public MatchResult(bool success, SearchPrecisionScore searchPrecision) + { + Success = success; + SearchPrecision = searchPrecision; + } + + public MatchResult(bool success, SearchPrecisionScore searchPrecision, List matchData, int rawScore) + { + Success = success; + SearchPrecision = searchPrecision; + MatchData = matchData; + RawScore = rawScore; + } + + public bool Success { get; set; } + + /// + /// The final score of the match result with search precision filters applied. + /// + public int Score { get; private set; } + + /// + /// The raw calculated search score without any search precision filtering applied. + /// + private int _rawScore; + + public int RawScore + { + get { return _rawScore; } + set + { + _rawScore = value; + Score = ScoreAfterSearchPrecisionFilter(_rawScore); + } + } + + /// + /// Matched data to highlight. + /// + public List MatchData { get; set; } + + public SearchPrecisionScore SearchPrecision { get; set; } + + public bool IsSearchPrecisionScoreMet() + { + return IsSearchPrecisionScoreMet(_rawScore); + } + + private bool IsSearchPrecisionScoreMet(int rawScore) + { + return rawScore >= (int)SearchPrecision; + } + + private int ScoreAfterSearchPrecisionFilter(int rawScore) + { + return IsSearchPrecisionScoreMet(rawScore) ? rawScore : 0; + } + } + + public enum SearchPrecisionScore + { + Regular = 50, + Low = 20, + None = 0 + } +} diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index 468b94457..97e5f2574 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -5,6 +5,7 @@ using System.Linq; using NUnit.Framework; using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModel; namespace Flow.Launcher.Test { @@ -37,8 +38,8 @@ namespace Flow.Launcher.Test { var listToReturn = new List(); - Enum.GetValues(typeof(StringMatcher.SearchPrecisionScore)) - .Cast() + Enum.GetValues(typeof(SearchPrecisionScore)) + .Cast() .ToList() .ForEach(x => listToReturn.Add((int)x)); @@ -145,20 +146,20 @@ namespace Flow.Launcher.Test $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}"); } - [TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("chr", "Google Chrome", StringMatcher.SearchPrecisionScore.Low, true)] - [TestCase("chr", "Chrome", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("chr", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Low, true)] - [TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("chr", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.None, true)] - [TestCase("ccs", "Candy Crush Saga from King", StringMatcher.SearchPrecisionScore.Low, true)] - [TestCase("cand", "Candy Crush Saga from King",StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("cand", "Help cure hope raise on mind entity Chrome", StringMatcher.SearchPrecisionScore.Regular, false)] + [TestCase("goo", "Google Chrome", SearchPrecisionScore.Regular, true)] + [TestCase("chr", "Google Chrome", SearchPrecisionScore.Low, true)] + [TestCase("chr", "Chrome", SearchPrecisionScore.Regular, true)] + [TestCase("chr", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Regular, false)] + [TestCase("chr", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Low, true)] + [TestCase("chr", "Candy Crush Saga from King", SearchPrecisionScore.Regular, false)] + [TestCase("chr", "Candy Crush Saga from King", SearchPrecisionScore.None, true)] + [TestCase("ccs", "Candy Crush Saga from King", SearchPrecisionScore.Low, true)] + [TestCase("cand", "Candy Crush Saga from King",SearchPrecisionScore.Regular, true)] + [TestCase("cand", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Regular, false)] public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual( string queryString, string compareString, - StringMatcher.SearchPrecisionScore expectedPrecisionScore, + SearchPrecisionScore expectedPrecisionScore, bool expectedPrecisionResult) { // When @@ -182,32 +183,32 @@ namespace Flow.Launcher.Test $"Precision Score: {(int)expectedPrecisionScore}"); } - [TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("term", "Windows Terminal (Preview)", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sql s managa", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("sql s manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("servez", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("sql servz", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("sql serv man", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sql studio", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("mic", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("chr", "Shutdown", StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("mssms", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("a test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("test", "This is a test", StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("cod", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("code", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("codes", "Visual Studio Codes", StringMatcher.SearchPrecisionScore.Regular, true)] + [TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", SearchPrecisionScore.Regular, false)] + [TestCase("term", "Windows Terminal (Preview)", SearchPrecisionScore.Regular, true)] + [TestCase("sql s managa", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)] + [TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)] + [TestCase("sql s manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("sql manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("sql", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("sql serv", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("servez", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)] + [TestCase("sql servz", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)] + [TestCase("sql serv man", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("sql studio", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("mic", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)] + [TestCase("chr", "Shutdown", SearchPrecisionScore.Regular, false)] + [TestCase("mssms", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)] + [TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", SearchPrecisionScore.Regular, false)] + [TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).", SearchPrecisionScore.Regular, true)] + [TestCase("a test", "This is a test", SearchPrecisionScore.Regular, true)] + [TestCase("test", "This is a test", SearchPrecisionScore.Regular, true)] + [TestCase("cod", VisualStudioCode, SearchPrecisionScore.Regular, true)] + [TestCase("code", VisualStudioCode, SearchPrecisionScore.Regular, true)] + [TestCase("codes", "Visual Studio Codes", SearchPrecisionScore.Regular, true)] public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings( string queryString, string compareString, - StringMatcher.SearchPrecisionScore expectedPrecisionScore, + SearchPrecisionScore expectedPrecisionScore, bool expectedPrecisionResult) { // When @@ -238,7 +239,7 @@ namespace Flow.Launcher.Test string queryString, string compareString1, string compareString2) { // When - var matcher = new StringMatcher { UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular }; + var matcher = new StringMatcher { UserSettingSearchPrecision = SearchPrecisionScore.Regular }; // Given var compareString1Result = matcher.FuzzyMatch(queryString, compareString1); diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 5d1ea7f24..9cf3b0f4e 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -14,6 +14,7 @@ using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Plugin; using Flow.Launcher.ViewModel; +using Flow.Launcher.Plugin.SharedModel; namespace Flow.Launcher { @@ -132,11 +133,7 @@ namespace Flow.Launcher public event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent; - public (List MatchedData, int Score, bool Success) MatchString(string query, string stringToCompare) - { - var result = StringMatcher.FuzzySearch(query, stringToCompare); - return (result.MatchData, result.Score, result.Success); - } + public MatchResult FuzzySearch(string query, string stringToCompare) => StringMatcher.FuzzySearch(query, stringToCompare); #endregion diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 853925852..5eec3962a 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -17,6 +17,7 @@ using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModel; namespace Flow.Launcher.ViewModel { @@ -152,7 +153,7 @@ namespace Flow.Launcher.ViewModel { var precisionStrings = new List(); - var enumList = Enum.GetValues(typeof(StringMatcher.SearchPrecisionScore)).Cast().ToList(); + var enumList = Enum.GetValues(typeof(SearchPrecisionScore)).Cast().ToList(); enumList.ForEach(x => precisionStrings.Add(x.ToString())); diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs index c7013aa67..4e3f4f513 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Commands/Bookmarks.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Flow.Launcher.Infrastructure; +using Flow.Launcher.Plugin.SharedModel; namespace Flow.Launcher.Plugin.BrowserBookmark.Commands {