W Zsh (jak również w bash) możesz użyć niektórych rozszerzeń słów historii, aby oznaczyć argumenty z poprzednich poleceń.
Ten przykład pokazuje uzyskanie 2. parametru z poprzedniego polecenia w historii z !:#
rozszerzeniem:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
Często zapominam, jaki dokładnie jest parametr # danego argumentu, a pisanie !:#
nie zawsze jest takie szybkie, gdy pamiętam, który to argument. Wiem o meta-.
zamianie ostatniego argumentu, ale czasami nie jest to ostatni argument, którego chcę.
Chciałbym dodać argumenty z poprzedniego polecenia jako sugestie wykonania dowolnego polecenia, które wpisuję w Zsh.
Byłem w stanie dowiedzieć się, jak utworzyć funkcję powłoki, która może utworzyć tablicę argumentów (0..N) z ostatniego polecenia i powiązać go z konkretnym poleceniem.
_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
Tak to wygląda po ukończeniu foo, w którym nacisnąłem klawisz tab <TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
Działa to świetnie do wykonania polecenia „foo”, ale chciałbym, aby były to opcje dla każdego rozszerzenia zsh, które wykonuję. Wydaje mi się, że ma to coś wspólnego z elementami uzupełniającymi zstyle, ale po kilku godzinach hackowania dookoła zdałem sobie sprawę, że nie jestem już tak głęboki.
Jak mogę uzyskać argumenty z poprzedniego polecenia jako sugerowane uzupełnienia dowolnego polecenia w Zsh?
Mam udostępniony mój pełny plik kompilacji zshrc na bitbucket, jeśli to pomaga. Wiele z nich pochodzi z różnych źródeł, a niektóre samodzielnie zhakowałem.
AKTUALIZACJA:
Odpowiedź Juliena Nicoulauda zbliżyła mnie, zaznaczam ją jako zaakceptowaną, ponieważ doprowadziła mnie tam, gdzie potrzebowałem.
W mojej konkretnej konfiguracji, używając sugerowanego:
zstyle ':completion:*' completer _last_command_args _complete
Nie działało to dla mnie całkiem dobrze, ponieważ powodowało, że uzupełnianie tabulatorami wyświetlało tylko listę argumentów z ostatniego polecenia (chociaż faktycznie uzupełniałoby to również nazwy plików, po prostu ich nie wyświetlał). Zmiana kolejności _complete _last_command_args
na odwrotną. Wyświetla normalne nazwy plików, ale nie ostatnie_polecenia_args
Zgaduję, że ma to coś wspólnego ze sposobem działania narzędzia uzupełniającego. Myślę, że wyświetla tylko dane wyjściowe z pierwszej metody, która powraca pomyślnie, ale mam problem z analizowaniem źródła zsh, aby w pełni zrozumieć, co się dzieje. Byłem w stanie dostosować moją metodę, aby zawierała wywołanie, aby _complete
wyświetlała zarówno ostatnie polecenia argumentu, jak i zwykłe autouzupełnianie. Nie do końca tak oddzielny, ale działa wystarczająco dobrze dla mnie.
Oto pełna funkcja, której użyłem wraz z innymi rzeczami zstyle, które mam:
# 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
Inne linie zstyle, które mam, nie są konieczne, aby to działało, ale mogą mieć wpływ na to, dlaczego to działa dla mnie:
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
Teraz, gdy jestem w katalogu z file1.txt
i file2.txt
, a moim ostatnim poleceniem było echo foo bar baz
, otrzymuję to do autouzupełniania, czego właśnie chciałem:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
( insert-last-word
) podoba mi się to copy-earlier-word
, które przełącza między słowami linii osiągniętej przez insert-last-word
. Dla twojego .zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word