Skip to content

Commit

Permalink
Implemented possibility to add commandline arguments in the Program P…
Browse files Browse the repository at this point in the history
…lugin
  • Loading branch information
Roy committed Aug 14, 2020
1 parent 5c1713f commit 02b3c8b
Show file tree
Hide file tree
Showing 12 changed files with 654 additions and 485 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Plugin.Program.ProgramArgumentParser;
using NUnit.Framework;
using Wox.Plugin;

namespace Microsoft.Plugin.Program.UnitTests.ProgramArgumentParser
{
public class ProgramArgumentParserTests
{
[TestCase("Microsoft Edge", "Microsoft Edge", null)]
[TestCase("Microsoft Edge ---inprivate", "Microsoft Edge ---inprivate", null)]
[TestCase("Microsoft Edge -- -inprivate", "Microsoft Edge", "-inprivate")]
[TestCase("Microsoft Edge -inprivate", "Microsoft Edge", "-inprivate")]
[TestCase("Microsoft Edge /inprivate", "Microsoft Edge", "/inprivate")]
[TestCase("edge.exe --inprivate", "edge.exe --inprivate", null)]
[TestCase("edge.exe -- --inprivate", "edge.exe", "--inprivate")]
[TestCase("edge.exe", "edge.exe", null)]
[TestCase("edge", "edge", null)]
[TestCase("cmd -c \"ping 1.1.1.1\"", "cmd", "-c \"ping 1.1.1.1\"")]
public void ProgramArgumentParserTestsCanParseQuery(string inputQuery, string expectedProgram, string expectedProgramArguments)
{
// Arrange
var argumentParsers = new IProgramArgumentParser[]
{
new DoubleDashProgramArgumentParser(),
new InferedProgramArgumentParser(),
new NoArgumentsArgumentParser(),
};

// Basis version oft he Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but didn't want to conenct this to that project
var splittedSearchString = inputQuery?.Split(Query.TermSeparator, System.StringSplitOptions.RemoveEmptyEntries);
var cleanQuery = string.Join(Query.TermSeparator, splittedSearchString);
var query = new Query(cleanQuery, cleanQuery, splittedSearchString, string.Empty);

// Act
string program = null, programArguments = null;
foreach (var argumentParser in argumentParsers)
{
if (argumentParser.TryParse(query, out program, out programArguments))
{
break;
}
}

// Assert
Assert.AreEqual(expectedProgram, program);
Assert.AreEqual(expectedProgramArguments, programArguments);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs
using Win32Program = Microsoft.Plugin.Program.Programs.Win32Program;

[TestFixture]
public class Win32Tests
public class Win32Tests
{
private static readonly Win32Program _notepadAppdata = new Win32Program
{
Expand Down Expand Up @@ -439,7 +439,7 @@ public void Win32AppsShouldSetNameAsTitleWhileCreatingResult()
StringMatcher.Instance = new StringMatcher();

// Act
var result = _cmderRunCommand.Result("cmder", mock.Object);
var result = _cmderRunCommand.Result("cmder", string.Empty, mock.Object);

// Assert
Assert.IsTrue(result.Title.Equals(_cmderRunCommand.Name, StringComparison.Ordinal));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Wox.Plugin;

namespace Microsoft.Plugin.Program
{
public interface IProgramArgumentParser
{
bool Enabled { get; }

bool TryParse(Query query, out string program, out string programArguments);
}
}
83 changes: 50 additions & 33 deletions src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Plugin.Program.ProgramArgumentParser;
using Microsoft.Plugin.Program.Programs;
using Microsoft.Plugin.Program.Storage;
using Microsoft.PowerToys.Settings.UI.Lib;
Expand All @@ -17,7 +18,7 @@

namespace Microsoft.Plugin.Program
{
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, IDisposable
public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, IDisposable
{
internal static ProgramPluginSettings _settings { get; set; }

Expand All @@ -26,11 +27,18 @@ public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, I
private static PluginInitContext _context;

private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;
private bool _disposed = false;
private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper(), new BinaryStorage<IList<UWPApplication>>("UWP"));
private static Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper;
private bool _disposed = false;
private PackageRepository _packageRepository = new PackageRepository(new PackageCatalogWrapper(), new BinaryStorage<IList<UWPApplication>>("UWP"));
private static Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper;
private static Win32ProgramRepository _win32ProgramRepository;

private static readonly IProgramArgumentParser[] _programArgumentParsers = new IProgramArgumentParser[]
{
new DoubleDashProgramArgumentParser(),
new InferedProgramArgumentParser(),
new NoArgumentsArgumentParser()
};

public Main()
{
_settingsStorage = new PluginJsonStorage<ProgramPluginSettings>();
Expand Down Expand Up @@ -79,19 +87,28 @@ public void Save()

public List<Result> Query(Query query)
{
var results1 = _win32ProgramRepository.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));
foreach (var programArgumentParser in _programArgumentParsers)
{

if (!programArgumentParser.Enabled) continue;
if (!programArgumentParser.TryParse(query, out var program, out var programArguments)) continue;

var results1 = _win32ProgramRepository.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(program, programArguments, _context.API));

var results2 = _packageRepository.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));
var results2 = _packageRepository.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(program, programArguments, _context.API));

var result = results1.Concat(results2).Where(r => r != null && r.Score > 0);
var maxScore = result.Max(x => x.Score);
result = result.Where(x => x.Score > _settings.MinScoreThreshold * maxScore);
var result = results1.Concat(results2).Where(r => r != null && r.Score > 0);
var maxScore = result.Max(x => x.Score);
result = result.Where(x => x.Score > _settings.MinScoreThreshold * maxScore);

return result.ToList();
return result.ToList();
}

return new List<Result>(0);
}

public void Init(PluginInitContext context)
Expand Down Expand Up @@ -184,24 +201,24 @@ public void ReloadData()
public static void UpdateSettings(PowerLauncherSettings _)
{
}

public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.API.ThemeChanged -= OnThemeChanged;
_win32ProgramRepositoryHelper.Dispose();
_disposed = true;
}
}
}

