Mengabaikan diakritik / aksen saat mencari

12

Apakah ada cara untuk menginstruksikan Vim bahwa saya ingin mengabaikan diakritik / aksen saat mencari? Sebagai contoh, saya ingin dapat mencari

kočička

dengan masuk

/kocicka

The ignorecasedan smartcasepilihan yang sangat berguna, tetapi mereka tampaknya tidak ada hubungannya dengan diakritik / aksen.

s3rvac
sumber
3
Terkait: :h [[=dan :h patterns-composing.
muru

Jawaban:

16

Seperti @muru disebutkan dalam komentar , Anda bisa menggunakan kelas ekivalensi (dijelaskan dalam :help /[[) yang tampaknya merupakan ekspresi kelas karakter yang dievaluasi sebagai seperangkat karakter yang sama (yaitu sama setelah Anda menghilangkan aksen / diakritik).

Misalnya, untuk mencari kočičkadan kocickadengan pola yang sama, Anda bisa menggunakan ini:

ko[[=c=]]i[[=c=]]ka

di mana [[=c=]]kelas ekivalensi untuk ckarakter.


Untuk secara otomatis memasukkan kelas karakter ini setiap kali Anda menekan csaat melakukan pencarian, Anda dapat menggunakan pemetaan ini:

cnoremap <expr> c getcmdtype() =~ '[?/]' ? '[[=c=]]' : 'c'

yang bisa dipecah seperti ini:

  • <expr> ketik evaluasi ekspresi
  • getcmdtype() =~ '[?/]' uji apakah Anda sedang menulis pencarian mundur atau maju
  • '[[=c=]]'mengembalikan kelas ekivalensi untuk ckarakter jika tes sebelumnya berhasil
  • 'c'kembalikan ckarakter sebaliknya

Pemetaan sebelumnya memiliki 2 kelemahan:

  1. itu hanya mencakup ckarakter
  2. itu bisa membuat polanya sulit dibaca

Ini dapat ditingkatkan dengan memetakan kembali <CR>seperti ini:

cnoremap <CR> <C-\>e getcmdtype() =~ '[?/]' ? substitute(getcmdline(), '\a', '[[=\0=]]', 'g'): getcmdline()<CR><CR>

Ketika Anda menekan <CR>setelah menulis pola pencarian, pemetaan akan secara otomatis mengganti semua karakter alfabet dengan rekan kelas ekivalen mereka.


Pemetaan untuk <CR>mirip dengan pemetaan sebelumnya c, kecuali tidak menggunakan argumen <expr>tetapi pemetaan sistem <C-\>e.
<expr>memungkinkan Anda untuk memasukkan evaluasi ekspresi, sementara <C-\>ememungkinkan Anda untuk mengganti seluruh baris perintah dengan evaluasi ekspresi.

pengguna9433424
sumber
1
Lebih lanjut, jika Anda ingin pergi ke arah sebaliknya, misalnya, /kočičkacocok kocicka, maka Anda dapat menggunakan '[[:lower:][:upper:]]'sebagai gantinya '\a'. Alternatif '[:alpha:]'dan '\I'sepertinya tidak bekerja dengan karakter multi-byte; namun, '[^[:punct:]]'tampaknya berhasil (meskipun saya kurang yakin), dan saya kira membangun kelas kesetaraan Anda sendiri (misalnya, '[А-яЁё]') juga.
kevinlawler
Saya berharap ada pengaturan untuk itu. Saat menggunakan [[= c =]] bekerja tetapi kesalahan ketik berarti Anda harus mengklik backspace 7 kali. Juga keterbacaan menderita.
daliusd