我正在读书如何获得命令别名的 bash 补全?我想,Shawn J. Goff 的答案需要一些东西:减少用户设置,所以我编写了一个小脚本,旨在从您的 中获取.bashrc
,但它不太有效,所以希望有人能发现我的错误。
function make-completion-wrapper-1 () {
local function_name="$2"
local arg_count=$(($#-3))
local comp_function_name="$(complete -pr $1|sed -e 's/^\(.* -F \)\([^ ]*\) [^ ]*$/\2/')"
shift 2
local function="
function $function_name {
((COMP_CWORD+=$arg_count))
COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
"$comp_function_name"
return 0
}"
echo "$function"
eval "$function"
}
function make-completion-wrapper-2 () {
local function_name="$1"
local alias_name="$2"
local comp_function_base="$(complete -pr $3|sed -e 's/^\(.* -F\)\( [^ ]*\) [^ ]*$/\1/')"
echo "$comp_function_base $function_name $alias_name"
eval "$comp_function_base $function_name $alias_name"
}
[ -e ~/.cache/bash_alias_complete ] && rm ~/.cache/bash_alias_complete
alias | \
sed \
-e 's/^alias //' \
-e '/^\([^=]\+\)='\''\1 /d' \
-e "/'.*=/d" -e '/\$/d' \
-e h \
-e "s/.*='\([^ ]*\)\( .*\)'$/\1! \1\2/" \
-e 'y/ -!/__ /' -eG -e 's!\n[^=]*='\''\(.*\)'\''! \1!' \
-e 's/^/make-completion-wrapper-1 /p' \
-e 's/^[^ ]* [^ ]* \([^ ]*\) .*$/\1/' \
-e x \
-e 's!='\''\([^ ]*\) .*$! \1!' \
-e x \
-e 's!^!make-completion-wrapper-2 !' \
-e G \
-e 'y/\n/ /' \
> ~/.cache/bash_alias_complete
. ~/.cache/bash_alias_complete
当我按下该键时,出现以下错误Tab:
bash: COMP_POINT - : syntax error: operand expected (error token is "- ")
笔记:上面的代码可以放置在一个文件中,例如myfuncs.bash
,然后可以直接在 shell 中获取该代码或从$HOME/.bashrc
.
有关此代码的完整更改历史记录,请参阅https://github.com/hildred/scripts.git
答案1
错误消息 COMP_POINT 来自Bash 参考手册:
COMP_POINT
当前光标位置相对于当前命令开头的索引。如果当前光标位置位于当前命令的末尾,则该变量的值等于${#COMP_LINE}。此变量仅在 shell 函数和由可编程完成工具调用的外部命令中可用(请参阅可编程完成)。
尝试一下这个
我尝试按原样使用您的代码。当采购直到最后一行的所有内容时效果都很好。当该行运行时,. ~/.cache/bash_alias_complete
我收到错误。太多了,无法包含在这里。
将结果生成到文件中似乎存在一些问题~/.cache/bash_alias_complete
。
我遇到的错误
我有以下别名:
$ alias|grep cdc
alias cdl='cdctl -o1'
alias cdu='cdctl -o0'
您的sed
命令允许其通过,然后传播到我的缓存文件,导致这些命令导致以下错误:
$ make-completion-wrapper-1 cdctl _cdctl__o1 cdctl -o1
$ make-completion-wrapper-2 _cdctl__o1 cdl cdctl
$ make-completion-wrapper-1 cdctl _cdctl__o0 cdctl -o0
$ make-completion-wrapper-2 _cdctl__o0 cdu cdctl
bash: complete: cdctl: no completion specification
_cdctl__o1 cdl
还有其他示例,但要点是命令sed
并不像可能需要的那么严格,这最终是您遇到的问题。