开发者

How to diff two lines in an open file in vim?

I occasionally see very long lines in my code that I need to check if they are the same. Is there a way in vim to select two lines and diff them to show any differences between the two?

For example, given the two lines in vim:

AVeryLongReturnType* MyLongClassName:has开发者_运维问答AnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *lists);
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *1ists);

I would like vim to tell me that the two lines are in fact different because each spells "lists" differently. Is this possible, and if so, how do I do it?


A quick and dirty solution is to just select both lines and sort them while removing duplicates:

  • select lines
  • ":sort u"
  • if only one line remains, both were equal
  • if both remain, there most be some difference

An undo recovers everything again.


An alternative to @sehe's approach would not require the use of temp files:

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)

This will still be pretty hard to read, since it keeps everything on a single line, so I came up with this modification:

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)))

This new command takes a vimscript expression as its argument, wherein the variable text refers to whichever line is being preprocessed. So you can call, e.g.

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

For your sample data, this gives the two buffers

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

and

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

Only the lines that start with Parameter are highlighted.

You can even build up from there, creating a command

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

Notice that I modified the regexp a bit so that it will keep trailing spaces at the end of lines. You could get it to ignore them entirely by moving the \s* to after the \zs. See :help /\zs if you're unfamiliar with what that vim-specific RE atom does.

A nicety would be to make the command take a range (see :help command-range), which you could use by diffing the first line of the range with the last line. So then you just visual-select from the first line to the second and call the command.


I used linediff.vim.

This plugin provides a simple command, ":Linediff", which is used to diff two separate blocks of text.


That is not a feature, however it is easily scripted, e.g. in your vimrc:

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

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

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

This will open the current and next lines in vertical split in another tab. Note that this code is a sample

  • it doesn't check whether next line exists (there are any following lines)
  • it doesn't cleanup the tempfiles created
  • a nice improvement would be to take a range, or use the '' mark to select the other line

You can leave off the 'vert' in order to have a horizontal split

Map it to something fancy so you don't have to :call it manually:

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


you could also just create a new empty window buffer and copy line, then make command:

:windo diffthis 

this should open a new window showing the differences of those 2 lines

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