vim执行diff命令两次

vim执行diff命令两次,vim,diff,Vim,Diff,我发现我的vim有一个奇怪的行为:它执行每个diff命令两次,我不知道为什么 (我在Windows上运行这个,我怀疑这与此有关。)根据答案,它没有 所以我的vimrc中有这个: set diffexpr=MyDiff() function! DoubleQuoteCond(s) return a:s =~ ' ' ? '"' . a:s . '"' : a:s endfunction function! MyDiff() if &shell =~ '\<cmd'

我发现我的vim有一个奇怪的行为:它执行每个diff命令两次,我不知道为什么

(我在Windows上运行这个,我怀疑这与此有关。)根据答案,它没有

所以我的vimrc中有这个:

set diffexpr=MyDiff()

function! DoubleQuoteCond(s)
  return a:s =~ ' ' ? '"' . a:s . '"' : a:s
endfunction

function! MyDiff()
   if &shell =~ '\<cmd'
    let prog = DoubleQuoteCond($VIMRUNTIME . '\diff')
  else
    let prog = substitute($VIMRUNTIME, ' ', '" ', '') . '\diff')
  endif

  let opt = '-a --binary'
  if &diffopt =~ 'icase' | let opt .= ' -i' | endif
  if &diffopt =~ 'iwhite' | let opt .= ' -b' | endif

  let file1 = DoubleQuoteCond(v:fname_in)
  let file2 = DoubleQuoteCond(v:fname_new)
  let file3 = DoubleQuoteCond(v:fname_out)

  let cmdline = join([prog, opt, file1, file2, '>', file3], ' ')

  " no silent execute for debugging reasons
  execute '!' . cmdline 
endfunction
现在这种情况发生了:

  • 执行此cmdline时,会弹出一个cmd窗口,并创建文件
    VIdCC22.tmp

    由于没有
    静默执行
    ,我必须按enter键才能继续
  • 紧接着,vim再次执行相同的操作,就好像调用了两次
    MyDiff()
  • 现在vim拾取差异输出并按预期显示
当我将
diffexpr
设置为
'
时,diff shell命令只执行一次


第二次执行从何而来?设置
'differxpr'

如果差异输出看起来正常,Vim将进行测试

(这来自
:help E810

你无法避免这一点。但是,您可以检查测试,因为Vim传递恒定的虚拟文件内容(“分别为line1”和“line2”),并在这种情况下短路外部命令执行,如下所示:

if
\   getfsize(v:fname_in) <= 6 &&
\   getfsize(v:fname_new) <= 6 &&
\   readfile(v:fname_in, 0, 1)[0] ==# 'line1' &&
\   readfile(v:fname_new, 0, 1)[0] ==# 'line2'
    return
endif
if

\getfsize(v:fname_in)糟糕透了!我还没有看过文件的内容。我如何使命令执行短路?我的意思是,vim希望输出文件以某种方式显示,所以我必须让它做它自己的事情,不是吗?我已经在我的答案中添加了一个示例实现。我想vim在第一次调用
MyDiff()
之后读取
v:fname\u的内容,所以不执行test命令对我没有帮助。不,但是,您可以伪造输出(例如,使用
writefile()
),但这种方式不会调用您的实际差异,因此会强制您使用Enter进行确认。是的,我可以这样做。o当我使用
silent execute
时,我也不必按enter键。我已经使用diff功能很多年了,但直到最近才注意到这种行为。我只是想知道第二次处决是从哪里来的。现在我明白了,我想我还是保持原样吧。
if
\   getfsize(v:fname_in) <= 6 &&
\   getfsize(v:fname_new) <= 6 &&
\   readfile(v:fname_in, 0, 1)[0] ==# 'line1' &&
\   readfile(v:fname_new, 0, 1)[0] ==# 'line2'
    return
endif