У zsh (як і bash) ви можете використовувати деякі розширення слів історії історії для позначення аргументів попередніх команд.
Цей приклад показує отримання 2-го параметра з попередньої команди в історії з !:#
розширенням:
% echo foo bar baz
foo bar baz
% echo !:2
echo bar
bar
Я часто точно забуваю, який параметр # є певним аргументом, і набір тексту !:#
не завжди такий швидкий, коли я пам'ятаю, який це аргумент. Я знаю про те, meta-.
щоб замінити останній аргумент, але іноді це не останній аргумент, який я хочу.
Я хотів би додати аргументи з попередньої команди як пропозиції виконати будь-яку команду, яку я набираю в zsh.
Я зміг зрозуміти, як створити функцію оболонки, яка може створити масив аргументів (0..N) з останньої команди та прив’язати її до певної команди.
_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
Ось так виглядає для завершення просто foo, де я натиснув клавішу вкладки на <TAB>
:
% echo bar baz qux
bar baz qux
% foo <TAB>
bar baz echo qux
Це чудово підходить для виконання команди "foo", але я хотів би, щоб це були варіанти для будь-якого розширення zsh, яке я роблю. Я думаю, що це має щось спільне з елементами zstyle kompleter, але через кілька годин злому я зрозумів, що я вийшов з глибини.
Як я можу отримати аргументи з попередньої команди як запропоновані доповнення для будь-якої команди в zsh?
У мене повноцінний файл комп’ютерної програми zshrc ділиться на bitbucket, якщо це допомагає. Багато його посилається з найрізноманітніших джерел, а деякі з них я сам зламав.
ОНОВЛЕННЯ:
@ Відповідь Юлієна Нікуло мене наблизила, я відзначаю це як прийняте, оскільки отримало мене там, де мені потрібно було дістатися.
З моєю конкретною конфігурацією, використовуючи запропоновані:
zstyle ':completion:*' completer _last_command_args _complete
Для мене це не дуже спрацювало, тому що в результаті заповнення вкладки відображався лише список аргументів з останньої команди (хоча він насправді також доповнював імена файлів, просто не відображав їх). Змінюючи порядок, _complete _last_command_args
робив зворотне. Він відображатиме звичайні імена файлів, але не last_command_args
Я здогадуюсь, це має щось спільне із способом завершення робіт. Я думаю, що він відображає лише вихідний результат із першого методу, який успішно повертається, але у мене виникають проблеми з аналізом джерела zsh, щоб зрозуміти, що все відбувається. Мені вдалося налаштувати свій метод, щоб він включив виклик, щоб _complete
він відображав як останні команди команд аргументу, так і звичайні елементи автозаповнення. Не зовсім як розділений, але працює досить добре для мене.
Ось повна функція, яку я використовував разом з іншими елементами zstyle:
# 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
Інші лінійки zstyle, які мені не потрібні, але можуть вплинути на те, чому це працює для мене:
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
Тепер, якщо я перебуваю в каталозі з file1.txt
і file2.txt
, і моєю останньою командою було echo foo bar baz
, я отримую це для автозаповнення, яке саме те, що я хотів:
% ls
bar baz echo foo
- files -
file1.txt file2.txt
^[ .
( insert-last-word
), мені подобається copy-earlier-word
, який цикли між словами рядка, досягнутого insert-last-word
. Для вашого .zshrc
:autoload copy-earlier-word && zle -N copy-earlier-word && bindkey '^[,' copy-earlier-word