Bagaimana cara menangguhkan riwayat VIM?

8

Ketika kita mengedit file, kita biasanya melakukan banyak UNDO berturut-turut, katakanlah, 20 kali. Dalam VIM, itu biasanya dilakukan dengan menekan u20 kali, dan itu membuat VIM naik "ke atas" di tumpukan sejarah 20 posisi. Jika Anda kemudian memastikan change, semua 20 perintah sejarah terakhir hilang, dan digantikan oleh change. Saya ingin membuatnya changetanpa kehilangan 20 posisi itu. Jadi saya kira saya ingin memberitahu VIM untuk berhenti merekam riwayat sebelum saya melakukannya change, dan melanjutkan riwayat sesudahnya (tidak ingin changedalam sejarah).

EDIT Mencoba menjadi lebih jelas: Saya memiliki fungsi FFyang memperbarui baris terakhir file ketika buffer ditulis. Jadi, jika saya melakukan 20 undos + write, yang terakhir writemembuka cabang undo baru. Saya mencoba menambahkan undojoindi dalam FF(mencoba mengikuti saran oleh jlmg di bawah), tetapi urutan write-undo-write memberikan kesalahan: undojoint tidak diizinkan setelah membatalkan . Saya malah bisa melakukan beberapa sed ....setelah meninggalkan vimsebagai gantinya, tetapi karena saya menggunakan ini melalui SSHsaya lebih suka solusi vim-only (jalankan perintah setelah membongkar buffer tidak menulis ke file).

EDIT 2 Coba lakukan ini di VIM: buka file kosong, dan lakukan:

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

Jika sekarang Anda melakukan <CTRL>R, VIM akan menulis '3' kembali, selanjutnya <CTRL>RAnda mendapatkan 4. Ini terjadi bahkan jika Anda melakukan :wsetelah masing-masing <CTRL>R. Namun, jika setiap kali Anda melakukan :wAnda menjalankan fungsinya melalui BufWritePre, <CTRL>Rtidak akan menulis 3kembali. Dan inilah yang ingin saya lakukan, itu sebabnya saya menulis untuk 'menunda hisotry', tapi mungkin yang saya minta tidak mungkin, selain bekerja dengan penuh undotree().

Luis A. Florit
sumber
1
Pertanyaan ini mengenai topik untuk situs ini, tetapi karena ini berkaitan dengan fitur potensial VIM yang cukup esoteris, apakah Anda sudah mempertimbangkan mencoba vim.stackexchange.com? Maksud saya, saya tahu UNIX dan saya tahu vi, tetapi bagi saya viperintah undo membatalkan sekali, dan kemudian ketika Anda menekan ulagi membatalkan undo ("redo"). Itu nyata vi. Jadi saya dan pengguna lain dari situs ini mungkin tidak tahu jawaban atas pertanyaan Anda.
Celada
2
@Celada saya percaya itu vi.stackexchange.com , atau Vi dan Vim .
Satō Katsura
@SatoKatsura Anda memang benar!
Celada
1
@Celada: Saya tidak tahu vim.se, saya akan mencobanya. Ngomong-ngomong, sepertinya Sato tahu bagaimana membantu.
Luis A. Florit
Masalah yang Anda berikan "semua 20 perintah sejarah yang hilang telah hilang" telah diperbaiki dengan adanya cabang undo, sehingga membingungkan bahwa Anda kemudian ingin memperbaiki masalah Anda dengan menghindari pembuatannya. Anda mengatakan Anda bisa mendapatkan hasil yang Anda inginkan sed, tetapi sed tidak dapat melakukan undo Anda, jadi bagaimana cara kerjanya? Jika Anda dapat "menangguhkan sejarah", perilaku seperti apa yang Anda harapkan dari vim ketika Anda melakukan undo sesudahnya? Satu-satunya perilaku yang dapat saya visualisasikan adalah mengelompokkan perubahan tersebut (bersama dengan undo) dalam satu blok undo, maka jawaban saya. Tapi kalau bukan itu, apa?
JoL

Jawaban:

12

