diff --git a/autoload/smooth_scroll.vim b/autoload/smooth_scroll.vim index 17a6e8c..b17c90d 100644 --- a/autoload/smooth_scroll.vim +++ b/autoload/smooth_scroll.vim @@ -15,13 +15,13 @@ set cpo&vim " Scroll the screen up function! smooth_scroll#up(dist) let move_only = max([0, &scrolloff - (line('w$') - line("."))]) - call s:smooth_scroll('u', a:dist - l:move_only, 1) + call s:smooth_scroll('u', max([0, a:dist - l:move_only]), 1) endfunction " Scroll the screen down function! smooth_scroll#down(dist) let move_only = max([0, &scrolloff - (line(".") - line('w0'))]) - call s:smooth_scroll('d', a:dist - l:move_only, 1) + call s:smooth_scroll('d', max([0, a:dist - l:move_only]), 1) endfunction " Scroll to the center @@ -54,12 +54,15 @@ function! smooth_scroll#top(visual) endif let saved_mode=mode() + call s:prepare_context_top_scroll() let cur_top = line('w0') + &scrolloff let target_top = line('.') - let num_down = l:target_top - l:cur_top + let context_height = s:context_height() + let num_down = l:target_top - l:cur_top - l:context_height if l:num_down > 0 call s:smooth_scroll('d', l:num_down, 0) endif + call s:update_context_after_top_scroll() " Restore visual mode if l:saved_mode == "v" || l:saved_mode == "V" @@ -91,11 +94,58 @@ endfunction " Functions " ============================================================================== +function! s:context_active() abort + if !exists('g:context') || type(g:context) != v:t_dict + return 0 + endif + if get(g:context, 'presenter', '') ==# 'preview' + return 0 + endif + if !exists('w:context') || type(w:context) != v:t_dict || get(w:context, 'enabled', get(g:context, 'enabled', 1)) == 0 + return 0 + endif + if get(g:context, 'enabled', 1) == 0 + return 0 + endif + if get(get(g:context, 'filetype_blacklist', {}), &filetype, 0) || get(get(g:context, 'buftype_blacklist', {}), &buftype, 0) + return 0 + endif + + return 1 +endfunction + +function! s:context_height() abort + if !s:context_active() + return 0 + endif + + let l:height = len(get(w:context, 'lines', [])) + + " Make room for context.vim's separator line when a context popup is visible. + return l:height > 0 ? l:height + get(g:context, 'show_border', 0) : 0 +endfunction + +function! s:prepare_context_top_scroll() abort + if s:context_active() + let w:context.force_fix_strategy = 'scroll' + endif +endfunction + +function! s:update_context_after_top_scroll() abort + if exists('*context#update') && s:context_active() + silent! call context#update('smooth-scroll-zt') + endif +endfunction + " Scroll the window smoothly " dir: Direction of the scroll. 'd' is downwards, 'u' is upwards " dist: Distance, or the total number of lines to scroll " move: when 1, move the cursor too function! s:smooth_scroll(dir, dist, move) + if a:dist <= 0 + return + endif + let move_cmd='' if a:move == 1 if a:dir ==# 'd'