Vim: Salte para a posição anterior do cursor, NÃO edite o ponto

Vim: Salte para a posição anterior do cursor, NÃO edite o ponto

Estou tentando escrever uma pequena macro para acrescentar um ; até o final da linha atual (A;), depois retorne à posição do cursor de onde saltei antes de executar a macro.

Co e Ci não são o que eu preciso, nem '' e ``, que operam em pontos de edição. Não há como fazer isso sem colocar um marcador?

Responder1

Se você concordar em criar uma função minúscula em vez de uma macro minúscula, eu proporia o seguinte:

function! AppendString(string)
  if getline('.') !~ a:string.'$'
    let original_cursor_position = getpos('.')
    exec("s/$/".a:string."/")
    call setpos('.', original_cursor_position)
  endif
endfunction

A posição do cursor é obtida usando getpos()e posteriormente recuperada com setpos().

Esta função pode anexar qualquer string desejada. Também verifica se a linha já possui a string desejada no final, nesse caso não faz nada.

Você pode definir mapas de teclado que usam esta função que são úteis para diferentes idiomas:

" in ftplugin/cpp.vim
nnoremap <silent> <LocalLeader>; :call AppendString(";")<CR>

ou

" in ftplugin/python.vim
nnoremap <silent> <LocalLeader>: :call AppendString(":")<CR>

Responder2

Se você usar baixo nível setpos()em vez de :substitute(que tem outros efeitos colaterais indesejados, como adicionar o padrão ao histórico de pesquisa), a posição do cursor será mantida automaticamente:

:nnoremap <silent> <leader>; :call setline('.', getline('.') . ';')<CR>

Responder3

O comportamento de `` e o que é considerado "salto" são claramente explicados no documento.

De :help jump-motions:

Um "salto" é um dos seguintes comandos: "'", "`", "G", "/", "?", "n", "N", "%", "(", ")" , "[[", "]]", "{", "}", ":s", ":tag", "L", "M", "H" e os comandos que iniciam a edição de um novo arquivo. Se você fizer o cursor “saltar” com um desses comandos, a posição do cursor antes do salto será lembrada. Você pode retornar a essa posição com os comandos "''" e "``", a menos que a linha que contém essa posição tenha sido alterada ou excluída.

Aobviamente não está na lista, então "tick-tick-back", como Gary Bernhardt o chama, não funcionará "como está". Ainda é uma boa abordagem, mas você deve colocar explicitamente a marca de craseantesVocê fazA;

nnoremap <key> m`A;<Esc>``

Responder4

Acabei escrevendo uma função minúscula, uma versão menos flexível, mas mais compacta do que a que você acabou de postar.

Atalho de teclado:

nnoremap <leader>; :call AppendSC()<CR>

Função:

fun! AppendSC()
  let pos = getpos('.')
  s/.*/&;/
  call setpos('.', pos)
endf

informação relacionada