I'm the one that suggested changing the completion-display-width
readline variable at /r/bash, but then you didn't specify you only wanted it to work on this one completion function.
Anyway, in a completion function, you can detect whether it's triggered by TAB (COMP_TYPE == 9) or by TABTAB (COMP_TYPE == 63), and if the latter is the case, you could pad the results with spaces so they fill the entire width of the terminal. It's the least hackish thing I can think of. It would look something like this:
_foo_complete() {
local i file files
files=( ~/work/dev/jobs/"$2"* )
[[ -e ${files[0]} || -L ${files[0]} ]] || return 0
if (( COMP_TYPE == 63 )); then
for file in "${files[@]}"; do
printf -v 'COMPREPLY[i++]' '%*s' "-$COLUMNS" "${file##*/}"
done
else
COMPREPLY=( "${files[@]##*/}" )
fi
}
complete -F _foo_complete foo
On a side note, you really shouldn't parse ls output.
At the first time, zsh Completion System seems to be very complex and difficult to grasp. Let try an example.
First thing you need to know, zsh
completion system will load completion functions from $fpath
. Make sure your completions directory appear in:
print -rl -- $fpath
(If you used oh-my-zsh, there's .oh-my-zsh/completions
existed in $fpath
, you can just create it and put your completion functions there)
Now, you must create a completion file for your function, its name must start with underscore _
, plus your function name. In your case, its name is _eb_instances
.
Add theses lines to _eb_instances
file:
#compdef eb_instances
_eb_instances() {
local state
_arguments \
'1: :->aws_profile'\
'*: :->eb_name'
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "$@" prod staging dev
esac
}
_eb_instances "$@"
You are done. Save the file and start new session to test completion. You will see some thing like this:
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
You can read zsh completion system documentation about _arguments
function, state
variable. Also you need to change (cuonglm test)
with your sed
command and change prod staging dev
to your eb_names
function.
If you want to generate the 2nd argument base on what 1st argument passed, you can use $words[2]
variable:
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "$@" $(echo $words[2]) ;;
esac
Replace echo
with your real function, in your case, it's $(eb_names $words[2])
.
If you still feel hard to accomplish this, just define _eb_instances
and eb_instances
in your .zshrc
then call completion as:
compdef _eb_instances eb_instances
You need to initialize completion system with:
autoload -U compinit
compinit
(If you used oh-my-zsh
, it have been loaded)
Best Answer
You can use the following function, which use the same way
sudo
auto-completion generate the completion list:where
_command_offset
is defined in bash-completion (package).NOTE: the function need to be run in a interactive shell (i.e. if it is in a file, the file need to be sourced instead of just run.) or the necessary completion rules/functions will not be defined.
PS.
compgen -A
only works for builtin actions, what you should have tried (but doesn't work either) iscompgen -F
(or actuallycompgen -o bashdefault -o default -o nospace -F _git
). The reason this doesn't work (and doc for bash built-in commands including compgen/complete) can be found in bash(1).