it-swarm-ko.tech

vi 모드에서 내 zsh 프롬프트 표시 모드 만들기

나는 사용한다 bindkey -v (bash-ers의 경우 set -o vi zsh 또는 vi (m) 모드에서도 작동한다고 생각합니다. 그러나 삽입 모드인지 명령 모드인지 여부를 알려주는 시각적 신호가 없다는 것이 버그입니다. 내 프롬프트가 모드를 표시하는 방법을 아는 사람이 있습니까?

48
xenoterracide

this via SU 을 (를) 찾았습니다. 다음은 기본 예제이지만 여전히 직접 사용자 정의하고 있습니다.

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

나는 아직 그것을 이해하지 못하는 것을 제외하고 그것을 설명 할 것이다.

25
xenoterracide

이미 zle-keymap-select 모드가 변경 될 때마다 실행됩니다. 터미널이 지원하는 것 (및 모드 표시기 표시의 취향)에 따라 프롬프트 이외의 다른 시각적 표시기를 설정할 수 있습니다.

커서 모양을 변경하는 표준 terminfo capability 가 있습니다. 그러나 일부 터미널은 두 모드에서 동일한 커서를 표시합니다. 덜 눈에 띄는 커서에 대한 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을 에뮬레이트하지만 모든 기능을 지원하지는 않습니다.

여러 줄 프롬프트에서 reset-prompt를 사용하는 데 문제가있는 사람들을 위해 다음과 같이 작동했습니다. http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.htmlhttps://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
9
Sebastian Blask

이것은 zsh에서 'Block'과 'Beam'모양 사이에서 커서를 변경하는 데 사용하는 것입니다.

(-Termite, gnome-terminalmate-terminal)

# 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'
}
6
Rotareti

I- 빔과 블록 사이에서 커서 모양을 변경하는 또 다른 솔루션입니다 (밑줄의 경우 \033[4 q 사용). 이것을 ~/.zshrc에 추가하십시오.

zle-keymap-select () {
if [ $KEYMAP = vicmd ]; then
    printf "\033[2 q"
else
    printf "\033[6 q"
fi
}
zle -N zle-keymap-select
zle-line-init () {
zle -K viins
printf "\033[6 q"
}
zle -N zle-line-init
bindkey -v

https://bbs.archlinux.org/viewtopic.php?id=95078 에서 수정되었습니다. 그놈 터미널에서 테스트 3.22.


최신 정보

커서 모양 변경에 대한 또 다른 해결책 여기에서 찾을 수 있음 . 이것은 분명히 iTerm2에서 작동하며 테스트 할 수단이 없지만 다른 사람에게 유용 할 수 있도록 여기에 추가 할 수 있습니다. ~/.zshrc의 마지막 추가는

function zle-keymap-select zle-line-init
{
    # change cursor shape in iTerm2
    case $KEYMAP in
        vicmd)      print -n -- "\E]50;CursorShape=0\C-G";;  # block cursor
        viins|main) print -n -- "\E]50;CursorShape=1\C-G";;  # line cursor
    esac

    zle reset-Prompt
    zle -R
}

function zle-line-finish
{
    print -n -- "\E]50;CursorShape=0\C-G"  # block cursor
}

zle -N zle-line-init
zle -N zle-line-finish
zle -N zle-keymap-select
6
joelostblom

당신은 시도 할 수 있습니다 VimMode

5
Hemant

Sebastian Blask 's post 를 기반으로 한 또 다른 버전이 있습니다. 내가 찾을 수있는 다른 모든 솔루션은 여분의 줄, 오른쪽 상태 또는 추가 문자를 사용했기 때문에 가능한 한 방해가되지 않도록 의도되었습니다.

이것은 단순히 $ 일반 모드가 활성화 된 경우 흰색에서 빨간색으로. 원하는대로 프롬프트 편집

bindkey -v
function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      Prompt=$'%{\e[0;32m%}%~%{\e[0m%} %{\e[0;31m%}$%{\e[0m%} ' ;;
        (main|viins) Prompt=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
        (*)          Prompt=$'%{\e[0;32m%}%~%{\e[0m%} $ ' ;;
    esac
    zle reset-Prompt
}

zle -N zle-line-init
zle -N zle-keymap-select
3
sealj553

현재 Zsh를 Bullet Train 테마로 사용하고 있습니다. Sebastian Blask 's answer 에 의해 주어진 예에 따라, 나는 다음 코드로 끝났습니다.

bindkey -v
KEYTIMEOUT=1

function zle-line-init zle-keymap-select {
    case ${KEYMAP} in
        (vicmd)      BULLETTRAIN_Prompt_CHAR="N" ;;
        (main|viins) BULLETTRAIN_Prompt_CHAR="I" ;;
        (*)          BULLETTRAIN_Prompt_CHAR="I" ;;
    esac
    zle reset-Prompt
}

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

이것은 기본값 $ 을 문자 [~ # ~] n [~ # ~] 를 일반 모드로, [~ # ~] i [~ # ~] 를 삽입 모드로 설정합니다.

이 이미지는 일반 모드에서 누를 때의 예입니다 Ctrl+C:

enter image description here

3
Luciano Almeida

oh-my-zsh 사용자를위한 버전

여기에서 찾을 수있는 oh-my-zsh라는 vi-mode 용 플러그인이 있습니다.

robbyrussell/oh-my-zsh/plugins/vi-mode

Antigen을 사용하여 플러그인을 관리하므로이를 .zshrc에 추가하는 것만 큼 간단했습니다.

antigen bundle vi-mode
2
Jonathan Landrum

zsh-vim-mode 플러그인은 삽입, 명령, 검색, 바꾸기 및 시각적 모드에 대한 표시기를 표시 할 수 있습니다. 다른 답변의 기본 기술을 사용하여 다양한 ZLE 후크 (zle-keymap-select, zle-isearch-update 등)에 연결합니다. [[ $ZLE_STATE = *overwrite* ]]에서 교체 모드를 확인합니다. 시각적 모드를 식별하기 위해 $REGION_ACTIVE를 확인합니다.

Isearch 모드를 떠날 때 ZSH가 이벤트를 발생시키는 방법에 대한 몇 가지 단점으로 인해 논리가 복잡합니다.

모듈의 또 다른 멋진 기능은 모드에 따라 커서 모양과 색상을 변경하는 기능입니다. 예를 들어, INSERT 모드에서 세로 막대를 사용하고 SEARCH 모드에서 깜박이는 밑줄을 사용할 수 있습니다.

1
Tim Smith