您将如何标记缓冲区中与其他行完全相同的所有行?通过标记它们,我的意思是突出显示它们或添加字符或其他内容。我想保留缓冲区中各行的顺序。
之前:
foo
bar
foo
baz
后:
foo*
bar
foo*
baz
Answers:
作为前班轮:
: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//
贾斯汀的非正则表达式方法可能更快:
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()
hi link Repeat Statement
到您的中~/.vimrc
。
为什么不使用:
V*
在正常模式下。
它只是搜索当前行的所有匹配项,从而突出显示它们(如果启用了设置,我认为这是默认设置),然后,您可以使用
n
浏览比赛
尝试:
:%s:^\(.\+\)\n\1:\1*\r\1:
希望这行得通。
更新:下次尝试。
:%s:^\(.\+\)$\(\_.\+\)^\1$:\1\r\2\r\1*: