Como suspender o histórico do VIM?

8

Quando editamos um arquivo, geralmente fazemos muitos UNDO seguidos, digamos, 20 vezes. No VIM, isso geralmente é feito pressionando-se u 20 vezes, e isso faz com que o VIM vá "para cima" nas 20 posições da pilha de histórico. Se você fizer um determinado change , todos os últimos 20 comandos de histórico serão perdidos e substituídos por change . Eu gostaria de fazer o change sem perder essas 20 posições. Então, eu acho que gostaria de dizer ao VIM para parar de gravar o histórico antes de eu fazer change e retomar o histórico depois (não quero change no histórico).

EDITAR Tentando ser mais claro: Eu tenho uma função FF que atualiza as últimas linhas de um arquivo quando o buffer é gravado. Portanto, se eu executar 20 undos + write , o último write abrirá uma nova ramificação de desfazer. Eu tentei adicionar undojoin dentro de FF (tentando seguir uma sugestão de jlmg abaixo), mas uma sequência write-undo-write dá um erro: undojoint não permitido após desfazer . Eu poderia fazer um pouco de sed .... depois de deixar vim , mas como eu uso isso através de SSH eu prefiro uma solução somente vim (execute um comando após descarregar o buffer não grava no arquivo).

EDIT 2 Tente fazer isso no VIM: abra um arquivo em branco e faça:

i1<ESC>:wa2<ESC>:wa3<ESC>:wa4<ESC>uu:w

Se agora você fizer um <CTRL>R , o VIM gravará o '3' de volta, mais <CTRL>R obterá o 4 . Isso acontece MESMO se você fizer um :w após cada <CTRL>R . No entanto, se cada vez que você executar um :w executar uma função via BufWritePre , o <CTRL>R não gravará o 3 de volta. E é isso que eu quero fazer, é por isso que escrevi para 'suspende hisotry', mas talvez o que eu esteja perguntando não seja possível, além de trabalhar com o undotree() completo.

    
por Luis A. Florit 03.12.2016 / 14:08

2 respostas

11

Você não precisa suspender o histórico do Vim. Os dados reais formam uma árvore e você pode recuperá-la com a função undotree() . Existem, é claro, vários plugins que transformam isso em algo mais fácil de usar, f.i. gundo , mundo e undotree . Se você também habilitar desfazer persistência (cf. :h undo-persistence ), poderá navegar facilmente pelo histórico de alterações de um arquivo.

    
por 03.12.2016 / 14:43
0

Se eu entendi corretamente o que você quer é que depois de desfazer deve desfazer o change e os 20 undos.

Quando o vim executa uma função ou comando, todas as ações que ele faz são desfeitas juntas. Não tenho certeza se essas ações podem incluir undos. Talvez essa parte da documentação possa ajudar:

3. Undo blocks                      *undo-blocks*

One undo command normally undoes a typed command, no matter how many changes
that command makes.  This sequence of undo-able changes forms an undo block.
Thus if the typed key(s) call a function, all the commands in the function are
undone together.

If you want to write a function or script that doesn't create a new undoable
change but joins in with the previous change use this command:

                        *:undoj* *:undojoin* *E790*
:undoj[oin]     Join further changes with the previous undo block.
            Warning: Use with care, it may prevent the user from
            properly undoing changes.  Don't use this after undo
            or redo.
            {not in Vi}

This is most useful when you need to prompt the user halfway through a change.
For example in a function that calls |getchar()|.  Do make sure that there was
a related change before this that you must join with.

This doesn't work by itself, because the next key press will start a new
change again.  But you can do something like this: >

    :undojoin | delete

After this an "u" command will undo the delete command and the previous
change.

To do the opposite, break a change into two undo blocks, in Insert mode use
CTRL-G u.  This is useful if you want an insert command to be undoable in
parts.  E.g., for each sentence.  |i_CTRL-G_u|
Setting the value of 'undolevels' also breaks undo.  Even when the new value
is equal to the old value.

Infelizmente, tentei usar :undo 2 | undojoin | normal ohi , mas recebi a mensagem de erro E790: undojoin is not allowed after undo .

No entanto, se as ações forem executadas em uma função como esta:

function F()
  undo 2
  normal ohi
endfunction

, em seguida, chamá-lo com :call F() realiza a undo e outra ação em um bloco de undo. Observe que, como você está usando desfazer, está criando uma nova ramificação de desfazer. Depois disso, você pode usar o comando normal mode g- para desfazer F() ; usar u será como ter feito :undo 3 no começo.

    
por 03.12.2016 / 17:39

Tags