Add JumpToNearbyTag functionality (#780)

* Add JumpToNearbyTag functionality

Closes #779

Updated functions:

`s:GetNearbyTag()` - Allow for a direction parameter to be passed into
the routine. This will allow for a forward or backward search. It will
default to a backward search line the current behavior if the
`a:direction` parameter is not used.

`s:JumpToTag()` - Allow for an optional parameter to be passed in to
specify the tag instead of using the tag under the cursor on the current
line. This also allows this routine to be executed from the file window
instead of the tagbar window. Assume `autoclose=0` if passing in the tag.

Add new functions:

`s:JumpToNearbyTag()` - This routine will do a forward or backward search
for the nearst tag using the `GetNearbyTag()` with the new direction
field, then call the `JumpToTag()` with the tag we found.

`tagbar#jumpToNextTag()` - New public facing wrapper routine around the
`JumpToNearbyTag()` routine. Optionally take in `a:lnum` and
`a:search_method` to be used in other routines. If `a:lnum` is not
present, then the line number will search from the next or previous line
depending on the `a:direction` value.

TODO:
- [ ] Still need to write up the documentation for this.
- [ ] Possibly look at providing default keymap. Currently this can be
  done using a custom definition in `.vimrc`.

* Add documentation and fix lazy scroll

Added documentation for this feature
Corrected the lazy scroll behavior when the next/prev tag is visible
Use the existing `w:autoclose` if set, else default to 0.

* Fix argument ordering

Correct the argument ordering and numbering for the jumpToNearbyTag()
routine.
Add documentation example for the 'nearest' search-method.
Rename jumpToNextTag() to jumpToNearbyTag() to be more inline with the
other routines.

* remove debug

* Fix current line processing

In the event there is a tag on the immediately previous/next line, then
the GetNearbyTag will return that tag even if the scoped-stl
search-method is set.

* Cleanup optional argument initialization

* Update tagbar#jumpToNearbyTag() - remove lnum and add flags parameter

Changes to the tagbar#jumpToNearbyTag() routine to allow more
flexibility. Removing the optional lnum parameter as this likely will
not be needed and could actually cause confusion in its use. Add a flags
field so different options can be set such as the 's':'scroll_offset'
option.
This commit is contained in:
David Hegland 2021-08-04 09:26:06 -05:00 committed by GitHub
parent 23ea1961b9
commit cd74f18d10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 12 deletions

View File

@ -2332,10 +2332,9 @@ function! s:IsLineVisible(line) abort
endfunction
" s:JumpToTag() {{{2
function! s:JumpToTag(stay_in_tagbar) abort
let taginfo = s:GetTagInfo(line('.'), 1)
let autoclose = w:autoclose
function! s:JumpToTag(stay_in_tagbar, ...) abort
let taginfo = a:0 > 0 ? a:1 : s:GetTagInfo(line('.'), 1)
let force_lazy_scroll = a:0 > 1 ? a:2 : 0
if empty(taginfo) || !taginfo.isNormalTag()
" Cursor line not on a tag. Check if this is the start of a foldable
@ -2359,6 +2358,11 @@ function! s:JumpToTag(stay_in_tagbar) abort
endif
let tagbarwinnr = winnr()
if exists('w:autoclose')
let autoclose = w:autoclose
else
let autoclose = 0
endif
call s:GotoFileWindow(taginfo.fileinfo)
@ -2368,7 +2372,7 @@ function! s:JumpToTag(stay_in_tagbar) abort
" 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
if g:tagbar_jump_lazy_scroll != 0 || force_lazy_scroll
let noscroll = s:IsLineVisible(taginfo.fields.line)
endif
@ -3166,20 +3170,27 @@ function! s:GetNearbyTag(request, forcecurrent, ...) abort
return {}
endif
let curline = a:0 > 0 ? a:1 : line('.')
let direction = a:0 > 1 ? a:2 : -1
let ignore_curline = a:0 > 2 ? a:3 : 0
let typeinfo = fileinfo.typeinfo
if a:0 > 0
let curline = a:1
else
let curline = line('.')
endif
let tag = {}
if direction < 0
let endline = 1
let increment = -1
else
let endline = line('$')
let increment = 1
endif
" If a tag appears in a file more than once (for example namespaces in
" C++) only one of them has a 'tline' entry and can thus be highlighted.
" The only way to solve this would be to go over the whole tag list again,
" making everything slower. Since this should be a rare occurence and
" highlighting isn't /that/ important ignore it for now.
for line in range(curline, 1, -1)
for line in range(curline, endline, increment)
if has_key(fileinfo.fline, line)
let curtag = fileinfo.fline[line]
if a:request ==# 'nearest-stl' && typeinfo.getKind(curtag.fields.kind).stl
@ -3191,7 +3202,7 @@ function! s:GetNearbyTag(request, forcecurrent, ...) abort
\ && curline <= curtag.fields.end
let tag = curtag
break
elseif a:request ==# 'nearest' || line == curline
elseif a:request ==# 'nearest' || (line == curline && ignore_curline == 0)
let tag = curtag
break
endif
@ -3201,6 +3212,31 @@ function! s:GetNearbyTag(request, forcecurrent, ...) abort
return tag
endfunction
" s:JumpToNearbyTag() {{{2
function! s:JumpToNearbyTag(direction, request, flags) abort
let fileinfo = tagbar#state#get_current_file(0)
if empty(fileinfo)
return {}
endif
let lnum = a:direction > 0 ? line('.') + 1 : line('.') - 1
let lazy_scroll = a:flags =~# 's' ? 0 : 1
let tag = s:GetNearbyTag(a:request, 1, lnum, a:direction, 1)
if empty(tag)
" No next tag found
if a:direction > 0
echo '...no next tag found'
else
echo '...no previous tag found'
endif
return
endif
call s:JumpToTag(1, tag, lazy_scroll)
endfunction
" s:GetTagInfo() {{{2
" Return the info dictionary of the tag on the specified line. If the line
" does not contain a valid tag (for example because it is empty or only
@ -4020,5 +4056,18 @@ function! tagbar#jump() abort
call s:JumpToTag(1)
endfun
" tagbar#jumpToNearbyTag() {{{2
" params:
" direction = -1:backwards search 1:forward search
" [search_method] = Search method to use for GetTagNearLine()
" [flags] = list of flags (as a string) to control behavior
" 's' - use the g:tagbar_scroll_offset setting when jumping
function! tagbar#jumpToNearbyTag(direction, ...) abort
let search_method = a:0 >= 1 ? a:1 : 'nearest-stl'
let flags = a:0 >= 2 ? a:2 : ''
call s:JumpToNearbyTag(a:direction, search_method, flags)
endfunction
" Modeline {{{1
" vim: ts=8 sw=4 sts=4 et foldenable foldmethod=marker foldcolumn=1

View File

@ -329,6 +329,20 @@ COMMANDS *tagbar-commands*
This command will call the |tagbar#jump()| function.
:TagbarJumpPrev *:TagbarJumpPrev*
Jump to the previous tag under the cursor. This works in the file window.
This will search for the previous {'nearest-stl'} type tag starting at the
line just before the current line and do a backwards search.
This command will call the |tagbar#jumpToNearbyTag(-1)| function.
:TagbarJumpNext *:TagbarJumpNext*
Jump to the next tag under the cursor. This works in the file window.
This will search for the next {'nearest-stl'} type tag starting at the
line just after the current line and do a forward search.
This command will call the |tagbar#jumpToNearbyTag(1)| function.
------------------------------------------------------------------------------
FUNCTIONS *tagbar-functions*
@ -378,6 +392,45 @@ FUNCTIONS *tagbar-functions*
This is the function called when using the |:TagbarJump| command.
*tagbar#jumpToNearbyTag()*
This function will jump to the next tag or previous tag starting a search
from the line under the cursor. This works when in the file window instead
of inside the tagbar window like the |tagbar#jump()| function.
The direction of search must be provided. If the [direction] is greater
than 0, then it will do a forward search. If the [direction] is less
than 0, then it will do a backward search.
Can also optionally provide a [search_method] which is used in the
|tagbar#GetTagNearLine()| function call and behaves the same way. This
will default to *'nearest-stl'* if not specified.
Can optionally provide a flags field [flags] to control the nearby tag
jumping. The flags should be a string of characters with the following
meanings:
's' - use the |g:tagbar_scroll_off| setting when jumping
Full syntax:
tagbar#jumpToNearbyTag(direction [, {search-method} [, {flags}]])
Examples:
>
" These keymaps will jump to the next/prev tag that can be scoped. Ex:
" function calls, class definitions, etc.
nnoremap t] :call tagbar#jumpToNearbyTag(1)
nnoremap t[ :call tagbar#jumpToNearbyTag(-1)
" These keymaps will jump to the next/prev tag regardless of type. Ex:
" function calls, class definitions, variable definitions, typedefs, etc.
nnoremap t] :call tagbar#jumpToNearbyTag(1, 'nearest')
nnoremap t[ :call tagbar#jumpToNearbyTag(-1, 'nearest')
" These keymaps will jump to the next/prev tag regardless of type, and
" will also use the jump_offset configuration to position the cursor
nnoremap t] :call tagbar#jumpToNearbyTag(1, 'nearest', 's')
nnoremap t[ :call tagbar#jumpToNearbyTag(-1, 'nearest', 's')
<
------------------------------------------------------------------------------
KEY MAPPINGS *tagbar-keys*

View File

@ -197,6 +197,8 @@ command! -nargs=0 TagbarDebugEnd call tagbar#debug#stop_debug()
command! -nargs=0 TagbarTogglePause call tagbar#toggle_pause()
command! -nargs=0 TagbarForceUpdate call tagbar#ForceUpdate()
command! -nargs=0 TagbarJump call tagbar#jump()
command! -nargs=0 TagbarJumpPrev call tagbar#jumpToNearbyTag(-1)
command! -nargs=0 TagbarJumpNext call tagbar#jumpToNearbyTag(1)
" Modeline {{{1