我正在尝试编写一个 bash 补全,它可以让我补全其他 shell 所在的目录名称。
例如,假设我在 /very/long/path/name
中打开了另一个 shell ,我目前在一个包含子目录的目录中 foo
和 bar
.当我输入 cd <Tab>
,我想看看:
$ cd <Tab>
foo/ bar/ /very/long/path/name
我有这个命令来生成可能完成的列表:
ps -Cbash -opid= | xargs pwdx | cut -d" " -f2 | sort -u | while read; do echo ${REPLY#$PWD/}; done | grep -v "^$"
为简洁起见,我将其写为 ...pipeline...
.
在我的系统上有一个 _cd
产生常规补全的函数:
$ 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
}
最佳答案
您需要根据组合选项列表评估当前匹配项。这是一个说明移动部件的测试脚本:
#!/bin/bash
mkdir -p {my,other}/path/to/{a,b,c}
function _cd() {
COMPREPLY=( my/path/to/a my/path/to/b );
}
complete -o nospace -F _cd cd
function _cd2() {
local cur opts;
cur="${COMP_WORDS[COMP_CWORD]}";
_cd;
opts="${COMPREPLY[@]} other/path/to/c"; # here we combine options
COMPREPLY=($(compgen -W "${opts}" -- ${cur})); # here is the secret sauce
}
complete -F _cd2 cd
complete -p cd
最重要的点在 _cd2
的 compgen
部分:从组合的选择集中选择最合适的选项(在 $opts
).
关于Bash 完成使 'cd' 命令从其他正在运行的 shell 完成工作目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26550327/