In zsh (sowie in bash) können Sie einige Protokollworterweiterungen verwenden, um Argumente aus früheren Befehlen zu kennzeichnen.
In diesem Beispiel wird gezeigt, wie der zweite Parameter aus dem vorherigen Befehl im Verlauf mit !:#
Erweiterung abgerufen wird:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
Ich vergesse oft genau, welcher # -Parameter ein bestimmtes Argument ist, und die Eingabe !:#
ist nicht immer so schnell, wenn ich mich erinnere, welches Argument es ist. Ich weiß meta-.
, dass ich das letzte Argument ersetzen muss, aber manchmal ist es nicht das letzte Argument, das ich möchte.
Ich möchte die Argumente aus dem vorherigen Befehl als Vorschläge hinzufügen, um jeden Befehl zu vervollständigen, den ich in zsh eingebe.
Ich konnte herausfinden, wie man eine Shell-Funktion erstellt, die aus dem letzten Befehl ein Array von Argumenten (0..N) erzeugt und an einen bestimmten Befehl bindet.
_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
}
# trying to get last_command_args to be suggested for any command, this just works for foo
compdef _last_command_args foo
So sieht es aus, wenn ich nur foo beende, bei dem ich die Tabulatortaste drücke <TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
Dies funktioniert hervorragend, um den Befehl "foo" auszuführen, aber ich möchte, dass dies Optionen für jede zsh-Erweiterung sind, die ich mache. Ich denke, es hat etwas mit dem Zstyle-Completer-Zeug zu tun, aber nach ein paar Stunden des Herumhackens wurde mir klar, dass ich überfordert bin.
Wie kann ich die Argumente aus meinem vorherigen Befehl als vorgeschlagene Vervollständigungen für jeden Befehl in zsh abrufen?
Ich habe meine vollständige zshrc-Compinstall-Datei auf bitbucket verteilt, wenn das hilft. Viele davon stammen aus verschiedenen Quellen und einige davon habe ich selbst zusammen gehackt.
AKTUALISIEREN:
@ Julien Nicoulauds Antwort hat mich sehr nahe gebracht. Ich markiere es als akzeptiert, da es mich dahin gebracht hat, wo ich es brauchte.
Mit meiner speziellen Konfiguration, unter Verwendung der vorgeschlagenen:
zstyle ':completion:*' completer _last_command_args _complete
Hat bei mir nicht ganz geklappt, da beim Vervollständigen der Registerkarte nur die Liste der Argumente aus dem letzten Befehl angezeigt wurde (obwohl auch die Dateinamen vollständig waren, sie nur nicht angezeigt wurden). Ändern der Reihenfolge, um _complete _last_command_args
das Gegenteil zu tun. Es würde die normalen Dateinamen anzeigen, aber nicht last_command_args
Ich vermute, das hat etwas mit der Funktionsweise von Completer zu tun. Ich denke, es zeigt nur die Ausgabe der ersten Methode an, die erfolgreich zurückgegeben wird, aber ich habe Probleme, die zsh-Quelle zu analysieren, um vollständig zu verstehen, was los ist. Ich konnte meine Methode dahingehend optimieren _complete
, dass sie einen Aufruf von enthält , der sowohl die letzten Argumentbefehle als auch das reguläre automatische Vervollständigen anzeigt. Nicht ganz so getrennt, funktioniert aber gut genug für mich.
Hier ist die volle Funktion, die ich zusammen mit den anderen Zstyle-Dingen verwendet habe:
# adds the arguments from the last commadn to the autocomplete list
# I wasn't able to get this to work standalone and still print out both regular
# completion plus the last args, but this works well enough.
_complete_plus_last_command_args() {
last_command=$history[$[HISTCMD-1]]
last_command_array=("${(s/ /)last_command}")
_sep_parts last_command_array
_complete
}
_force_rehash() {
(( CURRENT == 1 )) && rehash
return 1 # Because we didn't really complete anything
}
zstyle ':completion:::::' completer _force_rehash _complete_plus_last_command_args _approximate
Andere Zstyle-Linien, die ich habe, sind nicht erforderlich, um zu funktionieren, können aber den Grund dafür beeinflussen, warum dies bei mir funktioniert:
zstyle -e ':completion:*:approximate:*' max-errors 'reply=( $(( ($#PREFIX + $#SUFFIX) / 3 )) )'
zstyle ':completion:*:descriptions' format "- %d -"
zstyle ':completion:*:corrections' format "- %d - (errors %e})"
zstyle ':completion:*:default' list-prompt '%S%M matches%s'
zstyle ':completion:*' group-name ''
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*' menu select
zstyle ':completion:*' verbose yes
Wenn ich mich jetzt in einem Verzeichnis mit file1.txt
und befinde file2.txt
und mein letzter Befehl war echo foo bar baz
, bekomme ich das für die automatische Vervollständigung, was genau das ist, was ich wollte:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
( insert-last-word
) zu ergänzen , mag ich copy-earlier-word
, welche Zyklen zwischen Wörtern der Zeile von erreicht werden insert-last-word
. Für Ihre .zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word