Pengganti case preserving dalam Vim

154

Bisa ini dilakukan di Vim?

Yang saya maksud adalah: mencari 'BadJob' dan mengganti dengan 'GoodJob' akan melakukan penggantian berikut

'badjob' -> 'goodjob'  
'BadJob' -> 'GoodJob'  
'badJob' -> 'goodJob'  
'BADJOB' -> 'GOODJOB'
davetapley
sumber
16
Ini harus menjadi fitur vim. Sangat masuk akal.
Bach

Jawaban:

120

Gunakan abolish.vim :

:%S/badjob/goodjob/g
Mark Lodato
sumber
13
Kami tidak pantas menerima Paus Tim.
Andrew Keeton
1
Plugin ini sepertinya tidak berfungsi untuk saya. Jika saya menyukai kata BadJobdan ingin menggantinya GoodJob, saya tidak dapat menggunakannya %S/badjob/goodjob/g. Gagal mendeteksi kecocokan.
Roymunson
@Roymunson Yang perlu Anda lakukan adalah ini:, %S/BadJob/GoodJob/gmaka perintah Subvert akan beralih ke mode case campuran dan akan melakukan semua substitusi seperti yang diberikan oleh OP.
shivams
28

Saya tidak tahu apakah ini jenis solusi yang Anda cari ... tetapi saya telah menggunakan ini: keepcase.vim

Tidak ada dukungan di vim ...

LB40
sumber
11

tentu kamu bisa

:s/\cbad/\= strpart(submatch(0), 0 ,1) == toupper(strpart(submatch(0), 0, 1)) ? "GOOD" : "good"/

ps. Saya menebak keepcase.vim merangkum beberapa logika yang sama :)

fc.
sumber
Ya itu sejak 2007::% SubstituteCase / \ cbadjob / GoodJob / g ^^
Luc Hermitte
Berarti sejak gVim 7.2? Saya mencobanya di gVim 7.1 (12-Mei-2007) dan itu tidak berhasil :(
fc.
Tidak, saya telah menambahkan perintah: SubstituteCase ke plugin pada 2007. Itu saja. Plugin ini tersedia di vim.org, dan tidak dikirimkan dengan vim seperti biasanya dengan sebagian besar plugin.
Luc Hermitte
1. Ini gagal ketika pengguna memilikinya :set ignorecase. 2. Badakan diganti dengan GOODalih-alih Good. 3. " job" Bagian dari pertanyaan diabaikan, jadi ini juga akan menggantikan lambadalamgooda. Perbaikan dan penjelasan untuk bug ini dan beberapa hal lain dalam jawaban saya . (Juga LOLOWL!)
Aaron Thoma
7

Anda dapat menempel dan mengadaptasi ini:
(Tentu saja, jika Anda melakukan ini dari waktu ke waktu, Anda akan menginginkan plugin alih-alih keburukan ini. Tetapi bagi beberapa yang terburu-buru dan hanya membutuhkannya sekali, ini adalah hack cepat untuk kesenangan menyisipkan Anda :)

:%s/\cbad\zejob/\= ( submatch(0)[0] is# toupper(submatch(0)[0]) ? 'G' : 'g' ) . ( submatch(0)[1] is# toupper(submatch(0)[1]) ? 'OOD' : 'ood' )

Terlepas dari pola pencarian, Anda harus mengedit empat 'string 'dalam kode pengganti: Edit bagian-bagian dengan huruf tebal :

:% s / \ c bad \ ze job / \ =
(submatch (0) [0] adalah # toupper (submatch (0) [0])? ' G ': ' g ').
(submatch (0) [1] adalah # toupper (submatch (0) [1])? ' OOD ': ' ood ')

Jangan gunakan versi 'oranye' ini untuk menempel, karena karakter linebreak-nya juga akan melanggar perintah.

/\zeadalah vim regex sintaksis gula untuk menandai lookahead positif: Pola setelah \zediperiksa, tetapi tidak diganti.


is#?? Biarkan saya jelaskan ... (Jika tertarik.)

#(juga dalam ==#dan lainnya ) memberlakukan sensitivitas kasus. Kalau tidak, dengan :set ignorecase(yang saya gunakan, karena itu diperlukan untuk berguna :set smartcase), vim akan mempertimbangkan 'a' == 'A'!!

Gila apa adanya, kita harus memperhitungkannya: Karena ini tergantung pada pengaturan pengguna, ==haruskah NEVAR digunakan! (Kecuali di mana itu akan menjadi yang Anda inginkan.) Saya bahkan akan mengikuti rekomendasi untuk digunakan ==#ketika membandingkan bilangan bulat: http://learnvimscriptthehardway.stevelosh.com/chapters/22.html#code-defensive

is#alih-alih ==#adalah cara pengkodean lain secara defensif: Ini meningkatkan keamanan tipe: http://google.github.io/styleguide/vimscriptguide.xml?showone=Type_checking#Type_checking
Ini harus digunakan saat membandingkan dengan string literal.

'single-quoted'alih-alih "double quoted" string adalah praktik lain yang baik: http://google.github.io/styleguide/vimscriptguide.xml?showone=Strings#Strings


HT @fc. - jawaban ini dibangun berdasarkan jawaban mereka , memperbaiki beberapa kekurangan.

Aaron Thoma
sumber
4

Jika Anda hanya mencocokkan string (tidak tergantung kasus) yang tepat dengan beberapa kapitalisasi yang mungkin, kemungkinan lain adalah:

:s/abc/\={'abc':'xyz','Abc':'Xyz'}[submatch(0)]/i
rampion
sumber
2

Alternatif untuk plugin keepcase adalah SmartCase - mengganti kata-kata sambil menyimpan case aslinya . (Jangan biarkan diri Anda patah semangat dengan peringkat buruk.)

Ingo Karkat
sumber
1
Apakah ada trik untuk mempersingkat yang sulit diingat dan membosankan untuk mengetik perintah seperti :%s/file\A\?size/\=SmartCase("LastModifiedTime")/ig?
Michael Härtl
@ MichaelHärtl: Anda dapat menggunakan :SmartCaseperintah. Saya telah memperpanjang itu di garpu saya sendiri . Perhatikan bahwa ini membutuhkan perpustakaan-ingo sebagai ketergantungan.
Ingo Karkat