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.
I would have said that it is simply Tail Call Optimization, but in fact (as the last link points out), bash
doesn't optimize tail calls. It only seems to optimize the case where the command to be executed is a simple command (that is, not a compound command).
The second command is not a tail call of pstree
, because pstree
is not the last thing in the command line. (It's a tail call of echo
, but echo
is usually a built-in so no subprocess will be created for it regardless.)
To save reading all those links (although I hope they are interesting), the idea is that if you know that a function/program/whatever will return immediately after calling some other function/program/whatever, and that the value returned will be the value returned by the called function/program/whatever, then you might as well just reuse the current stack frame (or process, in the case of a shell script) instead of pushing a new stack frame (creating a new process), calling the function (running the script), and then returning. In a shell script, you can do that manually by using exec
for the last command, but it would be possible for the shell to do that automatically.
zsh
and ksh
both seem to be able to do that, but not bash
:
$ zsh -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───pstree
$ ksh -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───pstree
$ bash -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───bash───pstree
But that observation is just an observation, based on the versions of those shells which I happen to have installed, so YMMV:
$ zsh --version
zsh 5.0.2 (x86_64-pc-linux-gnu)
$ ksh --version
version sh (AT&T Research) 93u+ 2012-08-01
$ bash --version
GNU bash, version 4.2.45(1)-release (x86_64-pc-linux-gnu)
Best Answer
Since
git
is an alias ending with a space, bash performs alias expansion on the word immediately after it:From the docs:
Make
git
an alias without the space:Note that:
So, you don't need
\git
there.