zsh의 vim 모드를 어떻게 사용자 정의합니까?


25

좋아, 마침내 나는 큰 변화를 만들었다. 내 .zshenv에서 EDITOR를 변경했습니다.

export EDITOR=vim

내가 가진 몇 가지 질문이 있는데, 그 질문들에 대해 별도의 질문을 시작하고 싶지 않았습니다. 여기 있습니다:

  1. vim에서와 같이 zsh가 삽입 모드와 명령 모드를 구별하도록하려면 어떻게해야합니까? vim과 같이 커서를 밑줄에서 블록으로 변경하는 것이 바람직하지만, 맨 아래에 텍스트를 표시해도 효과가 있습니다.

  2. vim처럼 작동하도록하려면 어떻게해야합니까? 예를 들어, 기본적으로 명령 모드에 있고 하나의 명령 후에 나가지 않습니다.


//, 명령 행 편집에 이상한 동작이 있었습니까? ~에서 Delete키를 누를 때 삽입 되는 캐릭터를 만났습니다 zsh. 여기에 대해 질문했습니다 : superuser.com/questions/997593/…
Nathan Basanese

답변:


25

1. ) ( http://zshwiki.org/home/examples/zlewidgetshttp://pthree.org/2009/03/28/add-vim-editing-mode-to-your-zsh-prompt/ 참조 ) :

기능 zle-line-init zle-keymap-select {
    RPS1 = "$ {$ {KEYMAP / vicmd /-NORMAL-} / (main | viins) /-INSERT-}"
    RPS2 = $ RPS1
    zle 재설정 프롬프트
}
zle -N zle-line-init
zle -N zle 키맵 선택

어디에:

2. ) 나는 그것을하기 위해 또 다른 zsh-widget을 작성해야한다고 생각합니다. 첫 번째 문제에 대한 두 링크 중 첫 번째 링크에서 영감을 얻으십시오.


22

여러 줄 프롬프트를 사용할 때 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}'

이것은 내 블로그 게시물에서 나온 것입니다.


이 답변은 많은 표를 얻어야합니다. 이 솔루션을 본 것은 처음이며 다른 사람들이 볼 수없는 곳에서 작동합니다. 나는 zle-line-init위젯으로 쓸데없는 시간을 보냈다 . Pawel이 제공 한 내용과 빙고에 맞게 변경되었습니다!
Colin R

감사! 여전히 100 % 방탄은 아닙니다. 때때로 이전 출력의 일부 라인이 삭제되는 상황이 발생하지만 거의 무시하지 않습니다.
Paweł Gościcki

1
RPROMPT2상태가 연속 라인에 표시되도록 설정해야합니다. 또한 이것을 사용할 때 setopt transient_rprompt이전에 승인 된 라인에 대한 모드가 표시되지 않도록 할 수 있습니다 .
qqx 2015 년

여전히 누락 된 한 가지 : emacs 모드 ( bindkey -e)로 다시 전환 하면 여전히 표시 [INS]됩니다.
Daniel

1
@cheflo이 설정의 현재 버전을 여기에서 확인할 수 있습니다 : github.com/pjg/dotfiles/blob/master/.zshrc#L518-L584- 아마도 도움이 될 것입니다
Paweł Gościcki

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

이 두 줄은 명령 모드에서 시작되는지 확인합니다.


어쨌든 삽입 모드에서하지 작업, zsh을 시작 하는가는
baldrs

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)'

참고 :이를 zsh (5.3.1)가있는 MacOS (10.12.6)의 Terminal.app (2.7.3)에서만 테스트했습니다. 또한 추가 edit-command-line하면 모드도 올바르게 설정됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.