Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 15 additions & 21 deletions Plugins/Flow.Launcher.Plugin.Program/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,17 @@ public List<Result> 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<IProgram>()
.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;
}

Expand All @@ -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()
Expand All @@ -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()
Expand Down
1 change: 1 addition & 0 deletions Plugins/Flow.Launcher.Plugin.Program/Programs/IProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public interface IProgram
string UniqueIdentifier { get; set; }
string Name { get; }
string Location { get; }
bool Enabled { get; }
}
}
56 changes: 24 additions & 32 deletions Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Comment on lines +271 to +280
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍


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 =>
{
Expand All @@ -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;
}

Expand All @@ -324,9 +311,14 @@ public List<Result> 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;
},
Expand Down
169 changes: 63 additions & 106 deletions Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =>
{
Expand All @@ -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;
}

Expand Down Expand Up @@ -141,18 +124,20 @@ public List<Result> 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"
Expand Down Expand Up @@ -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)
Expand All @@ -282,47 +265,23 @@ private static IEnumerable<string> ProgramPaths(string directory, string[] suffi
{
if (!Directory.Exists(directory))
return new string[] { };
var files = new List<string>();
var folderQueue = new Queue<string>();
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)
Expand All @@ -340,23 +299,20 @@ private static string Extension(string path)

private static ParallelQuery<Win32> UnregisteredPrograms(List<Settings.ProgramSource> sources, string[] suffixes)
{
var listToAdd = new List<string>();
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<Win32> StartMenuPrograms(string[] suffixes)
Expand All @@ -369,15 +325,16 @@ private static ParallelQuery<Win32> 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;
}

Expand Down