问题
I am using vim with the fugitive extension. It has a :Gdiff command which brings you into vimdiff mode, but what is the right/quick way to close/quit vimdiff mode?
I.e., let's say I am editing the file FooBar.txt under Git repository. I fire up :Gdiff, review my changes in vimdiff, and then I want to get back and continue editing FooBar.txt or any other file :)
UPDATE1: I'm going to give these quick combos a try next working day :)
"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>
UPDATE2: My current mappings (closes diff window only!)
"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
Also, please help me decide if the following should be an anwser: https://stackoverflow.com/a/15975201/275980
回答1:
You can execute windo set nodiff noscrollbind
and then close the second window.
Update: there is a diffoff
command. Use windo diffoff
, not what I wrote in previous line.
回答2:
According to: https://github.com/tpope/vim-fugitive/issues/36
Close the other window. The easiest way to do this if you haven't shifted focus to it is
<C-W><C-O>
, which means "make this Window the Only window."
回答3:
I had no luck with diffoff
, but I just learned that :Gedit
with no argument will bring you back to the working-directory version of the file, as opposed to some earlier version you were reviewing.
And as q
(no need for :q
) will close the diff sidebar, you can do q
followed by :Gedit
to get rid of the sidebar and then go back to the current version of the file.
回答4:
This works fine for me, combining some of the existing ideas here:
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>
回答5:
I've found a simple solution for this. You can check it here: 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
回答6:
None of the above solutions worked for me. Ended up doing this instead:
nnoremap <Leader>D :Gedit<CR><C-w>h :q<CR><C-w>k
回答7:
An alternative to <C-W><C-O>
, if you have multiple windows, would be move to the other diff window and do <C-W>c
, which close only one window.
If you close the wrong diff window do a :Gedit
Be careful and don't confuse <C-W>c
with <C-W><C-C>
回答8:
this is what I have to leave the vimdiff windows after using :Gdiff
nnoremap gD :q!<CR> :Gedit!<CR>
回答9:
noremap <leader>do :diffoff \| windo if &diff \| hide \| endif<cr>
Quite diff mode and close other diff windows. (Note: fugitive will auto delete its hidden buffers.)
回答10:
My function will work both from diff window and file window. But probably won't handle itself with multiple diffs opened. For that you'll need to use fugitive#buffer(n).path()
to scan and match.
command! Gdiffoff call Gdiffoff()
function! Gdiffoff()
let diffbufnr = bufnr('^fugitive:')
if diffbufnr > -1 && &diff
diffoff | q
if bufnr('%') == diffbufnr | Gedit | endif
setlocal nocursorbind
else
echo 'Error: Not in diff or file'
endif
endfunction
Add a key binding:
nnoremap <silent> <leader>gD :Gdiffoff<CR>
回答11:
Yet another way. What I have in fugitive.vim - first save some info (s:gitbufname) when diff starts:
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
and later when leaving the buffer switch window to the saved buffer and restore:
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
...
回答12:
Check the vimdiff
toggling between diffthis
and diffoff
here
at this page.
The code:
nnoremap <silent> <Leader>df :call DiffToggle()<CR>
function! DiffToggle()
if &diff
diffoff
else
diffthis
endif
:endfunction
回答13:
Method 1:
- open a compare by:
:windo diffthis
- close it by:
:windo diffoff
Method 2:
I recommend just using the most simple command: :q<CR>
when you want to do it quickly, add the mapping:
" Set mapleader
let mapleader = ","
let g:mapleader = ","
and
" Quickly close the current window
nnoremap <leader>q :q<CR>
It works well for me. Exit vimdiff just by ,q
, because normally your cursor in the old file.
回答14:
Was using the code below based on https://stackoverflow.com/a/15113951/10999673 :
if !exists(":Gdiffoff")
command Gdiffoff bw! fugitive://*
endif
but it gave me an error "E93: more than one match for ..." in a 3 way diff, so i instead used the answer from https://stackoverflow.com/a/4867969/10999673 and finally have this:
function! GetBufferList()
return filter(range(1,bufnr('$')), 'buflisted(v:val)')
endfunction
function! GetMatchingBuffers(pattern)
return filter(GetBufferList(), 'bufname(v:val) =~ a:pattern')
endfunction
function! WipeMatchingBuffers(pattern)
let l:matchList = GetMatchingBuffers(a:pattern)
let l:count = len(l:matchList)
if l:count < 1
echo 'No buffers found matching pattern ' . a:pattern
return
endif
if l:count == 1
let l:suffix = ''
else
let l:suffix = 's'
endif
exec 'bw ' . join(l:matchList, ' ')
echo 'Wiped ' . l:count . ' buffer' . l:suffix . '.'
endfunction
command! -nargs=1 Gdiffoff call WipeMatchingBuffers('fugitive://')
I just tweaked, copied and pasted the code into my .vimrc
回答15:
Running :Gwrite
after merging to your satisfaction will close the other two diff panes in addition to updating the git cache to mark the file as merged.
来源:https://stackoverflow.com/questions/2703644/how-do-you-exit-vimdiff-mode-in-vim-specifically-for-fugitive