我正在创建一个shell程序,它是一个命令行工具。我想为这个工具创建自己的自动完成功能。
我想做两件不同的事情(也许我应该发两个问题):
--install
和-i
,我想在文件路径上自动完成,例如ls
命令。--unit-test
和-t
,我想在特定目录的文件路径上自动完成,我可以运行my_app --directory
。 my_app_autocomplete
档案
__my_app_autocomplete()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts="--help -h --install -i --run -r --rebuild -rb --show-running-containers -ps --stop -s --remove -rm --logs -l --bash -b --sass -css --unit-tests -t"
containers="nginx php mysql mongo node"
sass="watch"
# By default, autocomplete with options
if [[ ${prev} == my_app ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
# By default, autocomplete with options
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
# For --install and -i options, autocomplete with folder
if [ ${prev} == --install ] || [ ${prev} == -i ] ; then
COMPREPLY=( $(compgen -d -- ${cur}) )
return 0
fi
# For --stop --remove --logs and --bash, autocomplete with containers
if [ ${prev} == --stop ] || [ ${prev} == -s ] || [ ${prev} == --remove ] || [ ${prev} == -rm ] || [ ${prev} == --logs ] || [ ${prev} == -l ] || [ ${prev} == --bash ] || [ ${prev} == -b ] ; then
COMPREPLY=( $(compgen -W "${containers}" -- ${cur}) )
return 0
fi
# For --sass and -css, complete with sass options
if [ ${prev} == --sass ] || [ ${prev} == -css ] ; then
COMPREPLY=( $(compgen -W "${sass}" -- ${cur}) )
return 0
fi
# For --unit-tests and -t, complete with relative to my_app folder paths
if [ ${prev} == --unit-tests ] || [ ${prev} == -t ] ; then
COMPREPLY=( $(compgen -d -- ${cur}) )
return 0
fi
}
complete -F __my_app_autocomplete my_app
我在特定点上挣扎:自动完成文件路径。
我不理解compgen
选项以及如何使用它。也许我可以尝试运行子命令,但我不知道语法,除了man of bash - Programmable completion builtins之外我找不到任何有用的信息,这些信息没有提供有关compgen
的更多信息。
在这种情况下,当我这样做时:
user@computer:~$ my_app --install D[TAB][TAB]
我想:
user@computer:~$ my_app --install Documents/
我获得:
user@computer:~$ myapp --install Documents
在行尾有一个空格,这是一个问题,因为我必须删除它并添加/
以便能够重做[TAB][TAB]
以自动完成子目录
将-o nospace
选项complete
应用于complete -o nospace -F __my_app_autocomplete my_app
:
user@computer:~$ myapp --i[TAB][TAB]
user@computer:~$ myapp --install
行为是:
user@computer:~$ myapp --install D[TAB][TAB]
user@computer:~$ myapp --install Documents
没有空间。
--install
没有空间。
问题:
/
)-o filenames
以导航到子目录将complete
选项complete -o filenames -F __my_app_autocomplete my_app
应用于user@computer:~$ myapp --i[TAB][TAB]
user@computer:~$ myapp --install
:
user@computer:~$ myapp --install D[TAB][TAB]
user@computer:~$ myapp --install Documents/
行为是:
/
带空格
user@computer:~$ myapp --install f[TAB][TAB]
user@computer:~$ myapp --install file
FROM amazonlinux
WORKDIR /shared
RUN yum -y install gcc
ADD http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz /shared
RUN tar -xzf perl-5.22.1.tar.gz
RUN /shared/perl-5.22.1/Configure -des -Dprefix=/opt/perl-5.22.1/localperl
RUN make -C /shared/perl-5.22.1
RUN make -C /shared/perl-5.22.1 test
RUN make -C /shared/perl-5.22.1 install
,如果是目录,则没有空格
Step 14/20 : ADD http://www.cpan.org/src/5.0/perl-5.22.1.tar.gz /shared
Downloading 15.92 MB/15.92 MB
---> Using cache
---> 24f3b38dee5f
Step 15/20 : RUN tar -xzf perl-5.22.1.tar.gz
---> Using cache
---> 42ecf82ce73d
Step 16/20 : RUN /shared/perl-5.22.1/Configure -des -Dprefix=/opt/perl-5.22.1/localperl
---> Using cache
---> dfe8d71f5ff1
Step 17/20 : RUN make -C /shared/perl-5.22.1/
---> Running in 2766b0c8e9a5
make: Entering directory `/shared/perl-5.22.1'
make: Leaving directory `/shared/perl-5.22.1'
make: *** No targets specified and no makefile found. Stop.
The command '/bin/sh -c make -C /shared/perl-5.22.1/' returned a non-zero code: 2
ish-mac:testanalyse ish$ ls -l
如果是文件,请使用空格
似乎只为完成而没有在单词列表中定义的路径设置路径,因此它不会影响其他完成,我认为这是我需要的第一部分。
我会打开另一个问题以避免混淆:How to autocomplete a bash commandline with file paths from a specific directory without displaying this directory?
答案 0 :(得分:1)
替代
complete -F __my_app_autocomplete my_app
带
complete -o filenames -F __my_app_autocomplete my_app
在这里您可以找到所有解释的compgen选项:
https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html