Como eu mudo o cursor do Vim no modo Insert / Normal?

106

Gostaria de saber, se possível, como mudar o cursor no Vim (em cor, forma, etc.) dependendo do modo em que você está.

Estou constantemente esquecendo que não estou no modo de inserção e começo a digitar o código, o que resulta em todo tipo de coisa maluca acontecendo. Seria útil se houvesse algum tipo de indicação visual no cursor.

Lanrat
fonte
19
Eu sugiro que você aprenda uma regra: parar de digitar => sair do modo de inserção. Assim, você nunca observará uma situação em que se esqueceu de que não está no modo de inserção.
ZyX
2
@ZyX exceto quando você se esquece de sair do modo de inserção após ter parado de digitar: p
iniciado
3
@ZyX é uma boa regra e sempre fiz isso, mas os indicadores visuais ainda são importantes. A maconha é legal agora e eu esqueço o que estou fazendo o tempo todo.
felwithe

Respostas:

107

Uma opção popular para indicar a mudança de e para o modo de inserção é alternar a cursorlineopção, que é responsável por se a linha da tela atual é destacada (consulte :help cursorline):

:autocmd InsertEnter,InsertLeave * set cul!

ou alternativamente,

:autocmd InsertEnter * set cul
:autocmd InsertLeave * set nocul

Modifique o CursorLinegrupo de realce para alterar o estilo da linha do cursor de acordo com sua preferência (consulte :help :highlighte :help highlight-groups).

ib.
fonte
5
Também defini cul para realçar bg em vez de sublinhado padrão: hi CursorLine cterm = NONE ctermbg = black
Nikita Prokopov
Existe uma razão para isso não funcionar no vim do cygwin? Estou no editor e inseri os dois conjuntos de linhas e não consegui definir nenhum tipo de destaque, além do destaque de coluna ou linha
inteira
@Tankor: A cursorlineopção não depende de nenhum recurso específico da plataforma; ele está disponível em qualquer instância do Vim compilada com o +syntaxrecurso (o que geralmente é o caso).
ib.
Claro, salve isso em seu ~ / .vimrc para permanência como zo:echo 'autocmd InsertEnter,InsertLeave * set cul!' >>~/.vimrc
alquimia
75

O seguinte funciona em xterm, urxvt e outros emuladores de terminal no Linux; iTerm2 no macOS; Git Bash com ConEmu no Windows; e mais (ver comentários):

let &t_SI = "\e[6 q"
let &t_EI = "\e[2 q"

" Optionally reset the cursor on start:
augroup myCmds
au!
autocmd VimEnter * silent !echo -ne "\e[2 q"
augroup END

