Авто выделение одинаковых строк текста

13

Я видел, как опытный ниндзя Vim делал это некоторое время назад, но я понятия не имел, с чего начать.

А) Есть ли способ настроить цвет фона vims так, чтобы выделялись последовательные строки с одинаковым содержимым.

Б) Если кто-то знает, как это сделать, то неплохо было бы сделать это, если бы выделение происходило в последовательных строках, а учитывалось только первое слово (а не вся строка).

Вторая настройка, если подсветка может быть настроена на разные цвета, используется в зависимости от количества совпадающих строк (или активны слова в зависимости от AB). Таким образом, у нас есть только две последовательные линии, которые соответствуют зеленым, 3-5 последовательных линий, затем оранжевым, 6+, а затем красным.

Мартин Йорк
источник

Ответы:

10

Следующие matchнаборы, кажется, работают для (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

Кажется, порядок здесь имеет решающее значение. Если после Lowили Mediumвстречаются совпадения Critical, они попадают под более слабые требования к ним и аналогично для Lowwrt Medium.

Подсветка появляется не сразу после добавления, скажем, 3-й или 6-й строки дубликата, а после того, как вы немного переместитесь после их добавления. Я не уверен, что именно это вызывает.

Для B, я думаю, вы могли бы заменить регулярное выражение на:

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

В общем, заменить все (.*)с (\S+).*и \1с \1.*, или то , что представляет собой слово для вас.

Мур
источник
Я дал этому ответу галочку, потому что для меня это как сделать подсвечивание, в котором я нуждался (как выражено вопросом). Регулярное выражение @Matts приятно, но не отвечает на тот вопрос, который я задал (изменение подсветки).
Мартин Йорк
8

В качестве отправной точки, вот шаблон поиска, который совпадает с повторяющимися строками (игнорируя изменения в начальных пробелах):

              \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 предоставит больше информации о том, как сделать регулярные выражения, как это

:help syntax покажет вам, как взять это регулярное выражение и превратить его в то, что выделено для вас

Научиться писать синтаксические скрипты может быть непросто, поэтому хорошим краткосрочным решением является сделать это «на лету», убедившись 'incsearch', что поиски выделены и сопоставлены ключи для выполнения вышеуказанного поиска, т.е.nnoremap <F5> /^\s*\(.\+\)\n\zs\(\s*\1\n\)\+<CR>

Мэтт Бём
источник
Есть ли какой-нибудь автоматизированный способ распространения регулярных выражений, подобных этому? Это обеспечивает такое четкое изображение.
Муру
1
Я делал это вручную. Самый простой способ в vim - сделать что-то вроде yy10pстроки с полным регулярным выражением, затем выбрать части, которые вы хотите удалить, и нажать r<space>. Может быть, я добавлю команду «заменить все, кроме выделения в этой строке пробелами», чтобы немного ускорить процесс.
Мэтт Бём
Вот это да! Это довольно много усилий!
Муру
1
Я сделал (действительно некрасивую) функцию vim, чтобы сделать это немного быстрее: gist.github.com/mattboehm/da63a48eedf6f14375aa . Выберите линию, нажмите, ,rзатем соедините линии вместе <space>в обычном / визуальном режиме.
Мэтт Бём