如何在vim的打开文件中区分两行?

时间:2011-04-01 21:20:28

标签: vim

我偶尔会在代码中看到很长的行,我需要检查它们是否相同。在vim中是否有一种方法可以选择两条线并对它们进行区分以显示两条线之间的差异?

例如,给定vim中的两行:

AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *lists);
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *1ists);

我希望vim告诉我这两条线实际上是不同的,因为每个法术的“列表”都不同。这是可能的,如果是这样,我该怎么做?

5 个答案:

答案 0 :(得分:20)

已经是一个老问题了,但对于谁仍然感兴趣:快速而肮脏的解决方案是只选择两行并对其进行排序,同时删除重复项:

  • 选择行
  • “:sort u”
  • 如果只剩下一行,则两者相等
  • 如果两者都存在,则会有一些差异

撤消会再次恢复所有内容。

答案 1 :(得分:8)

@ sehe方法的替代方法不需要使用临时文件:

funct! DiffTwoTexts(text1, text2)
  new
  put =a:text1
  normal ggdd
  diffthis
  new
  put =a:text2
  normal ggdd
  diffthis
endfunct

funct! DiffTwoLines(line1, line2)
  let text1 = getline(a:line1)
  let text2 = getline(a:line2)
  call DiffTwoTexts(text1, text2)
endfunct

comma! DiffWithNext call DiffTwoLines('.', line('.') + 1)

这仍然很难阅读,因为它将所有内容保存在一行中,所以我想出了这个修改:

funct! EvalTextPreprocessor(expr, text)
  let text = a:text
  return eval(a:expr)
endfunct

comma! -nargs=1 DiffWithNextPre call DiffTwoTexts(
      \ EvalTextPreprocessor(<q-args>, getline('.')),
      \ EvalTextPreprocessor(<q-args>, getline(line('.') + 1)))

这个新命令将vimscript表达式作为其参数,其中变量text指的是正在预处理的任何一行。所以你可以打电话,例如

DiffWithNextPre split(text, '[(,)]\zs')

对于您的样本数据,这将提供两个缓冲区

AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(
That *is,
 Overloaded *with,
 Multiple *different,
 Parameter *lists)
;

AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(
That *is,
 Overloaded *with,
 Multiple *different,
 Parameter *1ists)
;

仅突出显示以Parameter开头的行。

你甚至可以从那里建立一个命令

comma! DiffTwoCFunctionSigs DiffWithNextPre split(text, '[(,)]\s*\zs')

请注意,我稍微修改了正则表达式,以便在行尾保留尾随空格。您可以将\s*移到\zs之后完全忽略它们。如果您不熟悉特定于vim的RE原子的作用,请参阅:help /\zs

准确的做法是让命令占用一个范围(参见:help command-range),你可以通过将最后一行的范围的第一行差异化来使用。那么你只需从第一行到第二行进行视觉选择并调用命令。

答案 2 :(得分:5)

这不是一个功能,但它很容易编写脚本,例如在你的vimrc中:

function! DiffLineWithNext()
    let f1=tempname()
    let f2=tempname()

    exec ".write " . f1
    exec ".+1write " . f2

    exec "tabedit " . f1
    exec "vert diffsplit " . f2
endfunction

这将在另一个选项卡中打开垂直分割中的当前和下一行。 请注意,此代码是示例

  • 它不会检查下一行是否存在(有任何后续行)
  • 它不会清除创建的临时文件
  • 一个很好的改进是采用范围,或使用''标记来选择其他

你可以不使用'vert'来进行水平分割

将其映射到某种奇特的东西,这样您就不必手动:call

:nnoremap <F10> :call DiffLineWithNext()^M

答案 3 :(得分:3)

我使用linediff.vim

此插件提供了一个简单的命令“:Linediff”,用于区分两个单独的文本块。

答案 4 :(得分:1)

你也可以创建一个新的空窗口缓冲区和复制线,然后创建命令:

:windo diffthis 

这应该打开一个新窗口,显示这两行的差异