如何获得命令别名的bash补全?


57

我希望在命令行别名上使用制表符补全,例如,说我定义了以下别名:

alias apt-inst='sudo aptitude install'

当我按下Tab键时,是否有办法获得aptitude提供的补全?例如,当我编写“ sudo aptitude install gnumer”并单击选项卡时,aptitude将其完成为gnumeric,或者如果存在不确定性,则列出以gnumer开头的所有可用软件包。如果使用别名进行操作,则不会执行任何操作-无法完成。


Answers:


30

在Ubuntu论坛上一个很好的话题。Ole J提出以下别名完成定义功能:

function make-completion-wrapper () {
  local function_name="$2"
  local arg_count=$(($#-3))
  local comp_function_name="$1"
  shift 2
  local function="
    function $function_name {
      ((COMP_CWORD+=$arg_count))
      COMP_WORDS=( "$@" \${COMP_WORDS[@]:1} )
      "$comp_function_name"
      return 0
    }"
  eval "$function"
  echo $function_name
  echo "$function"
}

使用它为您的别名定义一个完成函数,然后将该函数指定为别名的完成者:

make-completion-wrapper _apt_get _apt_get_install apt-get install
complete -F _apt_get_install apt-inst

我更喜欢使用别名为现有程序添加经常使用的参数。例如,对于grep,我一直想跳过设备和二进制文件,因此我为设置了别名grep。要添加诸如的新命令grepbin,我在~/bin文件夹中使用一个shell脚本。如果该文件夹在您的路径中,它将自动完成。


2
太棒了,我担心这不可能。
levesque 2010年

请注意,此代码存在一些问题。请参阅我的回答以获取其解释和解决方案。
汤姆·黑尔

注意:我在另一条命令上使用了此技术,并且在传递args时,我不得不使用complete -o default -F ...来代替complete -F ...文件名自动完成等功能(Bash 4.3.46)。
joelittlejohn

28

尝试complete-alias,它可以完全解决此问题。

安装后,您可以使用一个通用函数来完成许多别名,如下所示:

complete -F _complete_alias <myalias1>
complete -F _complete_alias <myalias2>
complete -F _complete_alias <myalias3>

您可能希望通过.bash_profile或类似方式在每个bash实例中提供complete_alias文件。

安装

mkdir ~/.bash_completion.d
curl https://raw.githubusercontent.com/cykerway/complete-alias/master/bash_completion.sh \
     > ~/.bash_completion.d/complete_alias

应用

source ~/.bash_completion.d/complete_alias

alias container=docker\ container
complete -F _complete_alias container

container现在可以由原始_docker()完成处理程序自动完成;

$ container l<Tab>
logs  ls    

$ container s<Tab>
start  stats  stop   

2
鉴于该软件似乎是您的,您可以做得更好。添加有关安装的说明。描述它的作用以及如何使用它。否则,这只是垃圾邮件。
muru

@muru我正在考虑在此处粘贴一些代码,但可能比此处接受的时间更长。我假设人们在阅读README文件中的Install部分时没有问题,在这种情况下,只有几行。
Cyker '16

2
重点是仅从答案就可以判断访问所说的README是否值得。
muru

这是一个适当的答案,可以准确地解决问题。
ЯрославРахматуллин

1
这是一个非常出色且非常全面的答案,非常有用,谢谢!由于@muru出现问题,它可能已更新。
布莱恩·托平

3

2018答案

您必须将别名添加到程序“ complete”中。根据要实现的自动完成的类型,必须使用-c或-F。

对于包自动完成:

complete -c name_of_your_alias

对于命令自动完成:

complete -F name_of_your_alias

要检查您的别名是否正确添加:

complete | grep name_of_your_alias

最后,要从“ complete”中删除别名:

complete -r name_of_your_alias

在您的情况下:

complete -c apt-inst

1
请不要在评论中继续回答。如果您有话要说,请将其编辑为答案。
G-Man

2
complete -F xxx在OSX上不起作用(仅显示用法complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...])。你有指针吗?谢谢。
Anthony Kong


2

这是Shawn J. Goff的答案中的代码,并进行了一些改进:

  • 修复了以突出显示的语法错误shell-check,例如""$@"实际上函数定义字符串结尾的第一个。
  • 删除了,return 0以便可以将基础函数的返回值传递回调用方。

# Wraps a completion function, eg for use with an alias.
# Usage:
# make-completion-wrapper <actual completion function> <name of new func.>
#                         <command name> <list supplied arguments>
# eg.
#   alias agi='apt-get install'
#   make-completion-wrapper _apt_get _apt_get_install apt-get install
#     # defines a function called _apt_get_install (that's $2) that will
#     # complete the 'agi' alias. 
#   complete -F _apt_get_install agi
function make-completion-wrapper {
  local function_name="$2"
  local arg_count=$(( $#-3 ))
  local comp_function_name="$1"
  shift 2
  local function="function $function_name {
      (( COMP_CWORD += $arg_count ))
      COMP_WORDS=( \"\$@\" \${COMP_WORDS[@]:1} )
      \"$comp_function_name\"
    }"
  eval "$function"
  # echo "$function"
}
export -f make-completion-wrapper

恐怕在Bash 4.3.46中对我不起作用。Shaun J. Goff的答案确实有用。
joelittlejohn

1
“结束”功能定义字符串是有意的;关键是将来自外部函数的参数包含到COMP_WORDS数组中。如果我们使用make-completion-wrapper _apt_get _apt_get_install apt-get install作为一个例子,之后shift 2$@包含apt-get installapt-get install分配时,函数定义包括(两个文字)COMP_WORDS
Jeffery To

0

作为@Giles答案的扩展,以下便捷功能自动命名生成的包装器,make-completion-wrapper以便可以在一行中定义完成:

function complete-alias  {
    # uses make-completion-wrapper: https://unix.stackexchange.com/a/4220/50978
    # example usage
    # complete-alias _pass pshow pass show
    # complete-alias _pass pgen pass generate

    EXISTING_COMPLETION_FN=${1} && shift
    ALIAS=${1} && shift
    AUTOGEN_COMPLETION_FN="__autogen_completion_${ALIAS}"
    make-completion-wrapper ${EXISTING_COMPLETION_FN} ${AUTOGEN_COMPLETION_FN} ${*}
    complete -F ${AUTOGEN_COMPLETION_FN} ${ALIAS}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.