how to add custom completion to ls command in bash_completion? - bash

i am trying for suggest custom options in bash completion in commands linux ( centos 7 )
i am know the this code add custom command to bash and suggest options
path : /etc/bash_completion.d/foo
_foo()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-i(--incoming) -o(-outgoing) -m(--missed) -a(-all) "
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
}
complete -F _foo foo
foo -[tab]
-i(--incoming) -o(-outgoing) -m(--missed) -a(-all)
goal me is extend this source code to built in commands in linux such as ls
trying me is :
path : /etc/bash_completion.d/ls
_ls()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="-a(--all) -h(--human-readable) -r(--reverse) "
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
}
complete -F _ls ls
when this code used not suggest folders and files complete in ls command
ls -[tab]
-a(--all) -h(--human-readable) -r(--reverse)
ls[tab]
not suggest files and directory
goal me is add custom option for suggest in bash and not behaviour command

Related

How to autocomplete files under specific directory?

I created a command memo as follows:
memo() {
vi $HOME/memo/$1
}
I want to apply bash-completion to my memo to open files that is already in $HOME/memo directory:
$ memo [TAB] # to show files in $HOME/memo
$HOME/memo contains directory, so listing the file under memo is not sufficient.
In other words, I want to apply what is used in ls command in $HOME/memo to memo:
$ ls [TAB]
foo.md bar/
I tried the below but it doesn't work for nested directories:
_memo() {
local cur
local files
_get_comp_words_by_ref -n : cur
files=$(ls $MEMODIR)
COMPREPLY=( $(compgen -W "${files}" -- "${cur}") )
}
complete -F _memo memo
MEMODIR=$HOME/memo
Here's a simple example:
_memo()
{
local MEMO_DIR=$HOME/memo
local cmd=$1 cur=$2 pre=$3
local arr i file
arr=( $( cd "$MEMO_DIR" && compgen -f -- "$cur" ) )
COMPREPLY=()
for ((i = 0; i < ${#arr[#]}; ++i)); do
file=${arr[i]}
if [[ -d $MEMO_DIR/$file ]]; then
file=$file/
fi
COMPREPLY[i]=$file
done
}
complete -F _memo -o nospace memo

customize bash autocompletion

How to customize bash autocomplete to list the files in another directory for only one script option (-seq), for other script options (-speed, -define) default autocomplete is O.K. this is what I have
export files=`ls /home/tests/`
echo $files #debug
_xtest () { .
local cur
COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]}
#case "$cur" in
COMPREPLY=( $(compgen -W "${files}" -- ${cur}) )
# esac
return 0
}
complete -F _xtest -o filenames xtest
When I try to run from shell I get the below message before the list of files
> xtest -seq [TAB][TAB]
bash: .: filename argument required
.: usage: . filename [arguments]
Is there a way not to receive this message before the file list ?
How to enable default bash completion for other options ?
should use $prev instead of $cur :
_xtest () {
local prev
COMPREPLY=()
prev=${COMP_WORDS[COMP_CWORD-1]}
case "$prev" in
-seq )
COMPREPLY=( $(compgen -W "${files}" -- ${cur}) ) ;;
esac
return 0
}
complete -F _xtest -o filenames xtest

bash complete with colon

I'm trying to add auto-complete function to mytool command with following _mytool complete function:
_mytool()
{
local cur
_get_comp_words_by_ref -n : cur
# my implementation here
COMPREPLY=() # Array variable storing the possible completions.
cur=${COMP_WORDS[COMP_CWORD]}
if [[ $cur = -* ]]; then
COMPREPLY=( $(compgen -W '-a:first -a:second' -- $cur) )
fi
__ltrim_colon_completions "$cur"
}
complete -F _mytool mytool
Because there is ":" in my COMPREPLY, I try to make it work by using _get_comp_words_by_ref and __ltrim_colon_completions function, which is learnt from: here
But it still not work when type:
$mytool -a:[TAB]
there is no auto-complete at all. I was expecting bash will print the following completion for me:
-a:first -a:second
my bash version:
4.3.46(1)-release
What am I missing? Thanks!

bash completion with different options based on first value

I'm currently trying to write a bash_completion script for one of our tools.
Was looking at the apt-get and chkconfig scripts for some help.
Basically what I want to do is get a different option selection based on the first value.
There can be more than one option to a value.
command <value1> <--option1> <--option2> ...
command <value2> <--option3> <--option4> ...
Looking at the apt-get script, it will return the same list of options for any first value.
So this is not what I need.
Here is what I got so far:
_supdeploy()
{
local cur prev opts cword
_init_completion || return
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="deploy destroy supported list fulllist status fullstatus getip shutdown powerOff powerOn"
case "${prev}" in
deploy)
if [[ "$cur" == -* ]]; then
if [[ $cword -eq 2 || $cword -eq 3 || $cword -eq 4 ]]; then
COMPREPLY=( $( compgen -W '--hostname --os --version' -- "$cur" ) )
fi
fi
return 0
;;
destroy)
if [[ "$cur" == -* ]]; then
COMPREPLY=( $( compgen -W '--name --silent' -- "$cur" ) )
fi
return 0
;;
*)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
;;
esac
} &&
complete -F _supdeploy supdeploy
I get a different selection of options for both deploy and destroy.
But I can only use one -- option.
When I try to use -- again, nothing happens, and without the -- I get the list from opts.
It is probably something easy, but I can't find the error here at the moment.
I also have it tried without the $cword before, same result
Instead of prev, you just want to look at the value of the first argument each time:
case ${COMP_WORDS[1]} of
It gets a little tricker if you allow "general" options to precede the subcommand, but in general you want to look at the first non-option argument, not necessarily the previous argument.

Bash filename autocompletion after switch/parameter

I tried this other questions's accepted answer but it doesn't work for me. So please don't vote this as duplicate.
My script is named "tracker" and it accepts the following switches: --dummy --audit_sessiones --user_count --detailed_user_count --parfile
The --parfile switcj should be followed by a filename.
I have this autocompletion script:
_tracker()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--dummy --audit_sessiones --user_count --detailed_user_count --parfile"
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
opts="ls *"
if [[ ${prev} == --parfile ]]; then
COMPREPLY=( "${files[#]##*/}" )
return 0
fi
}
complete -F _tracker tracker
Autocompletion of switches works fine.
But I also want the user to be able to use filename autocompletion right after the parameter --parfile but I haven't been able to make it work.
complete has a -o default option so you can remove the opts="ls *"; if ... fi part and just do complete -F _tracker -o default tracker.
According to bash manual:
If the -o default option was supplied to complete when
the compspec was defined, readline's default completion will
be performed if the compspec (and, if attempted, the default
bash completions) generate no matches.
Try replacing COMPREPLY=( "${files[#]##*/}" ) with COMPREPLY=( $(compgen -f ${cur}) )
More information about auto completion can be found in the following links
An introduction to bash completion: part 1
An introduction to bash completion: part 2

Resources