如何为文件搜索和自定义搜索配置 bash 自动完成?
How to configure bash autocomplete for file search and custom search?
我想要一个自动完成上传脚本的命令,该命令将远程 运行,但用户也可以选择本地脚本进行上传。这是一个小例子来说明我在 bash 完整逻辑中遇到的问题。
_test_complete()
{
local cur prev opts uploaded_scripts
uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [[ ${prev} == '-s' ]] ; then
COMPREPLY=( $(compgen -W "${uploaded_scripts}" -- ${cur}) )
return 0
fi
}
complete -F _test_complete remote
该示例几乎可以工作,但它不再自动完成本地文件搜索。
$ remote -s proc<TAB><TAB>
proc1.sh proc2.sh
$ remote -s proc1.sh ./<TAB><TAB>
当您执行通常的文件搜索 ./
时没有任何反应,应该列出当前目录中的文件。关于如何启用两者的任何想法?
编辑:上面的例子有一个问题,你只能选择一个完整的文件。我破解了一个有效的解决方案,但如果有人有更好的解决方案,请发表评论。还有来自已接受答案的 -o default
。
_test_complete()
{
local cur prev opts uploaded_scripts
uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
[[ $COMP_CWORD == '1' ]] && LAST_OPT=''
[[ ${prev:0:1} == '-' ]] && LAST_OPT=${prev}
if [[ ${LAST_OPT} == '-s' ]]; then
COMPREPLY=( $(compgen -o default -W "${uploaded_scripts}" -- ${cur}) )
return 0
fi
}
complete -F _test_complete remote
您只需将本地目录中的所有文件也添加到 COMPREPLY
。 complete -f -- abc
生成以 abc
.
开头的文件列表
顺便说一句:除了 "${COMP_WORDS[COMP_CWORD]}"
和 COMP_CWORD-1
,您还可以使用 </code> 和 <code>
,它们由 bash 提供给任何完成函数.
但在这里我完全放弃了 if
,因为你似乎想在 -s
之后允许多个文件。由于您不建议 -s
本身,因此一直建议文件:
_test_complete() {
local cur="" prev="" uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=( $(
compgen -W "${uploaded_scripts}" -- "$cur"
compgen -f -- "$cur"
) )
}
complete -F _test_complete remote
注意:COMPREPLY=( $(...) )
写起来容易,但有一些缺陷。包含空格的文件将被拆分为多个建议,而 *
等特殊符号将展开并生成更多建议。为避免这种情况,请设置 IFS=$'\n'; set -o noglob
或使用 mapfile -t COMPREPLY < <(...)
.
完成此操作后,您可以使用 complete -o filenames -F ...
以便在插入时也正确引用那些有问题的建议。
您可以使用 complete
的 -o default
选项 (通常我会同时使用 -o default
和 -o bashdefault
) :
complete -o default -F _test_complete remote
根据man bash
:
bashdefault
Perform the rest of the default bash completions if the compspec generates no matches.
default
Use readline's default filename completion if the compspec generates no matches.
我想要一个自动完成上传脚本的命令,该命令将远程 运行,但用户也可以选择本地脚本进行上传。这是一个小例子来说明我在 bash 完整逻辑中遇到的问题。
_test_complete()
{
local cur prev opts uploaded_scripts
uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [[ ${prev} == '-s' ]] ; then
COMPREPLY=( $(compgen -W "${uploaded_scripts}" -- ${cur}) )
return 0
fi
}
complete -F _test_complete remote
该示例几乎可以工作,但它不再自动完成本地文件搜索。
$ remote -s proc<TAB><TAB>
proc1.sh proc2.sh
$ remote -s proc1.sh ./<TAB><TAB>
当您执行通常的文件搜索 ./
时没有任何反应,应该列出当前目录中的文件。关于如何启用两者的任何想法?
编辑:上面的例子有一个问题,你只能选择一个完整的文件。我破解了一个有效的解决方案,但如果有人有更好的解决方案,请发表评论。还有来自已接受答案的 -o default
。
_test_complete()
{
local cur prev opts uploaded_scripts
uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
[[ $COMP_CWORD == '1' ]] && LAST_OPT=''
[[ ${prev:0:1} == '-' ]] && LAST_OPT=${prev}
if [[ ${LAST_OPT} == '-s' ]]; then
COMPREPLY=( $(compgen -o default -W "${uploaded_scripts}" -- ${cur}) )
return 0
fi
}
complete -F _test_complete remote
您只需将本地目录中的所有文件也添加到 COMPREPLY
。 complete -f -- abc
生成以 abc
.
顺便说一句:除了 "${COMP_WORDS[COMP_CWORD]}"
和 COMP_CWORD-1
,您还可以使用 </code> 和 <code>
,它们由 bash 提供给任何完成函数.
但在这里我完全放弃了 if
,因为你似乎想在 -s
之后允许多个文件。由于您不建议 -s
本身,因此一直建议文件:
_test_complete() {
local cur="" prev="" uploaded_scripts='proc1.sh proc2.sh'
COMPREPLY=( $(
compgen -W "${uploaded_scripts}" -- "$cur"
compgen -f -- "$cur"
) )
}
complete -F _test_complete remote
注意:COMPREPLY=( $(...) )
写起来容易,但有一些缺陷。包含空格的文件将被拆分为多个建议,而 *
等特殊符号将展开并生成更多建议。为避免这种情况,请设置 IFS=$'\n'; set -o noglob
或使用 mapfile -t COMPREPLY < <(...)
.
完成此操作后,您可以使用 complete -o filenames -F ...
以便在插入时也正确引用那些有问题的建议。
您可以使用 complete
的 -o default
选项 (通常我会同时使用 -o default
和 -o bashdefault
) :
complete -o default -F _test_complete remote
根据man bash
:
bashdefault
Perform the rest of the default bash completions if the compspec generates no matches.
default
Use readline's default filename completion if the compspec generates no matches.