it-swarm-pt.tech

fazer meu prompt de exibição do zsh no modo vi

Eu uso bindkey -v (para bash-ers set -o vi Acho que funciona no modo zsh também) ou vi (m). mas me incomoda que eu não tenha nenhuma dica visual para me dizer se estou no modo de inserção ou modo de comando. Alguém sabe como posso fazer meu prompt exibir o modo?

48
xenoterracide

Eu encontrei this via SU . Aqui está o exemplo básico, embora eu ainda o esteja personalizando:

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

Eu explicaria, exceto que eu realmente não entendo ainda

25
xenoterracide

Você já encontrou zle-keymap-select, Que é executado sempre que o modo muda. Você pode usá-lo para definir outro indicador visual que não seja o Prompt, dependendo do suporte do seu terminal (e do seu gosto no visor do indicador de modo, é claro).

Existe um padrão recurso terminfo para alterar a forma do cursor. No entanto, alguns terminais exibem o mesmo cursor nos dois modos. A noção do Xterm de um cursor menos visível é fazê-lo piscar (e isso deve ser ativado com o argumento da linha de comando -bc Ou com o recurso cursorBlink).

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

Em alguns terminais, você também pode alterar a cor do cursor com print -n '\e]12;pink\a' (Por nome da cor) ou print -n '\e]12;#abcdef\a' (Por especificação RGB). Essas seqüências são descritas na documentação do xterm, no arquivo ctlseqs ; os emuladores de terminal modernos normalmente imitam o xterm, embora possam não suportar todos os seus recursos.

18

Para as pessoas com problemas ao usar o prompt de redefinição com prompts de várias linhas, isso funcionou para mim: http://zeitlens.com/posts/2014-06-29-howto-zsh-vi-style.html Em combinação com https://stackoverflow.com/questions/3622943/zsh-vi-mode-status-line Acabei fazendo:

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

Isto é o que eu uso para alterar o cursor entre as formas 'Block' e 'Beam' no zsh:

(Testado com Cupim, gnome-terminal e mate-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

Outra solução para alterar a forma do cursor entre o feixe I e o bloco (para sublinhado, use \033[4 q). Adicione isso ao seu ~/.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

Modificado de https://bbs.archlinux.org/viewtopic.php?id=95078 . Testado no terminal gnome 3.22.


Atualizar

Ainda outra solução para alterar as formas do cursor pode ser encontrada aqui . Aparentemente, este funciona para o iTerm2, que não tenho como testar, mas adicioná-lo aqui caso seja útil para outra pessoa. A adição final ao seu ~/.zshrc seria

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

você pode tentar VimMode

5
Hemant

Aqui está mais uma versão, baseada em post de Sebastian Blask . O objetivo era que fosse o menos intrusivo possível, pois todas as outras soluções que encontrei usavam linhas extras, status à direita ou caracteres adicionados.

Isso simplesmente muda a cor de $ de branco para vermelho quando o modo normal está ativado. Edite o prompt ao seu gosto

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

Atualmente, estou usando o Zsh com o tema Bullet Train . Seguindo o exemplo dado por resposta de Sebastian Blask , acabei com o código abaixo

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

Isso mudará apenas o padrão $ para as letras [~ # ~] n [~ # ~] para o modo normal e [~ # ~] i [~ # ~] para inserir o modo.

Esta imagem é um exemplo quando, no modo normal, pressiono Ctrl+C:

enter image description here

3
Luciano Almeida

Uma versão para oh-my-zsh Comercial

Existe um plugin para oh-my-zsh chamado vi-mode que pode ser encontrado aqui:

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

Eu uso o Antigen para gerenciar meus plugins, por isso é tão simples quanto adicionar isso ao meu .zshrc:

antigen bundle vi-mode
2
Jonathan Landrum

O plug-in zsh-vim-mode é capaz de mostrar um indicador para os modos de inserção, comando, pesquisa, substituição e visual. Ele usa a técnica básica de outras respostas para conectar-se aos vários ganchos do ZLE (zle-keymap-select, zle-isearch-update, etc.). Verifica [[ $ZLE_STATE = *overwrite* ]] para o modo de substituição. Verifica $REGION_ACTIVE para identificar o modo visual.

A lógica é complicada por algumas peculiaridades de como o ZSH dispara eventos ao sair do modo isearch.

Outro recurso interessante do módulo é a capacidade de alterar a forma e a cor do cursor com base no modo. Por exemplo, você pode usar uma barra vertical no modo INSERT e um sublinhado piscando no modo SEARCH.

1
Tim Smith