Der folgende Code, der aus dieser Stack Overflow-Antwort und diesem Diskussionsthread der Ubuntu-Foren angepasst wurde, fügt Vervollständigungen für alle von Ihnen definierten Aliase hinzu:
# Automatically add completion for all aliases to commands having completion functions
function alias_completion {
local namespace="alias_completion"
# parse function based completion definitions, where capture group 2 => function and 3 => trigger
local compl_regex='complete( +[^ ]+)* -F ([^ ]+) ("[^"]+"|[^ ]+)'
# parse alias definitions, where capture group 1 => trigger, 2 => command, 3 => command arguments
local alias_regex="alias ([^=]+)='(\"[^\"]+\"|[^ ]+)(( +[^ ]+)*)'"
# create array of function completion triggers, keeping multi-word triggers together
eval "local completions=($(complete -p | sed -Ene "/$compl_regex/s//'\3'/p"))"
(( ${#completions[@]} == 0 )) && return 0
# create temporary file for wrapper functions and completions
rm -f "/tmp/${namespace}-*.tmp" # preliminary cleanup
local tmp_file; tmp_file="$(mktemp "/tmp/${namespace}-${RANDOM}XXX.tmp")" || return 1
local completion_loader; completion_loader="$(complete -p -D 2>/dev/null | sed -Ene 's/.* -F ([^ ]*).*/\1/p')"
# read in "<alias> '<aliased command>' '<command args>'" lines from defined aliases
local line; while read line; do
eval "local alias_tokens; alias_tokens=($line)" 2>/dev/null || continue # some alias arg patterns cause an eval parse error
local alias_name="${alias_tokens[0]}" alias_cmd="${alias_tokens[1]}" alias_args="${alias_tokens[2]# }"
# skip aliases to pipes, boolean control structures and other command lists
# (leveraging that eval errs out if $alias_args contains unquoted shell metacharacters)
eval "local alias_arg_words; alias_arg_words=($alias_args)" 2>/dev/null || continue
# avoid expanding wildcards
read -a alias_arg_words <<< "$alias_args"
# skip alias if there is no completion function triggered by the aliased command
if [[ ! " ${completions[*]} " =~ " $alias_cmd " ]]; then
if [[ -n "$completion_loader" ]]; then
# force loading of completions for the aliased command
eval "$completion_loader $alias_cmd"
# 124 means completion loader was successful
[[ $? -eq 124 ]] || continue
completions+=($alias_cmd)
else
continue
fi
fi
local new_completion="$(complete -p "$alias_cmd")"
# create a wrapper inserting the alias arguments if any
if [[ -n $alias_args ]]; then
local compl_func="${new_completion/#* -F /}"; compl_func="${compl_func%% *}"
# avoid recursive call loops by ignoring our own functions
if [[ "${compl_func#_$namespace::}" == $compl_func ]]; then
local compl_wrapper="_${namespace}::${alias_name}"
echo "function $compl_wrapper {
(( COMP_CWORD += ${#alias_arg_words[@]} ))
COMP_WORDS=($alias_cmd $alias_args \${COMP_WORDS[@]:1})
(( COMP_POINT -= \${#COMP_LINE} ))
COMP_LINE=\${COMP_LINE/$alias_name/$alias_cmd $alias_args}
(( COMP_POINT += \${#COMP_LINE} ))
$compl_func
}" >> "$tmp_file"
new_completion="${new_completion/ -F $compl_func / -F $compl_wrapper }"
fi
fi
# replace completion trigger by alias
new_completion="${new_completion% *} $alias_name"
echo "$new_completion" >> "$tmp_file"
done < <(alias -p | sed -Ene "s/$alias_regex/\1 '\2' '\3'/p")
source "$tmp_file" && rm -f "$tmp_file"
}; alias_completion
Bei einfachen Aliasnamen (nur Befehl, keine Argumente) wird dem Alias die ursprüngliche Vervollständigungsfunktion zugewiesen. Für Aliase mit Argumenten wird eine Wrapper-Funktion erstellt, die die zusätzlichen Argumente in die ursprüngliche Vervollständigungsfunktion einfügt.
Im Gegensatz zu den Skripten, aus denen es entwickelt wurde, werden in der Funktion Anführungszeichen sowohl für den Alias-Befehl als auch für seine Argumente berücksichtigt (ersteres muss jedoch mit dem Vervollständigungsbefehl übereinstimmen und kann nicht verschachtelt werden). Außerdem sollten Aliase zuverlässig in Befehlslisten und herausgefiltert werden Pipes (die übersprungen werden, da es unmöglich ist, herauszufinden, was in ihnen zu vervollständigen ist, ohne die gesamte Shell-Befehlszeilen-Parsing-Logik neu zu erstellen).
Verwendungszweck
Speichern Sie den Code entweder als Shell-Skriptdatei und geben Sie den Quellcode ein, oder kopieren Sie die Funktion wholesale in .bashrc
(oder Ihre zugehörige Punktdatei ). Das Wichtigste ist, die Funktion aufzurufen, nachdem sowohl die Bash-Vervollständigung als auch die Alias-Definitionen eingerichtet wurden (der obige Code ruft die Funktion direkt nach ihrer Definition auf, und zwar im Sinne von „Quelle und Vergessen“) steht dir besser). Wenn Sie die Funktion nach dem Beenden nicht in Ihrer Umgebung verwenden möchten, können Sie sie unset -f alias_completion
nach dem Aufrufen hinzufügen .
Anmerkungen
Wenn Sie bash
4.1 oder höher verwenden und dynamisch geladene Vervollständigungen verwenden, versucht das Skript, Vervollständigungen für alle Ihre Aliasbefehle zu laden, damit die Wrapperfunktionen für Ihre Aliase erstellt werden können.
bash --version
, um dies zu bekommen (nicht verwenden-v
, andere Ausgabe).