如何使用文件路径自动完成bash命令行? [英] How to autocomplete a bash commandline with file paths?
问题描述
我正在创建一个shell程序,它是一个命令行工具.我要为此工具创建自己的自动完成功能.
I am creating a shell program which is a command line tool. I want to create my own auto-completion for this tool.
我想做两种不同的事情(也许我应该发布两个问题):
I want to do two different things (maybe should I post two questions):
- 对于选项
--install
和-i
,我想像ls
命令一样自动完成文件路径. - 对于选项
--unit-test
和-t
,我想对可以运行my_app --directory
的特定目录中的文件路径自动完成.
- for the options
--install
and-i
, I want to auto-complete on file paths, like thels
command do. - for the options
--unit-test
and-t
, I want to auto-complete on file paths from a particular directory which I can get runningmy_app --directory
.
my_app_autocomplete
文件
my_app_autocomplete
file
__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
问题
我在一个特定的方面苦苦挣扎:自动完成文件路径.
Problem
I struggle on a particular point: auto-complete file paths.
我不了解compgen
选项以及如何使用它.也许我可以尝试运行一个子命令,但是我不知道语法,而且除了
I don't understand compgen
options and how to do things with it. Maybe I could try to run a subcommand but I don't know the syntax and I can't find any useful information except man of bash - Programmable completion builtins which does not give much information about compgen
.
在这种情况下,当我这样做时:
In this case, when I do:
user@computer:~$ my_app --install D[TAB][TAB]
我想要:
user@computer:~$ my_app --install Documents/
我获得:
user@computer:~$ myapp --install Documents
该行的末尾有一个空格,这是一个问题,因为我必须擦除它并添加一个/
以便能够重做[TAB][TAB]
以自动完成子目录.
with a blank space at the end of the line, which is a problem because I have to erase it and add a /
to be able to redo [TAB][TAB]
to auto-complete for sub-directories.
在complete
上将选项-o nospace
应用为:
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
)之后手动添加空格 - 我必须添加
/
才能导航到子目录
- It removes spaces for all options, forcing me to manually add a space after those that aren't file paths (like
--install
) - I have to add
/
to navigate into sub directories
在complete
上将选项-o filenames
应用为:
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/
带/
,如果是目录,则没有空格
with a /
and without space if it's a directory
user@computer:~$ myapp --install f[TAB][TAB]
user@computer:~$ myapp --install file
如果是文件则带空格
似乎只为未在单词列表中定义的补全设置路径,因此它不会影响其他补全,我认为这是我需要的第一部分.
It seems to set paths only for completion not defined in an list of words, so it does not affect other completions, I think it's the first part of what I need.
I will open another question to avoid mixing things: How to autocomplete a bash commandline with file paths from a specific directory without displaying this directory?
推荐答案
自动完成文件路径
替代
complete -F __my_app_autocomplete my_app
与
complete -o filenames -F __my_app_autocomplete my_app
在这里您可以找到所有解释的compgen选项:
Here you can find all the compgen options explained:
https://www.gnu.org /software/bash/manual/html_node/Programmable-Completion-Builtins.html
这篇关于如何使用文件路径自动完成bash命令行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!