Anda tidak perlu menangguhkan riwayat Vim. Data aktual membentuk pohon, dan Anda dapat mengambilnya dengan undotree()fungsinya. Tentu saja ada sejumlah plugin yang mengubahnya menjadi sesuatu yang lebih ramah pengguna, seperti gundo , mundo , dan undotree . Jika Anda juga mengaktifkan undo persistence (lih. :h undo-persistence) Anda dapat dengan mudah menavigasi seluruh perubahan sejarah file.

Satō Katsura
sumber
Menarik, saya tidak tahu bahwa hal itu sebenarnya adalah pohon. Dalam kasus saya, saya hanya ingin kembali satu kali, yaitu ke cabang undo sebelumnya. Apakah Anda tahu bagaimana melakukan hal itu? Tampaknya undotree()harus membantu?
Luis A. Florit
Sebenarnya, dalam kasus khusus ini yang memotivasi pertanyaan saya, saya ingin itu changetidak muncul sama sekali, di mana pun, di history, atau di undopohon. Itu sebabnya pertanyaan saya adalah untuk "menangguhkan sejarah".
Luis A. Florit
@ LuisA.Florit: Cara cepat dan mudah untuk melakukan ini adalah dengan :earlier, yang menerima satuan waktu dan akan menyeberang membatalkan cabang jika perlu (mis. :earlier 1hMembuat buffer terlihat seperti itu satu jam yang lalu). Jika Anda tidak dapat menggunakan unit waktu (karena perubahannya terlalu berdekatan?) Maka Anda harus menggunakan g-berjalan undo tree beberapa langkah sekaligus.
Kevin
0

Jika saya mengerti Anda dengan benar apa yang Anda inginkan adalah bahwa setelah melakukan undo harus membatalkan itu changedan 20 membatalkan .

Ketika vim mengeksekusi fungsi atau perintah, semua tindakan yang dilakukannya dibatalkan bersama-sama. Saya tidak yakin apakah tindakan itu mungkin termasuk undos. Mungkin bagian dokumentasi ini dapat membantu:

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.

Sayangnya, saya mencoba menggunakan :undo 2 | undojoin | normal ohi, tetapi saya mendapat pesan kesalahan E790: undojoin is not allowed after undo.

Namun, jika tindakan dilakukan dalam fungsi seperti ini:

function F()
  undo 2
  normal ohi
endfunction

kemudian memanggilnya dengan :call F()melakukan tindakan undodan lainnya dalam satu blok undo. Perhatikan bahwa karena Anda menggunakan undo Anda membuat cabang undo baru. Setelah selesai, Anda dapat menggunakan perintah mode normal g-, untuk membatalkan F(); menggunakan uakan seperti yang dilakukan :undo 3di awal.

JoL
sumber
Tidak yakin apakah ini berfungsi ... Yang saya inginkan adalah, setelah Anda melakukan beberapa undo, semua yang Anda lakukan dalam fungsi F()Anda tidak membuka cabang undo baru. Dalam kasus saya, F()dijalankan setiap kali saya menulis file, dan jika saya melakukannya undodan kemudian menulis file, F()buka cabang undo baru. Aku mencoba dengan undojoindi awal F(), tetapi urutan write-undo-write memberikan kesalahan: undojoint not allowed after undo.
Luis A. Florit
Diperbarui pertanyaan saya mencoba menjadi lebih jelas.
Luis A. Florit
@ LuisA.Florit saya menulis dalam jawaban yang :undojointidak bekerja untuk apa yang Anda inginkan, menyebutkan kesalahan yang sama, dan saya tidak menyarankan untuk digunakan :undojoinpada awal F(). F()dimaksudkan untuk melakukan apa yang :undojointidak bisa, yaitu bergabung dengan undo dan perintah lain dalam satu blok undo.
JoL
@ LuisA.Florit Anda mengatakan Anda ingin menghindari membuat cabang undo, tetapi saya tidak dapat menemukan alasan mengapa Anda menginginkannya. Saya pikir inti dari pertanyaan Anda adalah untuk dapat membatalkan perintah dan beberapa membatalkan sekaligus. Melihat ke belakang, saya ingin tahu apakah maksud Anda adalah untuk tidak kehilangan perubahan yang telah Anda batalkan. Jika itu kasusnya, keberadaan pohon undo tepat seperti yang Anda inginkan. Anda dapat menavigasi dengan g-dan g+.
JoL
Ya, sepertinya pohon undo adalah yang saya butuhkan.
Luis A. Florit