如何在vim中退出vimdiff模式,特别是针对Fugitive?

69

我正在使用vim和fugitive扩展。它有一个:Gdiff命令可以进入vimdiff模式,但是关闭/退出vimdiff模式的正确/快捷方式是什么?

也就是说,假设我正在编辑Git存储库下的文件FooBar.txt。我启动:Gdiff,在vimdiff中查看我的更改,然后我想回到并继续编辑FooBar.txt或任何其他文件 :)

UPDATE1: 我会在下一个工作日尝试这些快捷键组合 :)

"vimdiff current vs git head (fugitive extension)
nnoremap <Leader>gd :Gdiff<cr> 
"switch back to current file and closes fugitive buffer
nnoremap <Leader>gD :diffoff!<cr><c-w>h:bd<cr>

更新2: 我当前的映射(仅关闭差异窗口!)

"vimdiff current vs git head (fugitive extension)
nnoremap <Leader>gd :Gdiff<cr> 
"switch back to current file and closes fugitive buffer
nnoremap <Leader>gD <c-w>h<c-w>c

另外,请帮我决定以下内容是否应该作为答案:https://dev59.com/tnE85IYBdhLWcg3wl0nF#15975201


1
gD对我来说不需要:diffoff!<cr> - blueyed
2
仅关注diff窗口和使用:q关闭它似乎就可以解决问题了。不过,如果有一种简单的方法可以在任何一个窗口中完成这个操作就更好了。 - Aaron Gibralter
看起来大多数,如果不是全部的答案都是针对Fugitive插件的,只有部分适用于更简单的Vim配置。 - MarkHu
15个回答

61

更新:有一个 diffoff 命令。使用 windo diffoff 命令,而不是我在上一行中写的命令。


8
同样的操作,对吗?我是从vim_use群组的Tony M.那里了解到这个命令的。 - wik
6
这不会关闭由:Gdiff打开的窗口,对吗? - blueyed
@blueyed 是的,它不会。我不使用fugitive,但是使用 VCSVimDiffVCSCommand 插件创建的diff模式)如果您在第二个缓冲区上运行:bw,则会替换为非diff模式(在运行VCSVimDiff之前处于活动状态)。这非常方便,但这是VCSCommand插件独有的功能,而不是vim开箱即用提供的功能。如果您想要,可以在vimrc中创建具有类似功能的autocommand。 - ZyX
@BjornTipling 什么不起作用?diffoff 禁用 vimdiff 模式,无论哪个插件启动它。 - ZyX
它不会关闭窗口并将用户带回到他们在输入Gdiff之前的位置,@jtriley的答案可以做到这一点。这就是原始问题想要的:“然后我想回去继续编辑FooBar.txt” - Bjorn
3
@BjornTipling 我个人不喜欢<C-W><C-O>的原因是它关闭所有窗口,包括Git状态窗口,而这个窗口在进行更深入的调查时非常有用,例如,在Git状态窗口中有一个<S-D>映射,可以在突出显示的文件上打开差异模式。 - wik

41

3
在我看来,这应该是被选中的答案。 - lkraav
10
但是,如果在进入Gdiff之前有多个窗口打开,这将会引起问题-- Gdiff只会在原始缓冲区旁边添加一个缓冲区,而不会关闭任何其他窗口。你需要重新打开所有其他正在处理的内容。 - matthias
3
当你从git状态窗口进行diff时,这种方法并不是特别有用,因为它会关闭所有窗口... - wik
Gdiff会打开另一个带有分割窗口的缓冲区(标签页),所以这种方法行不通。 - Geoffrey

13

我使用 diffoff 没有成功,但是我刚刚学到如果不带参数使用:Gedit,将会返回当前工作目录中的文件版本,而不是你之前查看的某个较早的版本。

另外,使用 q(无需使用 :q )可以关闭 diff 侧边栏,你可以先执行 q 再执行 :Gedit 来摆脱侧边栏并回到当前文件的版本。


