当命令是别名时,制表符补全不适用于参数

当命令是别名时,制表符补全不适用于参数

我有一个别名 ee,是为我最喜欢的编辑器 mg 定义的。当我做类似的事情时

mg fo

然后点击 tab,如果文件 foo 存在,我会得到 tab 补全:

mg foo

在我使用的大多数系统上(例如,多年来所有版本的 ubuntu,以及一些安装的 debian),

ee fo

也正确完成

ee foo

但在我使用的一个系统(具有 Debian 6.0 和 GNU bash 4.1.5(1)-release)上,带有别名的版本的制表符补全失败。请注意,这是不是完成别名本身的问题 - 这是完成别名的问题论点别名命令的。有没有办法修复 Debian 系统上的这种行为?升级到 bash 4.2.x?摆弄配置文件?

答案1

编辑:好的。看来我可能误判了局势。以为你的意思是程序选项如下:

$ mplayer_alias -pla<tab><tab>
-playing-msg  -playlist
$

但猜测这是文件完成。我不知道,但试试吧。

作为快速修复,这应该有效:

complete -f -o default ee

给予:

$ ee<tab><tab>
file1 file2 file3
$

作为可编程完成内置函数。例如,-X pattern可能有用。例如排除.swp.swo文件:

complete -f -X '*.sw[op]' ee

只显示.zip, .ZIP:

complete -f -o default -X '!*.+(zip|ZIP)' my_unzip_alias

有些可能需要您添加shopt -s extglob到配置文件中。



旧答案:

你可以在你的.bash_completion.

至少作为首发。

核心思想是complete使用现有的完整脚本简单地添加别名真实的程序。这里我假设它们都是以下格式:

complete -F _complete_function_from_original program_name

您可以通过执行以下命令来获取它是什么complete -p program_name:最好先检查一下。

对于某些方法,例如apt-get只能使用别名+加载:

_load_comp_hack apt-get myalias

对于其他人,比如mplayer需要一个函数包装器,例如:

myalias() { mplayer "$@"; }
                      |
                      +--- Could be messy

很可能有更好的方法来解决这个问题,但对我来说效果很好。我主要将它用于包装脚本,在其中扩展原始程序的功能。还没有在别名上使用过它。

我觉得这个黑客攻击不安全,但你可以看看它是否有效。

_load_comp_hack()
{
    local cc=
    # Make sure completion scripts are sourced.
    # Report error if source fail.
    if . "/usr/share/bash-completion/completions/$1" >/dev/null 2>&1; then
        # Extract the completion function used by the "real" program.
        if cc="$(complete -p "$1" | cut -d' ' -f3)"; then
            # Add it to the alias
            complete -F "$cc" "$2"
            return 0
        fi
    fi
    echo "bash-completion '$1' for '$2' not found."
}

_load_comp_hack mplayer mplad
_load_comp_hack apt-get z
                |       |
                |       +----- Alias, script or function
                +------------- Real function

有些程序使用更通用的完成方式,例如_longopt,通过它无法找到源文件。通常也不需要来源,因此一个更简单的变体可能是:

_load_comp_hack()
{
    local cc=
    if cc=$(complete -p "$1" | cut -d' ' -f3); then
            complete -F "$cc" "$2"
    fi
}

IIRC,这里的一个问题是一些完成脚本直到第一次运行才加载,如第一个:
prog tabtab。作为替代方案,可以将其添加为else如果文件来源失败。

答案2

您的问题是: bash-completion 不理解别名。因此,如果您编写别名,它只会被视为未知命令,并且不会自动完成。如果您想要的话,您可以回退到默认文件名完成。或者,您可以安装一个程序它会在自动完成之前扩展别名,并将别名作为其别名命令完成。

相关内容