diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 9f3160746b8..8f124f3a40b 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -71,21 +71,17 @@ public List Query(Query query) Win32[] win32; UWP.Application[] uwps; - lock (IndexLock) - { // just take the reference inside the lock to eliminate query time issues. - win32 = _win32s; - uwps = _uwps; - } - - var results1 = win32.AsParallel() - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, _context.API)); + win32 = _win32s; + uwps = _uwps; - var results2 = uwps.AsParallel() - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, _context.API)); + var result = win32.Cast() + .Concat(uwps) + .AsParallel() + .Where(p => p.Enabled) + .Select(p => p.Result(query.Search, _context.API)) + .Where(r => r?.Score > 0) + .ToList(); - var result = results1.Concat(results2).Where(r => r != null && r.Score > 0).ToList(); return result; } @@ -97,10 +93,9 @@ public void Init(PluginInitContext context) public static void IndexWin32Programs() { var win32S = Win32.All(_settings); - lock (IndexLock) - { - _win32s = win32S; - } + + _win32s = win32S; + } public static void IndexUWPPrograms() @@ -109,10 +104,9 @@ public static void IndexUWPPrograms() var support = Environment.OSVersion.Version.Major >= windows10.Major; var applications = support ? UWP.All() : new UWP.Application[] { }; - lock (IndexLock) - { - _uwps = applications; - } + + _uwps = applications; + } public static void IndexPrograms() diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs index b42acfbce5b..d4c96e5b730 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs @@ -9,5 +9,6 @@ public interface IProgram string UniqueIdentifier { get; set; } string Name { get; } string Location { get; } + bool Enabled { get; } } } diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index def121723be..3ea78156d77 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -265,27 +265,30 @@ public class Application : IProgram public Application(){} - private int Score(string query) - { - var displayNameMatch = StringMatcher.FuzzySearch(query, DisplayName); - var descriptionMatch = StringMatcher.FuzzySearch(query, Description); - var score = new[] { displayNameMatch.Score, descriptionMatch.Score }.Max(); - return score; - } public Result Result(string query, IPublicAPI api) { - var score = Score(query); - if (score <= 0) - { // no need to create result if score is 0 + var title = (Name, Description) switch + { + (var n, null) => n, + (var n, var d) when d.StartsWith(n) => d, + (var n, var d) when n.StartsWith(d) => n, + (var n, var d) when !string.IsNullOrEmpty(d) => $"{n}: {d}", + _ => Name + }; + + var matchResult = StringMatcher.FuzzySearch(query, title); + + if (!matchResult.Success) return null; - } var result = new Result { + Title = title, SubTitle = Package.Location, Icon = Logo, - Score = score, + Score = matchResult.Score, + TitleHighlightData = matchResult.MatchData, ContextData = this, Action = e => { @@ -294,23 +297,7 @@ public Result Result(string query, IPublicAPI api) } }; - if (Description.Length >= DisplayName.Length && - Description.Substring(0, DisplayName.Length) == DisplayName) - { - result.Title = Description; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData; - } - else if (!string.IsNullOrEmpty(Description)) - { - var title = $"{DisplayName}: {Description}"; - result.Title = title; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, title).MatchData; - } - else - { - result.Title = DisplayName; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, DisplayName).MatchData; - } + return result; } @@ -324,9 +311,14 @@ public List ContextMenus(IPublicAPI api) Action = _ => { - Main.StartProcess(Process.Start, new ProcessStartInfo( - !string.IsNullOrEmpty(Main._settings.CustomizedExplorer) ? Main._settings.CustomizedExplorer:Settings.Explorer, - Main._settings.CustomizedArgs.Replace("%s",$"\"{Package.Location}\"").Trim())); + Main.StartProcess(Process.Start, + new ProcessStartInfo( + !string.IsNullOrEmpty(Main._settings.CustomizedExplorer) + ? Main._settings.CustomizedExplorer + : Settings.Explorer, + Main._settings.CustomizedArgs + .Replace("%s",$"\"{Package.Location}\"") + .Trim())); return true; }, diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index 7f90367ab84..092418b6c40 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -33,29 +33,30 @@ public class Win32 : IProgram private const string ApplicationReferenceExtension = "appref-ms"; private const string ExeExtension = "exe"; - private int Score(string query) - { - var nameMatch = StringMatcher.FuzzySearch(query, Name); - var descriptionMatch = StringMatcher.FuzzySearch(query, Description); - var executableNameMatch = StringMatcher.FuzzySearch(query, ExecutableName); - var score = new[] { nameMatch.Score, descriptionMatch.Score, executableNameMatch.Score }.Max(); - return score; - } - public Result Result(string query, IPublicAPI api) { - var score = Score(query); - if (score <= 0) - { // no need to create result if this is zero + var title = (Name, Description) switch + { + (var n, null) => n, + (var n, var d) when d.StartsWith(n) => d, + (var n, var d) when n.StartsWith(d) => n, + (var n, var d) when !string.IsNullOrEmpty(d) => $"{n}: {d}", + _ => Name + }; + + var matchResult = StringMatcher.FuzzySearch(query, title); + + if (!matchResult.Success) return null; - } var result = new Result { + Title = title, SubTitle = FullPath, IcoPath = IcoPath, - Score = score, + Score = matchResult.Score, + TitleHighlightData = matchResult.MatchData, ContextData = this, Action = e => { @@ -72,24 +73,6 @@ public Result Result(string query, IPublicAPI api) } }; - if (Description.Length >= Name.Length && - Description.Substring(0, Name.Length) == Name) - { - result.Title = Description; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, Description).MatchData; - } - else if (!string.IsNullOrEmpty(Description)) - { - var title = $"{Name}: {Description}"; - result.Title = title; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, title).MatchData; - } - else - { - result.Title = Name; - result.TitleHighlightData = StringMatcher.FuzzySearch(query, Name).MatchData; - } - return result; } @@ -141,18 +124,20 @@ public List ContextMenus(IPublicAPI api) Action = _ => { var args = !string.IsNullOrWhiteSpace(Main._settings.CustomizedArgs) - ?Main._settings.CustomizedArgs + ? Main._settings.CustomizedArgs .Replace("%s",$"\"{ParentDirectory}\"") - .Replace("%f",$"\"{FullPath}\""): - Main._settings.CustomizedExplorer==Settings.Explorer - ? $"/select,\"{FullPath}\"" - : Settings.ExplorerArgs; - - Main.StartProcess(Process.Start, new ProcessStartInfo( - !string.IsNullOrWhiteSpace(Main._settings.CustomizedExplorer) - ? Main._settings.CustomizedExplorer - : Settings.Explorer, - args)); + .Replace("%f",$"\"{FullPath}\"") + : Main._settings.CustomizedExplorer==Settings.Explorer + ? $"/select,\"{FullPath}\"" + : Settings.ExplorerArgs; + + Main.StartProcess(Process.Start, + new ProcessStartInfo( + !string.IsNullOrWhiteSpace(Main._settings.CustomizedExplorer) + ? Main._settings.CustomizedExplorer + : Settings.Explorer, + args)); + return true; }, IcoPath = "Images/folder.png" @@ -264,9 +249,7 @@ private static Win32 ExeProgram(string path) var program = Win32Program(path); var info = FileVersionInfo.GetVersionInfo(path); if (!string.IsNullOrEmpty(info.FileDescription)) - { program.Description = info.FileDescription; - } return program; } catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) @@ -282,47 +265,23 @@ private static IEnumerable ProgramPaths(string directory, string[] suffi { if (!Directory.Exists(directory)) return new string[] { }; - var files = new List(); - var folderQueue = new Queue(); - folderQueue.Enqueue(directory); - do + try { - var currentDirectory = folderQueue.Dequeue(); - try - { - foreach (var suffix in suffixes) - { - try - { - files.AddRange(Directory.EnumerateFiles(currentDirectory, $"*.{suffix}", SearchOption.TopDirectoryOnly)); - } - catch (DirectoryNotFoundException e) - { - ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" + - "|The directory trying to load the program from does not exist", e); - } - } - } - catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) - { - ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" + - $"|Permission denied when trying to load programs from {currentDirectory}", e); - } + var paths = Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories) + .Where(x => suffixes.Contains(Extension(x))); + return paths; - try - { - foreach (var childDirectory in Directory.EnumerateDirectories(currentDirectory, "*", SearchOption.TopDirectoryOnly)) - { - folderQueue.Enqueue(childDirectory); - } - } - catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) - { - ProgramLogger.LogException($"|Win32|ProgramPaths|{currentDirectory}" + - $"|Permission denied when trying to load programs from {currentDirectory}", e); - } - } while (folderQueue.Any()); - return files; + } + catch (DirectoryNotFoundException e) + { + ProgramLogger.LogException($"Directory not found {directory}", e); + return new string[] { }; + } + catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException) + { + ProgramLogger.LogException($"Permission denied {directory}", e); + return new string[] { }; + } } private static string Extension(string path) @@ -340,23 +299,20 @@ private static string Extension(string path) private static ParallelQuery UnregisteredPrograms(List sources, string[] suffixes) { - var listToAdd = new List(); - sources.Where(s => Directory.Exists(s.Location) && s.Enabled) + var paths = sources.Where(s => Directory.Exists(s.Location) && s.Enabled) .SelectMany(s => ProgramPaths(s.Location, suffixes)) - .ToList() .Where(t1 => !Main._settings.DisabledProgramSources.Any(x => t1 == x.UniqueIdentifier)) - .ToList() - .ForEach(x => listToAdd.Add(x)); - - var paths = listToAdd.Distinct().ToArray(); - - var programs1 = paths.AsParallel().Where(p => Extension(p) == ExeExtension).Select(ExeProgram); - var programs2 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(LnkProgram); - var programs3 = from p in paths.AsParallel() - let e = Extension(p) - where e != ShortcutExtension && e != ExeExtension - select Win32Program(p); - return programs1.Concat(programs2).Concat(programs3); + .Distinct(); + + var programs = paths.AsParallel().Select(x => Extension(x) switch + { + ExeExtension => ExeProgram(x), + ShortcutExtension => LnkProgram(x), + _ => Win32Program(x) + }); + + + return programs; } private static ParallelQuery StartMenuPrograms(string[] suffixes) @@ -369,15 +325,16 @@ private static ParallelQuery StartMenuPrograms(string[] suffixes) var paths2 = ProgramPaths(directory2, suffixes); var toFilter = paths1.Concat(paths2); - var paths = toFilter + + var programs = toFilter + .AsParallel() .Where(t1 => !disabledProgramsList.Any(x => x.UniqueIdentifier == t1)) - .Select(t1 => t1) .Distinct() - .ToArray(); - - var programs1 = paths.AsParallel().Where(p => Extension(p) == ShortcutExtension).Select(LnkProgram); - var programs2 = paths.AsParallel().Where(p => Extension(p) == ApplicationReferenceExtension).Select(Win32Program); - var programs = programs1.Concat(programs2).Where(p => p.Valid); + .Select(x => Extension(x) switch + { + ShortcutExtension => LnkProgram(x), + _ => Win32Program(x) + }).Where(x => x.Valid); return programs; }