сделать так, чтобы мой zsh prompt показывал режим в vi режиме

сделать так, чтобы мой zsh prompt показывал режим в vi режиме

Я использую bindkey -v(для bash-еров, set -o viя думаю, это работает и в zsh) или vi(m) режим. но меня раздражает, что у меня нет визуальной подсказки, которая бы показывала, нахожусь ли я в режиме вставки или в командном режиме. Кто-нибудь знает, как заставить мою подсказку отображать режим?

решение1

я нашелэтотс помощьюСУ. Вот базовый пример, хотя я все еще настраиваю его под себя:

function zle-line-init zle-keymap-select {
    RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}"
    RPS2=$RPS1
    zle reset-prompt
}

zle -N zle-line-init
zle -N zle-keymap-select

Я бы объяснил, но я пока не совсем понимаю.

решение2

Вы уже нашли, zle-keymap-selectкоторый выполняется при изменении режима. Вы можете использовать его для установки какого-либо другого визуального индикатора, нежели приглашение, в зависимости от того, что поддерживает ваш терминал (и вашего вкуса в отображении индикатора режима, конечно).

Есть стандартвозможность terminfoдля изменения формы курсора. Однако некоторые терминалы отображают один и тот же курсор в обоих режимах. Понятие Xterm о менее заметном курсоре заключается в том, чтобы заставить его мигать (и это должно быть включено с помощью -bcаргумента командной строки или cursorBlinkресурса).

zle-keymap-select () {
  case $KEYMAP in
    vicmd) print -rn -- $terminfo[cvvis];; # block cursor
    viins|main) print -rn -- $terminfo[cnorm];; # less visible cursor
  esac
}

С некоторыми терминалами вы также можете изменить цвет курсора с помощью print -n '\e]12;pink\a'(по названию цвета) или print -n '\e]12;#abcdef\a'(по спецификации RGB). Эти последовательности описаны в документации xterm, вctlseqsфайл; современные эмуляторы терминала обычно эмулируют xterm, хотя они могут не поддерживать все его функции.

решение3

Для людей, испытывающих проблемы с использованием функции сброса-подсказки с многострочными подсказками в сочетании сhttps://stackoverflow.com/questions/3622943/zsh-vi-mode-status-lineВ итоге я сделал следующее:

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]

function insert-mode () { echo "-- INSERT --" }
function normal-mode () { echo "-- NORMAL --" }

precmd () {
    # yes, I actually like to have a new line, then some stuff and then 
    # the input line
    print -rP "
[%D{%a, %d %b %Y, %H:%M:%S}] %n %{$fg[blue]%}%m%{$reset_color%}"

    # this is required for initial prompt and a problem I had with Ctrl+C or
    # Enter when in normal mode (a new line would come up in insert mode,
    # but normal mode would be indicated)
    PS1="%{$terminfo_down_sc$(insert-mode)$terminfo[rc]%}%~ $ "
}
function set-prompt () {
    case ${KEYMAP} in
      (vicmd)      VI_MODE="$(normal-mode)" ;;
      (main|viins) VI_MODE="$(insert-mode)" ;;
      (*)          VI_MODE="$(insert-mode)" ;;
    esac
    PS1="%{$terminfo_down_sc$VI_MODE$terminfo[rc]%}%~ $ "
}

function zle-line-init zle-keymap-select {
    set-prompt
    zle reset-prompt
}
preexec () { print -rn -- $terminfo[el]; }

zle -N zle-line-init
zle -N zle-keymap-select

решение4

Вот что я использую для изменения формы курсора между «Блоком» и «Лучом» в zsh:

(Проверено сТермит,gnome-терминалимат-терминал)

# vim mode config
# ---------------

# Activate vim mode.
bindkey -v

# Remove mode switching delay.
KEYTIMEOUT=5

# Change cursor shape for different vi modes.
function zle-keymap-select {
  if [[ ${KEYMAP} == vicmd ]] ||
     [[ $1 = 'block' ]]; then
    echo -ne '\e[1 q'

  elif [[ ${KEYMAP} == main ]] ||
       [[ ${KEYMAP} == viins ]] ||
       [[ ${KEYMAP} = '' ]] ||
       [[ $1 = 'beam' ]]; then
    echo -ne '\e[5 q'
  fi
}
zle -N zle-keymap-select

# Use beam shape cursor on startup.
echo -ne '\e[5 q'

# Use beam shape cursor for each new prompt.
preexec() {
   echo -ne '\e[5 q'
}

Связанный контент