Mise en surbrillance automatique du texte des lignes identiques

13

J'ai vu un ninja vim qualifié le faire il y a quelque temps, mais je ne savais pas du tout commencer.

A) Existe-t-il un moyen de configurer la couleur d'arrière-plan de vims afin que les lignes consécutives avec un contenu identique soient mises en évidence.

B) Si quelqu'un sait comment faire cela, un bon réglage serait que la mise en évidence se produise sur des lignes consécutives mais ne considère que le premier mot (pas la ligne entière).

Un deuxième ajustement si la surbrillance peut être configurée en différentes couleurs est utilisé en fonction du nombre de lignes correspondantes (ou des mots en fonction de AB est actif). Donc, nous n'avons que deux lignes consécutives qui correspondent ensuite au vert, 3 à 5 lignes consécutives puis à l'orange, 6+ puis au rouge.

Martin York
la source
Post similaire: Pliage par motif de recherche regex
Peter Rincker

Réponses:

10

Les matchensembles suivants semblent fonctionner pour (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

Il semble que l'ordre soit crucial ici. Si les correspondances Lowou Mediumviennent après Critical, elles sont subsumées par les exigences plus lâches de celles-ci, et de même pour Lowwrt Medium.

La surbrillance n'apparaît pas immédiatement après avoir ajouté, disons, une 3e ou 6e ligne de dupe, mais une fois que vous vous déplacez un peu après les avoir ajoutées. Je ne sais pas exactement ce qui le déclenche.

Pour B, j'imagine que vous pourriez remplacer l'expression régulière par:

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

En général, remplacez tous les mots (.*)par (\S+).*et \1par \1.*, ou tout ce qui constitue un mot pour vous.

muru
la source
J'ai donné cette réponse la coche parce que pour moi c'est comment faire la mise en évidence dont j'avais besoin (comme exprimé par la question). @Matts expression régulière sympa mais ne répond pas à la question que j'ai posée (changement de la surbrillance)
Martin York
8

Comme point de départ, voici un modèle de recherche qui correspond aux lignes en double (en ignorant les changements dans les espaces blancs de tête):

              \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 fournira plus d'informations sur la façon de faire des expressions rationnelles comme celle-ci

:help syntax vous montrera comment prendre cette expression régulière et la transformer en quelque chose qui est mis en évidence pour vous

Apprendre à écrire des scripts de syntaxe peut être difficile, donc une bonne solution à court terme est de le faire `` à la volée '' en veillant à 'incsearch'ce que les recherches soient mises en évidence et en mappant une clé pour effectuer la recherche ci-dessus, c'est-à-dirennoremap <F5> /^\s*\(.\+\)\n\zs\(\s*\1\n\)\+<CR>

Matt Boehm
la source
Existe-t-il un moyen automatisé de distribuer l'expression régulière comme ça? Il fournit une représentation si claire.
muru le
1
Je l'ai fait à la main. Le moyen le plus simple et rapide dans vim serait de faire quelque chose comme yy10psur la ligne avec l'expression régulière complète, puis de sélectionner les parties que vous souhaitez supprimer et frapper r<space>. Je vais peut-être ajouter une commande pour «remplacer tout sauf la sélection sur cette ligne avec des espaces» pour accélérer un peu les choses.
Matt Boehm
Hou la la! C'est pas mal d'efforts!
muru
1
J'ai créé une fonction vim (vraiment moche) pour rendre cela un peu plus rapide: gist.github.com/mattboehm/da63a48eedf6f14375aa . Sélectionnez une ligne, appuyez sur ,rpuis joignez les lignes <space>en mode normal / visuel.
Matt Boehm