public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_context.API.ThemeChanged -= OnThemeChanged;
_win32ProgramRepositoryHelper.Dispose();
_disposed = true;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ProjectGuid>{FDB3555B-58EF-4AE6-B5F1-904719637AB4}</ProjectGuid>
<AppDesignerFolder>Properties</AppDesignerFolder>
Expand Down Expand Up @@ -91,9 +91,9 @@

<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Linq;
using Wox.Plugin;

namespace Microsoft.Plugin.Program
{
public class DoubleDashProgramArgumentParser : IProgramArgumentParser
{
const string doubleDash = "--";

public bool Enabled { get; } = true;

public bool TryParse(Query query, out string program, out string programArguments)
{
if (!string.IsNullOrEmpty(query?.Search))
{
// First Argument is always (part of) the programa, 2nd term is possibly a Program Argument
if (query.Terms.Length > 1)
{
for (int i = 1; i < query.Terms.Length; i++)
{
if (string.Equals(query.Terms[i], doubleDash, StringComparison.Ordinal))
{
program = string.Join(Query.TermSeparator, query.Terms.Take(i));
programArguments = string.Join(Query.TermSeparator, query.Terms.Skip(i + 1));
return true;
}
}
}
}

program = null;
programArguments = null;
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Wox.Plugin;

namespace Microsoft.Plugin.Program
{
public class InferedProgramArgumentParser : IProgramArgumentParser
{
private static readonly Regex ArgumentPrefixRegex = new Regex("^[-/][a-zA-Z]+", RegexOptions.Compiled);

public bool Enabled { get; } = true;

public bool TryParse(Query query, out string program, out string programArguments)
{
if (!string.IsNullOrEmpty(query?.Search))
{
// First Argument is always (part of) the programa, 2nd term is possibly a Program Argument
if (query.Terms.Length > 1)
{
for (int i = 1; i < query.Terms.Length; i++)
{
if (ArgumentPrefixRegex.IsMatch(query.Terms[i]))
{
program = string.Join(Query.TermSeparator, query.Terms.Take(i));
programArguments = string.Join(Query.TermSeparator, query.Terms.Skip(i));
return true;
}
}
}
}

program = null;
programArguments = null;
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Wox.Plugin;

namespace Microsoft.Plugin.Program.ProgramArgumentParser
{
public class NoArgumentsArgumentParser : IProgramArgumentParser
{
public bool Enabled { get; } = true;

public bool TryParse(Query query, out string program, out string programArguments)
{
program = query?.Search;
programArguments = null;
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ namespace Microsoft.Plugin.Program.Programs
public interface IProgram
{
List<ContextMenuResult> ContextMenus(IPublicAPI api);

Result Result(string query, IPublicAPI api);

Result Result(string query, string queryArguments, IPublicAPI api);
string UniqueIdentifier { get; set; }

string Name { get; }
Expand Down
Loading

0 comments on commit 02b3c8b

Please sign in to comment.