From 266b3a5595c0d021fc341b70a515109f41d19989 Mon Sep 17 00:00:00 2001 From: John Wilson Date: Tue, 15 Feb 2022 20:32:11 +0000 Subject: [PATCH 1/2] Add zsh completion shim and documentation. --- docs/dotnet-suggest.md | 2 ++ .../SuggestionShellScriptHandlerTest.cs | 11 ++++++++++- src/System.CommandLine.Suggest/ShellType.cs | 3 ++- .../SuggestionShellScriptHandler.cs | 3 +++ .../dotnet-suggest-shim.zsh | 15 +++++++++++++++ .../dotnet-suggest.csproj | 4 ++++ 6 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh diff --git a/docs/dotnet-suggest.md b/docs/dotnet-suggest.md index cc5c1103fb..5c5358793d 100644 --- a/docs/dotnet-suggest.md +++ b/docs/dotnet-suggest.md @@ -14,6 +14,8 @@ On the machine where you'd like to enable completion, you'll need to do two thin * For bash, add the contents of [dotnet-suggest-shim.bash](https://github.com/dotnet/command-line-api/blob/master/src/System.CommandLine.Suggest/dotnet-suggest-shim.bash) to `~/.bash_profile`. + * For zsh, add the contents of [dotnet-suggest-shim.zsh](https://github.com/dotnet/command-line-api/blob/master/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh) to `~/.zshrc`. + * For PowerShell, add the contents of [dotnet-suggest-shim.ps1](https://github.com/dotnet/command-line-api/blob/master/src/System.CommandLine.Suggest/dotnet-suggest-shim.ps1) to your PowerShell profile. You can find the expected path to your PowerShell profile by running the following in your console: ```console diff --git a/src/System.CommandLine.Suggest.Tests/SuggestionShellScriptHandlerTest.cs b/src/System.CommandLine.Suggest.Tests/SuggestionShellScriptHandlerTest.cs index 2dda947a7f..5a96e6171d 100644 --- a/src/System.CommandLine.Suggest.Tests/SuggestionShellScriptHandlerTest.cs +++ b/src/System.CommandLine.Suggest.Tests/SuggestionShellScriptHandlerTest.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.CommandLine.Invocation; using System.CommandLine.IO; using System.CommandLine.Parsing; using System.Threading.Tasks; @@ -53,5 +52,15 @@ await _parser.InvokeAsync( _console.Out.ToString().Should().Contain("Register-ArgumentCompleter"); } + + [Fact] + public async Task It_should_print_zsh_shell_script() + { + await _parser.InvokeAsync( + "script zsh", + _console); + + _console.Out.ToString().Should().Contain("_dotnet_zsh_complete()"); + } } } diff --git a/src/System.CommandLine.Suggest/ShellType.cs b/src/System.CommandLine.Suggest/ShellType.cs index 3fda370d78..6f6fec0f20 100644 --- a/src/System.CommandLine.Suggest/ShellType.cs +++ b/src/System.CommandLine.Suggest/ShellType.cs @@ -6,6 +6,7 @@ namespace System.CommandLine.Suggest public enum ShellType { Bash, - PowerShell + PowerShell, + Zsh } } diff --git a/src/System.CommandLine.Suggest/SuggestionShellScriptHandler.cs b/src/System.CommandLine.Suggest/SuggestionShellScriptHandler.cs index b7106cbf79..5e68a051b2 100644 --- a/src/System.CommandLine.Suggest/SuggestionShellScriptHandler.cs +++ b/src/System.CommandLine.Suggest/SuggestionShellScriptHandler.cs @@ -18,6 +18,9 @@ public static void Handle(IConsole console, ShellType shellType) case ShellType.PowerShell: PrintToConsoleFrom(console, "dotnet-suggest-shim.ps1"); break; + case ShellType.Zsh: + PrintToConsoleFrom(console, "dotnet-suggest-shim.zsh"); + break; default: throw new SuggestionShellScriptException($"Shell '{shellType}' is not supported."); } diff --git a/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh b/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh new file mode 100644 index 0000000000..27cfe9951f --- /dev/null +++ b/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh @@ -0,0 +1,15 @@ +# dotnet suggest shell complete script start +_dotnet_zsh_complete() +{ + local fullpath=`which ${words[1]}` + local position line + read -nl position + position=$(($position-1)) + read -l line + line=$(echo "${line}" | sed s/\"/'\\\"'/g) + local completions=`dotnet-suggest get --executable "$fullpath" --position ${position} -- "${line}"` + reply=( "${(ps:\n:)completions}" ) +} +compctl -K _dotnet_zsh_complete + -f `dotnet-suggest list` +export DOTNET_SUGGEST_SCRIPT_VERSION="1.0.0" +# dotnet suggest shell complete script end diff --git a/src/System.CommandLine.Suggest/dotnet-suggest.csproj b/src/System.CommandLine.Suggest/dotnet-suggest.csproj index ee994e3f6f..fd82500868 100644 --- a/src/System.CommandLine.Suggest/dotnet-suggest.csproj +++ b/src/System.CommandLine.Suggest/dotnet-suggest.csproj @@ -37,6 +37,10 @@ PreserveNewest + + + PreserveNewest + From 1d017ca52bbb6cec296142091161dfd98f217805 Mon Sep 17 00:00:00 2001 From: John Wilson Date: Fri, 18 Feb 2022 17:12:06 +0000 Subject: [PATCH 2/2] ZSH shim script updated to use modern completions (thanks to @baronfel for the work on this). --- .../dotnet-suggest-shim.zsh | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh b/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh index 27cfe9951f..8aca6e16b9 100644 --- a/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh +++ b/src/System.CommandLine.Suggest/dotnet-suggest-shim.zsh @@ -1,15 +1,39 @@ # dotnet suggest shell complete script start _dotnet_zsh_complete() { - local fullpath=`which ${words[1]}` - local position line - read -nl position - position=$(($position-1)) - read -l line - line=$(echo "${line}" | sed s/\"/'\\\"'/g) - local completions=`dotnet-suggest get --executable "$fullpath" --position ${position} -- "${line}"` - reply=( "${(ps:\n:)completions}" ) + # debug lines, uncomment to get state variables passed to this function + # echo "\n\n\nstate:\t'$state'" + # echo "line:\t'$line'" + # echo "words:\t$words" + + # Get full path to script because dotnet-suggest needs it + # NOTE: this requires a command registered with dotnet-suggest be + # on the PATH + full_path=`which ${words[1]}` # zsh arrays are 1-indexed + # Get the full line + # $words array when quoted like this gets expanded out into the full line + full_line="$words" + + # Get the completion results, will be newline-delimited + completions=$(dotnet suggest get --executable "$full_path" -- "$full_line") + # explode the completions by linefeed instead of by spaces into the descriptions for the + # _values helper function. + + exploded=(${(f)completions}) + # for later - once we have descriptions from dotnet suggest, we can stitch them + # together like so: + # described=() + # for i in {1..$#exploded}; do + # argument="${exploded[$i]}" + # description="hello description $i" + # entry=($argument"["$description"]") + # described+=("$entry") + # done + _values 'suggestions' $exploded } -compctl -K _dotnet_zsh_complete + -f `dotnet-suggest list` + +# apply this function to each command the dotnet-suggest knows about +compdef _dotnet_zsh_complete $(dotnet-suggest list) + export DOTNET_SUGGEST_SCRIPT_VERSION="1.0.0" # dotnet suggest shell complete script end