How to create script with auto-complete?
As for place where to put your completions, see this question and also the comments for the accepted answer there.
8 Answers 8
You’ll have to create a new file:
For a static autocompletion ( —help / —verbose for instance) add this:
_foo() < local cur prev opts COMPREPLY=() cur="$" prev="$" opts="--help --verbose --version" if [[ $ == -* ]] ; then COMPREPLY=( $(compgen -W "$" -- $) ) return 0 fi > complete -F _foo foo
- COMP_WORDS is an array containing all individual words in the current command line.
- COMP_CWORD is an index of the word containing the current cursor position.
- COMPREPLY is an array variable from which Bash reads the possible completions.
And the compgen command returns the array of elements from —help , —verbose and —version matching the current word «$» :
compgen -W "--help --verbose --version" -- ""
Tip: If someone wants suggestions for words not starting with — and show them without having to start typing the target word, just remove the if [. ] then and fi lines.
The path in the answer looks to be obsolete. User completion scripts can be stored in ~/.local/share/bash-completion/completions/ after creating it. System completion scripts are generally stored in /usr/share/bash-completion/completions/ .
Can you help me understand why the path in the answer is obsolete? Is it technology or convention that is evolving. From my .. «experiment» it seems like it is just convention evolving. What convention is it, so I can read about the history of it so I can understand why they made those decisions? The «experiment»: even when I place my completion scripts in ~/.local/share/bash-completion/completions/ , they do not automatically get sourced. It’s no different than if they’re at ~/my/completion/dir . Not a big deal, I just source them manually either way.
I see /etc/bash_completion.d/ gets automatically loaded according to other links here, but I don’t see anything about ~/.local . I know that’s an XDG thing, but I guess I just suck at google-fu because I cannot find anything about automatic sourcing from the share/bash-completion/completions directory.
Here is a complete tutorial.
Let’s have an example of script called admin.sh to which you would like to have autocomplete working.
#!/bin/bash while [ $# -gt 0 ]; do arg=$1 case $arg in option_1) # do_option_1 ;; option_2) # do_option_2 ;; shortlist) echo option_1 option_2 shortlist ;; *) echo Wrong option ;; esac shift done
Note the option shortlist . Calling the script with this option will print out all possible options for this script.
And here you have the autocomplete script:
_script() < _script_commands=$(/path/to/your/script.sh shortlist) local cur COMPREPLY=() cur="$" COMPREPLY=( $(compgen -W "$" -- $) ) return 0 > complete -o nospace -F _script ./admin.sh
Note that the last argument to complete is the name of the script you want to add autocompletion to. All you need to do is to add your autocomplete script to bashrc as :
source /path/to/your/autocomplete.sh
The path in the answer looks to be obsolete, and the sourcing is largely unnecessary. User completion scripts are sourced from ~/.local/share/bash-completion/completions/ ; this directory can be created by the user. System completion scripts are generally stored in /usr/share/bash-completion/completions/ .
You can use the Programmable Completion. Have look at /etc/bash_completion and /etc/bash_completion.d/* for some examples.
I believe this platform is supposed to be a more practical alternative to full documentations that could be found with a simple google search. Dumping a documentation link doesn’t help that. The link containing an anchor surely doesn’t make much difference.
The provided link has that already — it might today, but it mightn’t tomorrow. Or next year. Or in a decade. Whatever you might suggest about the documentation still being relevant, Stack Overflow discourages link-only answers for these reasons.
All of the bash completions are stored in /etc/bash_completion.d/ . So if you’re building software with bash_completion it would be worthwhile to have the deb/make install drop a file with the name of the software in that directory. Here’s an example bash completion script for Rsync:
# bash completion for rsync have rsync && _rsync() < # TODO: _split_longopt local cur prev shell i userhost path COMPREPLY=() cur=`_get_cword` prev=$_expand || return 0 case "$prev" in --@(config|password-file|include-from|exclude-from)) _filedir return 0 ;; -@(T|-temp-dir|-compare-dest)) _filedir -d return 0 ;; -@(e|-rsh)) COMPREPLY=( $( compgen -W 'rsh ssh' -- "$cur" ) ) return 0 ;; esac case "$cur" in -*) COMPREPLY=( $( compgen -W '-v -q -c -a -r -R -b -u -l -L -H \ -p -o -g -D -t -S -n -W -x -B -e -C -I -T -P \ -z -h -4 -6 --verbose --quiet --checksum \ --archive --recursive --relative --backup \ --backup-dir --suffix= --update --links \ --copy-links --copy-unsafe-links --safe-links \ --hard-links --perms --owner --group --devices\ --times --sparse --dry-run --whole-file \ --no-whole-file --one-file-system \ --block-size= --rsh= --rsync-path= \ --cvs-exclude --existing --ignore-existing \ --delete --delete-excluded --delete-after \ --ignore-errors --max-delete= --partial \ --force --numeric-ids --timeout= \ --ignore-times --size-only --modify-window= \ --temp-dir= --compare-dest= --compress \ --exclude= --exclude-from= --include= \ --include-from= --version --daemon --no-detach\ --address= --config= --port= --blocking-io \ --no-blocking-io --stats --progress \ --log-format= --password-file= --bwlimit= \ --write-batch= --read-batch= --help' -- "$cur" )) ;; *:*) # find which remote shell is used shell=ssh for (( i=1; i < COMP_CWORD; i++ )); do if [[ "$" == -@(e|-rsh) ]]; then shell=$ break fi done if [[ "$shell" == ssh ]]; then # remove backslash escape from : cur=$ userhost=$ path=$ # unescape spaces path=$ if [ -z "$path" ]; then # default to home dir of specified # user on remote host path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null) fi # escape spaces; remove executables, aliases, pipes # and sockets; add space at end of file names COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \ command ls -aF1d "$path*" 2>/dev/null | \ sed -e 's/ /\\\\\\\ /g' -e 's/[*@|=]$//g' \ -e 's/[^\/]$/& /g' ) ) fi ;; *) _known_hosts_real -c -a "$cur" _filedir ;; esac return 0 > && complete -F _rsync $nospace $filenames rsync # Local variables: # mode: shell-script # sh-basic-offset: 4 # sh-indent-comment: t # indent-tabs-mode: nil # End: # ex: ts=4 sw=4 et filetype=sh
It would likely be worthwhile to review one of the bash completion files in there that most closely matches your program. One of the simplest examples is the rrdtool file.
How to enable autocomplete in terminal
In case we don’t have the bash-completion package installed, we install it:
aptitude install bash-completion
Enable autocomplete on TTYs for all users
We look in / etc / profile for the following lines .
# enable bash completion in interactive shells
#if [-f / etc / bash_completion] &&! shopt -oq posix; then
#. / etc / bash_completion
#fi
if ["$ BASH"]; then
if [-f / etc / bash_completion] &&! shopt -oq posix; then
. / etc / bash_completion
fi
fi
The latter will activate bash_completion for all users, including root. But it will only enable it on TTYs, and not on terminal emulators.
We reset the TTY and that’s it.
As you can see, we have added an if to the original file, which confirms that the bash_completion runs only when we are in Bash. Without that conditional, GDM will give us the previously mentioned error, since GDM would be calling bash_completion, and for some reason it conflicts with xsession.
Enable autocompletion in terminal emulators for all users
We look in /etc/bash.bashrc for the following lines .
# enable bash completion in interactive shells
#if [-f / etc / bash_completion] &&! shopt -oq posix; then
#. / etc / bash_completion
#fi
. And we remove the «#» (we uncomment them), looking like this:
# enable bash completion in interactive shells
if [-f / etc / bash_completion] &&! shopt -oq posix; then
. / etc / bash_completion
fi
The latter will activate bash_completion for all users, including root. But it will only enable it on terminal emulators, and not on TTYs.
We restart any terminal and the changes will take effect.
Enable autocompletion in terminal emulators for one user only
We must create (or edit, if it exists) the file ~ / .bashrc.
We add (or search if they do not exist, but commented, as is done in /etc/bash.bashrc) so that it looks like this:
# enable bash completion in interactive shells
if [-f / etc / bash_completion] &&! shopt -oq posix; then
. / etc / bash_completion
fi
— If file we create it, we simply add these lines.
— If these lines exist but are not present, we add them to the end of the file.
— If it exists and these lines are, we simply uncomment them.
We restart the console and the changes will take effect.
Enable autocomplete when desired
We simply have to run bash_completion at the moment we want to use it. It will be deactivated once we end the session in the terminal (with the exit command) or close the terminal that we are using if we are in a graphical environment. To run it whenever we want, we do:
The content of the article adheres to our principles of editorial ethics. To report an error click here.
Full path to article: From Linux » FileLet’s UseLinux » How to enable autocomplete in terminal