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],