ZSH: история поиска по клавишам вверх и вниз?


22

В настоящее время у меня есть следующее .zshrc:

bindkey '^[[A' up-line-or-search
bindkey '^[[B' down-line-or-search

Тем не менее, это только кажется, что соответствует содержанию моего текущего ввода до появления пробела. Например, sudo ls /будет соответствовать каждой строке в моей истории, которая начинается с sudo, в то время как я хотел бы, чтобы она соответствовала только строкам, которые соответствуют всему моему вводу. (т.е. sudo ls /etcбудет соответствовать, но не соответствует sudo cat /var/log/messages)

Что мне нужно изменить, чтобы получить желаемое поведение?

Вот мой весь .zshrc на случай, если он уместен: https://gist.github.com/919566

Ответы:


9

Это документированное поведение :

down-line-or-search
Переместить строку вниз в буфере или, если она уже находится в нижней строке, выполнить поиск в истории вперед, чтобы найти строку, начинающуюся с первого слова в буфере.

Кажется, не существует существующего виджета, который делает именно то, что вы хотите, поэтому вам придется сделать свой собственный. Вот как определить виджет, который ведет себя как up-line-or-search, но используя начало строки (до курсора), а не первое слово в качестве строки поиска. Не проверено, особенно на многострочном вводе.

up-line-or-search-prefix () {
  local CURSOR_before_search=$CURSOR
  zle up-line-or-search "$LBUFFER"
  CURSOR=$CURSOR_before_search
}
zle -N up-line-or-search-prefix

Альтернативный подход - использовать history-beginning-search-backward, но вызывать его, только если курсор находится на первой строке. Непроверенные.

up-line-or-history-beginning-search () {
  if [[ -n $PREBUFFER ]]; then
    zle up-line-or-history
  else
    zle history-beginning-search-backward
  fi
}
zle -N up-line-or-history-beginning-search

Спасибо, Жиль, ваше первое решение работает довольно хорошо, но есть одна проблема, и я надеюсь, что вы поможете мне решить ее. Когда я вызываю префикс up-line-or-search-prefix для пустого ввода, он дает мне последнюю команду запуска - желаемое поведение. Однако, когда я снова запускаю префикс up-line-or-search-prefix, он выполняет поиск up-line-or-search по первому символу моего ввода. Можно ли как-то изменить ситуацию, чтобы нажатие стрелки вверх с пустым вводом пролистывало мою историю?
rps

@rps Ах, понял, это было первое слово, потому что аргумент отсутствовал (вместо того, чтобы быть пустым, как должно было). Используйте мою отредактированную версию.
Жиль "ТАК - перестань быть злым"

33

Zsh предоставляет эту функциональность с помощью

history-beginning-search-backward
history-beginning-search-forward

Ex.

bindkey "^[[A" history-beginning-search-backward
bindkey "^[[B" history-beginning-search-forward

Найти точный код ключа по
ctrl+vKEY

Ex.
ctrl+ vUP
ctrl+ vDOWN
ctrl+ vPageUp
ctrl+ vPageDown
и т. д.


1
Альтернативу для кодов клавиш, которые могут работать на разных терминалах, можно найти в zprezto [ 1 ]. <kbd> Вверх </ kbd> есть $terminfo[kcuu1], <kbd> Вниз </ kbd> есть $terminfo[kcud1].
Джастин C

8

В этом сообщении за 2013 год мы рекомендуем несколько сочетаний клавиш, которые соответствуют всем словам перед курсором.

# Cycle through history based on characters already typed on the line
autoload -U up-line-or-beginning-search
autoload -U down-line-or-beginning-search
zle -N up-line-or-beginning-search
zle -N down-line-or-beginning-search
bindkey "$key[Up]" up-line-or-beginning-search
bindkey "$key[Down]" down-line-or-beginning-search

(В более ранней версии этого ответа я использовал, $terminfoкак рекомендовано в одном из комментариев к сообщению в блоге. Некоторые значения terminfo перечислены здесь .)


1
zsh также предоставляет эти более дружественные псевдонимы (по крайней мере, в пакете ubuntu) /etc/zsh/zshrc, например $key[Up].
zzxyz

При использовании $terminfoвам необходимо изменить режимы терминала. Смотрите здесь .
Том Хейл,

Я отредактировал ответ, чтобы использовать $key[]вместо $terminfo[]. Я надеюсь, что это хорошо работает для читателей!
Joeytwiddle

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.