Menyorot Otomatis teks garis identik

13

Saya melihat seorang ninja vim yang terampil melakukan ini beberapa waktu lalu, tetapi saya tidak tahu harus memulainya.

A) Apakah ada cara untuk mengatur warna latar belakang vims sehingga garis berurutan dengan konten yang identik dapat disorot.

B) Jika seseorang tahu bagaimana melakukan itu tweak bagus untuk ini akan terjadi jika penyorotan terjadi pada baris berturut-turut tetapi hanya mempertimbangkan kata pertama (bukan seluruh baris).

Tweak kedua jika penyorotan dapat dikonfigurasikan ke warna berbeda digunakan berdasarkan jumlah baris yang cocok (atau kata-kata tergantung pada AB aktif). Jadi kita hanya memiliki dua garis berurutan yang cocok dengan hijau, 3-5 garis berurutan kemudian oranye, 6+ kemudian merah.

Martin York
sumber
Posting serupa: Lipat dengan pola pencarian regex
Peter Rincker

Jawaban:

10

Set berikut matchtampaknya berfungsi untuk (A):

:syn match Low /\v(.+)\n(\1\n)/
:syn match Medium /\v(.+)\n(\1\n){2,4}/
:syn match Critical /\v(.+)\n(\1\n){5,}/
:hi Critical  ctermfg=red
:hi Medium  ctermfg=yellow
:hi Low  ctermfg=green

Tampaknya urutannya sangat penting di sini. Jika Lowatau Mediumcocok setelah Critical, itu akan dimasukkan oleh persyaratan lebih longgar dari ini, dan juga untuk Lowwrt Medium.

Penyorotan tidak muncul segera setelah Anda menambahkan, katakanlah, garis dupe ke-3 atau ke-6, tetapi begitu Anda bergerak sedikit setelah menambahkannya. Saya tidak yakin apa yang memicu itu, tepatnya.

Untuk B, saya bayangkan Anda bisa mengganti regex dengan:

/\v(\S+).*\n(\1.*\n)/

Secara umum, ganti semua (.*)dengan (\S+).*dan \1dengan \1.*, atau apa pun yang merupakan kata untuk Anda.

muru
sumber
Saya memberikan jawaban ini kutu karena bagi saya ini adalah cara melakukan penyorotan yang saya butuhkan (seperti yang diungkapkan oleh pertanyaan). @Matts regular expression bagus tapi tidak menjawab pertanyaan aktual yang saya tanyakan (mengubah highlighting).
Martin York
8

Sebagai titik awal, berikut adalah pola pencarian yang cocok dengan garis duplikat (mengabaikan perubahan dalam spasi putih terkemuka):

              \zs                marks start of the pattern. Everything before here will not be highlighted
 ^                               start of the line
  \s*                            leading whitespace
       .\+                       match 1 or more non-newline characters
     \(   \)                     and use parens to capture this in match group 1

            \n                   match the newline character
                 \(        \)\+  1 or more
                      \1         copies of what was in the match group 1
                   \s*  \n       with leading whitespace followed by a newline
/^\s*\(.\+\)\n\zs\(\s*\1\n\)\+   the full regex

:help pattern akan memberikan info lebih lanjut tentang cara membuat regex seperti ini

:help syntax akan menunjukkan kepada Anda cara mengambil ekspresi reguler ini dan mengubahnya menjadi sesuatu yang disorot untuk Anda

Belajar menulis skrip sintaksis bisa jadi sulit, jadi solusi jangka pendek yang baik adalah dengan melakukan ini 'on the fly' dengan memastikan 'incsearch'diatur sehingga pencarian disorot dan memetakan kunci untuk melakukan pencarian di atas, yaitunnoremap <F5> /^\s*\(.\+\)\n\zs\(\s*\1\n\)\+<CR>

Matt Boehm
sumber
Apakah ada cara otomatis untuk mendistribusikan regex seperti itu? Ini memberikan gambaran yang jelas.
muru
1
Saya sudah melakukannya dengan tangan. Cara tercepat termudah di vim adalah melakukan sesuatu seperti yy10ppada baris dengan regex penuh lalu pilih bagian yang ingin Anda hapus dan tekan r<space>. Mungkin saya akan menambahkan perintah untuk 'mengganti semuanya kecuali pemilihan pada baris ini dengan spasi' untuk mempercepat segalanya.
Matt Boehm
Wow! Itu cukup usaha!
muru
1
Saya membuat fungsi vim (benar-benar jelek) untuk membuatnya lebih cepat: gist.github.com/mattboehm/da63a48eedf6f14375aa . Pilih satu baris, tekan ,rlalu gabungkan garis bersama <space>dalam mode normal / visual.
Matt Boehm