Могут ли zsh или bash расширить выражения истории, относящиеся к каталогам?

Например, предположим, что я только что скопировал что-то:

mv foo_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype

и я хотел бы использовать замену истории следующим образом:

mv bar_file.txt !!:2

Я удивлен, что zsh не расширяет для меня !!:2, когда я нажимаю [tab]. В более сложной ссылке на исторический аргумент мне действительно может понадобиться расширение, прежде чем я нажму return, просто чтобы я был уверен, что ссылаюсь на правильный аргумент. Есть ли способ заставить это сделать? (Я ожидаю, что это будет поведение по умолчанию. Это поведение по умолчанию, которое я каким-то образом непреднамеренно отключил или сломал?)

Если zsh не может этого сделать, может bash?

ОБНОВЛЕНИЕ: zsh расширит выражение истории, если оно относится к файлу, но не к каталогу:

mv foo_file.txt foo_bar_file.txt
mv bar_file.txt !!:2[TAB]

Он расширит его, если это просто произвольная строка:

echo one two three four
echo !!:1[TAB]

Но не в том случае, если вы пытаетесь переместить что-то в каталог. Все больше и больше похоже, что это ошибка.


person iconoclast    schedule 13.08.2011    source источник
comment
для меня он завершает вкладку, zsh 4.2.7.   -  person chad    schedule 14.08.2011
comment
@chad: я использую zsh 4.3.10, и он у меня не работает. Вы переходите в каталог? Это работает для меня, если я просто переименовываю файл, но не в том случае, если аргумент, который я хочу расширить, является каталогом.   -  person iconoclast    schedule 15.08.2011
comment
Если завершение табуляции по какой-либо причине не работает, вы можете использовать модификатор :p для вывода расширенного выражения истории, а не выполнять команду при нажатии Enter: mv bar_file.txt !!:2:p.   -  person chepner    schedule 09.04.2014


Ответы (5)


Я использую zsh в cygwin:

$ zsh --version
zsh 4.3.12 (i686-pc-cygwin)

$ setopt
interactive
monitor
shinstdin
zle

Я только что попробовал следующее:

$ touch foo_file.txt bar_file.txt
$ mkdir -p ~/to/some/long/path/that/i/do/not/want/to/retype
$ mv foo_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype

Затем я попробовал завершение табуляции, упомянутое выше:

$ mv bar_file.txt !!:2[TAB]

и это сработало нормально, последний аргумент был расширен следующим образом:

$ mv bar_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype
person Dario Buttari    schedule 27.09.2011

Вы можете псевдо-взломать его в bash:

$ shopt -s histreedit
$ shopt -s histverify

Затем, чтобы попробовать расширение:

$ echo !!:2 [now hit enter]
$ echo histverify

Теперь вы не можете расширять вкладки в bash. Однозначно нет. Это из-за порядка, в котором обрабатывается расширение bash.

person Foo Bah    schedule 13.08.2011

У меня отлично работает с zsh 4.3.17. Похоже, у вас вероятно есть ошибка, о которой стоит сообщить на zsh- список рассылки пользователей. Однако есть по крайней мере пять других сочетаний клавиш, которые должны выполнять то, что вы хотите: C-x *, которая по умолчанию привязана к expand-word, и Esc Space, или Meta-Space, или Esc !, или Meta-!, которые по умолчанию привязаны к expand-history. (Meta означает клавишу Alt для многих людей, хотя это зависит от настроек вашего терминала.)

Сказав это, Esc . (или Meta-. или Alt-.) — это более удобный способ извлечения последнего слова из предыдущей строки в истории, поскольку он обеспечивает мгновенную визуальную обратную связь. Вы также можете выбрать последнее слово из более старых строк, несколько раз нажав сочетание клавиш, или даже n последнее слово в предыдущей строке, поставив перед сочетанием клавиш префикс Alt-n. (или Meta-n или Esc n). Так, например, чтобы получить предпоследнее слово из 3-й новейшей строки истории, последовательность будет следующей:

  • Meta-. (возврат на одну строку истории, выбор последнего слова из этой строки)
  • Meta-. (возвращается еще раз, снова выбирая последнее слово)
  • Meta-2 Meta-. (возвращается еще раз, но на этот раз выбирает предпоследнее слово из этой строки)
person Adam Spiers    schedule 31.08.2012

Я пробовал то, что вы описали, и я не думаю, что bash поддерживает это.

person Delan Azabani    schedule 13.08.2011

В Баше Alt-. обычно привязан к yank-last-arg, который даст вам то, что вы хотите.

Вот ссылка на полный список команд, связанных с историей, которые можно привязать к нажатию клавиш http://www.gnu.org/software/bash/manual/bashref.html#Commands-For-History

Например,

ls /etc/passwd /etc/group
cat 
# press Alt+. (Alt dot) here, bash adds /etc/group
cat /etc/group
# press space, then press Alt+1 Alt+.
# bash adds the first argument of the previous command /etc/passwd
cat /etc/group /etc/passwd
person Nicholas Sushkin    schedule 28.10.2011