I am trying to write a bash termination that will allow me to populate the names of directories that contain other shells.
For example, suppose I have another shell open in /very/long/path/name, and I'm currently in a directory that contains fooand subdirs bar. When I type cd <Tab>, I want to see:
$ cd <Tab>
foo/ bar/ /very/long/path/name
I have this command to create a list of potential completions:
ps -Cbash -opid= | xargs pwdx | cut -d" " -f2 | sort -u | while read; do echo ${REPLY#$PWD/}; done | grep -v "^$"
For brevity, I will write this as ...pipeline....
My system has a function _cdthat performs regular termination:
$ complete -p cd
complete -o nospace -F _cd cd
_cd, (~ 30 , type _cd). , , , , _cd.
, -C complete , :
$ complete -C '...pipeline...' cd
$ cd <Tab>grep: cd: No such file or directory
grep: : No such file or directory
grep: cd: No such file or directory
- -F, COMPREPLY, :
$ function _cd2() { _cd; COMPREPLY=( ${COMPREPLY[@]} $(...pipeline...) ); }
$ cd <Tab>
foo/ bar/ name/
, . , - _cd, , , .
_cd _cd2, , . cd /ve<Tab>, - , .
, ?
: _cd:
$ type _cd
_cd is a function
_cd ()
{
local cur prev words cword;
_init_completion || return;
local IFS='
' i j k;
compopt -o filenames;
if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
_filedir -d;
return 0;
fi;
local -r mark_dirs=$(_rl_enabled mark-directories && echo y);
local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y);
for i in ${CDPATH//:/'
'};
do
k="${#COMPREPLY[@]}";
for j in $( compgen -d $i/$cur );
do
if [[ ( -n $mark_symdirs && -h $j || -n $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
j+="/";
fi;
COMPREPLY[k++]=${j#$i/};
done;
done;
_filedir -d;
if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
i=${COMPREPLY[0]};
if [[ "$i" == "$cur" && $i != "*/" ]]; then
COMPREPLY[0]="${i}/";
fi;
fi;
return 0
}