From 30c37f06ae9142a172cedbbb980bbd7dcbfdf6d1 Mon Sep 17 00:00:00 2001 From: Alekhya Date: Mon, 1 Jun 2020 15:25:14 -0700 Subject: [PATCH 01/44] Take space into consideration while calculating the first matched index (#3874) --- Flow.Launcher.Infrastructure/StringMatcher.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index aef8bf7ed43..94e119bcc17 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -83,9 +83,18 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption bool allSubstringsContainedInCompareString = true; var indexList = new List(); + List spaceIndices = new List(); for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++) { + + // To maintain a list of indices which correspond to spaces in the string to compare + // To populate the list only for the first query substring + if (fullStringToCompareWithoutCase[compareStringIndex].Equals(' ') && currentQuerySubstringIndex == 0) + { + spaceIndices.Add(compareStringIndex); + } + if (fullStringToCompareWithoutCase[compareStringIndex] != currentQuerySubstring[currentQuerySubstringCharacterIndex]) { matchFoundInPreviousLoop = false; @@ -147,7 +156,8 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption // proceed to calculate score if every char or substring without whitespaces matched if (allQuerySubstringsMatched) { - var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString); + var nearestSpaceIndex = CalculateClosestSpaceIndex(spaceIndices, firstMatchIndex); + var score = CalculateSearchScore(query, stringToCompare, firstMatchIndex - nearestSpaceIndex - 1, lastMatchIndex - firstMatchIndex, allSubstringsContainedInCompareString); return new MatchResult(true, UserSettingSearchPrecision, indexList, score); } @@ -155,6 +165,21 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption return new MatchResult (false, UserSettingSearchPrecision); } + // To get the index of the closest space which preceeds the first matching index + private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex) + { + if(spaceIndices.Count == 0) + { + return -1; + } + else + { + int? ind = spaceIndices.OrderBy(item => (firstMatchIndex - item)).Where(item => firstMatchIndex > item).FirstOrDefault(); + int closestSpaceIndex = ind ?? -1; + return closestSpaceIndex; + } + } + private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex, string fullStringToCompareWithoutCase, string currentQuerySubstring) { From d35b5169b584973ebd02b7670f0654199702a53d Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 22 Jun 2020 21:09:08 +1000 Subject: [PATCH 02/44] Add unit test more weight to start of new word --- Flow.Launcher.Test/FuzzyMatcherTest.cs | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index 68d5d43ace3..e65846bd8f7 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -225,5 +225,33 @@ public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings( $"Raw Score: {matchResult.RawScore}{Environment.NewLine}" + $"Precision Score: {(int)expectedPrecisionScore}"); } + + [TestCase("man", "Task Manager", "eManual")] + [TestCase("term", "Windows Terminal", "Character Map")] + [TestCase("winterm", "Windows Terminal", "Cygwin64 Terminal")] + public void WhenGivenAQueryResultsShouldGiveMoreScoreWeightToStartOfNewWord(string queryString, string compareString1, string compareString2) + { + // When + var matcher = new StringMatcher { UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular }; + + // Given + var compareString1Result = matcher.FuzzyMatch(queryString, compareString1); + var compareString2Result = matcher.FuzzyMatch(queryString, compareString2); + + Debug.WriteLine(""); + Debug.WriteLine("###############################################"); + Debug.WriteLine($"QueryString: \"{queryString}\"{Environment.NewLine}"); + Debug.WriteLine($"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}"); + Debug.WriteLine($"CompareString2: \"{compareString2}\", Score: {compareString2Result.Score}{Environment.NewLine}"); + Debug.WriteLine("###############################################"); + Debug.WriteLine(""); + + // Should + Assert.True(compareString1Result.Score > compareString2Result.Score, + $"Query: \"{queryString}\"{Environment.NewLine} " + + $"CompareString1: \"{compareString1}\", Score: {compareString1Result.Score}{Environment.NewLine}" + + $"Should be greater than{ Environment.NewLine}" + + $"CompareString2: \"{compareString2}\", Score: {compareString1Result.Score}{Environment.NewLine}"); + } } } \ No newline at end of file From 11c4aeae67c51e3f828330c3eabedc6378715428 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 22 Jun 2020 22:36:16 +1000 Subject: [PATCH 03/44] fix testing to be more reflective of testing intent --- Flow.Launcher.Test/FuzzyMatcherTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index e65846bd8f7..8a023e152ea 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -185,8 +185,8 @@ public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual( [TestCase("sql manag", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] [TestCase("sql", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] [TestCase("sql serv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, true)] - [TestCase("sqlserv", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] - [TestCase("sql servman", MicrosoftSqlServerManagementStudio, StringMatcher.SearchPrecisionScore.Regular, false)] + [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)] From b0ec1375e76ab24ce2fd021e3f98921755ee7034 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 23 Jun 2020 18:50:47 +1000 Subject: [PATCH 04/44] add test to safe guard exact matches --- Flow.Launcher.Test/FuzzyMatcherTest.cs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index 8a023e152ea..8fec5a16889 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -253,5 +253,31 @@ public void WhenGivenAQueryResultsShouldGiveMoreScoreWeightToStartOfNewWord(stri $"Should be greater than{ Environment.NewLine}" + $"CompareString2: \"{compareString2}\", Score: {compareString1Result.Score}{Environment.NewLine}"); } + + [TestCase("vim", "Vim", "ignoreDescription", "ignore.exe", "Vim Diff", "ignoreDescription", "ignore.exe")] + public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore( + string queryString, string firstName, string firstDescription, string firstExecutableName, + string secondName, string secondDescription, string secondExecutableName) + { + // Act + var matcher = new StringMatcher(); + var firstNameMatch = matcher.FuzzyMatch(queryString, firstName).RawScore; + var firstDescriptionMatch = matcher.FuzzyMatch(queryString, firstDescription).RawScore; + var firstExecutableNameMatch = matcher.FuzzyMatch(queryString, firstExecutableName).RawScore; + + var secondNameMatch = matcher.FuzzyMatch(queryString, secondName).RawScore; + var secondDescriptionMatch = matcher.FuzzyMatch(queryString, secondDescription).RawScore; + var secondExecutableNameMatch = matcher.FuzzyMatch(queryString, secondExecutableName).RawScore; + + var firstScore = new[] { firstNameMatch, firstDescriptionMatch, firstExecutableNameMatch }.Max(); + var secondScore = new[] { secondNameMatch, secondDescriptionMatch, secondExecutableNameMatch }.Max(); + + // Assert + Assert.IsTrue(firstScore > secondScore, + $"Query: \"{queryString}\"{Environment.NewLine} " + + $"Name of first: \"{firstName}\", Final Score: {firstScore}{Environment.NewLine}" + + $"Should be greater than{ Environment.NewLine}" + + $"Name of second: \"{secondName}\", Final Score: {secondScore}{Environment.NewLine}"); + } } } \ No newline at end of file From c363b9a5c0ebea75ddb1e17a6d4a63f4f8bc5bfb Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 23 Jun 2020 18:54:39 +1000 Subject: [PATCH 05/44] update tests for string matcher we expect the score to change since we updated the logic for calculating the distance from the first match --- Flow.Launcher.Test/FuzzyMatcherTest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index 8fec5a16889..5ebd4e450f9 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -124,12 +124,12 @@ public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterT } [TestCase(Chrome, Chrome, 157)] - [TestCase(Chrome, LastIsChrome, 103)] - [TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 21)] - [TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 15)] + [TestCase(Chrome, LastIsChrome, 147)] + [TestCase(Chrome, HelpCureHopeRaiseOnMindEntityChrome, 25)] + [TestCase(Chrome, UninstallOrChangeProgramsOnYourComputer, 21)] [TestCase(Chrome, CandyCrushSagaFromKing, 0)] - [TestCase("sql", MicrosoftSqlServerManagementStudio, 56)] - [TestCase("sql manag", MicrosoftSqlServerManagementStudio, 99)]//double spacing intended + [TestCase("sql", MicrosoftSqlServerManagementStudio, 110)] + [TestCase("sql manag", MicrosoftSqlServerManagementStudio, 121)]//double spacing intended public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore) { // When, Given From c142a50272c166c78825319dde57153e3d01a852 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 23 Jun 2020 19:02:04 +1000 Subject: [PATCH 06/44] update unit test naming, no logic changes --- Flow.Launcher.Test/FuzzyMatcherTest.cs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Test/FuzzyMatcherTest.cs b/Flow.Launcher.Test/FuzzyMatcherTest.cs index 5ebd4e450f9..468b944573e 100644 --- a/Flow.Launcher.Test/FuzzyMatcherTest.cs +++ b/Flow.Launcher.Test/FuzzyMatcherTest.cs @@ -77,7 +77,7 @@ public void MatchTest() } [TestCase("Chrome")] - public void WhenGivenNotAllCharactersFoundInSearchStringThenShouldReturnZeroScore(string searchString) + public void WhenNotAllCharactersFoundInSearchString_ThenShouldReturnZeroScore(string searchString) { var compareString = "Can have rum only in my glass"; var matcher = new StringMatcher(); @@ -92,7 +92,7 @@ public void WhenGivenNotAllCharactersFoundInSearchStringThenShouldReturnZeroScor [TestCase("cand")] [TestCase("cpywa")] [TestCase("ccs")] - public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm) + public void GivenQueryString_WhenAppliedPrecisionFiltering_ThenShouldReturnGreaterThanPrecisionScoreResults(string searchTerm) { var results = new List(); var matcher = new StringMatcher(); @@ -107,7 +107,10 @@ public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterT foreach (var precisionScore in GetPrecisionScores()) { - var filteredResult = results.Where(result => result.Score >= precisionScore).Select(result => result).OrderByDescending(x => x.Score).ToList(); + var filteredResult = results.Where(result => result.Score >= precisionScore) + .Select(result => result) + .OrderByDescending(x => x.Score) + .ToList(); Debug.WriteLine(""); Debug.WriteLine("###############################################"); @@ -130,14 +133,16 @@ public void WhenGivenStringsAndAppliedPrecisionFilteringThenShouldReturnGreaterT [TestCase(Chrome, CandyCrushSagaFromKing, 0)] [TestCase("sql", MicrosoftSqlServerManagementStudio, 110)] [TestCase("sql manag", MicrosoftSqlServerManagementStudio, 121)]//double spacing intended - public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryString, string compareString, int expectedScore) + public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring( + string queryString, string compareString, int expectedScore) { // When, Given var matcher = new StringMatcher(); var rawScore = matcher.FuzzyMatch(queryString, compareString).RawScore; // Should - Assert.AreEqual(expectedScore, rawScore, $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}"); + Assert.AreEqual(expectedScore, rawScore, + $"Expected score for compare string '{compareString}': {expectedScore}, Actual: {rawScore}"); } [TestCase("goo", "Google Chrome", StringMatcher.SearchPrecisionScore.Regular, true)] @@ -150,7 +155,7 @@ public void WhenGivenQueryStringThenShouldReturnCurrentScoring(string queryStrin [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)] - public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual( + public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual( string queryString, string compareString, StringMatcher.SearchPrecisionScore expectedPrecisionScore, @@ -199,7 +204,7 @@ public void WhenGivenDesiredPrecisionThenShouldReturnAllResultsGreaterOrEqual( [TestCase("cod", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)] [TestCase("code", VisualStudioCode, StringMatcher.SearchPrecisionScore.Regular, true)] [TestCase("codes", "Visual Studio Codes", StringMatcher.SearchPrecisionScore.Regular, true)] - public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings( + public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings( string queryString, string compareString, StringMatcher.SearchPrecisionScore expectedPrecisionScore, @@ -229,7 +234,8 @@ public void WhenGivenQueryShouldReturnResultsContainingAllQuerySubstrings( [TestCase("man", "Task Manager", "eManual")] [TestCase("term", "Windows Terminal", "Character Map")] [TestCase("winterm", "Windows Terminal", "Cygwin64 Terminal")] - public void WhenGivenAQueryResultsShouldGiveMoreScoreWeightToStartOfNewWord(string queryString, string compareString1, string compareString2) + public void WhenGivenAQuery_Scoring_ShouldGiveMoreWeightToStartOfNewWord( + string queryString, string compareString1, string compareString2) { // When var matcher = new StringMatcher { UserSettingSearchPrecision = StringMatcher.SearchPrecisionScore.Regular }; From 3abd2d0b07b0ea18b031f2518fe440fdd5c6ae4f Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 23 Jun 2020 20:46:36 +1000 Subject: [PATCH 07/44] fix formatting --- Flow.Launcher.Infrastructure/StringMatcher.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher.Infrastructure/StringMatcher.cs b/Flow.Launcher.Infrastructure/StringMatcher.cs index 94e119bcc17..79ccfd7af44 100644 --- a/Flow.Launcher.Infrastructure/StringMatcher.cs +++ b/Flow.Launcher.Infrastructure/StringMatcher.cs @@ -162,13 +162,13 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption return new MatchResult(true, UserSettingSearchPrecision, indexList, score); } - return new MatchResult (false, UserSettingSearchPrecision); + return new MatchResult(false, UserSettingSearchPrecision); } // To get the index of the closest space which preceeds the first matching index private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchIndex) { - if(spaceIndices.Count == 0) + if (spaceIndices.Count == 0) { return -1; } @@ -180,7 +180,7 @@ private int CalculateClosestSpaceIndex(List spaceIndices, int firstMatchInd } } - private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex, + private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQuerySubstringCharacterIndex, string fullStringToCompareWithoutCase, string currentQuerySubstring) { var allMatch = true; @@ -324,13 +324,13 @@ private int ScoreAfterSearchPrecisionFilter(int rawScore) public class MatchOption { /// - /// prefix of match char, use for hightlight + /// prefix of match char, use for highlight /// [Obsolete("this is never used")] public string Prefix { get; set; } = ""; /// - /// suffix of match char, use for hightlight + /// suffix of match char, use for highlight /// [Obsolete("this is never used")] public string Suffix { get; set; } = ""; From 2fd318fcbf8998036de9cb3bffaabff4a8fe5e25 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Tue, 26 May 2020 03:44:17 +0300 Subject: [PATCH 08/44] refactor logging in Core.Plugin.PluginInstaller --- Flow.Launcher.Core/Plugin/PluginInstaller.cs | 27 +++++--------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs index df38ca608cd..efb239d7edb 100644 --- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs +++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs @@ -1,9 +1,10 @@ -using System; +using System; using System.IO; using System.Windows; using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; using Flow.Launcher.Plugin; +using Flow.Launcher.Infrastructure.Logger; namespace Flow.Launcher.Core.Plugin { @@ -107,36 +108,20 @@ private static PluginMetadata GetMetadataFromJson(string pluginDirectory) metadata = JsonConvert.DeserializeObject(File.ReadAllText(configPath)); metadata.PluginDirectory = pluginDirectory; } - catch (Exception) + catch (Exception e) { - string error = $"Parse plugin config {configPath} failed: json format is not valid"; -#if (DEBUG) - { - throw new Exception(error); - } -#endif + Log.Exception($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: invalid json format", e); return null; } - if (!AllowedLanguage.IsAllowed(metadata.Language)) { - string error = $"Parse plugin config {configPath} failed: invalid language {metadata.Language}"; -#if (DEBUG) - { - throw new Exception(error); - } -#endif + Log.Error($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: invalid language {metadata.Language}"); return null; } if (!File.Exists(metadata.ExecuteFilePath)) { - string error = $"Parse plugin config {configPath} failed: ExecuteFile {metadata.ExecuteFilePath} didn't exist"; -#if (DEBUG) - { - throw new Exception(error); - } -#endif + Log.Error($"|PluginInstaller.GetMetadataFromJson|plugin config {configPath} failed: file {metadata.ExecuteFilePath} doesn't exist"); return null; } From 4abc9d85519da7b9a0eedad612ea29387c3d9415 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Tue, 26 May 2020 04:00:33 +0300 Subject: [PATCH 09/44] refactor Core.Plugin.PluginConfig --- Flow.Launcher.Core/Plugin/PluginConfig.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginConfig.cs b/Flow.Launcher.Core/Plugin/PluginConfig.cs index d12dee0c438..c3653453707 100644 --- a/Flow.Launcher.Core/Plugin/PluginConfig.cs +++ b/Flow.Launcher.Core/Plugin/PluginConfig.cs @@ -1,10 +1,8 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.IO; -using System.Threading.Tasks; using Newtonsoft.Json; -using Flow.Launcher.Infrastructure.Exception; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Plugin; @@ -14,23 +12,17 @@ namespace Flow.Launcher.Core.Plugin internal abstract class PluginConfig { private const string PluginConfigName = "plugin.json"; - private static readonly List PluginMetadatas = new List(); /// - /// Parse plugin metadata in giving directories + /// Parse plugin metadata in the given directories /// /// /// public static List Parse(string[] pluginDirectories) { - PluginMetadatas.Clear(); + var allPluginMetadata = new List(); var directories = pluginDirectories.SelectMany(Directory.GetDirectories); - ParsePluginConfigs(directories); - return PluginMetadatas; - } - private static void ParsePluginConfigs(IEnumerable directories) - { // todo use linq when diable plugin is implmented since parallel.foreach + list is not thread saft foreach (var directory in directories) { @@ -50,10 +42,12 @@ private static void ParsePluginConfigs(IEnumerable directories) PluginMetadata metadata = GetPluginMetadata(directory); if (metadata != null) { - PluginMetadatas.Add(metadata); + allPluginMetadata.Add(metadata); } } } + + return allPluginMetadata; } private static PluginMetadata GetPluginMetadata(string pluginDirectory) @@ -81,7 +75,6 @@ private static PluginMetadata GetPluginMetadata(string pluginDirectory) return null; } - if (!AllowedLanguage.IsAllowed(metadata.Language)) { Log.Error($"|PluginConfig.GetPluginMetadata|Invalid language <{metadata.Language}> for config <{configPath}>"); From 0ddd7f24f43d3d3e715970aa5164d6a0ea0372fa Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Wed, 10 Jun 2020 01:59:25 +0300 Subject: [PATCH 10/44] define plugin metadata file name as constant --- Flow.Launcher.Core/Plugin/PluginConfig.cs | 7 +++---- Flow.Launcher.Core/Plugin/PluginInstaller.cs | 5 +++-- Flow.Launcher.Infrastructure/Constant.cs | 1 + Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs | 3 +-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginConfig.cs b/Flow.Launcher.Core/Plugin/PluginConfig.cs index c3653453707..b946fa44d21 100644 --- a/Flow.Launcher.Core/Plugin/PluginConfig.cs +++ b/Flow.Launcher.Core/Plugin/PluginConfig.cs @@ -1,8 +1,9 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.IO; using Newtonsoft.Json; +using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Plugin; @@ -11,8 +12,6 @@ namespace Flow.Launcher.Core.Plugin internal abstract class PluginConfig { - private const string PluginConfigName = "plugin.json"; - /// /// Parse plugin metadata in the given directories /// @@ -52,7 +51,7 @@ public static List Parse(string[] pluginDirectories) private static PluginMetadata GetPluginMetadata(string pluginDirectory) { - string configPath = Path.Combine(pluginDirectory, PluginConfigName); + string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName); if (!File.Exists(configPath)) { Log.Error($"|PluginConfig.GetPluginMetadata|Didn't find config file <{configPath}>"); diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs index efb239d7edb..b284b957f5b 100644 --- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs +++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs @@ -4,6 +4,7 @@ using ICSharpCode.SharpZipLib.Zip; using Newtonsoft.Json; using Flow.Launcher.Plugin; +using Flow.Launcher.Infrastructure; using Flow.Launcher.Infrastructure.Logger; namespace Flow.Launcher.Core.Plugin @@ -21,7 +22,7 @@ internal static void Install(string path) } UnZip(path, tempFoler, true); - string iniPath = Path.Combine(tempFoler, "plugin.json"); + string iniPath = Path.Combine(tempFoler, Constant.PluginMetadataFileName); if (!File.Exists(iniPath)) { MessageBox.Show("Install failed: plugin config is missing"); @@ -95,7 +96,7 @@ internal static void Install(string path) private static PluginMetadata GetMetadataFromJson(string pluginDirectory) { - string configPath = Path.Combine(pluginDirectory, "plugin.json"); + string configPath = Path.Combine(pluginDirectory, Constant.PluginMetadataFileName); PluginMetadata metadata; if (!File.Exists(configPath)) diff --git a/Flow.Launcher.Infrastructure/Constant.cs b/Flow.Launcher.Infrastructure/Constant.cs index 0936ce8c44b..a96d0e5b3cd 100644 --- a/Flow.Launcher.Infrastructure/Constant.cs +++ b/Flow.Launcher.Infrastructure/Constant.cs @@ -8,6 +8,7 @@ public static class Constant { public const string FlowLauncher = "Flow.Launcher"; public const string Plugins = "Plugins"; + public const string PluginMetadataFileName = "plugin.json"; public const string ApplicationFileName = FlowLauncher + ".exe"; diff --git a/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs index 586513acd6f..e1b631517e2 100644 --- a/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.PluginManagement/Main.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -17,7 +17,6 @@ namespace Flow.Launcher.Plugin.PluginManagement public class Main : IPlugin, IPluginI18n { private static string APIBASE = "http://api.wox.one"; - private static string PluginConfigName = "plugin.json"; private static string pluginSearchUrl = APIBASE + "/plugin/search/"; private const string ListCommand = "list"; private const string InstallCommand = "install"; From 4ac19251d1fb3131c67f8ca164e4df99da0b3a29 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 13 Jun 2020 04:25:09 +0300 Subject: [PATCH 11/44] refactor Core.Configuration.Portable --- Flow.Launcher.Core/Configuration/Portable.cs | 56 +++++++++----------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index c46a6102da2..43a6074862a 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -32,10 +32,9 @@ public void DisablePortableMode() try { MoveUserDataFolder(DataLocation.PortableDataPath, DataLocation.RoamingDataPath); -#if DEBUG +#if !DEBUG // Create shortcuts and uninstaller are not required in debug mode, // otherwise will repoint the path of the actual installed production version to the debug version -#else CreateShortcuts(); CreateUninstallerEntry(); #endif @@ -60,10 +59,9 @@ public void EnablePortableMode() try { MoveUserDataFolder(DataLocation.RoamingDataPath, DataLocation.PortableDataPath); -#if DEBUG +#if !DEBUG // Remove shortcuts and uninstaller are not required in debug mode, // otherwise will delete the actual installed production version -#else RemoveShortcuts(); RemoveUninstallerEntry(); #endif @@ -126,13 +124,16 @@ public void CreateUninstallerEntry() { var uninstallRegSubKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; // NB: Sometimes the Uninstall key doesn't exist - using (var parentKey = - RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) - .CreateSubKey("Uninstall", RegistryKeyPermissionCheck.ReadWriteSubTree)) {; } + RegistryKey + .OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) + .CreateSubKey("Uninstall", RegistryKeyPermissionCheck.ReadWriteSubTree) + .Dispose(); - var key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) - .CreateSubKey(uninstallRegSubKey + "\\" + Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree); - key.SetValue("DisplayIcon", Constant.ApplicationDirectory + "\\app.ico", RegistryValueKind.String); + var key = RegistryKey + .OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) + .CreateSubKey($@"{uninstallRegSubKey}\{Constant.FlowLauncher}", RegistryKeyPermissionCheck.ReadWriteSubTree); + + key.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String); using (var portabilityUpdater = NewUpdateManager()) { @@ -142,7 +143,8 @@ public void CreateUninstallerEntry() internal void IndicateDeletion(string filePathTodelete) { - using (StreamWriter sw = File.CreateText(filePathTodelete + "\\" + DataLocation.DeletionIndicatorFile)){} + var deleteFilePath = Path.Combine(filePathTodelete, DataLocation.DeletionIndicatorFile); + File.CreateText(deleteFilePath).Close(); } /// @@ -152,21 +154,17 @@ internal void IndicateDeletion(string filePathTodelete) public void PreStartCleanUpAfterPortabilityUpdate() { // Specify here so this method does not rely on other environment variables to initialise - var portableDataPath = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), "UserData"); - var roamingDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); - - bool DataLocationPortableDeleteRequired = false; - bool DataLocationRoamingDeleteRequired = false; + var portableDataDir = Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location.NonNull()).ToString(), "UserData"); + var roamingDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FlowLauncher"); - if ((roamingDataPath + "\\" + DataLocation.DeletionIndicatorFile).FileExits()) - DataLocationRoamingDeleteRequired = true; + // Get full path to the .dead files for each case + var portableDataDeleteFilePath = Path.Combine(portableDataDir, DataLocation.DeletionIndicatorFile); + var roamingDataDeleteFilePath = Path.Combine(roamingDataDir, DataLocation.DeletionIndicatorFile); - if ((portableDataPath + "\\" + DataLocation.DeletionIndicatorFile).FileExits()) - DataLocationPortableDeleteRequired = true; - - if (DataLocationRoamingDeleteRequired) + // Should we switch from %AppData% to portable mode? + if (File.Exists(roamingDataDeleteFilePath)) { - FilesFolders.RemoveFolderIfExists(roamingDataPath); + FilesFolders.RemoveFolderIfExists(roamingDataDir); if (MessageBox.Show("Flow Launcher has detected you enabled portable mode, " + "would you like to move it to a different location?", string.Empty, @@ -176,18 +174,14 @@ public void PreStartCleanUpAfterPortabilityUpdate() Environment.Exit(0); } - - return; } - - if(DataLocationPortableDeleteRequired) + // Should we switch from portable mode to %AppData%? + else if (File.Exists(portableDataDeleteFilePath)) { - FilesFolders.RemoveFolderIfExists(portableDataPath); + FilesFolders.RemoveFolderIfExists(portableDataDir); MessageBox.Show("Flow Launcher has detected you disabled portable mode, " + "the relevant shortcuts and uninstaller entry have been created"); - - return; } } @@ -196,7 +190,7 @@ public bool CanUpdatePortability() var roamingLocationExists = DataLocation.RoamingDataPath.LocationExists(); var portableLocationExists = DataLocation.PortableDataPath.LocationExists(); - if(roamingLocationExists && portableLocationExists) + if (roamingLocationExists && portableLocationExists) { MessageBox.Show(string.Format("Flow Launcher detected your user data exists both in {0} and " + "{1}. {2}{2}Please delete {1} in order to proceed. No changes have occured.", From 94a2393221d326814fb522ac19c439a178c3fbbd Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Sat, 13 Jun 2020 21:02:37 +0300 Subject: [PATCH 12/44] refactor Core.Plugin.PluginInstaller --- Flow.Launcher.Core/Plugin/PluginInstaller.cs | 75 ++++++++------------ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginInstaller.cs b/Flow.Launcher.Core/Plugin/PluginInstaller.cs index b284b957f5b..7b980a3eea0 100644 --- a/Flow.Launcher.Core/Plugin/PluginInstaller.cs +++ b/Flow.Launcher.Core/Plugin/PluginInstaller.cs @@ -15,28 +15,28 @@ internal static void Install(string path) { if (File.Exists(path)) { - string tempFoler = Path.Combine(Path.GetTempPath(), "flowlauncher\\plugins"); - if (Directory.Exists(tempFoler)) + string tempFolder = Path.Combine(Path.GetTempPath(), "flowlauncher", "plugins"); + if (Directory.Exists(tempFolder)) { - Directory.Delete(tempFoler, true); + Directory.Delete(tempFolder, true); } - UnZip(path, tempFoler, true); + UnZip(path, tempFolder, true); - string iniPath = Path.Combine(tempFoler, Constant.PluginMetadataFileName); - if (!File.Exists(iniPath)) + string jsonPath = Path.Combine(tempFolder, Constant.PluginMetadataFileName); + if (!File.Exists(jsonPath)) { MessageBox.Show("Install failed: plugin config is missing"); return; } - PluginMetadata plugin = GetMetadataFromJson(tempFoler); + PluginMetadata plugin = GetMetadataFromJson(tempFolder); if (plugin == null || plugin.Name == null) { MessageBox.Show("Install failed: plugin config is invalid"); return; } - string pluginFolerPath = Infrastructure.UserSettings.DataLocation.PluginsDirectory; + string pluginFolderPath = Infrastructure.UserSettings.DataLocation.PluginsDirectory; string newPluginName = plugin.Name .Replace("/", "_") @@ -48,7 +48,9 @@ internal static void Install(string path) .Replace("*", "_") .Replace("|", "_") + "-" + Guid.NewGuid(); - string newPluginPath = Path.Combine(pluginFolerPath, newPluginName); + + string newPluginPath = Path.Combine(pluginFolderPath, newPluginName); + string content = $"Do you want to install following plugin?{Environment.NewLine}{Environment.NewLine}" + $"Name: {plugin.Name}{Environment.NewLine}" + $"Version: {plugin.Version}{Environment.NewLine}" + @@ -73,8 +75,7 @@ internal static void Install(string path) File.Create(Path.Combine(existingPlugin.Metadata.PluginDirectory, "NeedDelete.txt")).Close(); } - UnZip(path, newPluginPath, true); - Directory.Delete(tempFoler, true); + Directory.Move(tempFolder, newPluginPath); //exsiting plugins may be has loaded by application, //if we try to delelte those kind of plugins, we will get a error that indicate the @@ -130,58 +131,38 @@ private static PluginMetadata GetMetadataFromJson(string pluginDirectory) } /// - /// unzip + /// unzip plugin contents to the given directory. /// - /// The ziped file. - /// The STR directory. + /// The path to the zip file. + /// The output directory. /// overwirte - private static void UnZip(string zipedFile, string strDirectory, bool overWrite) + private static void UnZip(string zipFile, string strDirectory, bool overWrite) { if (strDirectory == "") strDirectory = Directory.GetCurrentDirectory(); - if (!strDirectory.EndsWith("\\")) - strDirectory = strDirectory + "\\"; - using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipedFile))) + using (ZipInputStream zipStream = new ZipInputStream(File.OpenRead(zipFile))) { ZipEntry theEntry; - while ((theEntry = s.GetNextEntry()) != null) + while ((theEntry = zipStream.GetNextEntry()) != null) { - string directoryName = ""; - string pathToZip = ""; - pathToZip = theEntry.Name; + var pathToZip = theEntry.Name; + var directoryName = String.IsNullOrEmpty(pathToZip) ? "" : Path.GetDirectoryName(pathToZip); + var fileName = Path.GetFileName(pathToZip); + var destinationDir = Path.Combine(strDirectory, directoryName); + var destinationFile = Path.Combine(destinationDir, fileName); - if (pathToZip != "") - directoryName = Path.GetDirectoryName(pathToZip) + "\\"; + Directory.CreateDirectory(destinationDir); - string fileName = Path.GetFileName(pathToZip); + if (String.IsNullOrEmpty(fileName) || (File.Exists(destinationFile) && !overWrite)) + continue; - Directory.CreateDirectory(strDirectory + directoryName); - - if (fileName != "") + using (FileStream streamWriter = File.Create(destinationFile)) { - if ((File.Exists(strDirectory + directoryName + fileName) && overWrite) || (!File.Exists(strDirectory + directoryName + fileName))) - { - using (FileStream streamWriter = File.Create(strDirectory + directoryName + fileName)) - { - byte[] data = new byte[2048]; - while (true) - { - int size = s.Read(data, 0, data.Length); - - if (size > 0) - streamWriter.Write(data, 0, size); - else - break; - } - streamWriter.Close(); - } - } + zipStream.CopyTo(streamWriter); } } - - s.Close(); } } } From 35cf51f82fc78ba43f60b32069b6f49457b45b3c Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 25 Jun 2020 01:55:20 +0300 Subject: [PATCH 13/44] refactor Core.Plugin.PluginsLoader --- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 65 ++++++++++++---------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 513d85c9670..50abd1819d5 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -127,65 +127,74 @@ public static IEnumerable DotNetPlugins(List source) return plugins; } - public static IEnumerable PythonPlugins(List source, string pythonDirecotry) + public static IEnumerable PythonPlugins(List source, string pythonDirectory) { - var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.Python); - string filename; - - if (string.IsNullOrEmpty(pythonDirecotry)) + // try to set Constant.PythonPath, either from + // PATH or from the given pythonDirectory + if (string.IsNullOrEmpty(pythonDirectory)) { var paths = Environment.GetEnvironmentVariable(PATH); if (paths != null) { - var pythonPaths = paths.Split(';').Where(p => p.ToLower().Contains(Python)); - if (pythonPaths.Any()) + var pythonInPath = paths + .Split(';') + .Where(p => p.ToLower().Contains(Python)) + .Any(); + + if (pythonInPath) { - filename = PythonExecutable; + Constant.PythonPath = PythonExecutable; } else { Log.Error("|PluginsLoader.PythonPlugins|Python can't be found in PATH."); - return new List(); } } else { Log.Error("|PluginsLoader.PythonPlugins|PATH environment variable is not set."); - return new List(); } } else { - var path = Path.Combine(pythonDirecotry, PythonExecutable); + var path = Path.Combine(pythonDirectory, PythonExecutable); if (File.Exists(path)) { - filename = path; + Constant.PythonPath = path; } else { - Log.Error("|PluginsLoader.PythonPlugins|Can't find python executable in (); + Log.Error($"|PluginsLoader.PythonPlugins|Can't find python executable in {path}"); } } - Constant.PythonPath = filename; - var plugins = metadatas.Select(metadata => new PluginPair + + // if we have a path to the python executable, + // load every python plugin pair. + if (String.IsNullOrEmpty(Constant.PythonPath)) { - Plugin = new PythonPlugin(filename), - Metadata = metadata - }); - return plugins; + return new List(); + } + else + { + return source + .Where(o => o.Language.ToUpper() == AllowedLanguage.Python) + .Select(metadata => new PluginPair + { + Plugin = new PythonPlugin(Constant.PythonPath), + Metadata = metadata + }); + } } public static IEnumerable ExecutablePlugins(IEnumerable source) { - var metadatas = source.Where(o => o.Language.ToUpper() == AllowedLanguage.Executable); - - var plugins = metadatas.Select(metadata => new PluginPair - { - Plugin = new ExecutablePlugin(metadata.ExecuteFilePath), - Metadata = metadata - }); - return plugins; + return source + .Where(o => o.Language.ToUpper() == AllowedLanguage.Executable) + .Select(metadata => new PluginPair + { + Plugin = new ExecutablePlugin(metadata.ExecuteFilePath), + Metadata = metadata + }); } } From 0d9cfd65a2a7a457c1bacb84ccc0ee70b94252bc Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 25 Jun 2020 02:59:06 +0300 Subject: [PATCH 14/44] refactor Core.Plugin.PluginsLoader (continued) --- Flow.Launcher.Core/Plugin/PluginsLoader.cs | 51 ++++++++-------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginsLoader.cs b/Flow.Launcher.Core/Plugin/PluginsLoader.cs index 50abd1819d5..1025f9bae34 100644 --- a/Flow.Launcher.Core/Plugin/PluginsLoader.cs +++ b/Flow.Launcher.Core/Plugin/PluginsLoader.cs @@ -21,7 +21,7 @@ public static class PluginsLoader public static List Plugins(List metadatas, PluginsSettings settings) { - var dotnetPlugins = DotNetPlugins(metadatas).ToList(); + var dotnetPlugins = DotNetPlugins(metadatas); var pythonPlugins = PythonPlugins(metadatas, settings.PythonDirectory); var executablePlugins = ExecutablePlugins(metadatas); var plugins = dotnetPlugins.Concat(pythonPlugins).Concat(executablePlugins).ToList(); @@ -46,75 +46,58 @@ public static IEnumerable DotNetPlugins(List source) var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); var plugin = (IPlugin)Activator.CreateInstance(type); #else - Assembly assembly; + Assembly assembly = null; + IPlugin plugin = null; + try { assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(metadata.ExecuteFilePath); - } - catch (Exception e) - { - erroredPlugins.Add(metadata.Name); - Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e); - return; - } + var types = assembly.GetTypes(); + var type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); - Type type; - try + plugin = (IPlugin)Activator.CreateInstance(type); + } + catch (Exception e) when (assembly == null) { - var types = assembly.GetTypes(); - - type = types.First(o => o.IsClass && !o.IsAbstract && o.GetInterfaces().Contains(typeof(IPlugin))); + Log.Exception($"|PluginsLoader.DotNetPlugins|Couldn't load assembly for the plugin: {metadata.Name}", e); } catch (InvalidOperationException e) { - erroredPlugins.Add(metadata.Name); - Log.Exception($"|PluginsLoader.DotNetPlugins|Can't find the required IPlugin interface for the plugin: <{metadata.Name}>", e); - return; } catch (ReflectionTypeLoadException e) { - erroredPlugins.Add(metadata.Name); - Log.Exception($"|PluginsLoader.DotNetPlugins|The GetTypes method was unable to load assembly types for the plugin: <{metadata.Name}>", e); - return; } - - IPlugin plugin; - try + catch (Exception e) { - plugin = (IPlugin)Activator.CreateInstance(type); + Log.Exception($"|PluginsLoader.DotNetPlugins|The following plugin has errored and can not be loaded: <{metadata.Name}>", e); } - catch (Exception e) + + if (plugin == null) { erroredPlugins.Add(metadata.Name); - - Log.Exception($"|PluginsLoader.DotNetPlugins|The following plugin has errored and can not be loaded: <{metadata.Name}>", e); return; } #endif - PluginPair pair = new PluginPair + plugins.Add(new PluginPair { Plugin = plugin, Metadata = metadata - }; - plugins.Add(pair); + }); }); metadata.InitTime += milliseconds; - } if (erroredPlugins.Count > 0) { - var errorPluginString = ""; + var errorPluginString = String.Join(Environment.NewLine, erroredPlugins); var errorMessage = "The following " + (erroredPlugins.Count > 1 ? "plugins have " : "plugin has ") + "errored and cannot be loaded:"; - erroredPlugins.ForEach(x => errorPluginString += x + Environment.NewLine); - Task.Run(() => { MessageBox.Show($"{errorMessage}{Environment.NewLine}{Environment.NewLine}" + From 4205db293e701c1fd66f7099d2d0f774f609de8f Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 25 Jun 2020 03:40:29 +0300 Subject: [PATCH 15/44] refactor Core.Plugin.PluginManager --- Flow.Launcher.Core/Plugin/PluginManager.cs | 71 +++++++--------------- 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/Flow.Launcher.Core/Plugin/PluginManager.cs b/Flow.Launcher.Core/Plugin/PluginManager.cs index b92226ccda5..5cde9de83a8 100644 --- a/Flow.Launcher.Core/Plugin/PluginManager.cs +++ b/Flow.Launcher.Core/Plugin/PluginManager.cs @@ -19,10 +19,6 @@ public static class PluginManager { private static IEnumerable _contextMenuPlugins; - /// - /// Directories that will hold Flow Launcher plugin directory - /// - public static List AllPlugins { get; private set; } public static readonly List GlobalPlugins = new List(); public static readonly Dictionary NonGlobalPlugins = new Dictionary(); @@ -32,27 +28,18 @@ public static class PluginManager // todo happlebao, this should not be public, the indicator function should be embeded public static PluginsSettings Settings; private static List _metadatas; - private static readonly string[] Directories = { Constant.PreinstalledDirectory, DataLocation.PluginsDirectory }; - private static void ValidateUserDirectory() - { - if (!Directory.Exists(DataLocation.PluginsDirectory)) - { - Directory.CreateDirectory(DataLocation.PluginsDirectory); - } - } + /// + /// Directories that will hold Flow Launcher plugin directory + /// + private static readonly string[] Directories = { Constant.PreinstalledDirectory, DataLocation.PluginsDirectory }; private static void DeletePythonBinding() { const string binding = "flowlauncher.py"; - var directory = DataLocation.PluginsDirectory; - foreach (var subDirectory in Directory.GetDirectories(directory)) + foreach (var subDirectory in Directory.GetDirectories(DataLocation.PluginsDirectory)) { - var path = Path.Combine(subDirectory, binding); - if (File.Exists(path)) - { - File.Delete(path); - } + File.Delete(Path.Combine(subDirectory, binding)); } } @@ -76,7 +63,8 @@ public static void ReloadData() static PluginManager() { - ValidateUserDirectory(); + // validate user directory + Directory.CreateDirectory(DataLocation.PluginsDirectory); // force old plugins use new python binding DeletePythonBinding(); } @@ -132,9 +120,10 @@ public static void InitializePlugins(IPublicAPI api) GlobalPlugins.Add(plugin); // Plugins may have multiple ActionKeywords, eg. WebSearch - plugin.Metadata.ActionKeywords.Where(x => x != Query.GlobalPluginWildcardSign) - .ToList() - .ForEach(x => NonGlobalPlugins[x] = plugin); + plugin.Metadata.ActionKeywords + .Where(x => x != Query.GlobalPluginWildcardSign) + .ToList() + .ForEach(x => NonGlobalPlugins[x] = plugin); } if (failedPlugins.Any()) @@ -164,9 +153,9 @@ public static List ValidPluginsForQuery(Query query) public static List QueryForPlugin(PluginPair pair, Query query) { + var results = new List(); try { - List results = null; var metadata = pair.Metadata; var milliseconds = Stopwatch.Debug($"|PluginManager.QueryForPlugin|Cost for {metadata.Name}", () => { @@ -175,13 +164,12 @@ public static List QueryForPlugin(PluginPair pair, Query query) }); metadata.QueryCount += 1; metadata.AvgQueryTime = metadata.QueryCount == 1 ? milliseconds : (metadata.AvgQueryTime + milliseconds) / 2; - return results; } catch (Exception e) { Log.Exception($"|PluginManager.QueryForPlugin|Exception for plugin <{pair.Metadata.Name}> when query <{query}>", e); - return new List(); } + return results; } public static void UpdatePluginMetadata(List results, PluginMetadata metadata, Query query) @@ -221,47 +209,34 @@ public static IEnumerable GetPluginsForInterface() where T : IFea public static List GetContextMenusForPlugin(Result result) { + var results = new List(); var pluginPair = _contextMenuPlugins.FirstOrDefault(o => o.Metadata.ID == result.PluginID); if (pluginPair != null) { - var metadata = pluginPair.Metadata; var plugin = (IContextMenu)pluginPair.Plugin; try { - var results = plugin.LoadContextMenus(result); + results = plugin.LoadContextMenus(result); foreach (var r in results) { - r.PluginDirectory = metadata.PluginDirectory; - r.PluginID = metadata.ID; + r.PluginDirectory = pluginPair.Metadata.PluginDirectory; + r.PluginID = pluginPair.Metadata.ID; r.OriginQuery = result.OriginQuery; } - return results; } catch (Exception e) { - Log.Exception($"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{metadata.Name}>", e); - return new List(); + Log.Exception($"|PluginManager.GetContextMenusForPlugin|Can't load context menus for plugin <{pluginPair.Metadata.Name}>", e); } } - else - { - return new List(); - } - + return results; } public static bool ActionKeywordRegistered(string actionKeyword) { - if (actionKeyword != Query.GlobalPluginWildcardSign && - NonGlobalPlugins.ContainsKey(actionKeyword)) - { - return true; - } - else - { - return false; - } + return actionKeyword != Query.GlobalPluginWildcardSign + && NonGlobalPlugins.ContainsKey(actionKeyword); } /// @@ -299,7 +274,7 @@ public static void RemoveActionKeyword(string id, string oldActionkeyword) GlobalPlugins.Remove(plugin); } - if(oldActionkeyword != Query.GlobalPluginWildcardSign) + if (oldActionkeyword != Query.GlobalPluginWildcardSign) NonGlobalPlugins.Remove(oldActionkeyword); From 8a5dc55a1bf7fd55134c6a3f31aa6c6227d6cdc4 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Thu, 25 Jun 2020 04:07:46 +0300 Subject: [PATCH 16/44] update text message when launcher update fails closes #10 --- Flow.Launcher.Core/Updater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/Updater.cs b/Flow.Launcher.Core/Updater.cs index 3c4a15d3033..3036055ba23 100644 --- a/Flow.Launcher.Core/Updater.cs +++ b/Flow.Launcher.Core/Updater.cs @@ -86,8 +86,8 @@ public async Task UpdateApp(bool silentIfLatestVersion = true) var targetDestination = updateManager.RootAppDirectory + $"\\app-{newReleaseVersion.ToString()}\\{DataLocation.PortableFolderName}"; FilesFolders.Copy(DataLocation.PortableDataPath, targetDestination); if (!FilesFolders.VerifyBothFolderFilesEqual(DataLocation.PortableDataPath, targetDestination)) - MessageBox.Show(string.Format("Flow Launcher was not able to move your user profile data to the new update version. Please manually" + - "move your profile data folder from {0} to {1}", DataLocation.PortableDataPath, targetDestination)); + MessageBox.Show("Flow Launcher was not able to move your user profile data to the new update version. Please manually " + + $"move your profile data folder from {DataLocation.PortableDataPath} to {targetDestination}"); } else { From 3a712b7e02348a5d77e244068b406164a0ff39d8 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Fri, 26 Jun 2020 17:36:25 +0300 Subject: [PATCH 17/44] Core/Portable: switch back to using statements --- Flow.Launcher.Core/Configuration/Portable.cs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 43a6074862a..622948e44b3 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -123,17 +123,13 @@ public void CreateShortcuts() public void CreateUninstallerEntry() { var uninstallRegSubKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; - // NB: Sometimes the Uninstall key doesn't exist - RegistryKey - .OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) - .CreateSubKey("Uninstall", RegistryKeyPermissionCheck.ReadWriteSubTree) - .Dispose(); - var key = RegistryKey - .OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default) - .CreateSubKey($@"{uninstallRegSubKey}\{Constant.FlowLauncher}", RegistryKeyPermissionCheck.ReadWriteSubTree); - - key.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String); + using (var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Default)) + using (var subKey1 = baseKey.CreateSubKey(uninstallRegSubKey, RegistryKeyPermissionCheck.ReadWriteSubTree)) + using (var subKey2 = subKey1.CreateSubKey(Constant.FlowLauncher, RegistryKeyPermissionCheck.ReadWriteSubTree)) + { + subKey2.SetValue("DisplayIcon", Path.Combine(Constant.ApplicationDirectory, "app.ico"), RegistryValueKind.String); + } using (var portabilityUpdater = NewUpdateManager()) { @@ -144,7 +140,9 @@ public void CreateUninstallerEntry() internal void IndicateDeletion(string filePathTodelete) { var deleteFilePath = Path.Combine(filePathTodelete, DataLocation.DeletionIndicatorFile); - File.CreateText(deleteFilePath).Close(); + using (var _ = File.CreateText(deleteFilePath)) + { + } } /// From ad006a2c62263fea20c87157e948508a9eb7f9a8 Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Fri, 26 Jun 2020 17:37:37 +0300 Subject: [PATCH 18/44] Core/Portable: update logging, exception handling also update comments in `PreStartCleanUpAfterPortabilityUpdate` --- Flow.Launcher.Core/Configuration/Portable.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Flow.Launcher.Core/Configuration/Portable.cs b/Flow.Launcher.Core/Configuration/Portable.cs index 622948e44b3..44e4434bed7 100644 --- a/Flow.Launcher.Core/Configuration/Portable.cs +++ b/Flow.Launcher.Core/Configuration/Portable.cs @@ -47,10 +47,7 @@ public void DisablePortableMode() } catch (Exception e) { -#if !DEBUG - Log.Exception("Portable", "Error occured while disabling portable mode", e); -#endif - throw; + Log.Exception("|Portable.DisablePortableMode|Error occured while disabling portable mode", e); } } @@ -74,10 +71,7 @@ public void EnablePortableMode() } catch (Exception e) { -#if !DEBUG - Log.Exception("Portable", "Error occured while enabling portable mode", e); -#endif - throw; + Log.Exception("|Portable.EnablePortableMode|Error occured while enabling portable mode", e); } } @@ -159,7 +153,8 @@ public void PreStartCleanUpAfterPortabilityUpdate() var portableDataDeleteFilePath = Path.Combine(portableDataDir, DataLocation.DeletionIndicatorFile); var roamingDataDeleteFilePath = Path.Combine(roamingDataDir, DataLocation.DeletionIndicatorFile); - // Should we switch from %AppData% to portable mode? + // If the data folder in %appdata% is marked for deletion, + // delete it and prompt the user to pick the portable data location if (File.Exists(roamingDataDeleteFilePath)) { FilesFolders.RemoveFolderIfExists(roamingDataDir); @@ -173,7 +168,8 @@ public void PreStartCleanUpAfterPortabilityUpdate() Environment.Exit(0); } } - // Should we switch from portable mode to %AppData%? + // Otherwise, if the portable data folder is marked for deletion, + // delete it and notify the user about it. else if (File.Exists(portableDataDeleteFilePath)) { FilesFolders.RemoveFolderIfExists(portableDataDir); From 0304d1271dff894a1bd4adedd3294df8adb62bf6 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Sun, 28 Jun 2020 15:43:17 +1000 Subject: [PATCH 19/44] update PackageVersion to 1.0.0 --- Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj index ff4700e944c..b97bffd454e 100644 --- a/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj +++ b/Flow.Launcher.Plugin/Flow.Launcher.Plugin.csproj @@ -15,7 +15,7 @@ 1.0.0 - 1.0.0-beta3 + 1.0.0 1.0.0 1.0.0 Flow.Launcher.Plugin From ef20e2eea503efabd9af0b4354c5dccdee04b760 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 29 Jun 2020 13:44:10 +1000 Subject: [PATCH 20/44] update appveyor version to 1.0.0 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c44372f9b2a..a4000d1a481 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: '0.9.0.{build}' +version: '1.0.0.{build}' init: - ps: | From 5ff278230b6ab51bb09e24dc76bdac2146db8327 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 29 Jun 2020 19:56:28 +1000 Subject: [PATCH 21/44] fix environment variable search to be case insensitive --- .../Search/EnvironmentVariables.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs index 977b9423e8a..2dec51e99a3 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -18,12 +18,14 @@ internal static bool IsEnvironmentVariableSearch(string search) internal static Dictionary LoadEnvironmentStringPaths() { - var envStringPaths = new Dictionary(); + var envStringPaths = new Dictionary(StringComparer.InvariantCultureIgnoreCase); foreach (DictionaryEntry special in Environment.GetEnvironmentVariables()) { if (Directory.Exists(special.Value.ToString())) { + // Variables are returned with a mixture of all upper/lower case. + // Call ToLower() to make them look consitent envStringPaths.Add(special.Key.ToString().ToLower(), special.Value.ToString()); } } @@ -82,11 +84,12 @@ internal static List GetEnvironmentStringPathSuggestions(string querySea foreach (var p in environmentVariables) { - if (p.Key.StartsWith(search)) + if (p.Key.StartsWith(search, StringComparison.InvariantCultureIgnoreCase)) { results.Add(new ResultManager(context).CreateFolderResult($"%{p.Key}%", p.Value, p.Value, query)); } } + return results; } } From 95a1b9a9684c499f468392e46d12e1b447a79495 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 29 Jun 2020 21:53:01 +1000 Subject: [PATCH 22/44] fix typo --- .../Search/EnvironmentVariables.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs index 2dec51e99a3..c576d6ee845 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/EnvironmentVariables.cs @@ -25,7 +25,7 @@ internal static Dictionary LoadEnvironmentStringPaths() if (Directory.Exists(special.Value.ToString())) { // Variables are returned with a mixture of all upper/lower case. - // Call ToLower() to make them look consitent + // Call ToLower() to make the results look consistent envStringPaths.Add(special.Key.ToString().ToLower(), special.Value.ToString()); } } From 3fa3090ee34fda35867a016fc55da3bb2bce47fb Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 30 Jun 2020 06:20:22 +1000 Subject: [PATCH 23/44] Explorer plugin- change DefaultFolderSubtitleString to path --- .../Search/DirectoryInfo/DirectoryInfoSearch.cs | 2 +- .../Search/FolderLinks/QuickFolderAccess.cs | 4 ++-- .../Search/WindowsIndex/IndexSearch.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs index b198395b8f8..02de0eeaedd 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/DirectoryInfo/DirectoryInfoSearch.cs @@ -65,7 +65,7 @@ private List DirectorySearch(SearchOption searchOption, Query query, str if (fileSystemInfo is System.IO.DirectoryInfo) { - folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, Constants.DefaultFolderSubtitleString, fileSystemInfo.FullName, query, true, false)); + folderList.Add(resultManager.CreateFolderResult(fileSystemInfo.Name, fileSystemInfo.FullName, fileSystemInfo.FullName, query, true, false)); } else { diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/FolderLinks/QuickFolderAccess.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/FolderLinks/QuickFolderAccess.cs index 689c865c069..ebde039d680 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/FolderLinks/QuickFolderAccess.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/FolderLinks/QuickFolderAccess.cs @@ -12,7 +12,7 @@ internal List FolderList(Query query, List folderLinks, Plug return folderLinks .Select(item => new ResultManager(context) - .CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query)) + .CreateFolderResult(item.Nickname, item.Path, item.Path, query)) .ToList(); string search = query.Search.ToLower(); @@ -21,7 +21,7 @@ internal List FolderList(Query query, List folderLinks, Plug return queriedFolderLinks.Select(item => new ResultManager(context) - .CreateFolderResult(item.Nickname, Constants.DefaultFolderSubtitleString, item.Path, query)) + .CreateFolderResult(item.Nickname, item.Path, item.Path, query)) .ToList(); } } diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs index 5401c2845c2..c1793b42bf9 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/WindowsIndex/IndexSearch.cs @@ -54,8 +54,8 @@ internal List ExecuteWindowsIndexSearch(string indexQueryString, string if (dataReaderResults.GetString(2) == "Directory") { folderResults.Add(resultManager.CreateFolderResult( - dataReaderResults.GetString(0), - Constants.DefaultFolderSubtitleString, + dataReaderResults.GetString(0), + dataReaderResults.GetString(1), dataReaderResults.GetString(1), query, true, true)); } From 492c02eea4660d01d2de89249b3524f9e1e75119 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 30 Jun 2020 06:45:04 +1000 Subject: [PATCH 24/44] add custom plugin ToolTip on result hover over --- Flow.Launcher.Plugin/Result.cs | 10 ++++++++++ Flow.Launcher/ResultListBox.xaml | 4 ++-- Flow.Launcher/ViewModel/ResultViewModel.cs | 8 ++++++++ .../Flow.Launcher.Plugin.Explorer/Search/Constants.cs | 2 +- .../Search/ResultManager.cs | 6 +++++- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index bfd2fb0a4fa..d210ba1d828 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -130,5 +130,15 @@ public Result() { } /// Plugin ID that generated this result /// public string PluginID { get; internal set; } + + /// + /// Show message as ToolTip on result Title hover over + /// + public string TitleToolTip { get; set; } + + /// + /// Show message as ToolTip on result SubTitle hover over + /// + public string SubTitleToolTip { get; set; } } } \ No newline at end of file diff --git a/Flow.Launcher/ResultListBox.xaml b/Flow.Launcher/ResultListBox.xaml index a8560c26347..3280dc457a1 100644 --- a/Flow.Launcher/ResultListBox.xaml +++ b/Flow.Launcher/ResultListBox.xaml @@ -62,7 +62,7 @@ @@ -71,7 +71,7 @@ - diff --git a/Flow.Launcher/ViewModel/ResultViewModel.cs b/Flow.Launcher/ViewModel/ResultViewModel.cs index 0a9731f1860..4392234eba3 100644 --- a/Flow.Launcher/ViewModel/ResultViewModel.cs +++ b/Flow.Launcher/ViewModel/ResultViewModel.cs @@ -29,6 +29,14 @@ public ResultViewModel(Result result, Settings settings) public string OpenResultModifiers => Settings.OpenResultModifiers; + public string ShowTitleToolTip => string.IsNullOrEmpty(Result.TitleToolTip) + ? Result.Title + : Result.TitleToolTip; + + public string ShowSubTitleToolTip => string.IsNullOrEmpty(Result.SubTitleToolTip) + ? Result.SubTitle + : Result.SubTitleToolTip; + public ImageSource Image { get diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs index 9c8a300bc8a..5285dfe6e97 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs @@ -16,7 +16,7 @@ internal static class Constants internal const string DifferentUserIconImagePath = "Images\\user.png"; internal const string IndexingOptionsIconImagePath = "Images\\windowsindexingoptions.png"; - internal const string DefaultFolderSubtitleString = "Ctrl + Enter to open the directory"; + internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory"; internal const char AllFilesFolderSearchWildcard = '>'; diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index e2fd1c7da5d..dacc57c221b 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -38,13 +38,15 @@ internal Result CreateFolderResult(string title, string subtitle, string path, Q return false; } } - + string changeTo = path.EndsWith(Constants.DirectorySeperator) ? path : path + Constants.DirectorySeperator; context.API.ChangeQuery(string.IsNullOrEmpty(query.ActionKeyword) ? changeTo : query.ActionKeyword + " " + changeTo); return false; }, + TitleToolTip = Constants.ToolTipOpenDirectory, + SubTitleToolTip = Constants.ToolTipOpenDirectory, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = path, ShowIndexState = showIndexState, WindowsIndexed = windowsIndexed } }; } @@ -85,6 +87,8 @@ internal Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = FilesFolders.OpenPath(retrievedDirectoryPath); return true; }, + TitleToolTip = Constants.ToolTipOpenDirectory, + SubTitleToolTip = Constants.ToolTipOpenDirectory, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = retrievedDirectoryPath, ShowIndexState = true, WindowsIndexed = windowsIndexed } }; } From 90b7559d32fb08a96af6931831d84b2f79d43c77 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 30 Jun 2020 07:53:46 +1000 Subject: [PATCH 25/44] show ToolTip directory path on current folder result --- Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index dacc57c221b..bfde8c2c735 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -87,8 +87,8 @@ internal Result CreateOpenCurrentFolderResult(string path, bool windowsIndexed = FilesFolders.OpenPath(retrievedDirectoryPath); return true; }, - TitleToolTip = Constants.ToolTipOpenDirectory, - SubTitleToolTip = Constants.ToolTipOpenDirectory, + TitleToolTip = retrievedDirectoryPath, + SubTitleToolTip = retrievedDirectoryPath, ContextData = new SearchResult { Type = ResultType.Folder, FullPath = retrievedDirectoryPath, ShowIndexState = true, WindowsIndexed = windowsIndexed } }; } From bd645126431378a218a149e90458df4707499c16 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 30 Jun 2020 08:15:10 +1000 Subject: [PATCH 26/44] add open containing folder to file results --- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 8 ++++++++ Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs | 2 +- .../Search/Constants.cs | 2 ++ .../Search/ResultManager.cs | 12 +++++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index ce067e8a0f9..98cd777aac4 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -8,6 +8,9 @@ namespace Flow.Launcher.Plugin.SharedCommands public static class FilesFolders { private const string FileExplorerProgramName = "explorer"; + + private const string FileExplorerProgramEXE = "explorer.exe"; + public static void Copy(this string sourcePath, string targetPath) { // Get the subdirectories for the specified directory. @@ -128,6 +131,11 @@ public static void OpenPath(string fileOrFolderPath) } } + public static void OpenContainingFolder(string path) + { + Process.Start(FileExplorerProgramEXE, $" /select,\"{path}\""); + } + /// /// This checks whether a given string is a directory path or network location string. /// It does not check if location actually exists. diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs index 90a3fb2e8ef..89dbb3f88d6 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/ContextMenu.cs @@ -156,7 +156,7 @@ private Result CreateOpenContainingFolderResult(SearchResult record) { try { - Process.Start("explorer.exe", $" /select,\"{record.FullPath}\""); + FilesFolders.OpenContainingFolder(record.FullPath); } catch (Exception e) { diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs index 5285dfe6e97..d474fb0e78d 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/Constants.cs @@ -18,6 +18,8 @@ internal static class Constants internal const string ToolTipOpenDirectory = "Ctrl + Enter to open the directory"; + internal const string ToolTipOpenContainingFolder = "Ctrl + Enter to open the containing folder"; + internal const char AllFilesFolderSearchWildcard = '>'; internal const char DirectorySeperator = '\\'; diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index bfde8c2c735..6a336c59a89 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -1,6 +1,7 @@ using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin.SharedCommands; using System; +using System.Diagnostics; using System.IO; using System.Linq; using System.Windows; @@ -105,7 +106,14 @@ internal Result CreateFileResult(string filePath, Query query, bool showIndexSta { try { - FilesFolders.OpenPath(filePath); + if (c.SpecialKeyState.CtrlPressed) + { + FilesFolders.OpenContainingFolder(filePath); + } + else + { + FilesFolders.OpenPath(filePath); + } } catch (Exception ex) { @@ -114,6 +122,8 @@ internal Result CreateFileResult(string filePath, Query query, bool showIndexSta return true; }, + TitleToolTip = Constants.ToolTipOpenContainingFolder, + SubTitleToolTip = Constants.ToolTipOpenContainingFolder, ContextData = new SearchResult { Type = ResultType.File, FullPath = filePath, ShowIndexState = showIndexState, WindowsIndexed = windowsIndexed } }; return result; From a0f931c1de6b7a4f36c88be524f8103380de20ed Mon Sep 17 00:00:00 2001 From: Steven Kalinke Date: Wed, 1 Jul 2020 08:57:48 +0200 Subject: [PATCH 27/44] Add GitHub Issue Templates --- .github/ISSUE_TEMPLATE/bug-report.md | 32 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/code-review.md | 21 +++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.md | 24 +++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/code-review.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 00000000000..7c1cd72c5a3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,32 @@ +--- +name: "\U0001F41E Bug report" +about: Create a report to help us improve +title: "\U0001F41E [Describe Your Bug]" +labels: '' +assignees: '' + +--- + +**Describe the bug/issue** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. ... +2. ... +3. ... + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Your System** +``` +Windows build number: (run "ver" at a command prompt) +Flow Launcher version: (Settings => About) +``` +**Flow Launcher Error Log** + diff --git a/.github/ISSUE_TEMPLATE/code-review.md b/.github/ISSUE_TEMPLATE/code-review.md new file mode 100644 index 00000000000..caa334ca73a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/code-review.md @@ -0,0 +1,21 @@ +--- +name: "\U0001F50E Code Review" +about: Describe (bad) code that needs to be improved +title: "\U0001F50E [Describe Problematic Code]" +labels: '' +assignees: '' + +--- + +**Point to the corresponding file and line number(s) which could be improved.** + +Click on the line number in GitHub to create an anchored link to the corresponding code section. For example: + + +https://github.com/Flow-Launcher/Flow.Launcher/blob/master/Flow.Launcher/Storage/TopMostRecord.cs#L8 + +Provide your alternative implementation idea: + +``` +Code +``` diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 00000000000..187a8b687fc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,24 @@ +--- +name: "⭐ Feature request" +about: Suggest an idea for this project +title: "⭐ [Describe Your Feature]" +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. From 16c7d5c5b7c0517e512cffafb92131d4d02d87e4 Mon Sep 17 00:00:00 2001 From: Steven Kalinke Date: Wed, 1 Jul 2020 08:57:48 +0200 Subject: [PATCH 28/44] Add GitHub Issue Templates --- .github/ISSUE_TEMPLATE/bug-report.md | 32 +++++++ .github/ISSUE_TEMPLATE/code-review.md | 21 +++++ .github/ISSUE_TEMPLATE/feature-request.md | 24 +++++ ISSUE_TEMPLATE.md | 102 ---------------------- 4 files changed, 77 insertions(+), 102 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/code-review.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md delete mode 100644 ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 00000000000..7c1cd72c5a3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,32 @@ +--- +name: "\U0001F41E Bug report" +about: Create a report to help us improve +title: "\U0001F41E [Describe Your Bug]" +labels: '' +assignees: '' + +--- + +**Describe the bug/issue** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. ... +2. ... +3. ... + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Your System** +``` +Windows build number: (run "ver" at a command prompt) +Flow Launcher version: (Settings => About) +``` +**Flow Launcher Error Log** + diff --git a/.github/ISSUE_TEMPLATE/code-review.md b/.github/ISSUE_TEMPLATE/code-review.md new file mode 100644 index 00000000000..caa334ca73a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/code-review.md @@ -0,0 +1,21 @@ +--- +name: "\U0001F50E Code Review" +about: Describe (bad) code that needs to be improved +title: "\U0001F50E [Describe Problematic Code]" +labels: '' +assignees: '' + +--- + +**Point to the corresponding file and line number(s) which could be improved.** + +Click on the line number in GitHub to create an anchored link to the corresponding code section. For example: + + +https://github.com/Flow-Launcher/Flow.Launcher/blob/master/Flow.Launcher/Storage/TopMostRecord.cs#L8 + +Provide your alternative implementation idea: + +``` +Code +``` diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 00000000000..187a8b687fc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,24 @@ +--- +name: "⭐ Feature request" +about: Suggest an idea for this project +title: "⭐ [Describe Your Feature]" +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 8575ec9b6e5..00000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,102 +0,0 @@ - - -### Are you submitting a bug report? - -(write your answer here) - - - - - -### Steps to reproduce - - - -1. -2. -3. - -### Flow Launcher Error Window text - - -(paste here) - - -### Detailed logs - - -(drop your log file here) - -### Screenshots (optional) - - -(drop your screenshot here) - From ca20370e844149ab6c05acd3690133aba00a650e Mon Sep 17 00:00:00 2001 From: Ioannis G Date: Wed, 1 Jul 2020 13:40:37 +0300 Subject: [PATCH 29/44] remove the hello-world plugins (#96) --- Flow.Launcher.sln | 30 ---------- .../HelloWorldCSharp/HelloWorldCSharp.csproj | 55 ------------------ Plugins/HelloWorldCSharp/Images/app.png | Bin 5706 -> 0 bytes Plugins/HelloWorldCSharp/Main.cs | 28 --------- Plugins/HelloWorldCSharp/plugin.json | 13 ----- .../HelloWorldFSharp/HelloWorldFSharp.fsproj | 36 ------------ Plugins/HelloWorldFSharp/Images/app.png | Bin 5706 -> 0 bytes Plugins/HelloWorldFSharp/Main.fs | 31 ---------- Plugins/HelloWorldFSharp/plugin.json | 12 ---- Plugins/HelloWorldPython/Images/app.png | Bin 5706 -> 0 bytes Plugins/HelloWorldPython/main.py | 27 --------- Plugins/HelloWorldPython/plugin.json | 12 ---- Scripts/post_build.ps1 | 1 - 13 files changed, 245 deletions(-) delete mode 100644 Plugins/HelloWorldCSharp/HelloWorldCSharp.csproj delete mode 100644 Plugins/HelloWorldCSharp/Images/app.png delete mode 100644 Plugins/HelloWorldCSharp/Main.cs delete mode 100644 Plugins/HelloWorldCSharp/plugin.json delete mode 100644 Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj delete mode 100644 Plugins/HelloWorldFSharp/Images/app.png delete mode 100644 Plugins/HelloWorldFSharp/Main.fs delete mode 100644 Plugins/HelloWorldFSharp/plugin.json delete mode 100644 Plugins/HelloWorldPython/Images/app.png delete mode 100644 Plugins/HelloWorldPython/main.py delete mode 100644 Plugins/HelloWorldPython/plugin.json diff --git a/Flow.Launcher.sln b/Flow.Launcher.sln index b244c97defd..2be28daf118 100644 --- a/Flow.Launcher.sln +++ b/Flow.Launcher.sln @@ -62,16 +62,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SolutionAssemblyInfo.cs = SolutionAssemblyInfo.cs EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorldCSharp", "Plugins\HelloWorldCSharp\HelloWorldCSharp.csproj", "{03FFA443-5F50-48D5-8869-F3DF316803AA}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Shell", "Plugins\Flow.Launcher.Plugin.Shell\Flow.Launcher.Plugin.Shell.csproj", "{C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.BrowserBookmark", "Plugins\Flow.Launcher.Plugin.BrowserBookmark\Flow.Launcher.Plugin.BrowserBookmark.csproj", "{9B130CC5-14FB-41FF-B310-0A95B6894C37}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Calculator", "Plugins\Flow.Launcher.Plugin.Calculator\Flow.Launcher.Plugin.Calculator.csproj", "{59BD9891-3837-438A-958D-ADC7F91F6F7E}" EndProject -Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "HelloWorldFSharp", "Plugins\HelloWorldFSharp\HelloWorldFSharp.fsproj", "{30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Flow.Launcher.Plugin.Explorer", "Plugins\Flow.Launcher.Plugin.Explorer\Flow.Launcher.Plugin.Explorer.csproj", "{F9C4C081-4CC3-4146-95F1-E102B4E10A5F}" EndProject Global @@ -253,18 +249,6 @@ Global {230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x64.Build.0 = Release|Any CPU {230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x86.ActiveCfg = Release|Any CPU {230AE83F-E92E-4E69-8355-426B305DA9C0}.Release|x86.Build.0 = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x64.ActiveCfg = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x64.Build.0 = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x86.ActiveCfg = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Debug|x86.Build.0 = Debug|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|Any CPU.Build.0 = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x64.ActiveCfg = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x64.Build.0 = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x86.ActiveCfg = Release|Any CPU - {03FFA443-5F50-48D5-8869-F3DF316803AA}.Release|x86.Build.0 = Release|Any CPU {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -301,18 +285,6 @@ Global {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x64.Build.0 = Release|Any CPU {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.ActiveCfg = Release|Any CPU {59BD9891-3837-438A-958D-ADC7F91F6F7E}.Release|x86.Build.0 = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.ActiveCfg = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x64.Build.0 = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.ActiveCfg = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Debug|x86.Build.0 = Debug|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|Any CPU.Build.0 = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.ActiveCfg = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x64.Build.0 = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.ActiveCfg = Release|Any CPU - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E}.Release|x86.Build.0 = Release|Any CPU {F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {F9C4C081-4CC3-4146-95F1-E102B4E10A5F}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -339,11 +311,9 @@ Global {A3DCCBCA-ACC1-421D-B16E-210896234C26} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {F35190AA-4758-4D9E-A193-E3BDF6AD3567} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {230AE83F-E92E-4E69-8355-426B305DA9C0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} - {03FFA443-5F50-48D5-8869-F3DF316803AA} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {C21BFF9C-2C99-4B5F-B7C9-A5E6DDDB37B0} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {9B130CC5-14FB-41FF-B310-0A95B6894C37} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {59BD9891-3837-438A-958D-ADC7F91F6F7E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} - {30DDA7D9-3712-44F4-BD18-DC1C05B2DD9E} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} {F9C4C081-4CC3-4146-95F1-E102B4E10A5F} = {3A73F5A7-0335-40D8-BF7C-F20BE5D0BA87} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/Plugins/HelloWorldCSharp/HelloWorldCSharp.csproj b/Plugins/HelloWorldCSharp/HelloWorldCSharp.csproj deleted file mode 100644 index 2e2ab78b5e9..00000000000 --- a/Plugins/HelloWorldCSharp/HelloWorldCSharp.csproj +++ /dev/null @@ -1,55 +0,0 @@ - - - - netcoreapp3.1 - {03FFA443-5F50-48D5-8869-F3DF316803AA} - Properties - HelloWorldCSharp - HelloWorldCSharp - false - false - - Library - - - - - AnyCPU - true - full - false - ..\..\Output\Debug\Plugins\HelloWorldCSharp\ - DEBUG;TRACE - prompt - 4 - false - - - - AnyCPU - pdbonly - true - ..\..\Output\Release\Plugins\HelloWorldCSharp\ - TRACE - prompt - 4 - false - - - - - PreserveNewest - - - - - - - - - - PreserveNewest - - - - \ No newline at end of file diff --git a/Plugins/HelloWorldCSharp/Images/app.png b/Plugins/HelloWorldCSharp/Images/app.png deleted file mode 100644 index bc5701ac8579a9cb9ff1a82361de77db3552ce7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5706 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

jqC^sc=X&;RfsdI+cIiHn^VM2Zih$U1t|`QwT? zxptHhrG%SNA;Og9T`_(U_20>gM$-6e2U9?oa<@d(zuvF9?b5Hr;{9y4`*=vrTj|w3 zFNc_Xe>wFE!MuK;)>8bQ?g0Q=eH)cJ$?BYCqUS)Y2rK{?}&Y**e^pn;Yu zo#FnphZ|;iJ%E#YwYq$onD)t^Uxh`~_HILCU3I~`8H%Kjas>x_tGV%2z_e$)tg5Wc zx6c&e`@a;)CGuGRZS`XLdSE12EBdbin|i^AsM7Ykm##XrZ-l%4T5fCyY>-zC>cp__ z|GQvC^tBhwS*8zn&PA_t$5OcMDF?e+!ETp7x+Qu!h23Q+GJ#iq+9l!aSSjG||i99M-aR@IL3ZE)k}Q(uUJpEx~N zJ-o&MPoexk&(yOX`us@I`Mc4ArP9*)ivbkEbrw_$8jhm4|8SUFU2-OmgQ&I@cdG+{ zWtqSa8BMC!Dnp23G>srK#C^U$>{VJ0G4q=ld^b0w6ZD9gSN$FJpA;toaw~;{i_!%n z2b@@+FRofVaK*948u_Sf}1-&}QAD0&~ME$z;od6y}T=C$aout`W+`!=@pA z1(L*0lKJ;lof+#Y&08+bPqLRj>aUgTbH<<1#rO7Ta!$kqHZ9pyeXwE0pIrO-W^yBQ z_uzJUVGdS68XsESStl^$t__vq|JHVzZs1mJ*ErRESaFgfG5V`bUKoAoE+KOEJ>z^P zq=P4lCt1jZx#NDpXP?s8aJVrx!DI@`A93=Q+Y0$TFq&%IQ zXp*l!uj7%z@2@O;(5nr2=UTBIE09iU{(pRd%f?sd(otkxUkKvFJ#M@w>=!ShO3bHv zM<9q5edmx2yyD}Z65`OHZwr8%NW{ z$S3)M?67e|8wCjr7S@9$rS&$uR7}vv>pF6C~#VV+J8;< z@^5kOW8ZoM5dmzkDs599UIo{BR8R$VQRp%tM6nacF(ZFHe(d!0g9vS2YVk|-_}y7=d_Rk_C4=fNt=?G+(Onx2uw{rZ~WtY4XZ){|WK`P%OxxH$IS zGl@EBL=}EV`1nrj<V zK`?h#geIVXTU9=Y?&G;`GqZ>~BpY@tnfdhH=!SqOXs&4Db`pE8H$5QSkDG53;EJoB z^9Mh!PxPg$7p)Y~1}P)90rNW2;I@54cPKSkl61%q{K%i^+ssuIH)sLU9A@JM0)>{4~|Mi_W zV;$bZQYJ=7+0M(M4qy0)gg$lDaM#vuFLjFN$c;rI{!@HucWwOoS}XdOjL20+{a68X zFLWei8K1J78^uWn!Qq#L=U=P&12EnZ>vd2NlzMr)bD65cvM>A~nj+c$lpeq@)e|{X zNB#2~i7;>}wYtgs9RMbYBO9vWtQ;OB7!cBL;%u=Jy=zF2+I@MqExhRY_v0G^5Igq5 zKQ{4>fTbs{4FFI3vSExa^uBoE%p#?&-6*6BKyPz4!-u%mkoIC=I7D?`8qIWu^pVmt)^*Gwg=M$3_&GOLeyqHI%@zUKM{3rl{v)qWsj`Q)Pm`C0p=S*B zFN~FYR8FzC@T}5kW945pqkUjV;3OwCto_lXWFZ#`Eri`hv_HBQ(=#EJQ~j$Z`WzL= zrT?g%sFuqiFKAgLe#jFO*E`Bs2%m^XG1E~Yhi=g0KHecI-VA% zRKW;J*ak|Ct;W=_3UHuyy5Jpi1U@Yddl^at{2t#P)Hf3A==n{?OMn2HrUuMrKF3s`qKci_P#Eo$&j))?_!>qc?zX%`W0aMvVkN-q+ z$t5qa&W?L^fwbG3NL(#4cVba?SK9D$Fb937au5`NUt z7vl4YVByl>Qc-!r3TF4yKCGlJm{ClU Query(Query query) - { - var result = new Result - { - Title = "Hello World from CSharp", - SubTitle = $"Query: {query.Search}", - IcoPath = "app.png" - }; - return new List {result}; - } - - public void Init(PluginInitContext context) - { - - } - } -} diff --git a/Plugins/HelloWorldCSharp/plugin.json b/Plugins/HelloWorldCSharp/plugin.json deleted file mode 100644 index 61d10b29129..00000000000 --- a/Plugins/HelloWorldCSharp/plugin.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ID": "CEA0FDFC6D3B4085823D60DC76F28844", - "ActionKeyword": "hc", - "Name": "Hello World CSharp", - "Description": "Hello World CSharp", - "Author": "happlebao", - "Version": "1.0.0", - "Language": "csharp", - "Website": "https://github.com/Flow-Launcher/Flow.Launcher", - "ExecuteFileName": "HelloWorldCSharp.dll", - "IcoPath": "app.png", - "Disabled": true -} \ No newline at end of file diff --git a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj b/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj deleted file mode 100644 index d688ab6a901..00000000000 --- a/Plugins/HelloWorldFSharp/HelloWorldFSharp.fsproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - netcoreapp3.1 - false - false - - - - ..\..\Output\Debug\Plugins\HelloWorldFSharp\ - DEBUG;TRACE - - - - ..\..\Output\Release\Plugins\HelloWorldFSharp\ - - - - - PreserveNewest - - - Always - - - - - - - - - - - - - \ No newline at end of file diff --git a/Plugins/HelloWorldFSharp/Images/app.png b/Plugins/HelloWorldFSharp/Images/app.png deleted file mode 100644 index bc5701ac8579a9cb9ff1a82361de77db3552ce7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5706 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

jqC^sc=X&;RfsdI+cIiHn^VM2Zih$U1t|`QwT? zxptHhrG%SNA;Og9T`_(U_20>gM$-6e2U9?oa<@d(zuvF9?b5Hr;{9y4`*=vrTj|w3 zFNc_Xe>wFE!MuK;)>8bQ?g0Q=eH)cJ$?BYCqUS)Y2rK{?}&Y**e^pn;Yu zo#FnphZ|;iJ%E#YwYq$onD)t^Uxh`~_HILCU3I~`8H%Kjas>x_tGV%2z_e$)tg5Wc zx6c&e`@a;)CGuGRZS`XLdSE12EBdbin|i^AsM7Ykm##XrZ-l%4T5fCyY>-zC>cp__ z|GQvC^tBhwS*8zn&PA_t$5OcMDF?e+!ETp7x+Qu!h23Q+GJ#iq+9l!aSSjG||i99M-aR@IL3ZE)k}Q(uUJpEx~N zJ-o&MPoexk&(yOX`us@I`Mc4ArP9*)ivbkEbrw_$8jhm4|8SUFU2-OmgQ&I@cdG+{ zWtqSa8BMC!Dnp23G>srK#C^U$>{VJ0G4q=ld^b0w6ZD9gSN$FJpA;toaw~;{i_!%n z2b@@+FRofVaK*948u_Sf}1-&}QAD0&~ME$z;od6y}T=C$aout`W+`!=@pA z1(L*0lKJ;lof+#Y&08+bPqLRj>aUgTbH<<1#rO7Ta!$kqHZ9pyeXwE0pIrO-W^yBQ z_uzJUVGdS68XsESStl^$t__vq|JHVzZs1mJ*ErRESaFgfG5V`bUKoAoE+KOEJ>z^P zq=P4lCt1jZx#NDpXP?s8aJVrx!DI@`A93=Q+Y0$TFq&%IQ zXp*l!uj7%z@2@O;(5nr2=UTBIE09iU{(pRd%f?sd(otkxUkKvFJ#M@w>=!ShO3bHv zM<9q5edmx2yyD}Z65`OHZwr8%NW{ z$S3)M?67e|8wCjr7S@9$rS&$uR7}vv>pF6C~#VV+J8;< z@^5kOW8ZoM5dmzkDs599UIo{BR8R$VQRp%tM6nacF(ZFHe(d!0g9vS2YVk|-_}y7=d_Rk_C4=fNt=?G+(Onx2uw{rZ~WtY4XZ){|WK`P%OxxH$IS zGl@EBL=}EV`1nrj<V zK`?h#geIVXTU9=Y?&G;`GqZ>~BpY@tnfdhH=!SqOXs&4Db`pE8H$5QSkDG53;EJoB z^9Mh!PxPg$7p)Y~1}P)90rNW2;I@54cPKSkl61%q{K%i^+ssuIH)sLU9A@JM0)>{4~|Mi_W zV;$bZQYJ=7+0M(M4qy0)gg$lDaM#vuFLjFN$c;rI{!@HucWwOoS}XdOjL20+{a68X zFLWei8K1J78^uWn!Qq#L=U=P&12EnZ>vd2NlzMr)bD65cvM>A~nj+c$lpeq@)e|{X zNB#2~i7;>}wYtgs9RMbYBO9vWtQ;OB7!cBL;%u=Jy=zF2+I@MqExhRY_v0G^5Igq5 zKQ{4>fTbs{4FFI3vSExa^uBoE%p#?&-6*6BKyPz4!-u%mkoIC=I7D?`8qIWu^pVmt)^*Gwg=M$3_&GOLeyqHI%@zUKM{3rl{v)qWsj`Q)Pm`C0p=S*B zFN~FYR8FzC@T}5kW945pqkUjV;3OwCto_lXWFZ#`Eri`hv_HBQ(=#EJQ~j$Z`WzL= zrT?g%sFuqiFKAgLe#jFO*E`Bs2%m^XG1E~Yhi=g0KHecI-VA% zRKW;J*ak|Ct;W=_3UHuyy5Jpi1U@Yddl^at{2t#P)Hf3A==n{?OMn2HrUuMrKF3s`qKci_P#Eo$&j))?_!>qc?zX%`W0aMvVkN-q+ z$t5qa&W?L^fwbG3NL(#4cVba?SK9D$Fb937au5`NUt z7vl4YVByl>Qc-!r3TF4yKCGlJm{ClU [ - Result (Title = "Hello World from F#", - SubTitle = sprintf "Query: %s" query.Search) - - Result (Title = "Browse source code of this plugin", - SubTitle = "click to open in browser", - Action = (fun ctx -> - initContext.CurrentPluginMetadata.Website - |> System.Diagnostics.Process.Start - |> ignore - true)) - - Result (Title = "Trigger a tray message", - Action = (fun _ -> - initContext.API.ShowMsg ("Sample tray message", "from the F# plugin") - false)) - ] diff --git a/Plugins/HelloWorldFSharp/plugin.json b/Plugins/HelloWorldFSharp/plugin.json deleted file mode 100644 index 845b93e4b0b..00000000000 --- a/Plugins/HelloWorldFSharp/plugin.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "ID": "8FF5D5C1F8194958A12E8668FB7ECC04", - "ActionKeyword": "hf", - "Name": "Hello World FSharp", - "Description": "Hello World FSharp", - "Author": "Ioannis G.", - "Version": "1.0.0", - "Language": "fsharp", - "Website": "https://github.com/Flow-Launcher/Flow.Launcher", - "ExecuteFileName": "HelloWorldFSharp.dll", - "IcoPath": "Images\\app.png" -} \ No newline at end of file diff --git a/Plugins/HelloWorldPython/Images/app.png b/Plugins/HelloWorldPython/Images/app.png deleted file mode 100644 index bc5701ac8579a9cb9ff1a82361de77db3552ce7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5706 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

jqC^sc=X&;RfsdI+cIiHn^VM2Zih$U1t|`QwT? zxptHhrG%SNA;Og9T`_(U_20>gM$-6e2U9?oa<@d(zuvF9?b5Hr;{9y4`*=vrTj|w3 zFNc_Xe>wFE!MuK;)>8bQ?g0Q=eH)cJ$?BYCqUS)Y2rK{?}&Y**e^pn;Yu zo#FnphZ|;iJ%E#YwYq$onD)t^Uxh`~_HILCU3I~`8H%Kjas>x_tGV%2z_e$)tg5Wc zx6c&e`@a;)CGuGRZS`XLdSE12EBdbin|i^AsM7Ykm##XrZ-l%4T5fCyY>-zC>cp__ z|GQvC^tBhwS*8zn&PA_t$5OcMDF?e+!ETp7x+Qu!h23Q+GJ#iq+9l!aSSjG||i99M-aR@IL3ZE)k}Q(uUJpEx~N zJ-o&MPoexk&(yOX`us@I`Mc4ArP9*)ivbkEbrw_$8jhm4|8SUFU2-OmgQ&I@cdG+{ zWtqSa8BMC!Dnp23G>srK#C^U$>{VJ0G4q=ld^b0w6ZD9gSN$FJpA;toaw~;{i_!%n z2b@@+FRofVaK*948u_Sf}1-&}QAD0&~ME$z;od6y}T=C$aout`W+`!=@pA z1(L*0lKJ;lof+#Y&08+bPqLRj>aUgTbH<<1#rO7Ta!$kqHZ9pyeXwE0pIrO-W^yBQ z_uzJUVGdS68XsESStl^$t__vq|JHVzZs1mJ*ErRESaFgfG5V`bUKoAoE+KOEJ>z^P zq=P4lCt1jZx#NDpXP?s8aJVrx!DI@`A93=Q+Y0$TFq&%IQ zXp*l!uj7%z@2@O;(5nr2=UTBIE09iU{(pRd%f?sd(otkxUkKvFJ#M@w>=!ShO3bHv zM<9q5edmx2yyD}Z65`OHZwr8%NW{ z$S3)M?67e|8wCjr7S@9$rS&$uR7}vv>pF6C~#VV+J8;< z@^5kOW8ZoM5dmzkDs599UIo{BR8R$VQRp%tM6nacF(ZFHe(d!0g9vS2YVk|-_}y7=d_Rk_C4=fNt=?G+(Onx2uw{rZ~WtY4XZ){|WK`P%OxxH$IS zGl@EBL=}EV`1nrj<V zK`?h#geIVXTU9=Y?&G;`GqZ>~BpY@tnfdhH=!SqOXs&4Db`pE8H$5QSkDG53;EJoB z^9Mh!PxPg$7p)Y~1}P)90rNW2;I@54cPKSkl61%q{K%i^+ssuIH)sLU9A@JM0)>{4~|Mi_W zV;$bZQYJ=7+0M(M4qy0)gg$lDaM#vuFLjFN$c;rI{!@HucWwOoS}XdOjL20+{a68X zFLWei8K1J78^uWn!Qq#L=U=P&12EnZ>vd2NlzMr)bD65cvM>A~nj+c$lpeq@)e|{X zNB#2~i7;>}wYtgs9RMbYBO9vWtQ;OB7!cBL;%u=Jy=zF2+I@MqExhRY_v0G^5Igq5 zKQ{4>fTbs{4FFI3vSExa^uBoE%p#?&-6*6BKyPz4!-u%mkoIC=I7D?`8qIWu^pVmt)^*Gwg=M$3_&GOLeyqHI%@zUKM{3rl{v)qWsj`Q)Pm`C0p=S*B zFN~FYR8FzC@T}5kW945pqkUjV;3OwCto_lXWFZ#`Eri`hv_HBQ(=#EJQ~j$Z`WzL= zrT?g%sFuqiFKAgLe#jFO*E`Bs2%m^XG1E~Yhi=g0KHecI-VA% zRKW;J*ak|Ct;W=_3UHuyy5Jpi1U@Yddl^at{2t#P)Hf3A==n{?OMn2HrUuMrKF3s`qKci_P#Eo$&j))?_!>qc?zX%`W0aMvVkN-q+ z$t5qa&W?L^fwbG3NL(#4cVba?SK9D$Fb937au5`NUt z7vl4YVByl>Qc-!r3TF4yKCGlJm{ClU Date: Thu, 2 Jul 2020 13:25:50 +0200 Subject: [PATCH 30/44] Update IssueTemplate --- .github/ISSUE_TEMPLATE/bug-report.md | 6 +++--- .github/ISSUE_TEMPLATE/code-review.md | 4 ++-- .github/ISSUE_TEMPLATE/discussion.md | 14 ++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.md | 6 +++--- 4 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/discussion.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 7c1cd72c5a3..23ced593e1b 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: "\U0001F41E Bug report" -about: Create a report to help us improve -title: "\U0001F41E [Describe Your Bug]" -labels: '' +about: Create a bug report to help us improve Flow Launcher +title: "[Describe Your Bug]" +labels: 'bug' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/code-review.md b/.github/ISSUE_TEMPLATE/code-review.md index caa334ca73a..5cc53abec77 100644 --- a/.github/ISSUE_TEMPLATE/code-review.md +++ b/.github/ISSUE_TEMPLATE/code-review.md @@ -1,8 +1,8 @@ --- name: "\U0001F50E Code Review" about: Describe (bad) code that needs to be improved -title: "\U0001F50E [Describe Problematic Code]" -labels: '' +title: "[Describe Problematic Code]" +labels: 'code review' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/discussion.md b/.github/ISSUE_TEMPLATE/discussion.md new file mode 100644 index 00000000000..8bd88c90fc8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/discussion.md @@ -0,0 +1,14 @@ +--- +name: "⁉️ Question/Discussion" +about: Create a report to help us improve +title: "[Ask a question or propose a change]" +labels: 'question/discussion' +assignees: '' + +--- + +**Question** +Describe your question. + +**Discussion** +Discuss a topic. diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 187a8b687fc..5931632359d 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,8 +1,8 @@ --- name: "⭐ Feature request" -about: Suggest an idea for this project -title: "⭐ [Describe Your Feature]" -labels: '' +about: Suggest a new idea or a feature enhacement +title: "[Describe Your Feature]" +labels: 'enhancement' assignees: '' --- From 8a860ec674283510e651b198c4a09a56437aff01 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 2 Jul 2020 21:29:13 +1000 Subject: [PATCH 31/44] fix the width of the blur effect --- Flow.Launcher/Themes/BlurBlack.xaml | 1 + Flow.Launcher/Themes/BlurWhite.xaml | 1 + 2 files changed, 2 insertions(+) diff --git a/Flow.Launcher/Themes/BlurBlack.xaml b/Flow.Launcher/Themes/BlurBlack.xaml index 488048cf44d..40ecbc778d0 100644 --- a/Flow.Launcher/Themes/BlurBlack.xaml +++ b/Flow.Launcher/Themes/BlurBlack.xaml @@ -21,6 +21,7 @@