7

I have an alias, ee, defined for my favorite editor, mg. When I do something like

mg fo

and then hit tab, if a file foo exists, I get tab completion to:

mg foo

On most systems I use (e.g., all versions of ubuntu for many years now, and some installs of debian),

ee fo

also completes properly to

ee foo

But on one system I use, which has Debian 6.0 and GNU bash 4.1.5(1)-release, tab completion fails for the version with the alias. Note that this is not a problem with completing the alias itself -- it's a problem with completing the arguments of the aliased command. Is there a way to fix this behavior on the Debian system? Upgrade to bash 4.2.x? Fiddle with config files?

2
  • 2
    Do you have the bash-completion package installed? Are you sourcing /etc/bash_completion?
    – jordanm
    May 15, 2013 at 16:54
  • @jordanm: Yes, bash-completion is installed. I don't know if I'm sourcing /etc/bash_completion automatically for each login session, but I'm guessing that I am somewhere, because $BASH_COMPLETION is defined. If I do an explicit "source /etc/bash_completion" it doesn't fix the problem.
    – user39248
    May 15, 2013 at 18:58

2 Answers 2

3

Edit: OK. Seems like I might have misread the situation. Thought you meant program options as in:

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

but guess it is file completion. I don't know, but give it a go.

As a quick fix this should work:

complete -f -o default ee

Giving:

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

as of Programmable Completion Builtins. E.g. the -X pattern can be useful. E.g. to exclude .swp and .swo files:

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

only show .zip, .ZIP:

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

some might need you to add shopt -s extglob in configuration file.



OLD Answer:

You could try out something like this in your .bash_completion.

At least as a starter.

The core idea is to simply add complete for the alias using the existing complete script for the real program. Here I assume that they are all in the format:

complete -F _complete_function_from_original program_name

You can get what it is by executing: complete -p program_name. Best to check first.

For some methods like apt-get one can use only alias + load:

_load_comp_hack apt-get myalias

For others like mplayer one need a function wrapper, as in e.g.:

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

It is quite possible there is a better way to solve this, but has worked fine for my use. I mostly use it for wrapper scripts where I extend the functionality of the original program. Have not used it on aliases.

I do not feel to safe on this hack, but you could see if it works.

_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

Some programs use more general completion like _longopt, by which the source file won't be located. Usually it is no need to source either, so a simpler variant could be:

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

One problem here, IIRC, is that some completion scripts are not loaded until first run, as in first:
prog tabtab. As an alternative perhaps add it as an else if sourcing of file fails.

4
  • Thanks for the suggestion. The real program does not seem to have its own completion defined; complete -p mg gives no result. And yet I get tab completion when I use the real program ...?
    – user39248
    May 16, 2013 at 20:35
  • @BenCrowell: Completions as in program options, not files?
    – Runium
    May 16, 2013 at 20:40
  • @BenCrowell: Updated answer. Is it correct now?
    – Runium
    May 16, 2013 at 21:53
  • Great, complete -f -o default ee is a fix. +1, answer accepted. Further testing also shows that the original problem was only occurring when there were multiple possible completions that were fairly long; under these conditions, mg was doing completion but ee wasn't. After doing complete -f -o default ee, ee works the same way on long completions as mg.
    – user39248
    May 17, 2013 at 22:54
0

Your problem is: bash-completion doesn't understand aliases. So if you write an alias, it's simply seen as an unknown command and won't be auto-completed. You can either fallback to default filename completion, if this is what you want. Or, you can install a program which expands aliases before auto-completion and complete your aliases as their aliased commands.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy