Skip to content

Commit

Permalink
Ensure that G and gg handle folds properly
Browse files Browse the repository at this point in the history
  • Loading branch information
subnut committed Nov 30, 2020
1 parent a6daae2 commit 24675ba
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions autoload/smoothie.vim
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,33 @@ function s:update_target(lines)
endif
endfunction

""
" Helper function to calculate the actual number of screen lines from a line
" to another. Useful for properly handling folds in case of cursor movements.
function s:calculate_screen_lines(from, to)
let l:from = a:from
let l:to = a:to
let l:from = (foldclosed(l:from) != -1 ? foldclosed(l:from) : l:from)
let l:to = (foldclosed(l:to) != -1 ? foldclosed(l:to) : l:to)
if l:from == l:to
return 0
endif
let l:lines = 0
let l:linenr = l:from
while l:linenr != l:to
if l:linenr < l:to
let l:lines +=1
let l:linenr = (foldclosedend(l:linenr) != -1 ? foldclosedend(l:linenr) : l:linenr)
let l:linenr += 1
elseif l:linenr > l:to
let l:lines -= 1
let l:linenr = (foldclosed(l:linenr) != -1 ? foldclosed(l:linenr) : l:linenr)
let l:linenr -= 1
endif
endwhile
return l:lines
endfunction

""
" Helper function to set 'scroll' to [count], similarly to what native ^U and
" ^D commands do.
Expand Down Expand Up @@ -319,8 +346,13 @@ function smoothie#gg()
" but before that, set the target, because v:count and v:count1 will be lost
let l:target = v:count1
let l:target = (l:target > line('$') ? line('$') : l:target)
let l:target = (foldclosed(l:target) != -1 ? foldclosed(l:target) : l:target)
if foldclosed('.') == l:target
let s:cursor_movement = v:false
return
endif
execute "normal! m'"
call s:update_target(l:target - line('.'))
call s:update_target(s:calculate_screen_lines(line('.'), l:target))
" suspend further commands till the destination is reached
" see point (3) of https://github.com/psliwka/vim-smoothie/issues/1#issuecomment-560158642
while line('.') != l:target
Expand All @@ -345,8 +377,13 @@ function smoothie#G()
endif
let l:target = (v:count ? v:count : line('$'))
let l:target = (l:target > line('$') ? line('$') : l:target)
let l:target = (foldclosed(l:target) != -1 ? foldclosed(l:target) : l:target)
if foldclosed('.') == l:target
let s:cursor_movement = v:false
return
endif
execute "normal! m'"
call s:update_target(l:target - line('.'))
call s:update_target(s:calculate_screen_lines(line('.'), l:target))
while line('.') != l:target
exe 'sleep ' . g:smoothie_update_interval . ' m'
endwhile
Expand Down

0 comments on commit 24675ba

Please sign in to comment.