Outras opções (substitua o número depois \e[):

Ps = 0  -> blinking block.
Ps = 1  -> blinking block (default).
Ps = 2  -> steady block.
Ps = 3  -> blinking underline.
Ps = 4  -> steady underline.
Ps = 5  -> blinking bar (xterm).
Ps = 6  -> steady bar (xterm).

Quando você usa o tmux , é importante usá-lo assim (sem o \<Esc>Ptmux;escape). tmux manterá o controle da forma correta do cursor quando você alternar entre janelas / painéis.

Se não funcionar para você, tente configurar TERM=xterm-256colorantes de iniciar o tmux ou adicione ao seu .tmux.conf( obrigado @Steven Lu ):

set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'
Laktak
fonte
2
Funciona muito bem no Alacritty agora
Steven Lu
Funciona perfeitamente no terminal xfce4
korst1k
@Charles Sobre por que não funciona em massa, veja isto: superuser.com/questions/304318/…
WesternGun
1
Minha atualização: finalmente trabalhando set -ga terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'em minha configuração tmux. Aparentemente, se você usar setpara terminal-overridessem -a, ele substituirá a configuração, que já está lá por padrão.
Steven Lu
1
a solução tem um atraso significativo de mudança de forma do modo de inserção para o modo normal no terminal simples (st suckless)
daGo
16

Se você estiver usando tmux e iTerm2 no macOS ,
o seguinte muda o cursor de um bloco para um cursor e destaca a linha atual

if exists('$TMUX')
  let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
  let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\"
else
  let &t_SI = "\<Esc>]50;CursorShape=1\x7"
  let &t_EI = "\<Esc>]50;CursorShape=0\x7"
endif
:autocmd InsertEnter * set cul
:autocmd InsertLeave * set nocul

crédito: https://gist.github.com/andyfowler/1195581

Intenções
fonte
1
Observe que isso é específico do iTerm . Uma vez que os padrões também funcionam, mas também funcionam em todos os outros terminais de suporte, esta provavelmente é a resposta errada. Olhe aqui -> stackoverflow.com/a/42118416/340947
Steven Lu
@StevenLu na verdade, aquele em sua resposta sugerida não funcionou para o iTerm2 (Mac), enquanto este funcionou. Este material é mais complicado do que você imagina.
CS de
Este cursor é definitivamente uma das coisas mais complicadas que existem. Acabei de perceber que nem acho que tenho uma configuração adequada, já que o tmux não parece estar realizando o rastreamento do estado do cursor, o que algumas respostas indicam ser uma possibilidade. Fiquei muito feliz em fazer o vim lidar com a configuração do cursor em uma linha no modo de inserção.
Steven Lu
Eu descobri essas coisas. A solução é ajustar o tmux para tratá-lo adequadamente, e isso pode não ser óbvio. O que eu precisava fazer era garantir que minha configuração do tmux terminal-overridesestava apenas sendo anexada, para que não prejudicasse a ,*:Ss=\E[%p1%d q:Se=\E[2 qparte de terminal-overrides. então minha configuração fica assim set -sa terminal-overrides ",xterm-256color-italic:Tc"(para definir a ativação de cor de 24 bits sem atropelar os estilos de cursor Ss / Se.
Steven Lu
13

Para alterar a forma do cursor em diferentes modos, você pode adicionar o seguinte em seu .vimrcarquivo.

Para o Terminal GNOME (versão 2.26):

if has("autocmd")
  au InsertEnter * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
  au InsertLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape block"
  au VimLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
endif

Se você usa mais de um perfil no Terminal GNOME, pode ser necessário adaptá-lo aos seus perfis.

Para Konsole no KDE4:

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

Isso funciona com várias guias e janelas.

Consulte também: “ Alterar a forma do cursor em modos diferentes ” no Wiki do Vim Tips .

IvanGL
fonte
13
Eu uso principalmente o vim no tmux em vez do ssh com putty. Existe uma opção mais universal?
lanrat de
Funcionou como um encanto. Obrigado.
Ernest
1
Alterar as configurações do gnome-terminal por meio de um comando gconftool-2 é uma ideia muito ruim. Isso não influencia apenas o terminal onde seu vim está sendo executado, mas também todas as outras guias atuais e futuras do gnome-terminal do mesmo perfil.
egmont,
isso funciona para o konsole, obrigado. Mas um problema é que sair do modo de inserção está lento, não sei por quê
Hoang Tran
1
@HoangTran useset ttimeoutlen=0
Bananach
10

Você pode tentar o plug - in terminus vim :

No modo de inserção, a forma do cursor muda para uma barra vertical fina. No modo de substituição, ele muda para um sublinhado. Ao retornar ao modo normal, ele retorna ao formato de "bloco" padrão.

Tim Gabets
fonte
Esta parece ser a solução mais sensata. Deve haver um: definido para isso diretamente no VIM, padrão.
user12711
Requisitos: gnome-terminal ( wiki.gnome.org/Apps/Terminal ) e outros terminais que usam a biblioteca VTE ( github.com/GNOME/vte ): Parcialmente compatível (por exemplo, suporta alterações de forma de cursor, mas não relatório de foco). No meu caso (gnome-terminal 3.6.2) não funciona de todo.
daGo
8

Acho útil ter apenas o cursor piscando no modo Inserir e estático nos outros modos.

set guicursor+=n-v-c:blinkon0
user41365
fonte
2

Não tenho certeza se alguém está enfrentando um atraso após atingir o Esc tecla para voltar ao modo normal para mostrar o cursor de bloco, mas se estiver, também corrijo este jeito.

Na verdade, estou usando o iTerm2 e o Vim dentro do meu terminal no macOS. E ao entrar no modo de inserção, o cursor continua sendo um bloco e fica meio confuso quando você está no modo de inserção ou modo normal.

Eu queria mostrar uma linha fina como cursor quando no modo de inserção e voltar para bloquear quando no modo normal, como o MacVim faz. E para fazer isso é muito simples, basta adicionar isso ao meu .vimrcarquivo conforme descrito aqui :

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

insira a descrição da imagem aqui

Mas como você pode ver, houve um atraso ao pressionar ESCpara sair do modo de inserção de volta ao modo normal e mostrar o bloco como cursor novamente. Então, para consertar, encontrei o seguinte:

set ttimeout
set ttimeoutlen=1
set listchars=tab:>-,trail:~,extends:>,precedes:<,space:.
set ttyfast

E agora funciona muito bem, como você pode ver:

consertar o atraso voltando ao bloco como cursor

Espero que possa ajudar mais alguém! 👻

alexventuraio
fonte
1

Não acho que isso acrescente muito às respostas que outras pessoas já deram, mas eu queria de alguma forma resumir as coisas em um só lugar e também ter links para as referências relevantes.

É assim que o snippet relevante do meu se .vimrcparece:

    " Cursor appearance
    "
    " See also: [1]'ANSI Control Functions Summary', [2]DECSCUSR, [3]xterm+tmux
    "   entry in terminfo.src.
    " [1] https://www.vt100.net/docs/vt510-rm/chapter4.html
    " [2] https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
    " [3] https://raw.githubusercontent.com/mirror/ncurses/master/misc/terminfo.src
    "
    " On:
    " - entered insert mode
    let &t_SI = "^[[5 q^[]12;Magenta\007" " blinking bar (Ss) in magenta (Cs)
    " - entered replace mode
    let &t_SR = "^[[0 q^[]12;Red\007" " blinking block (Ss) in red (Cs)
    " - leaving insert/replace mode
    let &t_EI = "^[[2 q^[]112\007" " terminal power-on style (Se) and colour (Cr)

Nota: Os '^['caracteres são, na verdade, um ESC(sequência de escape) caractere de controle.

Zdzisław Śliwiński
fonte
0

Isso funciona corretamente no terminal xfce4:

adicione o seguinte script ao seu .vimrc

if has("autocmd")
  au InsertEnter * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_BLOCK/TERMINAL_CURSOR_SHAPE_IBEAM/' ~/.config/xfce4/terminal/terminalrc"                                                                                          
  au InsertLeave * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_IBEAM/TERMINAL_CURSOR_SHAPE_BLOCK/' ~/.config/xfce4/terminal/terminalrc"                                                                                          
  au VimLeave * silent execute "!sed -i.bak -e 's/TERMINAL_CURSOR_SHAPE_IBEAM/TERMINAL_CURSOR_SHAPE_BLOCK/' ~/.config/xfce4/terminal/terminalrc"  
endif

Breve: Como você sabe, o xfce4-terminal mantém as preferências em .config/xfce4/terminal/terminalrcarquivo. O script muda TERMINAL_CURSOR_SHAPE_BLOCKpara TERMINAL_CURSOR_SHAPE_IBEAMquando você está no modo de inserção e volta para bloquear quando você sai do modo de inserção ou vim. Sinta-se livre para mudar IBEAMpara qualquer coisa que você quer ( BLOCK, IBEAMe UNDERLINEdisponível).

Amirali
fonte
0

Se você estiver usando uma versão moderna do nvim e quiser fazer isso, pode evitar algumas dessas soluções alternativas sofisticadas listadas acima.

As configurações abaixo mudarão do cursor de bloco no modo normal, para o cursor de sublinhado em substituir para o cursor de linha em inserir.

# ~/.tmux.conf
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",*256col*:Tc"
set -ga terminal-overrides '*:Ss=\E[%p1%d q:Se=\E[ q',w

" ~/.vimrc
" Sets cursor styles
" Block in normal, line in insert, underline in replace
set guicursor=n-v-c-sm:block,i-ci-ve:ver25-Cursor,r-cr-o:hor20

Consegui fazer isso funcionar com as seguintes configurações extraídas dessas duas fontes.

tui-cursor-shape

guicursor

thrgamon
fonte
-2

Normalmente, tenho o modo vim atual no statusline, entre outras coisas. Se você busca simplicidade, pode definir apenas essas informações na linha de status .

No entanto, geralmente as coisas realmente malucas acontecem quando você tem o caps lock pressionado e está no modo de comando (já que hjkl agora são HJKL - apenas J e K são suficientes para fazer você puxar os cabelos quando não entende o que está acontecendo. :h Je :h Kpara ver o que quero dizer). Apenas tome cuidado com a tecla Caps Lock e você ficará bem na maior parte do tempo, IMO.

GmonC
fonte
46
Como isso responde à pergunta?
David Rivers
1
@DavidRivers É uma aplicação do problema XY onde o OP estava pedindo uma resolução para seu problema (não sabendo que estava no modo normal do vim e querendo que o cursor mudasse para indicar isso), mas acabou satisfeito com uma alternativa (e IMO não uma ótima) solução (melhorando sua linha de status com o estado)
Steven Lu