From 6eadc1505482d1ee361adc976b57f10a98381b00 Mon Sep 17 00:00:00 2001 From: "David P. Sicilia" Date: Tue, 10 Nov 2020 17:07:57 -0500 Subject: [PATCH] Add g:tagbar_jump_lazy_scroll option. (#705) * Add g:tagbar_jump_lazy_scroll option. When this option is on, a jump to a tag will only cause the window to scroll if the tag line is not already visible on the window. If it is visible, the cursor will simply move to that line without scrolling the window. If the tagline is not visible then the window will be scrolled as in current behavior (according to the g:tagbar_jump_offset option). Fixes #703 * Factor our new logic into a function. * Add jump target line to doc. --- autoload/tagbar.vim | 50 +++++++++++++++++++++++++++++++-------------- doc/tagbar.txt | 10 +++++++++ plugin/tagbar.vim | 1 + 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/autoload/tagbar.vim b/autoload/tagbar.vim index 7eb6bd4..df55dd9 100644 --- a/autoload/tagbar.vim +++ b/autoload/tagbar.vim @@ -2269,6 +2269,15 @@ function! s:HighlightTag(openfolds, ...) abort endtry endfunction +" Is the given line number already visible in the window without +" any scrolling? +function! s:IsLineVisible(line) abort + let topline = line('w0') + let bottomline = line('w$') + let alreadyvisible = (a:line >= topline) && (a:line <= bottomline) + return alreadyvisible +endfunction + " s:JumpToTag() {{{2 function! s:JumpToTag(stay_in_tagbar) abort let taginfo = s:GetTagInfo(line('.'), 1) @@ -2286,6 +2295,13 @@ function! s:JumpToTag(stay_in_tagbar) abort " Mark current position so it can be jumped back to mark ' + " Check if the tag is already visible in the window. We must do this + " before jumping to the line. + let noscroll = 0 + if g:tagbar_jump_lazy_scroll != 0 + let noscroll = s:IsLineVisible(taginfo.fields.line) + endif + " Jump to the line where the tag is defined. Don't use the search pattern " since it doesn't take the scope into account and thus can fail if tags " with the same name are defined in different scopes (e.g. classes) @@ -2320,22 +2336,26 @@ function! s:JumpToTag(stay_in_tagbar) abort let taginfo.fileinfo.fline[curline] = taginfo endif - " Center the tag in the window and jump to the correct column if - " available, otherwise try to find it in the line - normal! z. - - " If configured, adjust the jump_offset and center the window on that - " line. Then fall-through adjust the cursor() position below that - if g:tagbar_jump_offset != 0 && g:tagbar_jump_offset < curline - if g:tagbar_jump_offset > winheight(0) / 2 - let jump_offset = winheight(0) / 2 - elseif g:tagbar_jump_offset < -winheight(0) / 2 - let jump_offset = -winheight(0) / 2 - else - let jump_offset = g:tagbar_jump_offset - endif - execute curline+jump_offset + if noscroll + " Do not scroll. + else + " Center the tag in the window and jump to the correct column if + " available, otherwise try to find it in the line normal! z. + + " If configured, adjust the jump_offset and center the window on that + " line. Then fall-through adjust the cursor() position below that + if g:tagbar_jump_offset != 0 && g:tagbar_jump_offset < curline + if g:tagbar_jump_offset > winheight(0) / 2 + let jump_offset = winheight(0) / 2 + elseif g:tagbar_jump_offset < -winheight(0) / 2 + let jump_offset = -winheight(0) / 2 + else + let jump_offset = g:tagbar_jump_offset + endif + execute curline+jump_offset + normal! z. + endif endif if taginfo.fields.column > 0 diff --git a/doc/tagbar.txt b/doc/tagbar.txt index 48636d2..bd27f5a 100644 --- a/doc/tagbar.txt +++ b/doc/tagbar.txt @@ -1079,6 +1079,16 @@ Examples: " Set the tag jump location to appear 25% from the top let g:tagbar_jump_offset = winheight(0) / 4 < + *g:tagbar_jump_lazy_scroll* +g:tagbar_jump_lazy_scroll~ +Default: 0 + +If set to non-zero, a jump to a tag will only scroll the window if the +tag is not already visible in the window. In other words, when jumping to +a tag that is already visible, the cursor will simply be placed on the line +containing the tag without scrolling the window. If the tag is not visible +in the window then the window will be scrolled and the tag (and cursor) +placed in the location dictated by |g:tagbar_jump_offset|. ------------------------------------------------------------------------------ HIGHLIGHT COLOURS *tagbar-highlight* diff --git a/plugin/tagbar.vim b/plugin/tagbar.vim index 4bbf9d5..56daedd 100644 --- a/plugin/tagbar.vim +++ b/plugin/tagbar.vim @@ -97,6 +97,7 @@ function! s:setup_options() abort \ ['height', 10], \ ['indent', 2], \ ['jump_offset', 0], + \ ['jump_lazy_scroll', 0], \ ['left', 0], \ ['help_visibility', 0], \ ['position', default_pos],