diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index 2a4270fb4b2..bc4e4b408df 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -1,8 +1,7 @@ +using Flow.Launcher.Plugin.SharedModels; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; -using static Flow.Launcher.Infrastructure.StringMatcher; namespace Flow.Launcher.Infrastructure { @@ -239,74 +238,6 @@ private static int CalculateSearchScore(string query, string stringToCompare, in 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 769237bcb03..76a370978bd 100644 --- a/Flow.Launcher.Infrastructure/UserSettings/Settings.cs +++ b/Flow.Launcher.Infrastructure/UserSettings/Settings.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.Text.Json.Serialization; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModels; namespace Flow.Launcher.Infrastructure.UserSettings { @@ -38,7 +39,7 @@ public string Language /// 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 @@ -48,8 +49,8 @@ public string QuerySearchPrecisionString { 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; @@ -58,8 +59,8 @@ public string QuerySearchPrecisionString { 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 698802ba3e6..0eefe5c4fbd 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 12e430e07d2..dd73eb0e523 100644 --- a/Flow.Launcher.Plugin/IPublicAPI.cs +++ b/Flow.Launcher.Plugin/IPublicAPI.cs @@ -1,5 +1,9 @@ -using System; +using Flow.Launcher.Plugin.SharedModels; +using JetBrains.Annotations; +using System; using System.Collections.Generic; +using System.IO; +using System.Threading; using System.Threading.Tasks; namespace Flow.Launcher.Plugin @@ -83,5 +87,18 @@ public interface IPublicAPI /// if you want to hook something like Ctrl+R, you should use this event /// event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent; + + MatchResult FuzzySearch(string query, string stringToCompare); + + Task HttpGetStringAsync(string url, CancellationToken token = default); + + Task HttpGetStreamAsync(string url, CancellationToken token = default); + + Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath); + + void AddActionKeyword(string pluginId, string newActionKeyword); + + void RemoveActionKeyword(string pluginId, string oldActionKeyword); + } } diff --git a/Flow.Launcher.Plugin/SharedModels/MatchResult.cs b/Flow.Launcher.Plugin/SharedModels/MatchResult.cs new file mode 100644 index 00000000000..5144eb61d66 --- /dev/null +++ b/Flow.Launcher.Plugin/SharedModels/MatchResult.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; + +namespace Flow.Launcher.Plugin.SharedModels +{ + 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 468b944573e..14a0fd92a05 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModels; namespace Flow.Launcher.Test { @@ -37,8 +38,8 @@ public List GetPrecisionScores() { 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 @@ public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring( $"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 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual( $"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 @@ public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord( 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 17673a62afa..427fd9fc639 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using System.Windows; using Squirrel; -using Flow.Launcher.Core; using Flow.Launcher.Core.Plugin; using Flow.Launcher.Core.Resource; using Flow.Launcher.Helper; @@ -14,6 +13,11 @@ using Flow.Launcher.Infrastructure.Image; using Flow.Launcher.Plugin; using Flow.Launcher.ViewModel; +using Flow.Launcher.Plugin.SharedModels; +using System.Threading; +using System.IO; +using Flow.Launcher.Infrastructure.Http; +using JetBrains.Annotations; namespace Flow.Launcher { @@ -127,6 +131,32 @@ public List GetAllPlugins() public event FlowLauncherGlobalKeyboardEventHandler GlobalKeyboardEvent; + public MatchResult FuzzySearch(string query, string stringToCompare) => StringMatcher.FuzzySearch(query, stringToCompare); + + public Task HttpGetStringAsync(string url, CancellationToken token = default) + { + return Http.GetAsync(url); + } + + public Task HttpGetStreamAsync(string url, CancellationToken token = default) + { + return Http.GetStreamAsync(url); + } + + public Task HttpDownloadAsync([NotNull] string url, [NotNull] string filePath) + { + return Http.DownloadAsync(url, filePath); + } + + public void AddActionKeyword(string pluginId, string newActionKeyword) + { + PluginManager.AddActionKeyword(pluginId, newActionKeyword); + } + + public void RemoveActionKeyword(string pluginId, string oldActionKeyword) + { + PluginManager.RemoveActionKeyword(pluginId, oldActionKeyword); + } #endregion #region Private Methods @@ -139,6 +169,7 @@ private bool KListener_hookedKeyboardCallback(KeyEvent keyevent, int vkcode, Spe } return true; } + #endregion } } diff --git a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs index 3c90f8712cb..98685dc1b72 100644 --- a/Flow.Launcher/ViewModel/SettingWindowViewModel.cs +++ b/Flow.Launcher/ViewModel/SettingWindowViewModel.cs @@ -17,6 +17,7 @@ using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Infrastructure.UserSettings; using Flow.Launcher.Plugin; +using Flow.Launcher.Plugin.SharedModels; namespace Flow.Launcher.ViewModel { @@ -153,7 +154,7 @@ public List QuerySearchPrecisionStrings { 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 c7013aa677b..60c4a0ee660 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.SharedModels; namespace Flow.Launcher.Plugin.BrowserBookmark.Commands { diff --git a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs index 624fe05bc80..0aa37cdf583 100644 --- a/Plugins/Flow.Launcher.Plugin.Sys/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Sys/Main.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; using System.Windows.Interop;