Come sospendere la cronologia VIM?


8

Quando modifichiamo un file, di solito eseguiamo UNDO molti di seguito, diciamo, 20 volte. In VIM, ciò viene di solito eseguito premendo u20 volte e ciò fa sì che VIM vada "in alto" nello stack della cronologia di 20 posizioni. Se poi ne fai un certo change, tutti questi ultimi 20 comandi della cronologia vengono persi e sostituiti da change. Vorrei fare changesenza perdere quelle 20 posizioni. Quindi immagino che vorrei dire a VIM di interrompere la registrazione della cronologia prima di me changee di riprenderla successivamente (non voglio changenella cronologia).

EDIT Sto cercando di essere più chiaro: ho una funzione FFche aggiorna le ultime righe di un file quando il buffer è scritto. Quindi, se eseguo 20 undos + write, l'ultimo writeapre un nuovo ramo di annullamento. Ho provato ad aggiungere undojoinall'interno FF(cercando di seguire un suggerimento di jlmg di seguito), ma una sequenza write-anndo-write dà un errore: annulla non consentito dopo aver annullato . Potrei invece fare un po ' sed ....dopo aver lasciato vim, ma poiché lo uso attraverso SSHpreferisco una soluzione solo vim (eseguire un comando dopo aver scaricato il buffer non scrive nel file).

MODIFICA 2 Prova a farlo in VIM: apri un file vuoto ed esegui:

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

Se ora fai un <CTRL>R, VIM riscriverà il '3' indietro, più <CTRL>Rotterrai il 4. Questo succede ANCHE se lo fai :wdopo ciascuno <CTRL>R. Tuttavia, se ogni volta che lo :wfai esegui un fuction via BufWritePre, <CTRL>Rnon scriverà il 3retro. E questo è quello che voglio fare, ecco perché ho scritto per "sospendere il suo spirito", ma forse quello che sto chiedendo non è possibile, oltre a lavorare con il pieno undotree().


1
Questa domanda è in argomento per questo sito, ma dal momento che riguarda una potenziale caratteristica abbastanza esoterica di VIM, hai preso in considerazione l'idea di provare vim.stackexchange.com? Voglio dire, conosco UNIX e lo so vi, ma per me viil comando di annullamento annulla una volta, quindi quando si preme di unuovo annulla l'annullamento ("redo"). Questo è vero vi. Quindi io e altri utenti di questo sito potremmo non conoscere la risposta alla tua domanda.
Celada,

2
@Celada Credo che sia vi.stackexchange.com , o Vi e Vim .
Satō Katsura,

@SatoKatsura hai perfettamente ragione!
Celada,

1
@Celada: non lo sapevo vim.se, ci avrei provato. Ad ogni modo, sembra che Sato sappia come aiutare.
Luis A. Florit,

Il problema che dai "tutti gli ultimi 20 comandi della cronologia sono andati persi" è risolto con l'esistenza dei rami di annullamento, quindi è confuso che tu voglia risolvere il tuo problema evitando la loro creazione. Dici che puoi ottenere il risultato che desideri sed, ma sed non può fare i tuoi annullamenti, quindi come funzionerà? Se tu fossi in grado di "sospendere la storia", che tipo di comportamento ti aspetteresti da Vim quando in seguito fai un annullamento? L'unico comportamento che ho potuto visualizzare è quello di raggruppare quei cambiamenti (insieme agli annullamenti) in un blocco di annullamento, quindi la mia risposta. Ma se non è così, cos'è?
JoL

Risposte:


12

Non è necessario sospendere la cronologia di Vim. I dati effettivi formano un albero e puoi recuperarli con la undotree()funzione. Esistono, ovviamente, numerosi plugin che lo trasformano in qualcosa di più user-friendly, fi gundo , mundo e undotree . Se si abilita anche l'annullamento della persistenza (cfr. :h undo-persistence), È possibile navigare facilmente nell'intera cronologia delle modifiche di un file.


Interessante, non sapevo che l'annullamento fosse in realtà un albero. Nel mio caso, voglio tornare solo una volta, ovvero al precedente ramo di annullamento. Sai come farlo? Sembra che undotree()dovrebbe aiutare?
Luis A. Florit,

In realtà, in questo caso particolare che ha motivato la mia domanda, voglio che changenon appaia affatto, ovunque, né dentro history, né undonell'albero. Ecco perché la mia domanda era "sospendere la storia".
Luis A. Florit,

@ LuisA.Florit: il modo rapido e semplice per farlo è con :earlier, che accetta un'unità di tempo e attraverserà i rami di annullamento se necessario (ad esempio, :earlier 1hfa apparire il buffer come un'ora fa). Se non riesci a usare un'unità di tempo (perché le modifiche erano troppo vicine tra loro?) Allora dovrai usare g-per camminare l'albero di annullamento alcuni passi alla volta.
Kevin,

0

Se ti capisco correttamente quello che vuoi è che dopo fare un annullamento dovrebbe annullare quello changee i 20 annullamenti.

Quando vim esegue una funzione o un comando, tutte le azioni che compie vengono annullate insieme. Non sono sicuro che tali azioni possano includere annullamenti. Forse questa parte della documentazione può aiutare:

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.

Purtroppo, ho provato a utilizzare :undo 2 | undojoin | normal ohi, ma ho ricevuto il messaggio di errore E790: undojoin is not allowed after undo.

Tuttavia, se le azioni vengono eseguite in una funzione come questa:

function F()
  undo 2
  normal ohi
endfunction

quindi chiamarlo con :call F()esegue l' undoazione e l'altra in un blocco di annullamento. Tieni presente che, poiché stai utilizzando Annulla, stai creando un nuovo ramo Annulla. Al termine puoi usare il normale comando mode g-, per annullare F(); usare usarà come aver fatto :undo 3all'inizio.


Non sono sicuro che undofunzioni ... Quello che voglio è che, dopo aver fatto qualcosa , tutto ciò che fai nella tua funzione F()non apre un nuovo ramo di annullamento. Nel mio caso, F()viene eseguito ogni volta che scrivo il file, e se lo faccio undoe quindi scrivo il file, F()apre un nuovo ramo di annullamento. Ho provato con undojoinall'inizio del F(), ma una sequenza di write-undo-scrittura dà un errore: undojoint not allowed after undo.
Luis A. Florit,

Aggiornato la mia domanda cercando di essere più chiaro.
Luis A. Florit,

@ LuisA.Florit Ho scritto nella risposta che :undojoinnon ha funzionato per quello che volevi, menzionando lo stesso errore, e non stavo suggerendo di usare :undojoinall'inizio F(). F()è destinato a fare ciò :undojoinche non è possibile, ovvero unire le operazioni di annullamento e altri comandi in un blocco di annullamento.
JoL

@ LuisA.Florit Dici che vuoi evitare di creare un ramo di annullamento, ma non riesco a trovare il motivo per cui lo desideri. Ho pensato che il punto della tua domanda fosse poter annullare i comandi e le ripetizioni multiple in una volta sola. Ripensandoci, mi chiedo se il tuo punto fosse non perdere i cambiamenti che hai annullato. In tal caso, l'esistenza dell'albero di annullamento è esattamente ciò che desideri. Puoi navigare con g-e g+.
JoL

Sì, sembra che l'albero di annullamento sia ciò di cui ho bisogno.
Luis A. Florit,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.