Ответ 1
Как один однострочный:
:syn clear Repeat | g/^\(.*\)\n\ze\%(.*\n\)*\1$/exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' | nohlsearch
Используется группа Repeat
, чтобы выделить повторяющиеся строки.
Разрушение:
-
syn clear Repeat
:: удалить все ранее найденные повторы -
g/^\(.*\)\n\ze\%(.*\n\)*\1$/
:: для любой строки, которая повторяется позже в файле- регулярное выражение
-
^\(.*\)\n
:: полная строка -
\ze
:: конец совпадения - проверьте остальную часть шаблона, но не потребляйте согласованный текст (положительный результат) -
\%(.*\n\)*
:: любое количество полных строк -
\1$
:: полный повтор строки согласованной полной строки
-
-
exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"'
:: добавить полные строки, соответствующие этому, в синтаксическую группуRepeat
-
exe
:: выполнить заданную строку как команду ex -
getline('.')
:: содержимое текущей строки, сопоставляемойg//
-
escape(..., '".\^$*[]')
:: избегать заданных символов с обратными косыми чертами, чтобы сделать законное регулярное выражение -
syn match Repeat "^...$"
:: добавить данную строку в синтаксическую группуRepeat
-
- регулярное выражение
-
nohlsearch
:: удалить выделение из поиска, выполненного дляg//
Justin non-regex метод, вероятно, быстрее:
function! HighlightRepeats() range
let lineCounts = {}
let lineNum = a:firstline
while lineNum <= a:lastline
let lineText = getline(lineNum)
if lineText != ""
let lineCounts[lineText] = (has_key(lineCounts, lineText) ? lineCounts[lineText] : 0) + 1
endif
let lineNum = lineNum + 1
endwhile
exe 'syn clear Repeat'
for lineText in keys(lineCounts)
if lineCounts[lineText] >= 2
exe 'syn match Repeat "^' . escape(lineText, '".\^$*[]') . '$"'
endif
endfor
endfunction
command! -range=% HighlightRepeats <line1>,<line2>call HighlightRepeats()