-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Zsh shell autocompletions #43970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zsh shell autocompletions #43970
Changes from all commits
f846256
2458f63
3d38c39
166851a
fc7f870
310a7c8
0f649dc
027ce97
f6a960b
e209577
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Console\Completion\Output; | ||
|
||
use Symfony\Component\Console\Completion\CompletionSuggestions; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
|
||
/** | ||
* @author Jitendra A <adhocore@gmail.com> | ||
*/ | ||
class ZshCompletionOutput implements CompletionOutputInterface | ||
{ | ||
public function write(CompletionSuggestions $suggestions, OutputInterface $output): void | ||
{ | ||
$options = $suggestions->getValueSuggestions(); | ||
foreach ($suggestions->getOptionSuggestions() as $option) { | ||
$options[] = '--'.$option->getName()."\t".$option->getDescription(); | ||
} | ||
$output->writeln(implode("\n", $options)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,80 @@ | ||||||
# This file is part of the Symfony package. | ||||||
# | ||||||
# (c) Fabien Potencier <fabien@symfony.com> | ||||||
# | ||||||
# For the full copyright and license information, please view | ||||||
# https://symfony.com/doc/current/contributing/code/license.html | ||||||
|
||||||
# | ||||||
# zsh completions for {{ COMMAND_NAME }} | ||||||
# | ||||||
# References: | ||||||
# - https://github.com/spf13/cobra/blob/master/zsh_completions.go | ||||||
# - https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Console/Resources/completion.bash | ||||||
# | ||||||
_sf_{{ COMMAND_NAME }}() { | ||||||
local lastParam flagPrefix requestComp out comp | ||||||
local -a completions | ||||||
|
||||||
# The user could have moved the cursor backwards on the command-line. | ||||||
# We need to trigger completion from the $CURRENT location, so we need | ||||||
# to truncate the command-line ($words) up to the $CURRENT location. | ||||||
# (We cannot use $CURSOR as its value does not work when a command is an alias.) | ||||||
words=("${=words[1,CURRENT]}") lastParam=${words[-1]} | ||||||
|
||||||
# For zsh, when completing a flag with an = (e.g., {{ COMMAND_NAME }} -n=<TAB>) | ||||||
# completions must be prefixed with the flag | ||||||
setopt local_options BASH_REMATCH | ||||||
if [[ "${lastParam}" =~ '-.*=' ]]; then | ||||||
# We are dealing with a flag with an = | ||||||
flagPrefix="-P ${BASH_REMATCH}" | ||||||
fi | ||||||
|
||||||
# Prepare the command to obtain completions | ||||||
requestComp="${words[0]} ${words[1]} _complete -szsh -S{{ VERSION }} -c$((CURRENT-1))" i="" | ||||||
for w in ${words[@]}; do | ||||||
w=$(printf -- '%b' "$w") | ||||||
# remove quotes from typed values | ||||||
quote="${w:0:1}" | ||||||
if [ "$quote" = \' ]; then | ||||||
w="${w%\'}" | ||||||
w="${w#\'}" | ||||||
elif [ "$quote" = \" ]; then | ||||||
w="${w%\"}" | ||||||
w="${w#\"}" | ||||||
fi | ||||||
# empty values are ignored | ||||||
if [ ! -z "$w" ]; then | ||||||
i="${i}-i${w} " | ||||||
fi | ||||||
done | ||||||
|
||||||
# Ensure atleast 1 input | ||||||
if [ "${i}" = "" ]; then | ||||||
requestComp="${requestComp} -i\" \"" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think it still requires -i option equal or 1 more than -c option that's why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then, does it work with an empty string?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no it can't be empty |
||||||
else | ||||||
requestComp="${requestComp} ${i}" | ||||||
fi | ||||||
|
||||||
# Use eval to handle any environment variables and such | ||||||
out=$(eval ${requestComp} 2>/dev/null) | ||||||
|
||||||
while IFS='\n' read -r comp; do | ||||||
if [ -n "$comp" ]; then | ||||||
# If requested, completions are returned with a description. | ||||||
# The description is preceded by a TAB character. | ||||||
# For zsh's _describe, we need to use a : instead of a TAB. | ||||||
# We first need to escape any : as part of the completion itself. | ||||||
comp=${c 10000 omp//:/\\:} | ||||||
local tab=$(printf '\t') | ||||||
comp=${comp//$tab/:} | ||||||
completions+=${comp} | ||||||
fi | ||||||
done < <(printf "%s\n" "${out[@]}") | ||||||
|
||||||
# Let inbuilt _describe handle completions | ||||||
eval _describe "completions" completions $flagPrefix | ||||||
return $? | ||||||
} | ||||||
|
||||||
compdef _sf_{{ COMMAND_NAME }} {{ COMMAND_NAME }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ public function provideCompletionSuggestions() | |
{ | ||
yield 'shell' => [ | ||
[''], | ||
['bash'], | ||
['bash', 'zsh'], | ||
]; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing if shell is zsh seems very specific for this place.
We could use a DTO. The
ZshCompletionOutput
would format the value with its specificities. By implementing the__toString
method, theBashCompletionOutput
would not require any change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or maybe some abstraction to tell/handle if the shell supports description for autocompleted suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would add complexity in all commands that implements completion. I'm not sure this is something we want.
Each command should set suggestions values, optionally with a description using this DTO.