Como voltar à posição do cursor antes de entrar no modo de inserção?

7

Estou tentando configurar mapeamentos de modo normal para facilitar a adição de espaço em branco ao redor do cursor:

<C-h>adicionará um espaço à direita do cursor;
<C-j>adicionará uma nova linha abaixo;
<C-k>adicionará uma nova linha acima;
<C-l>adicionará um espaço à direita do cursor; e
<C-Enter>adicionará uma nova linha na posição atual do cursor.

Também quero que a posição do cursor não se mova durante o comando. Para esquerda, direita e nova linha, isso é simples:

nnoremap <C-h> i <Esc>l
nnoremap <C-l> a <Esc>h
nnoremap <C-^M> i<CR><Esc><Backspace>

mas para acima e abaixo, os comandos correspondentes

nnoremap <C-j> o <Esc>k
nnoremap <C-k> O <Esc>j

vai me colocar de volta na linha certa, mas não na mesma coluna em que eu estava antes.

Existe alguma maneira de retornar à posição do cursor em que eu estava antes de entrar no modo de inserção? Meu melhor Google-fu trouxe apenas referências ao ''& double-backtick (não consigo descobrir como formatar a marcação lá) e :jumps/ <C-O>& <C-I>, nenhum dos quais parece funcionar da maneira que eu gostaria.

Isso pode ser resolvido sem o Vimscript? Ele pode ser resolvido com o Vimscript?

Ryan Lue
fonte

Respostas:

7

Você pode definir uma marca local para onde está antes de abrir uma nova linha e voltar a essa marca depois.

Você pode escolher qualquer letra para a marca, digamos, por exemplo x:

nnoremap <C-k> mxO<esc>`x
nnoremap <C-j> mxo<esc>`x
  • mxdefine a marca em xque o cursor está
  • `x move o cursor de volta para a posição da marca x

Você também pode ver o que o tpope escreveu no seu plug - in intacto e colocar o seguinte código dentro do seu vimrc:

set nostartofline

function! s:BlankUp(count) abort
  put!=repeat(nr2char(10), a:count)
  ']+1
endfunction

function! s:BlankDown(count) abort
  put =repeat(nr2char(10), a:count)
  '[-1
endfunction

nnoremap <c-k> :<c-u>call <SID>BlankUp(v:count1)<cr>
nnoremap <c-j> :<c-u>call <SID>BlankDown(v:count1)<cr>

A vantagem desta solução em relação à anterior é que ela aceita uma contagem e não altera nenhuma das suas marcas.
Por exemplo, para inserir 2 linhas acima da atual, pressione 2<C-k>3 linhas abaixo 3<C-j>.

PS: para escrever um backtick duplo no seu post, use backticks triplos antes e depois (e coloque espaços antes e depois do backtick duplo): ``

Editar
Acabei de notar que, no caso da 2ª solução, se você deseja que o cursor volte para a mesma coluna em que estava antes de colar uma nova linha, é necessário desativar a opção 'startofline':set nostartofline

Quando esta opção está desactivada, o número da coluna do cursor permanece o mesmo depois de usar vários comandos, como <C-d>, gg, dd, >>, :bnext, :25.
Veja :help 'startofline'para mais informações.

saginaw
fonte
6

Não há necessidade de vimscript aqui, os mapeamentos abaixo fazem exatamente o que você pede:

nnoremap <C-j> m`o<Esc>``
nnoremap <C-k> m`O<Esc>``
  • m` é usado para definir a "marca de contexto anterior",
  • o<Esc> faz o que você espera,
  • `` volta à marca de contexto anterior.
romainl
fonte
Observe também que você também pode usar m'e em ''vez de m`e``
EvergreenTree
2
@ EververreenTree, ''não vai pular para a coluna da direita, apenas para a linha da direita.
Romainl
Ah, eu não percebi isso.
EvergreenTree