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

57

No vim, quando eu bato ESC para retornar ao modo de comando, o cursor move um caractere para a esquerda. Isso não é o que eu esperaria, ocasionalmente eu imediatamente acertei l para voltar àquele ponto, talvez para deletar um personagem.

Existe algum motivo para esse comportamento? Isso é conveniente para um padrão de uso que estou perdendo? Eu sou novo no vim.

    
por Eric Wilson 15.04.2011 / 21:33

5 respostas

40

No modo de inserção, o cursor está entre os 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 propósito). Isso é um tanto incomum: a maioria dos editores sempre coloca o cursor entre os caracteres e tem a maioria dos comandos atuando no caracter após (não, estritamente falando, sob ) o cursor. Isso talvez se deva em parte ao fato de que, antes das GUIs, os terminais de texto sempre mostravam o cursor em um caractere (sublinhado ou em bloco, talvez piscando). Essa abstração falha no modo de inserção porque isso requer mais uma posição (posts vs cercas).

Alternar entre modos tem que mover o cursor por meio-caractere, por assim dizer. O comando i se move para a esquerda, para colocar o cursor antes do caractere que acabou. O comando a 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, ele será movido para a direita).

Suponho que o tipo de comportamento Esc faz sentido. Muitas vezes, você está digitando no final da linha, e lá Esc só pode ir para a esquerda. Então, o comportamento geral é o comportamento mais comum.

Pense no caractere sob o cursor como o último caractere interessante e no comando de inserção como a . Você pode repetir a Esc sem mover o cursor, exceto que você será atingido em uma posição à direita se você começar no início de uma linha não vazia.

    
por 15.04.2011 / 22:13
20

Visualmente, faz mais sentido no gvim:

Ao editar, o cursor fica entre os caracteres:

Quando estiver no modo normal, ele estará no topo do último caractere:

Por isso, não retorna um caractere, apenas entre entre r e s estar em r

    
por 10.06.2011 / 15:24
15

Esse comportamento é editável como respondido aqui , mas pare e pense sobre o que está acontecendo por um segundo. Quando você está no modo de inserção, você não está realmente sobre um personagem, mas entre eles. Quando você insere alguma coisa, o cursor pula 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, então queria fazer algo para ela. Acertar Esc colocaria 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 movendo-se como se estivesse no modo normal e depois alternando. Nesse caso, o cursor parece voltar um caractere, mas se você pensa assim, 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?

    
por 15.04.2011 / 21:39
5

Digite Alt + L para retornar ao modo de comando.

Não requer nenhum remapeamento ou alteração de configuração do vim. Isso funciona porque na maioria dos emuladores de terminal Alt + CHAVE envia um Esc seguido por KEY (no xterm você pode precisar para adicionar uma linha Xterm*metaSendsEscape: true no seu arquivo ~ / .Xdefaults). Esse comportamento permite que você "crie" outras combinações de modo de inserção que funcionam diretamente na caixa - como Alt + S para Backspace . p>

A propósito, ter o cursor no topo do personagem que você acabou de escrever pode ser muito inconveniente. Por exemplo, Esc d w não irá apagar a palavra após o texto que acabou de inserir.

    
por 06.08.2014 / 14:41
4

Aqui está 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])
    
por 12.06.2013 / 00:00

Tags