Bagaimana saya berhenti merekam saat berada di baris perintah?

19

Ketika saya merekam makro dengan qdan saya selesai, saya bisa mengetik:

  • q untuk berhenti merekam jika saya dalam mode normal atau visual.
  • <c-o>q untuk berhenti merekam jika saya dalam mode sisipkan.
  • ..

    Bagaimana saya berhenti merekam jika makro saya berakhir di mode perintah?

iago-lito
sumber
Apa kasus penggunaan Anda untuk ini? Saya benar-benar hanya ingin tahu :)
PhilippFrank 4-15
2
@ PhilippFrank Saya akan sering mencari dan mengganti pola yang sama dengan yang berbeda di berbagai blok teks. Dengan makro seperti itu, memilih blok, menulis pola pencarian aktual dan menempatkan kursor pada posisi yang baik untuk mengetik rantai pengganti dapat dilakukan secara otomatis. Ketika saya memainkannya, itu akan memilih blok, masuk ke mode perintah, ketik :'<,'>s/toBeReplaced//glalu letakkan kursor di antara keduanya //sehingga yang harus saya lakukan adalah mengetik newString<cr>dan saya selesai. :)
iago-lito
Jadi itu seperti makro dengan parameter. Ide yang sangat bagus, terima kasih!
PhilippFrank
@ PilipFrank jenis, ya. Aku senang kau menyukainya. :)
iago-lito

Jawaban:

12

Solusi lain adalah ketika dalam mode baris perintah, gunakan Ctrl-f, dan tekan quntuk berhenti merekam.

Ctrl-fmemungkinkan Anda untuk membuka jendela baris perintah, di mana Anda dapat mengedit perintah dalam mode normal. Untuk memvalidasi perintah, cukup gunakan enter.


Karena itu, setelah menambahkan sesuatu seperti:

cnoremap <c-q> <c-f>i<c-o>q

di Anda .vimrc, Anda dapat menggunakan <c-q>untuk berhenti merekam makro saat dalam mode perintah.


Florent

fflorent
sumber
Anda masih harus menghapus karakter <Cf> ( ^F) dari akhir makro, kan? Setidaknya itulah yang saya lihat.
VanLaser
Hampir sampai! Sangat berguna (saya tidak tahu tentang jendela baris perintah tapi ini bagus), tapi .. aargh! Sepertinya memasuki jendela ini dari mode insert kehilangan area yang Anda pilih. Apakah ada cara untuk membuat perintah yang Anda luncurkan dari jendela baris perintah berfungsi pada area yang dipilih?
iago-lito
@ VanLaser Tidak, karena Anda bisa terus mengetik perintah di jendela baris perintah. Makro Anda akan seperti qqSTARTMACRO:STARTCOMMANDLINEPART<c-f>i<c-o>qdan rekaman benar-benar berhenti saat Anda mengetik bagian perintah. Untuk menggunakan makro: @qFINISHYOURCOMMAND<cr>dan Anda selesai: tidak perlu mengeditnya. Sayangnya, ini tampaknya tidak berfungsi dari mode visual (atau itu kehilangan pilihan) .. atau apakah saya melewatkan sesuatu?
iago-lito
Ah, benar :) BTW, saya bisa memilih rentang visual, lalu lakukan @qdan rentang ditambahkan pada perintah mulai '<,'>- selama makro dimulai dengan :....
VanLaser
@ lago-lito Sebenarnya, sepertinya bahkan jika Anda tidak melihat pilihan Anda, kisaran yang ditentukan (yaitu '<,'>) masih cocok dengan pilihan ketika memvalidasi perintah.
fflorent
17

Salah satu cara untuk melakukannya:

  • mulai makro Anda seperti biasa (mis. qq... karakter lain)
  • ketika Anda mencapai mode cmdline, tulis semua karakter yang Anda inginkan
  • Anda ingin mengakhiri makro di sini. Tekan ESCuntuk keluar dari mode-cmdline, quntuk mengakhiri makro Anda.
  • hapus ESCdari qregister Anda (*): Anda dapat menempelkannya di buffer, menghapus ^[karakter, memilih seluruh barang lagi (berdasarkan karakter) dan menariknya kembali untuk mendaftar q.
  • itu saja: menjalankan makro Anda: @q.

Pada dasarnya, Anda sedikit "pasca-proses" makro Anda, karena disimpan dalam register :)

