Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [FEATURE][PATCH] Complete local executables with ./ prefix, if prefix-needed is false
Marlon Richert wrote:
> This allows local executables to be completed more easily, without the
> need for . in $path.
This is the type of thing which often can already be achieved with
styles and, where not, a few tweaks may enable it. The nearest example
from my own config involves using the fake style and a matcher to ignore
the prefix. But that's for a more specific context[1].
In this case for the style context, the tag 'commands' is used for a lot
of commands that aren't external Unix commands. The 'executables' tag is
better but guarded by a condition that will evaluate to false:
[[ -n "$path[(r).]" || $PREFIX = */* ]] &&
defs+=( 'executables:executable file:_files -g \*\(-\*\)'
The fake style is looked up in _description so a dummy call to it is one
option. The patch below adds that but I'd be interested in any thoughts
on that. With caveats[2], that allows:
zstyle -e ':completion:*:executables' fake 'reply=( ./*(-*) )'
zstyle ':completion:*:executables' matcher 'b:=./'
There is a command-path style looked up by _command_names to override
$path. But that doesn't entirely help for a couple of reasons. External
commands are completed based on keys of the commands association but
that will not contain commands based on relative directories listed in
$path. Even if it did, they can't be identified to add back a ./ prefix
so that they actually work. In the patch below, I do change it to use
path=( $cmdpath:A ) when the command-path style is set. That resolves
only the first of these issues and allows for relative paths in the
command-path style to work as intended, even if that isn't especially
useful.
Oliver
[1] If anyone's interested, that example is for ssh public keys. Just
the fake and matcher style are needed but it looks like this:
zstyle -e ':completion:*:((ssh|scp|sftp):*:option-i-1|ssh-add:*:argument-rest)' fake '[[ -prefix - ]] || reply=( ~/.ssh/id^*.pub(-.) )'
zstyle -e ':completion:*:((ssh|scp|sftp):*:option-i-1|ssh-add:*:argument-rest)' matcher '[[ -prefix - ]] || reply=( "l:|=*" )'
zstyle ':completion:*:((ssh|scp|sftp):*:option-i-1|ssh-add:*:argument-rest)' menu yes=0 search
zstyle ':completion:*:((ssh|scp|sftp):*:option-i-1|ssh-add:*:argument-rest)' list-colors "=(#b)(*/)(*)==38;5;208=0"
[2] With the fake style in general, the return status of the calling
completion function doesn't account for fake matches which may mean
unwanted later completers are invoked (e.g. _approximate).
diff --git a/Completion/Zsh/Type/_command_names b/Completion/Zsh/Type/_command_names
index b1c35f013..12cbd69c1 100644
--- a/Completion/Zsh/Type/_command_names
+++ b/Completion/Zsh/Type/_command_names
@@ -4,7 +4,7 @@
# complete only external commands and executable files. This and a
# `-' as the first argument is then removed from the arguments.
-local args defs ffilt
+local args defs expl ffilt
zstyle -t ":completion:${curcontext}:commands" rehash && rehash
@@ -16,8 +16,12 @@ defs=(
'commands:external command:_path_commands'
)
-[[ -n "$path[(r).]" || $PREFIX = */* ]] &&
- defs+=( 'executables:executable file:_files -g \*\(-\*\)' )
+if [[ -n "$path[(r).]" || $PREFIX = */* ]]; then
+ defs+=( 'executables:executable file:_files -g \*\(-\*\)' )
+else
+ # this is ignored but exists to facilitate the use of the fake style
+ _description executables expl 'executable file'
+fi
if [[ "$1" = -e ]]; then
shift
@@ -58,7 +62,7 @@ fi
if (( $#cmdpath )); then
local -a +h path
local -A +h commands
- path=( $cmdpath )
+ path=( $cmdpath:A )
fi
_alternative -O args "$defs[@]"
Messages sorted by:
Reverse Date,
Date,
Thread,
Author