airblade/vim-gitgutter

Height of the floating window is not wrapping-aware

swnakamura opened this issue · 5 comments

What is the latest commit SHA in your installed vim-gitgutter?
f19b620

What vim/nvim version are you on?
NVIM v0.8.0-dev-1070-g9b4cab012

I'm seeing an issue when the content of the line is longer than the &columns. Gitgutter fails to show the whole diff in the floating preview:
image

while I expect this behaviour:
image

This is because the height of the preview is calculated without considering line wrapping in the populate_hunk_preview_window function.

Here's a simple hack of mine to fix this issue for Neovim.

diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim
index 8d3074c..eb580da 100644
--- a/autoload/gitgutter/hunk.vim
+++ b/autoload/gitgutter/hunk.vim
@@ -505,6 +505,9 @@ function! s:populate_hunk_preview_window(header, body)

   if g:gitgutter_preview_win_floating
     if exists('*nvim_open_win')
+      let width = min([max(map(copy(a:body), 'strdisplaywidth(v:val)')), &columns])
+      let body_length = copy(a:body)->map('(strdisplaywidth(v:val)-1)/width+1')->join('+')->eval()
+
       let height = min([body_length, g:gitgutter_floating_window_options.height])

       " Assumes cursor is not in previewing window.
@@ -512,7 +515,6 @@ function! s:populate_hunk_preview_window(header, body)

       let [_scrolloff, &scrolloff] = [&scrolloff, 0]

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

Thanks! I like the screenshot :)

I'm away so I'll be able to look at this properly when I get back.

It works perfectly now. Now I can easily edit and diff texts with long lines with comfort. Thank you very much!

Hi @airblade .

Your fix is working perfectly in most cases, but it seems there is a corner case where gitgutter still fails to show the whole diff.

image

This can be, for example, reproduced by pressing $ in the long line and doing GitGutterPreviewHunk.

It seems like this can be fixed with the following:

diff --git a/autoload/gitgutter/hunk.vim b/autoload/gitgutter/hunk.vim
index 7eabf8f..a54b01c 100644
--- a/autoload/gitgutter/hunk.vim
+++ b/autoload/gitgutter/hunk.vim
@@ -565,7 +565,7 @@ endfunction
 function! s:screen_lines(lines)
   let [_virtualedit, &virtualedit]=[&virtualedit, 'all']
   let cursor = getcurpos()
-  normal! g$
+  normal! 0g$
   let available_width = virtcol('.')
   call setpos('.', cursor)
   let &virtualedit=_virtualedit

This function uses g$ to move to the rightest and then virtcol to get the window width. However, when the cursor is, for example, in the second line, it goes to the end of the second line, which makes the available_width twice of what's expected. This can be avoided by simply doing 0 beforehand.

@woodyzootopia Ah, of course. Thanks for letting me know and also for coming up with a solution. Please could you open a pull request? I'm away at the moment and can't make the change myself, but I can click a button in a browser.

Thank you for quick response! Created a PR.