使用冒号作为别名会破坏自动完成功能

使用冒号作为别名会破坏自动完成功能

我在 中使用冒号或其他前缀作为别名.bashrc

有一段时间我使用的快捷键如下:

alias :t="tmux"
alias :www="google-chrome --use-gl=desktop &>/dev/null &"
alias :ide="bash ~/netbeans-11.3/netbeans/bin/netbeans &>/dev/null &"
alias :bsh="/bin/bash"
alias :c="clear"
alias :d="docker"
alias :dc="docker-compose"

它奏效了。但我遇到了由于冒号而导致自动完成不起作用的问题:

complete -F _docker :d

当我调用完成时:d,什么也没有显示。

是碰撞吗?我该如何修复它?您是否看到更多碰撞即将发生?难道我做错了什么?

答案1

冒号在 Bash 中并不违法别名名称。明确禁止的字符有\, ", ', <space>, <tab>, <newline>, |, &, ;, (, ), <, >, /, $, `, =

假设你有bash 完成安装后,您可能会遇到两个问题(第一个问题通常与别名有关,无论其名称中是否有冒号):

  1. 完成函数是延迟加载的:

      # In a freshly opened shell
    $ alias bar='docker'
    $ complete -F _docker bar
    $ declare -pF _docker
    bash: declare: _docker: not found
      # Typing "bar", TAB, TAB:
    $ bar bash: completion: function `_docker' not found
    

    要解决此问题,您可以显式加载所需的函数(或围绕默认完成函数编写一个包装器,_completion_loader并使其也处理别名):

      # ...continue
    $ _completion_loader docker
    $ declare -pF _docker
    declare -f _docker
      # Typing "bar", TAB, TAB:
    $ bar 
    attach     container  ...
    
  2. 阅读线(提供行编辑和可编程完成在 Bash 中)处理包含在COMP_WORDBREAKS变量作为单词分隔符,默认情况:下位于其中,以支持用例,例如PATH对包含冒号分隔的路径列表的变量(例如)进行赋值。
    因此,尝试完成:foo命令行会给完成函数提供一个需要完成的损坏的单词数组。具体来说,中的元素COMP_WORDS将是:,foo和一个空字符串而不是:foo和 1 个空字符串。

    bash-completion 中提到了这一点GitHub 上的常见问题解答。请参阅“问题。当我尝试完成包含冒号的内容时,完成会出错。”

    该常见问题解答中提出的唯一解决方案是在命令行上反斜杠转义冒号:

      # In a freshly opened shell
    $ alias :foo='docker'
    $ complete -F _docker :foo
    $ _completion_loader docker
      # Typing "\:foo", TAB, TAB:
    $ \:foo 
    attach     container  ...
    

    但不幸的是,在命令前面添加反斜杠会阻止 Bash 执行别名扩展,从而导致“找不到命令”错误。但是,如果您可以选择定义函数(例如:d () { docker "$@"; })而不是别名,则此解决方案将起作用。

    当然,您也可以删除:from COMP_WORDBREAKS,但这会破坏PATH类似命令行的自动完成:

    $ COMP_WORDBREAKS=${COMP_WORDBREAKS/:/}
      #  Typing "PATH=/bin:/", TAB doesn't complete any further:
    $ PATH=/bin:/
    

相关内容