-
-
Notifications
You must be signed in to change notification settings - Fork 14
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
completion: add zsh #653
completion: add zsh #653
Conversation
We were already using the latest released version of this action, but it runs shellcheck on files ending in `.zsh`. Shellcheck does not support zsh, so this produces an error. The latest release of the action only supports ignoring directories, not files. And we shouldn't ignore the completions directory, because we want to run shellcheck on the `configlet.bash` completion script. For now, it looks like the best solution is to bump to the latest ref (2021-11-14). This includes an upstream commit [1] that is supposed to exclude `.zsh` files, but it doesn't seem to work. We need to use the `ignore_names` input that does not exist in the latest release. Running shellcheck on `configlet.zsh` produces these errors: In completions/configlet.zsh line 1: #compdef configlet ^-- SC2148 (error): Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. In completions/configlet.zsh line 25: words=($line[1] "${words[@]}") ^-- SC1087 (error): Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet). ^---^ SC2206 (warning): Quote to prevent word splitting/globbing, or split robustly with mapfile or read -a. In completions/configlet.zsh line 27: curcontext="${curcontext%:*:*}:configlet-command-$line[1]:" ^-- SC1087 (error): Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet). In completions/configlet.zsh line 28: case $line[1] in ^-- SC1087 (error): Use braces when expanding arrays, e.g. ${array[idx]} (or ${var}[.. to quiet). In completions/configlet.zsh line 95: (( $+functions[_configlet_commands] )) || ^----------------------------^ SC2154 (warning): functions is referenced but not assigned. ^-----------------^ SC2154 (warning): _configlet_commands is referenced but not assigned. In completions/configlet.zsh line 98: commands=( ^------^ SC2034 (warning): commands appears unused. Verify use (or export if used externally). For more information: https://www.shellcheck.net/wiki/SC1087 -- Use braces when expanding arrays,... https://www.shellcheck.net/wiki/SC2148 -- Tips depend on target shell and y... https://www.shellcheck.net/wiki/SC2034 -- commands appears unused. Verify u... [1] ludeeus/action-shellcheck@ceeca77f6538
Refactor later.
completions/configlet.zsh
Outdated
_configlet_complete_any_exercise_slug() { | ||
local -a cmd slugs slug_paths | ||
slug_paths=(./exercises/concept/*(/)) | ||
slugs=( ${${slug_paths#./exercises/concept/}%-*-*} ) | ||
slug_paths=(./exercises/practice/*(/)) | ||
slugs+=( ${${slug_paths#./exercises/practice/}%-*-*} ) | ||
compadd "$@" -a slugs | ||
} | ||
|
||
_configlet_complete_practice_exercise_slug() { | ||
local -a cmd slugs slug_paths | ||
slug_paths=(./exercises/practice/*(/)) | ||
slugs=( ${${slug_paths#./exercises/practice/}%-*-*} ) | ||
compadd "$@" -a slugs | ||
} |
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.
Yes, this could use a refactor.
Note that this can suggest invalid slugs, because it:
- doesn't respect
--track-dir
(see completions: suggests incorrect-e
slugs when-t
is used #637) - or read the track
config.json
file (see completions: for-e
, suggest only slugs that are in theconfig.json
file #642)
Let's handle that later - we should fix it for the bash and fish completion scripts too.
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.
Refactored somewhat in 833522b
(uuid) | ||
_arguments "${_arguments_options[@]}" \ | ||
"$_configlet_global_opts[@]" \ | ||
'(-n --num)'{-n+,--num=}'[How many UUIDs]:' \ |
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.
-optname+
The first argument may appear immediately after optname in the same word, or may appear as a separate word after the option. For example,-foo+:...
specifies that the completed option and argument will look like either-fooarg
or-foo arg
.
-optname=
The argument may appear as the next word, or in same word as the option name provided that it is separated from it by an equals sign, for example-foo=arg
or-foo arg
.
if is-at-least 5.2; then | ||
_arguments_options=(-s -S -C) | ||
else | ||
_arguments_options=(-s -C) | ||
fi |
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.
From man zshcompsys
:
The options of
_arguments
have the following meanings:
-s
Enable option stacking for single-letter options, whereby multiple single-letter options may be combined into a single word. For example, the two options-x
and-y
may be combined into a single word-xy
. By default, every word corresponds to a single option name (-xy
is a single option namedxy
).
Options beginning with a single hyphen or plus sign are eligible for stacking; words beginning with two hyphens are not.Note that
-s
after--
has a different meaning, which is documented in the segment entitled `Deriving spec forms from the help output'.
-C
Modify thecurcontext
parameter for an action of the form->state
. This is discussed in detail below.
-S
Do not complete options after a--
appearing on the line, and ignore the--
. For example, with-S
, in the linefoobar -x -- -y
the
-x
is considered an option, the-y
is considered an argument, and the--
is considered to be neither.
fi | ||
|
||
local line | ||
local curcontext="$curcontext" |
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.
From man zshcompsys
:
The option
-C
tells_arguments
to modify thecurcontext
parameter for an action of the form->state
. This is the standard parameter used to keep track of the current context. Here it (and not the context array) should be made local to the calling function to avoid passing back the modified value and should be initialised to the current value at the start of the function:local curcontext="$curcontext"
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.
Just tested it and it works nicely!
Add a zsh completion script and the ability to run
to write that script to stdout.
This commit also bumps the version of the shellcheck action, which is
necessary to prevent the action from running
shellcheck
on the new zshscript. Shellcheck does not support zsh, so CI would indicate an error
otherwise.
The bump must be to the latest commit - we already used the latest
release (1.1.0). An upstream commit that claims to exclude zsh
scripts seems to be insufficient - we need to use the
ignore_names
input that does not exist in the latest release.
Closes: #633
It seems like every tutorial for this is pretty bad.
Some links for the reviewer:
pacman
.git
./usr/share/zsh/functions/Completion/Unix/
and/usr/share/zsh/site-functions
for the completions for a program you know well.man zshcompsys
. Good luck.zsh
and enabling completions: https://wiki.archlinux.org/title/zsh#Command_completionTo test this PR, copy
configlet.zsh
to some directory, naming it_configlet
:(Don't put it under
/tmp
, or you might get an error message about an insecure completions folder).Then add that directory to your
fpath
. In.zshrc
:fpath=(~/configlet-comp $fpath)
And make sure that completions are also enabled in that file:
Then start a new zsh shell, and
configlet [Tab]
should work.The underlying issue is that the default
fpath
includes just/usr/local/share/zsh/site-functions
and directories in/usr/share/zsh
. We can't just write, as we can for bash:or add the completions to some standard user completions directory, like for fish:
So I think we have to provide instructions to make the user save the output of
configlet completion --shell zsh
to either:/usr/local/share/zsh/site-functions/_configlet
/usr/share/zsh/site-functions/_configlet
~/foo/_configlet
, explaining how to add~/foo
to their$fpath
where we probably should do the last, because:
/usr/share/zsh/site-functions
.