Saya ingin mengoptimalkan alur kerja "temukan dan ganti" saya di Vim. Itu adalah sesuatu yang sering saya lakukan, karena saya yakin sebagian besar dari Anda juga. Biasanya sesuatu di sepanjang baris - salin blok dan ubah nama variabel di beberapa tempat. Saya tahu, saya tahu, itu mungkin memicu refleks "mengapa Anda menyalin dan menempelkan kode", tapi jangan sampai menyimpang ... Ada banyak kasus penggunaan yang valid :)
Saya sangat menyadari pencarian dan mengganti perintah: :s
atau :%s
tetapi saya tidak menyukainya. Itu memaksa saya untuk mengetikkan nama variabel lengkap yang saya cari dan untuk apa saya mengubahnya. Mungkin ada cara yang lebih baik untuk memperbaiki jumlah pengetikan :%s
? Saya sering menggunakan nama variabel deskriptif panjang, jadi itu benar-benar pemecah kesepakatan bagi saya. Saya juga tidak suka bagaimana mengetik nama variabel dari awal adalah salah ketik dan dapat menghabiskan waktu dan tenaga otak memburu kesalahan ketik. Saya lebih suka mengetiknya sekali, lalu menyalin dan menempel untuk menghindari ini sepenuhnya jika memungkinkan.
Alur kerja saya saat ini menggunakan beberapa kombinasi gerakan / yank / select / search / put untuk bergerak di sekitar file dan mengganti satu per satu. Itu tidak bagus tetapi memiliki manfaat menghindari mengetikkan nama variabel lengkap. Saya mungkin hanya perlu mengetik beberapa huruf pertama dengan /
atau menggunakan perintah gerakan lain (misalnya fx
) tergantung pada apa yang ada di sekitar dan kemudian tekan ve
untuk memilih seluruh kata. Saya juga tidak keberatan harus mengulangi untuk setiap contoh. Saya tidak pernah melakukan penggantian temuan lengkap tanpa mengonfirmasi setiap perubahan. Tetapi akan jauh lebih disukai jika saya bisa mengulangi tindakan penggantian dengan penekanan tombol tunggal (yang saya tidak bisa lakukan dengan metode ini). setiap penggantian biasanya sesuatu seperti n
itu ve
maka p
(atau bahkan lebih buruk "0p
)
Apakah ada cara yang lebih cepat?
sumber
.
mengulangi "blok perintah" terakhir (tidak yakin dengan istilah yang tepat. misalnya: memindahkan + tindakan + teks. untuk contoh:cwtoto<Esc>
(ubah dari kursor ke akhir kata dengan "toto"),c/foo<enter>bar<Esc>
(ubah dari kursor ke sebelum " foo ", dan ganti dengan" bar "). Anda kemudian dapat memindahkan (dengan kursor, hjkl, atau angka + hjkl (melakukannya n kali), G (pergi ke akhir file), / sesuatu (pergi sebelum" sesuatu "), dll) dan kemudian tekan.
untuk mengulangi" blok perintah "yang saman
ve
"0p
. Yang sayangnya tidak dapat ditiru hanya dengan.
n ce ctrl-r 0 <esc> n.n.n.n.n.n.
Jawaban:
Saya sebenarnya memiliki alur kerja yang sangat mirip dengan milik Anda, (menyalin dan menempelkan blok yang serupa, lalu menggunakan
:s
untuk mengubah nama variabel) terutama ketika saya sedang menulis banyak baris yang serupa kecuali untuk variabel yang mereka gunakan. Tetapi ada beberapa hal yang saya lakukan yang mungkin berguna bagi Anda.Hal-hal umum vim
Hal pertama yang akan membantu Anda adalah menyadari bahwa
:s//foo/g
akan mengisi istilah pencarian apa pun yang Anda gunakan terakhir dan menggantinya dengan foo . Itu saja dapat menghemat banyak waktu, tetapi ketika Anda menggabungkannya dengan perintah asterisk (mencari kata di bawah kursor saat ini) itu menghemat banyak waktu. Misalnya, mengubah semuafoo
menjadispam
, alih-alih melakukanYang mengharuskan Anda mengetik foo dan spam (yang mungkin merupakan variabel lama), Anda cukup menavigasi ke foo, dan lakukan:
Dengan cara ini, Anda dapat dengan cepat mendapatkan nama variabel yang Anda ubah dengan mencarinya, maka Anda tidak perlu mengetiknya. Ini juga akan bekerja dengan baik dengan alur kerja Anda saat ini menggunakan
n
banyak. Ini juga bermanfaat untuk digunakanhlsearch
, karena Anda dapat secara visual mengetahui di mana variabel yang Anda ganti berada.(catatan samping: Perintah tanda bintang akan menambahkan batas kata, yaitu
\<
dan di\>
sekitar kata di bawah kursor. Jika Anda tidak menginginkan ini, gunakang*
saja.)Anda dapat menggunakan
@:
untuk mengulang perintah pengganti terakhir. Itu bagus jika Anda ingin melakukan:s
perintah pada banyak baris, tetapi tidak semuanya jadi:%s
tidak akan berfungsi. Pilihan lain adalah bendera konfirmasi, yaitu:%s///gc
. Ini akan memungkinkan Anda untuk mengetiky
ataun
pada setiap kejadian untuk memutuskan apakah Anda ingin menggantinya atau tidak.Seperti yang ditunjukkan Desty , Anda juga dapat melakukan &untuk menjalankan kembali perintah pengganti terakhir, tetapi perhatikan bahwa ini tidak akan menjaga bendera Anda (seperti
global
atauconfirm
). Apakah itu baik atau buruk tergantung pada pendapat pribadi Anda. Jika Anda ingin menggunakan ini tetapi menyimpannya juga, Anda bisa melakukannyaJika Anda ingin mengubah setiap kemunculan dalam sebuah blok, tetapi tidak setiap kecocokan dalam file, Anda selalu dapat menggunakan pilihan visual dari blok tersebut, yang akan mengisi
ke pengganti Anda, yang membatasi ke garis yang telah Anda pilih. Ketika dikombinasikan dengan pendekatan asterisk, saya menemukan ini sangat berguna. Selain itu, jika Anda membuat beberapa perintah pengganti pada blok garis yang sama, Anda dapat menggunakan gvuntuk memilih ulang baris yang sama untuk melakukan perintah lain. (apakah itu
:substitute
perintah biasa atau biasa saja)Jika Anda melakukan perintah pengganti lain, Anda tidak perlu memilih kembali baris yang sama, karena
:'<,'>
masih akan beroperasi pada baris yang sama. Namun, lebih mudah untuk mengetikdaripada
Plugin / Pemetaan yang saya suka
Saya memiliki pemetaan berikut di saya
.vimrc
yang memperluas pendekatan asterisk sehingga saya hanya perlu mengetik nama yang diinginkan baru:Untuk menggunakan ini, cukup letakkan kursor Anda pada kata yang ingin Anda ubah, dan ketik
<leader>rNewVarName<cr>
dan Anda selesai. Perhatikan bahwa ini akan menggantikan semua kecocokan tanpa memberi Anda opsi untuk mengonfirmasinya, jadi Anda mungkin tidak terlalu menyukainya. Tentu saja, Anda bisa mengubahnya menjadiUntuk memungkinkan opsi konfirmasi.
sunting : Mengikuti jawaban Misa dan komentar rcorre , Anda juga dapat menulis ini sebagai
Yang memiliki keuntungan mempertahankan register tanpa nama Anda tetap sama.
Jika Anda mengubah nama grup dari variabel yang sama secara bersamaan, misalnya, berubah
untuk
itu bisa menyusahkan untuk menggantikan mereka semua secara individual. Di sinilah tpope / vim-abolish berguna. Anda dapat mengganti semua ini dalam satu perintah dengan:
dan itu mengurus kapitalisasi untuk Anda.
Ini seharusnya banyak membantu Anda, tetapi beri tahu saya jika ada sesuatu tentang pendekatan yang tidak Anda sukai atau rasakan ini kurang. Saya senang berbicara tentang lebih banyak pendekatan. :)
Bacaan yang Disarankan:
:h s_c
:h *
:h g*
:h @:
:h /\<
:h &
sumber
<leader>rc
(ataucr
) menambahkannya/c
di akhir. Juga, saya telahset gdefault
menetapkan, karena saya hampir tidak pernah ingin mengganti satu hasil tunggal, jadi itu akan terjadiyiw:%s/\<<C-r>"\>//<left><left>
ctrl+r-ctrl+w
dalam pemetaan (seperti yang disarankan oleh @Mass) itu harus berfungsi sama tetapi tidak akan mengacaukan register yank Anda (yang mungkin atau mungkin tidak diinginkan).
untuk melakukan penggantian lebih lanjut.The
c_CTRL-R
keluarga peta dapat meningkatkan alur kerja Anda cukup sedikit:Anda tidak perlu mengetik nama variabel saat menggunakan
:s/
, cukup gunakanCTRL-R
CTRL-W
untuk memasukkan kata di bawah kursor ke dalam baris perintah (peringatan: ini tidak luput dari karakter khusus, seperti*
halnya).Setelah membuat perubahan kecil menggunakan
ce
, Anda dapat mencari menggunakan kata lama/
CTRL-R
-
. Kemudian gunakan.
untuk mengulangi perubahan.Jika Anda perlu melakukan perubahan pada pola pencarian
CTRL-R
/
akan menempatkan pencarian yang ada ke dalam baris perintah.Akhirnya, Anda dapat menggunakan konten register apa pun
CTRL-R
{register}
sumber
Ctrl-R
/
? Saya menggunakan ini cukup sering dalam:s
perintah jika saya ingin menggunakan istilah pencarian yang hampir tetapi tidak persis sama dengan yang sebelumnya.Ada beberapa metode lagi yang (mengejutkan saya!) Belum disebutkan.
Menggunakan
gn
Perintahgnberfungsi seperti nperintah, kecuali bahwa selain melompat ke pertandingan, itu memasuki mode visual, dengan seluruh pertandingan dipilih.
Jadi, untuk mengubah kata (atau apa pun yang dapat Anda cocokkan dengan ekspresi reguler!) Pertama cari 1 , lalu tekan cgndiikuti oleh teks yang ingin Anda ganti dengan dan Escuntuk kembali ke mode normal.
(Anda menyebutkan bahwa kadang-kadang teks pengganti yang ingin Anda gunakan disimpan dalam
"0
register yank - perhatikan bahwa Anda dapat dengan cepat memasukkan ini tanpa harus mengetik ulang dengan menekan Ctrl+R0dalam mode sisipkan.)Anda kemudian dapat melompat ke pertandingan berikutnya dan ulangi perubahan dengan satu .penekanan tombol!
Jika ada tempat di mana Anda tidak ingin melakukan penggantian, cukup tekan ununtuk membatalkan perubahan dan melompat ke pertandingan berikutnya.
1: cepat, dengan menggunakan saran lain pada halaman ini seperti *, Ctrl+RCtrl+W, dll Lihat juga komentar Peter Rincker ini selama lebih saran tentang bagaimana awalnya mengisi pencarian Anda.
Menggunakan Select Mode
(Saya belajar ini dari romainl 's posting di subreddit vim . Saya tidak tahu apakah dia diciptakan sendiri atau hanya lewat di.)
Mode pilih sedikit mirip dengan mode visual, kecuali jika Anda mulai mengetik teks yang dipilih segera diganti dengan apa yang Anda ketik (seperti cara kerja seleksi di sebagian besar editor lain).
Dengan demikian Anda dapat menggunakan trio pemetaan ini untuk melakukan pencarian / penggantian yang sangat cepat, yang dapat Anda ubah di pertengahan file, jika perlu:
Pemetaan mode normal : Memasuki mode pilih dengan kata terdekat dengan kursor yang dipilih.
Anda kemudian dapat mengetik pengganti untuk kata yang dipilih dan ( tanpa menekan Esc) gunakan:
Sisipkan pemetaan mode : Melompat ke pertandingan berikutnya dan memasuki mode pemilihan.
Anda kemudian dapat mengetik pengganti baru atau tekan .untuk menggunakan:
Pilih mode pemetaan : Masukkan kembali teks yang terakhir disisipkan - pada dasarnya, ulangi penyisipan terakhir.
sumber
gn
metode di akhir jawaban saya vi.stackexchange.com/a/13696/488 kemarin untuk apa nilainya! Jawaban Anda memiliki format yang jauh lebih bagus.gn
sekali), dan itu metode khusus, (bukan hanyagn
perintah) yang saya terkejut belum disebutkan.gn
. Memberi Anda lebih banyak opsi pencarian. Orang miskin adalah pemetaan bintang visual yang:xnoremap * :<c-u>let @/=@"<cr>gvy:let [@/,@"]=[@",@/]<cr>/\V<c-r>=substitute(escape(@/,'/\'),'\n','\\n','g')<cr><cr>
. Episode Vimcasts Terkait: Beroperasi pada pertandingan pencarian menggunakan gnPlugin https://github.com/terryma/vim-multiple-cursors menangani sebagian besar masalah ini.
Alur kerja saya biasanya sebagai berikut:
ctrl-n
sampai semuanya dipilih.c
dan mulai mengetik pengganti.Hal yang nyaman di sini adalah Anda juga dapat melakukan operasi yang lebih rumit dari sekadar mencari-ganti, meskipun saya menemukan bahwa jika Anda mengambilnya terlalu jauh, plugin mulai menampilkan beberapa gangguan.
sumber
Cara lain untuk melakukan hal-hal yang belum disebutkan: Anda dapat menggunakan jendela baris perintah (dibuka dengan
q:
dalam mode normal - lihat:help q:
untuk informasi lebih lanjut), di mana Anda memiliki akses penuh ke fitur pelengkapan otomatis Vim (i_CTRL-N
/i_CTRL-P
dan berbagaii_CTRL-X
urutan berada di antara mereka).Di jendela baris perintah Anda juga dapat menggunakan perintah mode normal untuk mengedit baris perintah, yang, misalnya, berarti Anda dapat menarik dan menempel bagian dari perintah sebelumnya dalam riwayat baris perintah Anda.
Perhatikan bahwa kursor Anda akan dipindahkan ke jendela baris perintah saat menggunakannya, artinya
CTRL-R CTRL-W
dan metode serupa yang melibatkan memasukkan teks di bawah kursor tidak akan berfungsi di sana, tidak seperti di baris perintah biasa.sumber
:substitute
perintah dengan menekan<ctrl-f>
Solusi untuk ini agak di antara jawaban lain untuk saya:
Katakanlah Anda memiliki 6 garis yang identik, dan Anda ingin mengganti 'apel' di tengah dua:
Apa yang saya lakukan adalah:
v
untuk masuk ke mode visual2j
:s/<C-R><C-W>/
yang menggunakan pemilihan visual sebagai rentang untuk:s
, dan kemudian menyisipkan kata di bawah kursor<C-F>
yang menempatkan Anda ke mode di mana Anda dapat mengedit perintah Anda seolah-olah itu adalah buffer. Jadi Anda bisa menggunakan pelengkap atau plugin apa pun yang ingin Anda pilih kata penggantinya, dan Anda selesai.Semua dalam satu baris, aliran untuk ini akan
/apples<CR>2nv/apples<CR>nn:s/<C-R><C-W/oranges<CR>
tetapi itu terlihat lebih buruk daripada itu.Dalam kasus Anda, Anda dapat menambahkan
/c
ke:s
perintah untuk melewatkan yang tidak Anda inginkan, jika kisaran Anda berisi beberapa Anda ingin melewatkan::s/<C-R><C-W/orange/c
.Atau (dan mungkin lebih sederhana), Anda bisa mencari seluruh kata yang ingin mengganti,
c
hange itu, kemudiangn
dan.
mengulangi pencarian dan menerapkan perubahan yang sama lagi. Tampaknya akan/\<apple\><CR>viwcorange<ESC>gn.gn.gn..ngn.
mengulanginya pada tiga, lalu lewati sebuah instance, lalu ulangi untuk yang terakhir kalinya.sumber
vim -Nu NONE
). Hanya berbunyi bip saat saya menekan yang pertama.
. Adakah yang tahu mengapa itu terjadi? Bagaimanapun, itu akan lebih mudah untuk digunakanciw
daripadaviw
dann
bukannyagn
untuk membuat perubahan dengan cara ini.Ini tidak sepenuhnya terkait dengan pertanyaan, tetapi masih harus membantu memilih kata yang akan diganti.
Pencarian tambahan (
set incsearch
) memungkinkan Anda mengetikkan awalan kata yang perlu Anda temukan, dan vim akan secara otomatis beralih ke kemunculan awalan pertama saat Anda mengetik lebih banyak dan lebih banyak lagi. Pencarian akan dikonfirmasi jika Anda menekan Enter dan dibuang di Esc (dalam kasus terakhir kursor akan melompat kembali ke tempat itu sebelum pencarian dimulai).Namun, pencarian tambahan menyediakan satu fitur lagi yang bermanfaat. Saat Anda sudah mengetik awalan kata dan kursor berada di posisi yang benar, tekan
<C-L>
untuk menambahkan karakter dari kata di bawah kursor ke string pencarian. Ini memungkinkan Anda untuk memasukkan string yang diganti dengan hampir tanpa penekanan tombol.Jadi, jika saya ingin mengganti
someOddVariableName
denganevenOdderVariableName
, saya/someOddV
dan sampai pada saat terjadinyasomeOddVariableName
;<C-L>
hinggasomeOddVariableName
muncul di baris pencarian sepenuhnya;:%s//evenOdderVariableName/g
atau yang mana pun menggantikan perintah yang Anda butuhkan; Anda mungkin ingin mengikuti jawaban lain di sini.sumber
Anda dapat menempatkan nama variabel di buffer terlebih dahulu (
yw
untuk menyalin kata), lalu salin-tempel:%s
dengan menekan<C-r>"
.sumber
Jika Anda ingin mengganti variabel di dalam blok yang baru (ditempel), saya punya dua saran:
Ganti otomatis
Pergi ke baris pertama dari blok baru, tekan
ma
. Ini menandai lokasi dan menamakannyaa
.Pergi ke baris terakhir dari blok baru, tekan
mb
. Sekarang Anda memiliki dua lokasi bernama.Sekarang ganti antara dua garis, seperti:
:'a,'bs/oldVarName/newVarName/g
.Artinya, ruang lingkup penggantian berada di antara dua nilai Anda.
Cara manual
Pergi ke baris pertama dari blok baru.
Gunakan
/oldVarName
untuk menemukan contoh pertamaoldVarName
.Ubah seperti ini:,
cwnewVarName<Esc>
yang akan mengubah katanewVarName
dan memukul pelarian.Gunakan
n
untuk pergi ke contoh berikutnya darioldVarName
.Gunakan
.
untuk mengulangi perubahan terakhir (yaitu mengulanginyacw
).sumber
Banyak jawaban lain di sini sudah mencakup cara-cara yang dibangun untuk meningkatkan alur kerja temukan-dan-ganti tapi saya ingin menyebutkan abolish.vim , sebuah plugin oleh Tim Pope. Itu membuat penggantian di mana Anda ingin mencakup berbagai kasus, biasanya disebabkan oleh variasi dalam kasus atau karena Anda perlu berurusan dengan bentuk kata tunggal dan jamak.
:S/child{,ren}/adult{,s}/g
dikonversi dengan benarchild
keadult
,Children
keAdults
danCHILD
keADULT
.Jika Anda berurusan dengan kata-kata cased camel, Anda harus memasukkan huruf kapital di mana Anda membutuhkannya dalam kata-kata asli dan pengganti.
%:S/wordWrap/textBreak/g
dengan benar menangani keduanyawordWrap
danwordwrap
.sumber
Seperti yang telah ditunjukkan oleh orang lain, jika kursor Anda berada di atas kata Anda, Anda dapat menggunakan Ctrl + r keluarga perintah, karena Ctrl + r Ctrl + w mungkin yang paling cocok untuk digunakan.
Metode itu, bagaimanapun, hanya berfungsi untuk memasukkan satu kata (yang tepat di bawah kursor), tetapi bagaimana jika ada beberapa bagian teks dalam buffer yang ingin kita gunakan? Karena Anda tidak dapat memindahkan kursor saat berada di baris perintah. Cara terbaik untuk melakukan ini adalah dengan menyalin bagian-bagian teks yang akan Anda perlukan ke register yang berbeda, yang dapat Anda lakukan dengan mengawali "{reg_letter} (kutipan dan surat dari register) ke operator penyalinan. Dengan cara ini dimungkinkan untuk masukkan berbagai kata di baris perintah nanti dengan Ctrl + r {reg_letter}. Ini sedikit canggung tapi berfungsi.
Tetapi kembali ke ide sebelumnya, alangkah baiknya jika kita akan memindahkan posisi kursor di atas buffer sambil menulis sebuah pola. Dengan begitu kita bisa "mengambil" teks dari posisi yang berbeda dengan Ctrl + r Ctrl + w, jadi saya membuat plugin yang melakukan hal itu: EXtend.vim Plugin ini juga memiliki banyak fitur lain untuk melakukan operasi substitusi.
sumber