145 lines
4.7 KiB
VimL
145 lines
4.7 KiB
VimL
" Author: Eric Van Dewoestine
|
|
"
|
|
" License: {{{
|
|
"
|
|
" Copyright (C) 2005 - 2015 Eric Van Dewoestine
|
|
"
|
|
" This program is free software: you can redistribute it and/or modify
|
|
" it under the terms of the GNU General Public License as published by
|
|
" the Free Software Foundation, either version 3 of the License, or
|
|
" (at your option) any later version.
|
|
"
|
|
" This program is distributed in the hope that it will be useful,
|
|
" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
" GNU General Public License for more details.
|
|
"
|
|
" You should have received a copy of the GNU General Public License
|
|
" along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"
|
|
" }}}
|
|
|
|
" Script Variables {{{
|
|
let s:call_hierarchy =
|
|
\ '-command <lang>_callhierarchy -p "<project>" -f "<file>" ' .
|
|
\ '-o <offset> -l <length> -e <encoding>'
|
|
" }}}
|
|
|
|
function! eclim#lang#hierarchy#CallHierarchy(lang, default_action, bang, ...) " {{{
|
|
if !eclim#project#util#IsCurrentFileInProject(1)
|
|
return
|
|
endif
|
|
|
|
call eclim#lang#SilentUpdate()
|
|
|
|
let project = eclim#project#util#GetCurrentProjectName()
|
|
let file = eclim#project#util#GetProjectRelativeFilePath()
|
|
let position = eclim#util#GetCurrentElementPosition()
|
|
let offset = substitute(position, '\(.*\);\(.*\)', '\1', '')
|
|
let length = substitute(position, '\(.*\);\(.*\)', '\2', '')
|
|
let command = s:call_hierarchy
|
|
let command = substitute(command, '<lang>', a:lang, '')
|
|
let command = substitute(command, '<project>', project, '')
|
|
let command = substitute(command, '<file>', file, '')
|
|
let command = substitute(command, '<offset>', offset, '')
|
|
let command = substitute(command, '<length>', length, '')
|
|
let command = substitute(command, '<encoding>', eclim#util#GetEncoding(), '')
|
|
if a:0
|
|
" doesn't support args that need quoting or escaping, just simply flags,
|
|
" etc.
|
|
let command .= ' ' . join(a:000, ' ')
|
|
endif
|
|
|
|
" return callees
|
|
if a:bang != ''
|
|
let command .= ' -c'
|
|
endif
|
|
|
|
let result = eclim#Execute(command)
|
|
if type(result) != g:DICT_TYPE
|
|
return
|
|
endif
|
|
|
|
if len(result) == 0
|
|
call eclim#util#Echo('No results found.')
|
|
return
|
|
endif
|
|
|
|
let lines = []
|
|
let info = []
|
|
let key = a:bang != '' ? 'callees' : 'callers'
|
|
call s:CallHierarchyFormat(result, key, lines, info, '')
|
|
|
|
call eclim#util#TempWindow('[Call Hierarchy]', lines)
|
|
exec 'set ft=' . a:lang
|
|
" fold function calls into their parent
|
|
setlocal foldmethod=expr
|
|
setlocal foldexpr='>'.len(substitute(getline(v:lnum),'^\\(\\s*\\).*','\\1',''))/2
|
|
setlocal foldtext=substitute(getline(v:foldstart),'^\\(\\s*\\)\\s\\s','\\1+\ ','').':\ '.(v:foldend-v:foldstart+1).'\ lines'
|
|
|
|
setlocal modifiable noreadonly
|
|
call append(line('$'), ['', '" use ? to view help'])
|
|
setlocal nomodifiable readonly
|
|
syntax match Comment /^".*/
|
|
|
|
let b:hierarchy_info = info
|
|
|
|
exec 'nnoremap <buffer> <silent> <cr> ' .
|
|
\ ':call <SID>Open("' . a:default_action . '")<cr>'
|
|
nnoremap <buffer> <silent> E :call <SID>Open('edit')<cr>
|
|
nnoremap <buffer> <silent> S :call <SID>Open('split')<cr>
|
|
nnoremap <buffer> <silent> T :call <SID>Open("tablast \| tabnew")<cr>
|
|
|
|
" assign to buffer var to get around weird vim issue passing list containing
|
|
" a string w/ a '<' in it on execution of mapping.
|
|
let b:hierarchy_help = [
|
|
\ '<cr> - open file with default action',
|
|
\ 'E - open with :edit',
|
|
\ 'S - open in a new split window',
|
|
\ 'T - open in a new tab',
|
|
\ ]
|
|
nnoremap <buffer> <silent> ?
|
|
\ :call eclim#help#BufferHelp(b:hierarchy_help, 'vertical', 40)<cr>
|
|
endfunction " }}}
|
|
|
|
function! s:CallHierarchyFormat(result, key, lines, info, indent) " {{{
|
|
if has_key(a:result, 'position')
|
|
call add(a:info, {
|
|
\ 'file': a:result.position.filename,
|
|
\ 'line': a:result.position.line,
|
|
\ 'col': a:result.position.column
|
|
\ })
|
|
call add(a:lines, a:indent . a:result.name)
|
|
else
|
|
call add(a:info, {'file': '', 'line': -1, 'col': -1})
|
|
call add(a:lines, a:indent . a:result.name)
|
|
endif
|
|
|
|
for call in get(a:result, a:key, [])
|
|
call s:CallHierarchyFormat(call, a:key, a:lines, a:info, a:indent . "\t")
|
|
endfor
|
|
endfunction " }}}
|
|
|
|
function! s:Open(action) " {{{
|
|
let line = line('.')
|
|
if line > len(b:hierarchy_info)
|
|
return
|
|
endif
|
|
|
|
let info = b:hierarchy_info[line - 1]
|
|
if info.file != ''
|
|
" go to the buffer that initiated the hierarchy
|
|
exec b:winnr . 'winc w'
|
|
|
|
let action = a:action
|
|
call eclim#util#GoToBufferWindowOrOpen(
|
|
\ info.file, action, info.line, info.col)
|
|
|
|
" force any previous messge from else below to be cleared
|
|
echo ''
|
|
else
|
|
call eclim#util#Echo('No associated file was found.')
|
|
endif
|
|
endfunction " }}}
|
|
|
|
" vim:ft=vim:fdm=marker
|