4
q将开始录制。所以不确定你使用的是什么类型的“q”。也许这是一个GUI Vim的东西或其他什么东西。 - Bjorn
一些插件会重新映射 q 键,仅在给定的缓冲区中 (map <buffer> q ZZ 或其他方式) 以关闭该缓冲区。对我来说,在 Fugitive git blame "侧边栏" 中发生了这种情况。不记得是否还在任何差异视图中使用过。 - Henrik N
“:Gedit”的默认行为可以更改。现在它将编辑索引中的相应文件,而不是工作树文件。 - Bohr
@systemovich 这个答案建议先执行 :q(或者只输入 q)来关闭差异侧边栏。 - Henrik N

4
这对我来说很有效,结合了一些现有的想法:
function! MyCloseDiff()
  if (&diff == 0 || getbufvar('#', '&diff') == 0)
        \ && (bufname('%') !~ '^fugitive:' && bufname('#') !~ '^fugitive:')
    echom "Not in diff view."
    return
  endif

  " close current buffer if alternate is not fugitive but current one is
  if bufname('#') !~ '^fugitive:' && bufname('%') =~ '^fugitive:'
    if bufwinnr("#") == -1
      b #
      bd #
    else
      bd
    endif
  else
    bd #
  endif
endfunction
nnoremap <Leader>gD :call MyCloseDiff()<cr>

4
我已经找到了一个简单的解决方案。你可以在这里查看:https://gist.github.com/radmen/5048080
" Simple way to turn off Gdiff splitscreen
" works only when diff buffer is focused
if !exists(":Gdiffoff")
  command Gdiffoff diffoff | q | Gedit
endif

我喜欢这个。Ex 命令又赢了。我想我会使用这个。 - sehe

4

以上的解决方案都不适用于我。最终,我采取了以下方法:

nnoremap <Leader>D :Gedit<CR><C-w>h :q<CR><C-w>k


1
刚刚想到这个:nnoremap g<C-q> ZZ:Gedit<CR>(参见我今天的问题)。我认为它更好一些,因为它避免了在窗口之间移动。 - sehe

4
如果你有多个窗口,可以选择移动到另一个差异窗口并执行"<C-W>c",只关闭一个窗口,这是替代"<C-W><C-O>"的方法。
如果你关闭了错误的差异窗口,可以执行":Gedit"。
请注意,不要将"<C-W>c"与"<C-W><C-C>"混淆。

这与我在我的gD映射中最终所做的非常相似:nnoremap <Leader>gD <c-w>h:bd<cr> - wik

1

方法一:

  • 通过以下命令打开比较窗口:

:windo diffthis

  • 通过以下命令关闭比较窗口:

:windo diffoff

方法二:

我建议使用最简单的命令::q<CR>

当您想快速完成时,请添加映射:

" Set mapleader
let mapleader = ","
let g:mapleader = ","

并且

" Quickly close the current window
nnoremap <leader>q :q<CR>

这对我非常有效。只需通过,q退出vimdiff,因为通常光标在旧文件中。


1

此页面中查看vimdiffdiffthisdiffoff之间的切换。

代码:

nnoremap <silent> <Leader>df :call DiffToggle()<CR>

function! DiffToggle()
    if &diff
        diffoff
    else
        diffthis
    endif
:endfunction

0

另一种方法。在我的fugitive.vim中 - 当diff开始时,首先保存一些信息(s:gitbufname):

function! s:Diff(vert,...) abort
  call sy#toggle()
  let s:startcol = winwidth(0)
  let &columns=(winwidth(0) * 2 - 20)
...
    if getwinvar('#', '&diff')
      let s:gitbufname = bufname("%")
      wincmd p
      call feedkeys(winnr."\<C-W>w", 'n')
    endif
...
endfunction

后来当离开缓冲区切换窗口时,返回保存的缓冲区并恢复:

augroup fugitive_diff
autocmd!
autocmd BufWinLeave *
  \ if s:can_diffoff(+expand('<abuf>')) && s:diff_window_count() == 2 |
  \   if exists('s:gitbufname') && winnr() != bufwinnr(s:gitbufname) |
  \     let nr = bufnr("%") | exe bufwinnr(s:gitbufname).'wincmd w' | exe 'buf'.nr |
  \   endif |
  \   call s:diffoff_all(getbufvar(+expand('<abuf>'), 'git_dir')) |
  \   call sy#toggle() |
  \   call airline#load_theme() | call airline#update_statusline() |
  \   let &columns=s:startcol |
  \ endif
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接