如何自动完成别名为单个命令的多级命令?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何自动完成别名为单个命令的多级命令?相关的知识,希望对你有一定的参考价值。

假设我有两个bash函数:

dock() { sudo docker $@ ;}

dock-ip() { sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}

如何使用第二个函数进行bash自动完成?

使用第一个,就像添加一样简单:

_completion_loader docker; complete -F _docker dock

这不适用于第二个。 Docker的自动完成源位于Debian Stretch上的/usr/share/bash-completion/completions/docker中。我有更多的函数,如dock-rundock-exec等,所以我不想为每个函数编写自定义完成函数。

此外,complete -F _docker_container_inspect dock-ip只是部分工作;选项卡仅列出容器,而不是完成部分字符串。


研究:

How do I autocomplete nested, multi-level subcommands?

https://superuser.com/questions/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases

答案

通过结合小时的bash完成经验,我拆开了docker完成脚本(/usr/share/bash-completion/completions/docker)和bash_completion.sh脚本来提供一个包装函数:

# Usage:
#   docker_alias_completion_wrapper <completion function> <alias/function name>
#
# Example:
#   dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
#   docker_alias_completion_wrapper __docker_complete_containers_running dock-ip
function docker_alias_completion_wrapper {
  local completion_function="$1";
  local alias_name="$2";

  local func=$(cat <<EOT
    # Generate a new completion function name
    function _$alias_name() {
        # Start off like _docker()
        local previous_extglob_setting=\$(shopt -p extglob);
        shopt -s extglob;

        # Populate \$cur, \$prev, \$words, \$cword
        _get_comp_words_by_ref -n : cur prev words cword;

        # Declare and execute
        declare -F $completion_function >/dev/null && $completion_function;

        eval "\$previous_extglob_setting";
        return 0;
    };
EOT
  );
  eval "$func";

  # Register the alias completion function
  complete -F _$alias_name $alias_name
}
export -f docker_alias_completion_wrapper

然后我创建了我的别名/函数,如下所示:

# Get container IP
dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
docker_alias_completion_wrapper __docker_complete_containers_running dock-ip

# Execute interactive container
dock-exec()  { docker exec -i -t --privileged $@ ;}
docker_alias_completion_wrapper __docker_complete_containers_all dock-exec

... 

请务必在配置文件别名脚本顶部调用_completion_loader docker;以加载主Docker完成脚本。我邀请更多熟练的bash程序员来改进这个答案。

以上是关于如何自动完成别名为单个命令的多级命令?的主要内容,如果未能解决你的问题,请参考以下文章

设计模式——命令模式

linux下如何建立多级文件目录?

如何设置 vscode 的代码片段,以便在自动完成后自动触发 vscode 的智能感知?

如何使用单个命令在 UNIX 文件系统中提取 JAR 并使用 JAR 命令指定其目标目录?

如何使用单个脚本自动打开 sqlite3.exe shell 并运行命令?

VSCode自定义代码片段——cli的终端命令大全