(*) Cara cepat untuk menghapus karakter terakhir dari makro yang disimpan dalam register qadalah:

:let @q = @q[:-2]
VanLaser
sumber
Ha ha! Ini sebenarnya adalah hack saya sejauh ini = D. Apakah tidak ada cara "kanonik" untuk melakukannya? (juga lebih cepat )
iago-lito
Saya tidak tahu satu, tapi saya tidak menggunakan makro terlalu banyak (saya lebih suka menulis fungsi kecil saja). Makro terasa samar bagi saya, ketika saya melihat mereka sesudahnya.
VanLaser
@ VanLaser: bisakah Anda memberikan sedikit detail tentang salurannya :let @q = @q[:-2]? Terutama bagaimana cara [:-2]kerjanya? :-)
statox
Ini "mengiris" dan berfungsi pada daftar, dan string (yang adalah bagaimana saya mengakses / mengatur di @qatas). Beberapa contoh di sini
VanLaser
@ VanLaser mereka benar-benar terlihat samar. Namun ada berguna untuk mengulangi, hal-hal kecil canggih yang perlu Anda lakukan dalam kasus yang sangat spesifik .. Anda tahu masalah semacam ini yang muncul hanya sekali dan hanya berlangsung selama beberapa minuts. Mampu berurusan dengan mereka dengan membuat macro on the fly dan tanpa harus menulis dan men-debug fungsi khusus hanya .. woo begitu luar biasa! ^ ^
iago-lito
3

Setelah membaca komentar Anda tentang use case, sepertinya Anda bisa menggunakan pemetaan kunci alih-alih makro.

Saya memiliki baris ini di .vimrc saya (tidak ingat di mana saya menemukannya):

nnoremap <Leader>s :%s/\<<C-r><C-w>\>//g<Left><Left>

Ini memiliki efek yang mirip dengan kasus penggunaan yang Anda gambarkan, menempatkan Anda pada baris perintah sehingga satu-satunya hal yang harus Anda lakukan adalah mengetikkan penggantian dan tekan enter, tetapi dalam kasus ini, mengganti semua kemunculan kata yang berada di bawah kursor Anda .

Untuk mengganti saja di dalam blok saat ini, saya pikir sesuatu seperti yang berikut ini akan berfungsi:

nnoremap <Leader>s m'va{<ESC>``:'<,'>s/\<<C-r><C-w>\>//g<Left><Left>

Tentu saja, Anda dapat memetakannya ke tombol apa pun yang Anda inginkan.

Apa yang dilakukan di atas: tandai posisi saat ini menggunakan penanda yang tidak disebutkan namanya, pilih secara visual blok saat ini, tinggalkan mode visual dan kembalikan kursor ke posisi yang disimpan (penanda pemilihan visual masih diatur), masukkan mode perintah dan ketik perintah pengganti , masukkan kata yang berada di bawah kursor dengan <C-r><C-w>, dan posisikan kursor Anda untuk mengetik pengganti.

dhakimian
sumber
Ya, saya punya yang ini juga. Namun, dalam kasus penggunaan khusus saya, toBeReplacedpolanya tidak sesederhana "kata di bawah kursor", itulah sebabnya saya memerlukan makro kecil dan spesifik yang dapat saya buat saat bepergian. Dan sekali lagi: terlalu spesifik untuk peta: \ Terima kasih pula :)
iago-lito
2
Mungkin, letakkan polanya di register, lalu sesuaikan pemetaan di atas untuk secara otomatis mendapatkan konten register sebagai toBeReplacedbagian (alih-alih kata saat ini di bawah kursor, yang lebih membatasi).
VanLaser
1
@ VanLaser Right, itu akan memungkinkan pemetaan umum, dan akan membuatnya lebih sederhana juga: va{:s/<C-r>0//g<Left><Left>Dengan ini Anda dapat menarik pola apa pun yang Anda butuhkan sebelumnya, dan kemudian cukup tekan tombol yang dipetakan untuk mengganti pola itu dengan sesuatu di saat ini blok.
dhakimian