Como suspender o histórico do VIM?

8

Quando editamos um arquivo, normalmente fazemos muitos UNDO seguidos, digamos, 20 vezes. No VIM, isso geralmente é realizado pressionando u20 vezes e faz com que o VIM suba na pilha de histórico 20 posições. Se você confirmar change, todos os últimos 20 comandos do histórico serão perdidos e substituídos por change. Eu gostaria de fazer o changesem perder essas 20 posições. Então, acho que gostaria de dizer ao VIM para parar de gravar o histórico antes de fazê-lo changee continuar o histórico depois (não o quero change).

EDIT Tentando ser mais claro: Eu tenho uma função FFque atualiza as últimas linhas de um arquivo quando o buffer é gravado. Portanto, se eu executar 20 undos + write, o último writeabre um novo ramo de desfazer. Tentei adicionar por undojoindentro FF(tentando seguir uma sugestão do jlmg abaixo), mas uma sequência write-undo-write dá um erro: undojoint não é permitido após desfazer . Em vez disso, eu poderia fazer algumas coisas sed ....depois de sair vim, mas como utilizo isso SSH, prefiro uma solução apenas para vim (execute um comando após descarregar o buffer não grava no arquivo).

EDIÇÃO 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 escreverá o '3' de volta, mais <CTRL>Rvocê receberá o 4. Isso acontece mesmo se você fizer um :wapós cada um <CTRL>R. No entanto, se cada vez que :wvocê executa uma função via BufWritePre, o<CTRL>R ela não escreverá o 3verso. E é isso que eu quero fazer, é por isso que escrevi para 'suspender a historia', mas talvez o que estou pedindo não seja possível, além de trabalhar com o máximo undotree().

Luis A. Florit
fonte
1
Esta questão está relacionada ao tópico deste site, mas, como se refere a um recurso potencial bastante esotérico do VIM, você já pensou em tentar vim.stackexchange.com? Quero dizer, eu conheço o UNIX e sei vi, mas vio comando desfazer para mim desfaz uma vez e, quando você pressiona unovamente, desfaz o desfazer ("refazer"). Isso é real vi. Portanto, eu e outros usuários deste site talvez não saibamos a resposta para sua pergunta.
Celada
2
@ Celada Eu acredito que é vi.stackexchange.com , ou Vi e Vim .
Satō Katsura
@SatoKatsura, você está absolutamente certo!
Celada
1
@ Celada: Eu não sabia vim.se, eu teria tentado isso. Enfim, parece que Sato sabe como ajudar.
Luis A. Florit
O problema que você fornece "todos os últimos 20 comandos do histórico foram perdidos" é corrigido com a existência dos desvios, portanto, é confuso que você deseje corrigir o problema, evitando a criação deles. Você diz que pode obter o resultado desejado sed, mas sed não pode desfazer suas ações, então como isso vai funcionar? Se você fosse capaz de "suspender a história", que tipo de comportamento você esperaria do vim ao desfazer uma ação depois? O único comportamento que eu pude visualizar é agrupar essas alterações (junto com as ações desfazer) em um bloco desfazer, daí a minha resposta. Mas se não é isso, o que é?
JOL

Respostas:

12

Você não precisa suspender o histórico do Vim. Os dados reais formam uma árvore e você pode recuperá-los com a undotree()função Existem, é claro, vários plugins que transformam isso em algo mais amigável ao usuário, fi gundo , mundo e não- árvore . Se você também ativar desfazer persistência (cf. :h undo-persistence), poderá navegar facilmente por todo o histórico de alterações de um arquivo.

Satō Katsura
fonte
Interessante, eu não sabia que o desfazer era na verdade uma árvore. No meu caso, só quero voltar uma vez, ou seja, para o ramo desfazer anterior. voce sabe como fazer isso? Parece que undotree()deve ajudar?
Luis A. Florit
Na verdade, nesse caso em particular que motivou minha pergunta, quero que changeisso não apareça, em lugar algum, nem dentro history, nem na undoárvore. Por isso minha pergunta foi "suspender a história".
Luis A. Florit
@ LuisA.Florit: A maneira rápida e fácil de fazer isso é :earlier, que aceita uma unidade de tempo e, se necessário, cruzará as ramificações, se necessário (por exemplo, :earlier 1hfaz com que o buffer pareça com uma hora atrás). Se você não puder usar uma unidade de tempo (porque as alterações foram muito próximas?), Será necessário usá-lo g-para percorrer a árvore de desfazer algumas etapas por vez.
Kevin
0

Se eu entendi direito, o que você quer é que, depois de desfazer, desfaça change e os 20 desfazer.

Quando o vim executa uma função ou comando, todas as ações que ele executa são desfeitas juntas. Não tenho certeza se essas ações podem incluir desfazer. Talvez esta 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 erroE790: 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 de :call F()executa a undoe outra ação em um bloco de desfazer. Observe que, ao usar desfazer, você cria um novo ramo de desfazer. Após terminar, você pode usar o comando do modo normal g-, para desfazer F(); usar userá como ter feito :undo 3no começo.

JoL
fonte
Não tenho certeza se isso funciona ... O que eu quero é que, depois de fazer algumas undo, tudo o que você faz em sua função F()não abra um novo ramo de desfazer. No meu caso, F()é executado toda vez que eu escrevo o arquivo e, se eu fizer undoe depois gravar, F()abre uma nova ramificação desfazer. Eu tentei com undojoinno início F(), mas uma seqüência write-desfazer-write dá um erro: undojoint not allowed after undo.
Luis A. Florit
Atualizei minha pergunta tentando ser mais clara.
Luis A. Florit
@ LuisA.Florit Eu escrevi na resposta que :undojoinnão funcionou para o que você queria, mencionando o mesmo erro, e eu não estava sugerindo o uso :undojoinno início de F(). F()destina-se a fazer o :undojoinque não podia, que é unir os desfazer e outros comandos em um bloco de desfazer.
JOL
@ LuisA.Florit Você diz que deseja evitar a criação de um ramo de desfazer, mas não consigo encontrar o motivo pelo qual você deseja isso. Eu pensei que o objetivo da sua pergunta era ser capaz de desfazer os comandos e os vários desfazer de uma só vez. Olhando para trás, me pergunto se seu objetivo era não perder as mudanças que você desfez. Se for esse o caso, a existência da árvore de desfazer é exatamente o que você deseja. Você pode navegar com g-e g+.
JOL
Sim, parece que a árvore de desfazer é o que eu preciso.
Luis A. Florit