From 67c8cca8900fdf543f234b49a3636717b505c1bb Mon Sep 17 00:00:00 2001 From: Andy Stewart Date: Tue, 27 Aug 2019 16:56:30 +0100 Subject: [PATCH] Support Vim's popup windows for hunk previews. Note this prevents staging partial hunks via the previw window. --- README.mkd | 8 ++-- autoload/gitgutter/hunk.vim | 73 ++++++++++++++++++++++++------------- doc/gitgutter.txt | 10 +++-- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/README.mkd b/README.mkd index fa4d91a..a6e1d70 100644 --- a/README.mkd +++ b/README.mkd @@ -200,6 +200,8 @@ To stage part of any hunk: * delete the lines you do not want to stage; * stage the remaining lines: either write (`:w`) the window or stage via `hs` or `:GitGutterStageHunk`. +Note the above workflow is not possible if you have opted in to preview hunks with Vim's popup windows. + See the FAQ if you want to unstage staged changes. The `.` command will work with both these if you install [repeat.vim](https://github.com/tpope/vim-repeat). @@ -269,7 +271,7 @@ You can customise: * Whether vim-gitgutter runs asynchronously (defaults to yes) * Whether to clobber or preserve non-gitgutter signs * The priority of gitgutter's signs. -* Whether to use a floating window for hunk previews (Neovim only) +* Whether to use a floating/popup window for hunk previews Please note that vim-gitgutter won't override any colours or highlights you've set in your colorscheme. @@ -455,9 +457,9 @@ let g:gitgutter_async = 0 ``` -#### To use floating windows for hunk previews +#### To use floating/popup windows for hunk previews -Add `let g:gitgutter_preview_win_floating = 1` to your vimrc. This only takes effect on Neovim. +Add `let g:gitgutter_preview_win_floating = 1` to your vimrc. Note that on Vim this prevents you staging (partial) hunks via the preview window. ### Extensions diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim index 38bfce2..5ca8bba 100644 --- a/autoload/gitgutter/hunk.vim +++ b/autoload/gitgutter/hunk.vim @@ -389,27 +389,42 @@ endfunction " Preview window: moves cursor to preview window. function! s:open_hunk_preview_window() if g:gitgutter_preview_win_floating - call s:close_hunk_preview_window() + if exists('*nvim_open_win') + call s:close_hunk_preview_window() - let buf = nvim_create_buf(v:false, v:false) - " Set default width and height for now. - let s:winid = nvim_open_win(buf, v:false, { - \ 'relative': 'cursor', - \ 'row': 1, - \ 'col': 0, - \ 'width': 42, - \ 'height': &previewheight, - \ 'style': 'minimal' - \ }) - call nvim_buf_set_option(buf, 'filetype', 'diff') - call nvim_buf_set_option(buf, 'buftype', 'nofile') - call nvim_buf_set_option(buf, 'bufhidden', 'delete') - call nvim_buf_set_option(buf, 'swapfile', v:false) + let buf = nvim_create_buf(v:false, v:false) + " Set default width and height for now. + let s:winid = nvim_open_win(buf, v:false, { + \ 'relative': 'cursor', + \ 'row': 1, + \ 'col': 0, + \ 'width': 42, + \ 'height': &previewheight, + \ 'style': 'minimal' + \ }) + call nvim_buf_set_option(buf, 'filetype', 'diff') + call nvim_buf_set_option(buf, 'buftype', 'nofile') + call nvim_buf_set_option(buf, 'bufhidden', 'delete') + call nvim_buf_set_option(buf, 'swapfile', v:false) - " Assumes cursor is in original window. - autocmd CursorMoved ++once call s:close_hunk_preview_window() + " Assumes cursor is in original window. + autocmd CursorMoved ++once call s:close_hunk_preview_window() - return + return + endif + + if exists('*popup_create') + let s:winid = popup_create('', { + \ 'line': 'cursor+1', + \ 'col': 'cursor', + \ 'moved': 'any', + \ }) + + call setbufvar(winbufnr(s:winid), '&filetype', 'diff') + call win_execute(s:winid, 'syntax enable') + + return + endif endif silent! wincmd P @@ -430,16 +445,22 @@ function! s:populate_hunk_preview_window(header, body) let height = min([body_length, &previewheight]) if g:gitgutter_preview_win_floating - " Assumes cursor is not in previewing window. - call nvim_buf_set_var(winbufnr(s:winid), 'hunk_header', a:header) + if exists('*nvim_open_win') + " Assumes cursor is not in previewing window. + call nvim_buf_set_var(winbufnr(s:winid), 'hunk_header', a:header) - let width = max(map(copy(a:body), 'strdisplaywidth(v:val)')) - call nvim_win_set_width(s:winid, width) - call nvim_win_set_height(s:winid, height) + let width = max(map(copy(a:body), 'strdisplaywidth(v:val)')) + call nvim_win_set_width(s:winid, width) + call nvim_win_set_height(s:winid, height) - call nvim_buf_set_lines( winbufnr(s:winid), 0, -1, v:false, []) - call nvim_buf_set_lines( winbufnr(s:winid), 0, -1, v:false, a:body) - call nvim_win_set_cursor( s:winid, [1,0]) + call nvim_buf_set_lines( winbufnr(s:winid), 0, -1, v:false, []) + call nvim_buf_set_lines( winbufnr(s:winid), 0, -1, v:false, a:body) + call nvim_win_set_cursor( s:winid, [1,0]) + endif + + if exists('*popup_create') + call popup_settext(s:winid, a:body) + endif else let b:hunk_header = a:header diff --git a/doc/gitgutter.txt b/doc/gitgutter.txt index 672efcf..8477828 100644 --- a/doc/gitgutter.txt +++ b/doc/gitgutter.txt @@ -438,11 +438,13 @@ it in your |vimrc|: *g:gitgutter_preview_win_floating* -Default: 1 (Neovim) - 0 (Vim) +Default: 0 (Vim) + 0 (NeoVim which does not support floating windows) + 1 (NeoVim which does support floating windows) -Whether to use floating windows for hunk previews. Only takes effect on -Neovim. +Whether to use floating/popup windows for hunk previews. Note that if you use +popup windows on Vim you will not be able to stage partial hunks via the +preview window. *g:gitgutter_terminal_reports_focus* Default: 1