How do you exit vimdiff mode in vim, specifically, for Fugitive?

VimVimdiffVim Fugitive

Vim Problem Overview


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

Vim Solutions


Solution 1 - Vim

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.

Solution 2 - Vim

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."

Solution 3 - Vim

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.

Solution 4 - Vim

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

Solution 5 - Vim

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>

Solution 6 - Vim

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

Solution 7 - Vim

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>

Solution 8 - Vim

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

Solution 9 - Vim

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.

Solution 10 - Vim

this is what I have to leave the vimdiff windows after using :Gdiff

nnoremap gD :q!<CR> :Gedit!<CR>

Solution 11 - Vim

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

Solution 12 - Vim

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>

Solution 13 - Vim

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

Solution 14 - Vim

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

Solution 15 - Vim

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwikView Question on Stackoverflow
Solution 1 - VimZyXView Answer on Stackoverflow
Solution 2 - VimjtrileyView Answer on Stackoverflow
Solution 3 - VimHenrik NView Answer on Stackoverflow
Solution 4 - VimJens NorrgrannView Answer on Stackoverflow
Solution 5 - VimblueyedView Answer on Stackoverflow
Solution 6 - VimradmenView Answer on Stackoverflow
Solution 7 - VimJosé LuisView Answer on Stackoverflow
Solution 8 - VimaemongeView Answer on Stackoverflow
Solution 9 - Vimjack guanView Answer on Stackoverflow
Solution 10 - VimAdolfo AbeggView Answer on Stackoverflow
Solution 11 - VimBohrView Answer on Stackoverflow
Solution 12 - VimrafiView Answer on Stackoverflow
Solution 13 - Vimcc9ciiView Answer on Stackoverflow
Solution 14 - VimwisefoolView Answer on Stackoverflow
Solution 15 - VimCalebView Answer on Stackoverflow