Add support for object movement
Is your feature request related to a problem? Please describe.
I'm always frustrated on object (e.g., function, method, class) movements in Vim,
Vim has ]], [[,..., ]m mappings; however it's very weak and only suit on some limited cases.
I know CoC provides :CocCommand document.jumpToPrevSymbol, but it only works on variable-like symbols.
Describe the solution you'd like Provide some commands or actions or mappings to jump to next object, for example:
" users may map to `]f`
:CocCommand document.jumpToNextFunction
" users may map to `]m`
" (I think CoC can provide better version than Vim's)
:CocCommand document.jumpToNextMethod
" users may map to `]c`
:CocCommand document.jumpToNextClass
" users may map to `]n`
:CocCommand document.jumpToNextNamespace
I thinks it will be very useful and more convenient than moving by outline list/window.
I have wrote a next/prev-function function for C; however it cannot works in C++ or Java, which may need LSP/AST-support to parse syntax (e.g., namespace, class, sub-class, macro-expanded function):
" @param is_visual
function! utils#next_func(...) abort
let is_visual = a:0 > 0 ? a:1 : 0
" Save the cursor position
let saved_cursor = getcurpos()
execute "normal! m'"
if (is_visual)
execute "normal! gv"
endif
call searchpair('{', '', '}', 'rW', function('utils#c_pair_skip'))
let ret = search('{', 'W', 0, 500, function('utils#c_pair_skip'))
if (!ret)
echohl WarningMsg | echo "Can't find next function" | echohl None
" Restore the cursor position
call cursor(saved_cursor[1:])
if (is_visual)
execute "normal! gv"
endif
endif
return ret
endfunction
" Adapt from:
" plugin/matchparen.vim
function! utils#get_syntax_name_stack() abort
let line = line('.')
let col = col('.')
let syntax_stack = synstack(line, col)
return map(syntax_stack, 'synIDattr(v:val, "name")')
endfunction
function! utils#c_pair_skip() abort
let syntax_name_stack = utils#get_syntax_name_stack()
let filtered_stack = filter(syntax_name_stack, 'v:val =~? "string\\|character\\|singlequote\\|escape\\|symbol\\|comment"')
return !empty(filtered_stack)
endfunction
The LSP don't provide information for AST, but only select ranges from symbols, you should use something based on treesister, like nvim-treesitter
Yes, I know LSP doesn’t provide AST, I mean this feature need LSP or AST support 😅
IMHO, LSP provides outline feature, so maybe this feature can based on it to implement?