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

如何在vim中区分打开文件中的两行?,vim,Vim,我偶尔会在代码中看到很长的行,我需要检查它们是否相同。在vim中是否有方法选择两条线并将其区分以显示两者之间的任何差异 例如,给定vim中的两行: AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *lists); AVeryLongReturnType* MyLongClassName:hasAnEvenL

我偶尔会在代码中看到很长的行,我需要检查它们是否相同。在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告诉我,这两行实际上是不同的,因为每一行的拼写“列表”不同。这可能吗?如果可能,我该怎么做?

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

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

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

    exec "tabedit " . f1
    exec "vert diffsplit " . f2
endfunction
这将在另一个选项卡的垂直拆分中打开当前行和下一行。 请注意,此代码是一个示例

  • 它不检查下一行是否存在(有任何后续行)
  • 它不会清理创建的临时文件
  • 一个很好的改进是选择一个范围,或者使用
    '
    标记选择另一行
您可以省略“垂直”以进行水平拆分

将它映射到一些新奇的东西,这样您就不必手动调用它了:

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

替代@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)))
对于示例数据,这提供了两个缓冲区

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

仅突出显示以
参数
开头的行

您甚至可以从那里构建,创建一个命令

comma! DiffTwoCFunctionSigs DiffWithNextPre split(text, '[(,)]\s*\zs')
请注意,我稍微修改了regexp,以便它在行的末尾保留尾随空格。通过将
\s*
移动到
\zs
之后,可以完全忽略它们。如果您不熟悉vim特定的re-atom的功能,请参阅
:help/\zs


一个精确的方法是使命令获取一个范围(请参见
:help command range
),您可以通过将范围的第一行与最后一行分开来使用该范围。因此,您只需从第一行到第二行进行可视化选择并调用命令。

您也可以创建一个新的空窗口缓冲区并复制行,然后生成命令:

:windo diffthis 

这将打开一个新窗口,显示这两行之间的差异。一个快速而肮脏的解决方案是只选择两行并对其进行排序,同时删除重复项:

  • 选线
  • “:排序u”
  • 如果只剩下一条线,两条线是相等的
  • 如果两者都保留下来,那么大多数情况下会有一些不同
撤消将再次恢复所有内容。

我使用过


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

感谢您展示了创建带参数的命令的示例。我有点不知所措(我的答案是我有史以来第一个vim脚本,除了在vimrc中设置选项…@sehe:这可能需要很多东西,是的:)如果你制作一个文件
~/.vim/plugins/diff\u两行。vim
并将代码放在其中,那么无论何时使用vim,你都可以使用这些命令。或者实际上,您可以将它们放在您的.vimrc中;让它成为一个插件只是稍微有点条理。请记住,您必须重新启动vim(或
:source
您的脚本)才能使命令工作。如果在两个缓冲区中使用
:diffthis
:difft
),则它们将不同。这就是genius。我一直在想一个好的干净的解决方案!如何在不同的拆分窗口中生成结果?@serup的“结果”是指您希望在新的拆分窗口中看到“不同”或“相等”两个词?有了这个提议,我真的不知道如果不再次引入一些助手脚本,它将在上面的“第二个点”之前和之后计算行数,如何做到这一点。。。如果这个数字改变,线条就相等,如果不改变,线条就必须不同。@CoryKlein我不认为这是一个“干净”的解决方案,但它非常有效:-)我喜欢它!谢谢,回答得很好!变量名前面的符号真的有必要吗?@MatthiasBraun-Oops。不,看来我在2011年对Vim脚本有一些误解!修正了。:-)我明白了。您现在将所有命令包装在
exec
s中有什么原因吗?我只是好奇,想了解更多关于Vim脚本的知识。@MatthiasBraun是的。从这里开始(我的原始代码实际上创建了名为
&f1
&f2
的文件,而不是错误地使用
tempname()
comma! DiffTwoCFunctionSigs DiffWithNextPre split(text, '[(,)]\s*\zs')
:windo diffthis