24

Хорошо, так что я наконец-то внес большие изменения. В моем .zshenv я изменил свой редактор:

export EDITOR=vim

У меня есть пара вопросов, которые настолько незначительны, что я не хотел задавать для них отдельные вопросы. Вот они:

  1. Как заставить zsh различать режим вставки и командный режим, как в vim? Предпочтительно, это изменит курсор с подчеркивания на блок, как в vim, но отображение текста внизу также будет работать.

  2. Как мне заставить его вести себя как vim? Например, я бы предпочел, чтобы он был в командном режиме по умолчанию и не выходил из него после одной команды.

4 ответа4

25

1. ) (см. Http://zshwiki.org/home/examples/zlewidgets и http://pthree.org/2009/03/28/add-vim-editing-mode-to-your-zsh-prompt/ ):

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

Куда:

  • "RPS" означает "правую строку приглашения" и определяет приглашение, появляющееся в правой части терминала, а синтаксис $ {variable/pattern/replace} является синтаксисом "раскрытия параметра", см. Http://mywiki .wooledge.org/BashSheet # Parameter_Operations.

  • 'zle -N' вызывает привязку определяемых пользователем виджетов 'zle-line-init' и 'zle-keymap-select' (к функциям оболочки с одинаковыми именами), так что они будут вызываться при инициализации редактора строк и раскладка клавиш изменяется соответственно, см .: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#SEC125.

2.) Я подозреваю, что для этого вам нужно написать еще один zsh-виджет, вдохновившись первой из двух ссылок на первую проблему.

20

Решение akira имеет следующую проблему при использовании многострочных приглашений: при переходе из режима ins в режим cmd перерисовка подсказки приводит к удалению нескольких строк из предыдущего вывода (а новое приглашение отображается несколькими строками выше). Сколько строк зависит от того, сколько строк у вас в приглашении.

Чтобы справиться с этим, используйте zle-line-finish , не используя zle reset-prompt . Пример:

# perform parameter expansion/command substitution in prompt
setopt PROMPT_SUBST

vim_ins_mode="[INS]"
vim_cmd_mode="[CMD]"
vim_mode=$vim_ins_mode

function zle-keymap-select {
  vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
  zle reset-prompt
}
zle -N zle-keymap-select

function zle-line-finish {
  vim_mode=$vim_ins_mode
}
zle -N zle-line-finish

И тогда вы можете добавить его в правую строку, например:

RPROMPT='${vim_mode}'

Это прямо из моего блога об этом:

5
zle-line-init() { zle -K vicmd; }
zle -N zle-line-init

эти две строки убедитесь, что он запускается в командном режиме

0

Ниже приведены настройки с измененным курсором и подсказка, отображающая, в каком режиме вы находитесь. Вы можете изменить DEFAULT_VI_MODE на viins или vicmd . Просто вставьте ниже в свежий .zshrc чтобы начать:

# Prefer vi shortcuts
bindkey -v
DEFAULT_VI_MODE=viins
KEYTIMEOUT=1

__set_cursor() {
    local style
    case $1 in
        reset) style=0;; # The terminal emulator's default
        blink-block) style=1;;
        block) style=2;;
        blink-underline) style=3;;
        underline) style=4;;
        blink-vertical-line) style=5;;
        vertical-line) style=6;;
    esac

    [ $style -ge 0 ] && print -n -- "\e[${style} q"
}

# Set your desired cursors here...
__set_vi_mode_cursor() {
    case $KEYMAP in
        vicmd)
          __set_cursor block
          ;;
        main|viins)
          __set_cursor vertical-line
          ;;
    esac
}

__get_vi_mode() {
    local mode
    case $KEYMAP in
        vicmd)
          mode=NORMAL
          ;;
        main|viins)
          mode=INSERT
          ;;
    esac
    print -n -- $mode
}

zle-keymap-select() {
    __set_vi_mode_cursor
    zle reset-prompt
}

zle-line-init() {
    zle -K $DEFAULT_VI_MODE
}

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

# Optional: allows you to open the in-progress command inside of $EDITOR
autoload -Uz edit-command-line
bindkey -M vicmd 'v' edit-command-line
zle -N edit-command-line

# PROMPT_SUBST enables functions and variables to re-run everytime the prompt
# is rendered
setopt PROMPT_SUBST

# Single quotes are important so that function is not run immediately and saved
# in the variable
RPROMPT='$(__get_vi_mode)'

Примечание: я проверял это только в Terminal.app (2.7.3) на MacOS (10.12.6) с zsh (5.3.1). Кроме того, если вы когда-нибудь добавите edit-command-line то режим также будет настроен правильно.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .