diff --git a/CHANGELOG.md b/CHANGELOG.md index 274907e..4bd29e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,17 @@ All notable changes to this project will be documented in this file. ## [Unreleased] -## [1.1.8] - 2024-09-xx +## [1.1.9] - 2024-09-16 + +- QuickLook support to preview folders and files +- Improved code quality and performance +- Enchanted config command. Now shows icon of the application which will be used to open configuration files + +## [1.1.8] - 2024-09-12 - Add autocomplete support for commands with arguments - After typing the full shortcut, for example `q dev`, pressing `Ctr+Tab` (autocomplete) will replace current query with - the - shortcut path + the shortcut path - Alias support for shortcuts. Add `Alias` field in the shortcut JSON file. Provide the alias name. Example: ```json diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/ContextMenu.cs b/Flow.Launcher.Plugin.ShortcutPlugin/ContextMenu.cs index a9f04d7..1c0d679 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/ContextMenu.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/ContextMenu.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using Flow.Launcher.Plugin.ShortcutPlugin.Extensions; using Flow.Launcher.Plugin.ShortcutPlugin.Models.Shortcuts; using Flow.Launcher.Plugin.ShortcutPlugin.Services.Interfaces; @@ -53,11 +54,14 @@ private void AddShortcutDetails(Result selectedResult, List contextMenu) return; } - contextMenu.Add(ResultExtensions.Result( - "Key", - shortcut.Key, - () => { _context.API.CopyToClipboard(shortcut.Key, showDefaultNotification: false); } - )); + if (!string.IsNullOrWhiteSpace(shortcut.Key)) + { + contextMenu.Add(ResultExtensions.Result( + "Key", + shortcut.Key, + () => { _context.API.CopyToClipboard(shortcut.Key, showDefaultNotification: false); } + )); + } if (shortcut.Alias is {Count: > 0}) { @@ -121,6 +125,7 @@ private void GetFileShortcutContextMenu(ICollection contextMenu, FileSho contextMenu.Add(ResultExtensions.Result( "Open containing folder", + Path.GetDirectoryName(filePath), action: () => { var path = Path.GetDirectoryName(filePath); @@ -142,6 +147,7 @@ private void GetFileShortcutContextMenu(ICollection contextMenu, FileSho contextMenu.Add(ResultExtensions.Result( "Copy path", + filePath, action: () => { _context.API.CopyToClipboard(filePath, showDefaultNotification: false); }, iconPath: Icons.Copy )); @@ -151,6 +157,22 @@ private void GetFileShortcutContextMenu(ICollection contextMenu, FileSho action: () => { _context.API.CopyToClipboard(filePath, true, false); }, iconPath: Icons.Copy )); + + var codeEditors = GetCodeEditors(); + + foreach (var (title, cmd, icon) in codeEditors) + { + contextMenu.Add(ResultExtensions.Result( + $"Open in {title}", + action: () => + { + CliWrap.Cli.Wrap(cmd) + .WithArguments(filePath) + .ExecuteAsync(); + }, + iconPath: icon + )); + } } private void GetDirectoryContextMenu(ICollection contextMenu, DirectoryShortcut directoryShortcut) @@ -172,9 +194,9 @@ private void GetDirectoryContextMenu(ICollection contextMenu, DirectoryS iconPath: Icons.FolderOpen )); - var visualCodeVersions = GetVisualCodeVersions(); + var codeEditors = GetCodeEditors(); - foreach (var (title, cmd, icon) in visualCodeVersions) + foreach (var (title, cmd, icon) in codeEditors) { contextMenu.Add(ResultExtensions.Result( $"Open in {title}", @@ -261,7 +283,7 @@ private void GetDirectoryContextMenu(ICollection contextMenu, DirectoryS } } - private static List<(string title, string executable, string icon)> GetVisualCodeVersions() + private static List<(string title, string executable, string icon)> GetCodeEditors() { var path = Environment.GetEnvironmentVariable("PATH"); var versions = new List<(string, string, string)>(); @@ -271,20 +293,20 @@ private void GetDirectoryContextMenu(ICollection contextMenu, DirectoryS return versions; } - var folders = path.Split(';'); - - foreach (var folder in folders) + var editors = new Dictionary { - if (File.Exists(Path.Combine(folder, "code.cmd"))) - { - versions.Add(("Visual Studio Code", "code", Icons.VisualCode)); - } - - if (File.Exists(Path.Combine(folder, "code-insiders.cmd"))) - { - versions.Add(("Visual Studio Code - Insiders", "code-insiders", Icons.VisualCodeInsiders)); - } - } + {"code.cmd", ("Visual Studio Code", "code", Icons.VisualCode)}, + {"code-insiders.cmd", ("Visual Studio Code - Insiders", "code-insiders", Icons.VisualCodeInsiders)}, + {"zed.exe", ("Zed", "zed", Icons.Zed)} + }; + + versions.AddRange( + path + .Split(';') + .SelectMany(_ => editors, (folder, editor) => new {folder, editor}) + .Where(t => File.Exists(Path.Combine(t.folder, t.editor.Key))) + .Select(t => t.editor.Value) + ); return versions; } diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Extensions/ResultExtensions.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Extensions/ResultExtensions.cs index e28f114..66f8ea1 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Extensions/ResultExtensions.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Extensions/ResultExtensions.cs @@ -6,6 +6,11 @@ namespace Flow.Launcher.Plugin.ShortcutPlugin.Extensions; public static class ResultExtensions { + public static List ToList(this Result result) + { + return new List {result}; + } + public static List EmptyResult() { return SingleResult(Resources.Shortcuts_Query_No_results_found); @@ -53,7 +58,8 @@ public static Result Result( object contextData = default, string autoCompleteText = null, IList titleHighlightData = default, - int score = default + int score = default, + string previewFilePath = null ) { return new Result @@ -69,7 +75,11 @@ public static Result Result( action?.Invoke(); return hideAfterAction; }, - AutoCompleteText = autoCompleteText ?? title + AutoCompleteText = autoCompleteText ?? title, + Preview = new Result.PreviewInfo + { + FilePath = previewFilePath + } }; } } \ No newline at end of file diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Flow.Launcher.Plugin.ShortcutPlugin.csproj b/Flow.Launcher.Plugin.ShortcutPlugin/Flow.Launcher.Plugin.ShortcutPlugin.csproj index d5bc2b8..ea207a3 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Flow.Launcher.Plugin.ShortcutPlugin.csproj +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Flow.Launcher.Plugin.ShortcutPlugin.csproj @@ -10,7 +10,7 @@ flow-launcher flow-plugin false false - 11 + latest true diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Images/zed.png b/Flow.Launcher.Plugin.ShortcutPlugin/Images/zed.png new file mode 100644 index 0000000..270ba82 Binary files /dev/null and b/Flow.Launcher.Plugin.ShortcutPlugin/Images/zed.png differ diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ConfigCommand.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ConfigCommand.cs index 95f8c9b..172b0f6 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ConfigCommand.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ConfigCommand.cs @@ -2,6 +2,7 @@ using System.IO; using CliWrap; using Flow.Launcher.Plugin.ShortcutPlugin.Extensions; +using Flow.Launcher.Plugin.ShortcutPlugin.Models.Shortcuts; using Flow.Launcher.Plugin.ShortcutPlugin.Services.Interfaces; namespace Flow.Launcher.Plugin.ShortcutPlugin.Models.Commands; @@ -37,25 +38,30 @@ private List ConfigCommandHandler(ActionContext context, List ar return new List { - ResultExtensions.Result("Open shortcuts config", shortcutsPath, () => - { - if (!File.Exists(shortcutsPath)) - { - CreateConfigFile(shortcutsPath); - } + CreateConfigResult("Open shortcuts config", shortcutsPath), + CreateConfigResult("Open variables config", variablesPath) + }; + } - OpenConfig(shortcutsPath); - }), - ResultExtensions.Result("Open variables config", variablesPath, () => + private Result CreateConfigResult(string title, string path) + { + return ResultExtensions.Result(title, path, () => { - if (!File.Exists(variablesPath)) + if (!File.Exists(path)) { - CreateConfigFile(variablesPath); + CreateConfigFile(path); } - OpenConfig(variablesPath); - }) - }; + OpenConfig(path); + }, + iconPath: File.Exists(path) ? path : null, + autoCompleteText: path, + previewFilePath: path, + contextData: new FileShortcut + { + Path = path + } + ); } private static void OpenConfig(string path) diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/HelpCommand.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/HelpCommand.cs index ee561f8..68ae5f1 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/HelpCommand.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/HelpCommand.cs @@ -35,21 +35,24 @@ private List HelpCommandHandler(ActionContext context, List argu "Open the plugin's documentation", Constants.ReadmeUrl, () => { ShortcutUtilities.OpenUrl(Constants.ReadmeUrl); }, - iconPath: Icons.Info + iconPath: Icons.Info, + autoCompleteText: Constants.ReadmeUrl ); var reportIssueResult = ResultExtensions.Result( "Report an issue on GitHub", Constants.GithubIssues, () => { ShortcutUtilities.OpenUrl(Constants.GithubIssues); }, - iconPath: Icons.Github + iconPath: Icons.Github, + autoCompleteText: Constants.GithubIssues ); var discordResult = ResultExtensions.Result( "Contact the developer on Discord", "Username: " + Constants.DiscordUsername, () => { _context.API.CopyToClipboard(Constants.DiscordUsername); }, - iconPath: Icons.Discord + iconPath: Icons.Discord, + autoCompleteText: Constants.DiscordUsername ); return new List {readmeResult, reportIssueResult, discordResult}; diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ListCommand.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ListCommand.cs index e3f46fa..735486b 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ListCommand.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ListCommand.cs @@ -1,3 +1,4 @@ +using System.Linq; using Flow.Launcher.Plugin.ShortcutPlugin.models; using Flow.Launcher.Plugin.ShortcutPlugin.Services.Interfaces; @@ -25,7 +26,7 @@ private Command CreateListCommand() .WithResponseFailure(("Failed to show all shortcuts", "Something went wrong")) .WithResponseSuccess(("List", "List all shortcuts")) .WithMultipleValuesForSingleArgument() - .WithHandler((_, arguments) => _shortcutsService.GetShortcuts(arguments)) + .WithHandler((_, arguments) => _shortcutsService.GetShortcuts(arguments.Skip(1).ToList())) .Build(); } } \ No newline at end of file diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ReloadCommand.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ReloadCommand.cs index b5c24dd..c04f1f5 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ReloadCommand.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Commands/ReloadCommand.cs @@ -37,7 +37,7 @@ private Command CreateReloadCommand() private List ReloadCommandHandler(ActionContext context, List arguments) { - return ResultExtensions.SingleResult("Reload plugin data", "", () => + return ResultExtensions.SingleResult("Reload plugin data", "This action will reload all plugin data", () => { _settingsService.Reload(); _shortcutsService.Reload(); diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Shortcuts/Shortcut.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Shortcuts/Shortcut.cs index 9ee8dc9..ddfbb4d 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Models/Shortcuts/Shortcut.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Models/Shortcuts/Shortcut.cs @@ -35,7 +35,14 @@ public string GetDerivedType() public string GetTitle() { - return $"{Key}{GetAlias()}"; + var title = $"{Key}{GetAlias()}"; + + return string.IsNullOrWhiteSpace(title) ? GetDerivedType() : title; + } + + public string GetSubTitle() + { + return ToString(); } private string GetAlias() diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/CommandsRepository.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/CommandsRepository.cs index dc2741b..12739ae 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/CommandsRepository.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/CommandsRepository.cs @@ -49,9 +49,9 @@ public List ResolveCommand(List arguments, Query query) var argsWithoutKey = arguments.Skip(1).ToList(); // In case this is a shortcut command, let's open shortcut - if (_shortcutsRepository.GetShortcuts(key) is not null) + if (_shortcutsRepository.TryGetShortcuts(key, out var shortcuts)) { - return _shortcutsService.OpenShortcuts(key, argsWithoutKey); + return _shortcutsService.OpenShortcuts(shortcuts, argsWithoutKey, true); } // If command was not found @@ -60,7 +60,7 @@ public List ResolveCommand(List arguments, Query query) // Show possible shortcuts var possibleShortcuts = _shortcutsRepository .GetPossibleShortcuts(key) - .SelectMany(s => _shortcutsService.OpenShortcut(s, argsWithoutKey)); + .SelectMany(s => _shortcutsService.OpenShortcut(s, argsWithoutKey, false)); // Return possible command matches var possibleCommands = GetPossibleCommands(key, query.ActionKeyword); @@ -107,10 +107,11 @@ public List ResolveCommand(List arguments, Query query) .Arguments.Cast() .Select(a => ResultExtensions.Result( - a.ResponseInfo.Item1, - a.ResponseInfo.Item2, + title: a.ResponseInfo.Item1, + subtitle: a.ResponseInfo.Item2, () => { _context.API.ChangeQuery($"{query.ActionKeyword} {a.ResponseInfo.Item1}"); }, - hideAfterAction: false + hideAfterAction: false, + autoCompleteText: $"{query.ActionKeyword} {a.ResponseInfo.Item1}" ) ) .ToList(); @@ -122,34 +123,34 @@ public List ResolveCommand(List arguments, Query query) private List ShowAvailableCommands(string actionKeyword) { return _commands - .Values.Select(c => new Result - { - Title = c.ResponseInfo.Item1 + " ", // FIXME: Wrong order without space - SubTitle = c.ResponseInfo.Item2, - IcoPath = Icons.Logo, - Score = 1000 - _commands.Count, - Action = _ => - { - _context.API.ChangeQuery($"{actionKeyword} {c.Key}"); - return false; - } - }) + .Values.Select(c => + ResultExtensions.Result( + title: c.ResponseInfo.Item1, + subtitle: c.ResponseInfo.Item2, + score: 1000 - _commands.Count, + hideAfterAction: false, + action: () => { _context.API.ChangeQuery($"{actionKeyword} {c.Key}"); }, + autoCompleteText: $"{actionKeyword} {c.Key}" + ) + ) .ToList(); } private IEnumerable GetPossibleCommands(string query, string actionKeyword) { return _commands - .Values.Where(c => + .Values + .Where(c => c.Key.StartsWith(query, StringComparison.InvariantCultureIgnoreCase) ) .Select(c => ResultExtensions.Result( - c.ResponseInfo.Item1, - c.ResponseInfo.Item2, + title: c.ResponseInfo.Item1, + subtitle: c.ResponseInfo.Item2, score: 1000, hideAfterAction: false, - action: () => { _context.API.ChangeQuery($"{actionKeyword} {c.Key}"); } + action: () => { _context.API.ChangeQuery($"{actionKeyword} {c.Key}"); }, + autoCompleteText: $"{actionKeyword} {c.Key}" ) ) .ToList(); diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/Interfaces/IShortcutsRepository.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/Interfaces/IShortcutsRepository.cs index ab43d27..ba96891 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/Interfaces/IShortcutsRepository.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/Interfaces/IShortcutsRepository.cs @@ -9,6 +9,7 @@ public interface IShortcutsRepository IList GetShortcuts(); IEnumerable GetPossibleShortcuts(string key); IList? GetShortcuts(string key); + bool TryGetShortcuts(string key, out List shortcuts); void AddShortcut(Shortcut shortcut); void RemoveShortcut(Shortcut shortcut); void DuplicateShortcut(Shortcut shortcut, string duplicateKey); diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/ShortcutsRepository.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/ShortcutsRepository.cs index 7e596b2..4d2b0fe 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/ShortcutsRepository.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Repositories/ShortcutsRepository.cs @@ -31,6 +31,11 @@ public IList GetShortcuts(string key) return _shortcuts.GetValueOrDefault(key); } + public bool TryGetShortcuts(string key, out List shortcuts) + { + return _shortcuts.TryGetValue(key, out shortcuts); + } + public IList GetShortcuts() { return _shortcuts.Values diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Services/CommandsService.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Services/CommandsService.cs index a5d76b7..5f3bef7 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Services/CommandsService.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Services/CommandsService.cs @@ -27,26 +27,7 @@ ICommandsRepository commandsRepository public List ResolveCommand(List arguments, Query query) { - var results = _commandsRepository.ResolveCommand(arguments, query); - - //TODO: Move this to different place? - results.ForEach(result => - { - if (string.IsNullOrEmpty(result.AutoCompleteText)) - { - result.AutoCompleteText = $"{query.ActionKeyword} {result.Title}"; - } - else if (result.ContextData is Shortcut) - { - result.AutoCompleteText = result.SubTitle; - } - else - { - result.AutoCompleteText = $"{query.ActionKeyword} {result.AutoCompleteText}"; - } - }); - - return results; + return _commandsRepository.ResolveCommand(arguments, query); } public void ReloadPluginData() diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Services/Interfaces/IShortcutsService.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Services/Interfaces/IShortcutsService.cs index b961632..ed22e51 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Services/Interfaces/IShortcutsService.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Services/Interfaces/IShortcutsService.cs @@ -7,8 +7,8 @@ public interface IShortcutsService { List RemoveShortcut(string key); List RemoveGroup(string key); - List OpenShortcuts(string key, IEnumerable arguments); - IEnumerable OpenShortcut(Shortcut shortcut, IEnumerable arguments); + List OpenShortcuts(IList shortcuts, IEnumerable arguments, bool expandGroups); + IEnumerable OpenShortcut(Shortcut shortcut, IEnumerable arguments, bool expandGroups); List DuplicateShortcut(string existingKey, string newKey); List ImportShortcuts(); List ExportShortcuts(); diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Services/ShortcutsService.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Services/ShortcutsService.cs index d722f1f..08148cf 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Services/ShortcutsService.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Services/ShortcutsService.cs @@ -38,17 +38,13 @@ public List GetShortcuts(List arguments) } var results = shortcuts - .Select(shortcut => - { - return ResultExtensions.Result( - shortcut.GetTitle(), - $"{shortcut}", - () => { _shortcutHandler.ExecuteShortcut(shortcut, arguments); }, - contextData: shortcut, - iconPath: GetIcon(shortcut), - autoCompleteText: $"{shortcut}" - ); - }) + .Select(shortcut => BuildShortcutResult( + shortcut: shortcut, + arguments: arguments, + title: shortcut.GetTitle(), + subtitle: shortcut.GetSubTitle(), + iconPath: GetIcon(shortcut) + )) .ToList(); var headerResult = ResultExtensions.Result( @@ -62,6 +58,10 @@ public List GetShortcuts(List arguments) return results; } + /// + /// Method used to get all groups in `q group list` command + /// + /// public List GetGroups() { var groups = _shortcutsRepository.GetGroups(); @@ -72,14 +72,10 @@ public List GetGroups() } return groups - .Select(group => - { - return ResultExtensions.Result( - group.GetTitle(), - $"{group}", - () => { _shortcutHandler.ExecuteShortcut(group, null); } - ); - }) + .Select(group => BuildShortcutResult( + shortcut: group, + arguments: [] + )) .ToList(); } @@ -91,8 +87,7 @@ public List RemoveShortcut(string key) public List RemoveGroup(string key) { return RemoveShortcut(_shortcutsRepository.GetShortcuts(key) - ? - .OfType() + ?.OfType() .Cast() .ToList()); } @@ -107,7 +102,8 @@ private List RemoveShortcut(List shortcuts) return shortcuts.Select(shortcut => { return ResultExtensions.Result( - string.Format(Resources.ShortcutsManager_RemoveShortcut_Remove_shortcut, shortcut.GetTitle()), + string.Format(Resources.ShortcutsManager_RemoveShortcut_Remove_shortcut, + shortcut.GetTitle()), shortcut.ToString(), () => { _shortcutsRepository.RemoveShortcut(shortcut); } ); @@ -115,45 +111,20 @@ private List RemoveShortcut(List shortcuts) .ToList(); } - public List OpenShortcuts(string key, IEnumerable arguments) + public List OpenShortcuts(IList shortcuts, IEnumerable arguments, + bool expandGroups) { - var shortcuts = _shortcutsRepository.GetShortcuts(key); - if (shortcuts is null) { return ResultExtensions.EmptyResult(); } - var args = arguments.ToList(); - var results = new List(); - - foreach (var shortcut in shortcuts) - { - if (shortcut is GroupShortcut groupShortcut) - { - results.AddRange(GetGroupShortcutResults(groupShortcut, args)); - continue; - } - - var temp = $"Open {shortcut.GetDerivedType().ToLower()} "; - var defaultKey = $"{temp}{shortcut.GetTitle()}"; - var highlightIndexes = Enumerable.Range(temp.Length, shortcut.GetTitle().Length).ToList(); - - results.Add( - BuildResult( - shortcut, - args, - defaultKey, - GetIcon(shortcut), - titleHighlightData: highlightIndexes - ) - ); - } - - return results; + return shortcuts.SelectMany(shortcut => OpenShortcut(shortcut, arguments, expandGroups)) + .ToList(); } - public IEnumerable OpenShortcut(Shortcut shortcut, IEnumerable arguments) + + public IEnumerable OpenShortcut(Shortcut shortcut, IEnumerable arguments, bool expandGroups) { if (shortcut is null) { @@ -163,18 +134,18 @@ public IEnumerable OpenShortcut(Shortcut shortcut, IEnumerable a var args = arguments.ToList(); var results = new List(); - /*if (shortcut is GroupShortcut groupShortcut) + if (expandGroups && shortcut is GroupShortcut groupShortcut) { results.AddRange(GetGroupShortcutResults(groupShortcut, args)); return results; - }*/ + } var temp = $"Open {shortcut.GetDerivedType().ToLower()} "; var defaultKey = $"{temp}{shortcut.GetTitle()}"; var highlightIndexes = Enumerable.Range(temp.Length, shortcut.GetTitle().Length).ToList(); results.Add( - BuildResult( + BuildShortcutResult( shortcut, args, defaultKey, @@ -292,7 +263,7 @@ out Dictionary parsedArguments return true; } - private string ExpandShortcut(Shortcut shortcut, IReadOnlyList arguments) + private string ExpandShortcutArguments(Shortcut shortcut, IReadOnlyList arguments) { if ( !arguments.Any() @@ -320,43 +291,25 @@ List arguments var highlightIndexes = Enumerable.Range(title.Length, groupShortcut.GetTitle().Length).ToList(); title += groupShortcut.GetTitle(); - var results = new List - { - new() - { - Title = title, - SubTitle = $"{groupShortcut} {joinedArguments}", - Action = _ => - { - _shortcutHandler.ExecuteShortcut(groupShortcut, arguments); - return true; - }, - IcoPath = GetIcon(groupShortcut), - TitleHighlightData = highlightIndexes, - Score = 100 - } - }; + + var results = BuildShortcutResult( + shortcut: groupShortcut, + arguments: arguments, + title: title, + subtitle: $"{groupShortcut} {joinedArguments}", + titleHighlightData: highlightIndexes, + score: 100 + ) + .ToList(); if (groupShortcut.Shortcuts is not null) { results.AddRange( - groupShortcut.Shortcuts.Select(shortcut => - { - var expandedShortcut = ExpandShortcut(shortcut, arguments); - - return new Result - { - Title = $"{shortcut.GetTitle() ?? shortcut.GetDerivedType()}", - SubTitle = expandedShortcut, - Action = _ => - { - _shortcutHandler.ExecuteShortcut(shortcut, arguments); - return true; - }, - IcoPath = GetIcon(shortcut), - ContextData = shortcut - }; - }) + groupShortcut.Shortcuts + .Select(shortcut => BuildShortcutResult( + shortcut: shortcut, + arguments: arguments + )) ); } @@ -367,57 +320,22 @@ List arguments var keyResults = groupShortcut.Keys - .Select(key => (groupShortcutKey: key, _shortcutsRepository.GetShortcuts(key))) - .Select(value => + .Select(key => { - var (key, shortcuts) = value; + var shortcuts = _shortcutsRepository.GetShortcuts(key); if (shortcuts is null) { - return new List - { - new() - { - Title = "Missing shortcut.", - SubTitle = $"Shortcut '{key}' not found.", - IcoPath = Icons.PriorityHigh - } - }; - } - - var selectResults = new List(); - - foreach (var shortcut in shortcuts) - { - if (shortcut is null) + return new Result { - selectResults.Add(new Result - { - Title = "Missing shortcut.", - SubTitle = $"Shortcut '{key}' not found.", - IcoPath = Icons.PriorityHigh - }); - - continue; - } - - var expandedShortcut = ExpandShortcut(shortcut, arguments); - - results.Add(new Result - { - Title = $"{shortcut.GetTitle() ?? shortcut.GetDerivedType()}", - SubTitle = expandedShortcut, - Action = _ => - { - _shortcutHandler.ExecuteShortcut(shortcut, arguments); - return true; - }, - IcoPath = GetIcon(shortcut), - ContextData = shortcut - }); + Title = "Missing shortcut.", + SubTitle = $"Shortcut '{key}' not found.", + IcoPath = Icons.PriorityHigh + }.ToList(); } - return selectResults; + return shortcuts.Select(shortcut => + BuildShortcutResult(shortcut: shortcut, arguments: arguments)); } ) .SelectMany(x => x); @@ -427,33 +345,33 @@ List arguments return results; } - private Result BuildResult( + private Result BuildShortcutResult( Shortcut shortcut, List arguments, - string defaultKey = null, + string title = null, string iconPath = null, - IList titleHighlightData = default + IList titleHighlightData = default, + string subtitle = null, + string autoCompleteText = null, + int score = 0 ) { - var expandedShortcut = ExpandShortcut(shortcut, arguments); + var expandedArguments = ExpandShortcutArguments(shortcut, arguments); + var expandedAll = _variablesService.ExpandVariables(expandedArguments); - return ResultExtensions.Result( - (string.IsNullOrEmpty(defaultKey) ? shortcut.GetDerivedType() : defaultKey) + - " ", // FIXME: Wrong order without space - expandedShortcut, - () => { _shortcutHandler.ExecuteShortcut(shortcut, arguments); }, + var result = ResultExtensions.Result( + title: (string.IsNullOrEmpty(title) ? shortcut.GetTitle() : title) + " ", + subtitle: subtitle ?? expandedArguments, + action: () => { _shortcutHandler.ExecuteShortcut(shortcut, arguments); }, contextData: shortcut, - iconPath: iconPath, + iconPath: iconPath ?? GetIcon(shortcut), titleHighlightData: titleHighlightData, - autoCompleteText: shortcut switch - { - FileShortcut fileShortcut => fileShortcut.Path, - DirectoryShortcut directoryShortcut => directoryShortcut.Path, - UrlShortcut urlShortcut => urlShortcut.Url, - ShellShortcut shellShortcut => shellShortcut.Arguments, - _ => null - } + autoCompleteText: autoCompleteText ?? expandedAll, + previewFilePath: expandedAll, + score: score ); + + return result; } private string GetIcon(Shortcut shortcut) diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Services/VariablesService.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Services/VariablesService.cs index 7216b65..222ba7b 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Services/VariablesService.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Services/VariablesService.cs @@ -26,21 +26,36 @@ public List GetVariables() var variables = _variablesRepository.GetVariables(); if (variables.Count == 0) + { return ResultExtensions.EmptyResult("No variables found."); + } - return variables - .Select(variable => new Result - { - Title = $"Variable '{variable.Name}'", - SubTitle = $"Value: '{variable.Value}'", - IcoPath = Icons.Logo, - Action = _ => - { - _context.API.CopyToClipboard(variable.Value); - return true; - } - }) - .ToList(); + var header = new Result + { + Title = "Variables", + SubTitle = "List of all variables", + IcoPath = Icons.Logo + }; + + var results = + variables + .Select(variable => new Result + { + Title = $"{variable.Name}", + SubTitle = $"{variable.Value}", + IcoPath = Icons.Logo, + Action = _ => + { + _context.API.CopyToClipboard($"Variable: {variable.Name} value: {variable.Value}"); + return true; + }, + AutoCompleteText = $"Variable: {variable.Name} value: {variable.Value}" + }) + .ToList(); + + results.Insert(0, header); + + return results; } public List GetVariable(string name) diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/Utilities/Icons.cs b/Flow.Launcher.Plugin.ShortcutPlugin/Utilities/Icons.cs index fda4023..5f249c7 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/Utilities/Icons.cs +++ b/Flow.Launcher.Plugin.ShortcutPlugin/Utilities/Icons.cs @@ -40,6 +40,8 @@ public static class Icons public const string VisualCodeInsiders = "Images\\vscode-insiders.png"; + public const string Zed = "Images\\zed.png"; + public const string PowerShellBlack = "Images\\powershell_black.png"; public const string WindowsTerminal = "Images\\windows-terminal.png"; diff --git a/Flow.Launcher.Plugin.ShortcutPlugin/plugin.json b/Flow.Launcher.Plugin.ShortcutPlugin/plugin.json index f14e870..e18c680 100644 --- a/Flow.Launcher.Plugin.ShortcutPlugin/plugin.json +++ b/Flow.Launcher.Plugin.ShortcutPlugin/plugin.json @@ -3,11 +3,11 @@ "Name": "Shortcuts", "Description": "Open user defined shortcut quickly from Flow Launcher", "Author": "Mantelis", - "Version": "1.1.8", + "Version": "1.1.9", "Language": "csharp", "ActionKeyword": "q", "Website": "https://github.com/mantasjasikenas/flow-launcher-shortcuts-plugin", - "UrlDownload":"https://github.com/mantasjasikenas/flow-launcher-shortcuts-plugin/releases/download/v1.1.8/Flow.Launcher.Plugin.ShortcutPlugin.zip", + "UrlDownload":"https://github.com/mantasjasikenas/flow-launcher-shortcuts-plugin/releases/download/v1.1.9/Flow.Launcher.Plugin.ShortcutPlugin.zip", "UrlSourceCode": "https://github.com/mantasjasikenas/flow-launcher-shortcuts-plugin/tree/master", "IcoPath": "images\\icon.png", "ExecuteFileName": "Flow.Launcher.Plugin.ShortcutPlugin.dll"