Por que `ESC` move o cursor de volta no vim?

62

No vim, quando pressiono ESCpara retornar ao modo de comando, o cursor move um caractere para a esquerda. Isso não é o que eu esperava, ocasionalmente eu batia imediatamente lpara voltar para aquele local, talvez para excluir um personagem.

Existe uma razão para esse comportamento? Isso é conveniente para um padrão de uso que estou ausente?

Eric Wilson
fonte
11
Eu nem percebi isso até agora ... e uso o vim todos os dias. Não faço ideia do porquê, mas estou interessado em ouvir as respostas.
Gabe.
5
ao voltar ao modo de inserção, você pode pressionar 'a' para acrescentar em vez de 'i' para inserir. Você retornará à posição em que estava antes de pressionar escape.
penguin359

Respostas:

40

No modo de inserção, o cursor está entre caracteres ou antes do primeiro ou após o último caractere. No modo normal, o cursor está sobre um caractere (novas linhas não são caracteres para esse fim). Isso é um tanto incomum: a maioria dos editores sempre coloca o cursor entre os caracteres e faz com que a maioria dos comandos atue no caractere depois (não, estritamente falando, abaixo ) do cursor. Talvez isso se deva em parte ao fato de que antes das GUIs, os terminais de texto sempre mostravam o cursor em um caractere (sublinhado ou bloco, talvez piscando). Essa abstração falha no modo de inserção porque isso requer mais uma posição (postagens versus cercas).

A alternância entre os modos deve mover o cursor por meio caractere, por assim dizer. O icomando se move para a esquerda, para colocar o cursor antes do caractere que acabou. O acomando se move para a direita. Sair do modo de inserção (pressionando Esc) move o cursor para a esquerda, se possível (se estiver no início da linha, é movido para a direita).

Suponho que o Esccomportamento meio que faça sentido. Muitas vezes, você está digitando no final da linha e Escsó pode ir para a esquerda. Portanto, o comportamento geral é o comportamento mais comum.

Pense no caractere abaixo do cursor como o último caractere interessante e no comando insert como a. Você pode repetir a Escsem mover o cursor, exceto que você encontrará uma posição correta se iniciar no início de uma linha não vazia.

Gilles 'SO- parar de ser mau'
fonte
21

Visualmente, faz mais sentido no gvim:

Ao editar, o cursor está entre os caracteres:
insira a descrição da imagem aqui

Quando no modo normal, está no topo do último caractere:
insira a descrição da imagem aqui

Por isso, não realmente voltar um personagem, só de estar entre r e spara estar em r

Martin Ueding
fonte
11
Bela foto. Para ser honesto, eu estou no acampamento, que diz que o personagem mdeve permanecer destacou ao voltar ao modo normal ...
Steven Lu
Opa links de fotos agora estão mortos.
Steven Lu
11
links de imagem agora mortos.
Steven Lu
11
Sim, hospedar manualmente suas imagens é mais trabalhoso e menos confiável do que apenas usar a ferramenta no editor de descontos neste site.
Steven Lu
11
Existe tudo de bom com eles de novo? É "cursor" o que digitou e seu texto menciona "j"
poige
15

Esse comportamento é editável conforme a resposta aqui , mas pare e pense no que está acontecendo por um segundo. Quando você está no modo de inserção, você não está realmente sobre um caractere, mas entre eles. Quando você insere algo, o cursor salta para o final do que você inseriu, para que a próxima coisa inserida seja depois disso. Agora pense se você acabou de digitar uma carta e queria fazer alguma coisa. Pressionar Esccolocaria o cursor de seleção diretamente sobre o último caractere que você inseriu. Se não fizesse isso, seria realmente um pouco estranho.

A situação em que você provavelmente está pensando é quando você está no modo de inserção se movendo como se estivesse no modo normal e depois muda. Nesse caso, o cursor parece retornar um caractere, mas se você pensar dessa maneira, isso mostra que você estava no modo de inserção e a última coisa que você fez não foi inserir. Talvez você deva passar mais tempo no modo normal?

Caleb
fonte
15
Isso não faz sentido para mim. Como você explica o comportamento de retroceder ie ESCpressionar repetidamente as teclas?
Warren Young.
4
Entrar no modo de inserção, não inserir nada e deixá-lo não é um teste justo. Por que você estaria no modo de inserção se não inseriu algo? Se você inserir algo, voltar ao modo normal deixa o caractere que você inseriu selecionado. Muito intuitivo.
Caleb
4
Não se trata de "justo", trata-se de poder explicativo. Se sua teoria da operação não explica todo o comportamento, é incompleta ou o comportamento do vi é inconsistente. Prefiro acreditar que o vi é perfeito em todos os sentidos e, portanto, consistente. :)
Warren Young
9
@Warren O comportamento de "andar para trás" iseguido de ESCé uma função ie é totalmente independente de ESC; especificamente, quando você pressiona, iestá solicitando ao vim que insira um caractere, o que, por definição, significa "insira um caractere anterior àquele em que eu estou", ao contrário do aque é "acrescente um caractere depois deste".
Kromey
3
Em geral, após cada alteração, quando deixo essa alteração, eu concluo essa alteração, e a próxima coisa que gostaria de fazer provavelmente envolverá uma alteração diferente. Assim, para mim, ao sair do modo de inserção (não importa como eu o inseri), geralmente prefiro que o cursor esteja no próximo caractere, para que eu esteja pronto para a próxima alteração, em vez de estar pronto para alterar o que acabei de inserir. inserido.
Kyle Strand
6

Digite Alt+ Lpara retornar ao modo de comando.

Não requer nenhuma alteração de remapeamento ou configuração do vim. Funciona porque na maioria dos emuladores de terminal Alt+ KEYenvia um Escseguido por KEY(no xterm, você pode precisar adicionar uma Xterm*metaSendsEscape: truelinha ao seu arquivo ~ / .Xdefaults). Esse comportamento permite que você "crie" outras combinações de modos de inserção que funcionem diretamente da caixa - como Alt+ Spara Backspace.

A propósito, colocar o cursor em cima do personagem que você acabou de escrever pode ser muito inconveniente. Por exemplo, Escdwnão excluirá a palavra após o texto que você acabou de inserir.

user79932
fonte
O inconveniente que você refere pode ser evitado digitando sempre um espaço no modo de inserção antes da fuga. Em seguida, o cursor que sai do modo de inserção é colocado sobre o espaço e você pode digitar Esc d epara excluir a palavra na frente. Voltei ao comportamento padrão porque senti que ele havia alterado outros comportamentos já codificados na minha cabeça.
mljrg
4

Aqui está a minha solução.

É uma versão mais concisa da solução oferecida na página da wikia sobre isso .

au InsertLeave * call cursor([getpos('.')[1], getpos('.')[2]+1])
Steven Lu
fonte
+1 aqui também, por citar a página da wiki, mesmo que o usuário não estivesse realmente pedindo uma maneira de mudar esse comportamento.
Kyle Strand
Você observará que, se você se aprofundar o suficiente no Vim, muitos plugins dependem do comportamento padrão (pouco intuitivo); portanto, se você ver alguma coisa comer aleatoriamente ou alterar um único caractere, isso pode ser causado. Eu não uso esse comando automático; funciona bem, no entanto.
Steven Lu