mirror of https://github.com/amix/vimrc.git
parent
20729bff94
commit
6dcca46b4a
@ -0,0 +1,158 @@ |
||||
let s:go_decls_var = { |
||||
\ 'init': 'ctrlp#decls#init()', |
||||
\ 'exit': 'ctrlp#decls#exit()', |
||||
\ 'enter': 'ctrlp#decls#enter()', |
||||
\ 'accept': 'ctrlp#decls#accept', |
||||
\ 'lname': 'declarations', |
||||
\ 'sname': 'decls', |
||||
\ 'type': 'tabs', |
||||
\} |
||||
|
||||
if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars) |
||||
let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var) |
||||
else |
||||
let g:ctrlp_ext_vars = [s:go_decls_var] |
||||
endif |
||||
|
||||
function! ctrlp#decls#init() |
||||
cal s:enable_syntax() |
||||
return s:decls |
||||
endfunction |
||||
|
||||
function! ctrlp#decls#exit() |
||||
unlet! s:decls s:current_dir s:target |
||||
endfunction |
||||
|
||||
" The action to perform on the selected string |
||||
" Arguments: |
||||
" a:mode the mode that has been chosen by pressing <cr> <c-v> <c-t> or <c-x> |
||||
" the values are 'e', 'v', 't' and 'h', respectively |
||||
" a:str the selected string |
||||
function! ctrlp#decls#accept(mode, str) |
||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' |
||||
let dir = getcwd() |
||||
try |
||||
" we jump to the file directory so we can get the fullpath via fnamemodify |
||||
" below |
||||
execute cd . s:current_dir |
||||
|
||||
let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|') |
||||
|
||||
" i.e: main.go |
||||
let filename = vals[1] |
||||
let line = vals[2] |
||||
let col = vals[3] |
||||
|
||||
" i.e: /Users/fatih/vim-go/main.go |
||||
let filepath = fnamemodify(filename, ":p") |
||||
|
||||
" acceptile is a very versatile method, |
||||
call ctrlp#acceptfile(a:mode, filepath) |
||||
call cursor(line, col) |
||||
silent! norm! zvzz |
||||
finally |
||||
"jump back to old dir |
||||
execute cd . fnameescape(dir) |
||||
endtry |
||||
endfunction |
||||
|
||||
function! ctrlp#decls#enter() |
||||
let s:current_dir = fnameescape(expand('%:p:h')) |
||||
let s:decls = [] |
||||
|
||||
let bin_path = go#path#CheckBinPath('motion') |
||||
if empty(bin_path) |
||||
return |
||||
endif |
||||
let command = printf("%s -format vim -mode decls", bin_path) |
||||
let command .= " -include ". get(g:, "go_decls_includes", "func,type") |
||||
|
||||
call go#cmd#autowrite() |
||||
|
||||
if s:mode == 0 |
||||
" current file mode |
||||
let fname = expand("%:p") |
||||
if exists('s:target') |
||||
let fname = s:target |
||||
endif |
||||
|
||||
let command .= printf(" -file %s", fname) |
||||
else |
||||
" all functions mode |
||||
let dir = expand("%:p:h") |
||||
if exists('s:target') |
||||
let dir = s:target |
||||
endif |
||||
|
||||
let command .= printf(" -dir %s", dir) |
||||
endif |
||||
|
||||
let out = system(command) |
||||
if v:shell_error != 0 |
||||
call go#util#EchoError(out) |
||||
return |
||||
endif |
||||
|
||||
if exists("l:tmpname") |
||||
call delete(l:tmpname) |
||||
endif |
||||
|
||||
let result = eval(out) |
||||
if type(result) != 4 || !has_key(result, 'decls') |
||||
return |
||||
endif |
||||
|
||||
let decls = result.decls |
||||
|
||||
" find the maximum function name |
||||
let max_len = 0 |
||||
for decl in decls |
||||
if len(decl.ident)> max_len |
||||
let max_len = len(decl.ident) |
||||
endif |
||||
endfor |
||||
|
||||
for decl in decls |
||||
" paddings |
||||
let space = " " |
||||
for i in range(max_len - len(decl.ident)) |
||||
let space .= " " |
||||
endfor |
||||
|
||||
call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s", |
||||
\ decl.ident . space, |
||||
\ decl.keyword, |
||||
\ fnamemodify(decl.filename, ":t"), |
||||
\ decl.line, |
||||
\ decl.col, |
||||
\ decl.full, |
||||
\)) |
||||
endfor |
||||
endfunc |
||||
|
||||
function! s:enable_syntax() |
||||
if !(has('syntax') && exists('g:syntax_on')) |
||||
return |
||||
endif |
||||
|
||||
syntax match CtrlPIdent '\zs\h\+\ze\s' |
||||
syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|' |
||||
syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|' |
||||
syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename |
||||
|
||||
highlight link CtrlPIdent Function |
||||
highlight link CtrlPKeyword Keyword |
||||
highlight link CtrlPFilename SpecialComment |
||||
highlight link CtrlPSignature Comment |
||||
endfunction |
||||
|
||||
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars) |
||||
|
||||
function! ctrlp#decls#cmd(mode, ...) |
||||
let s:mode = a:mode |
||||
if a:0 && !empty(a:1) |
||||
let s:target = a:1 |
||||
endif |
||||
return s:id |
||||
endfunction |
||||
|
@ -1,15 +1,180 @@ |
||||
if !exists("g:go_textobj_enabled") |
||||
let g:go_textobj_enabled = 1 |
||||
let g:go_textobj_enabled = 1 |
||||
endif |
||||
|
||||
if !exists("g:go_textobj_include_function_doc") |
||||
let g:go_textobj_include_function_doc = 1 |
||||
endif |
||||
|
||||
" ( ) motions |
||||
" { } motions |
||||
" s for sentence |
||||
" p for parapgrah |
||||
" < > |
||||
" t for tag |
||||
|
||||
function! go#textobj#Function(mode) |
||||
if search('^\s*func .*{$', 'Wce', line('.')) <= 0 |
||||
\ && search('^\s*func .*{$', 'bWce') <= 0 |
||||
let offset = go#util#OffsetCursor() |
||||
|
||||
let fname = expand("%:p") |
||||
if &modified |
||||
" Write current unsaved buffer to a temp file and use the modified content |
||||
let l:tmpname = tempname() |
||||
call writefile(getline(1, '$'), l:tmpname) |
||||
let fname = l:tmpname |
||||
endif |
||||
|
||||
let bin_path = go#path#CheckBinPath('motion') |
||||
if empty(bin_path) |
||||
return |
||||
endif |
||||
|
||||
let command = printf("%s -format vim -file %s -offset %s", bin_path, fname, offset) |
||||
let command .= " -mode enclosing" |
||||
|
||||
if g:go_textobj_include_function_doc |
||||
let command .= " -parse-comments" |
||||
endif |
||||
|
||||
let out = system(command) |
||||
if v:shell_error != 0 |
||||
call go#util#EchoError(out) |
||||
return |
||||
endif |
||||
|
||||
" if exists, delete it as we don't need it anymore |
||||
if exists("l:tmpname") |
||||
call delete(l:tmpname) |
||||
endif |
||||
|
||||
" convert our string dict representation into native Vim dictionary type |
||||
let result = eval(out) |
||||
if type(result) != 4 || !has_key(result, 'fn') |
||||
return |
||||
endif |
||||
|
||||
let info = result.fn |
||||
|
||||
if a:mode == 'a' |
||||
normal! Va{V |
||||
else " a:mode == 'i' |
||||
normal! Vi{V |
||||
" anonymous functions doesn't have associated doc. Also check if the user |
||||
" want's to include doc comments for function declarations |
||||
if has_key(info, 'doc') && g:go_textobj_include_function_doc |
||||
call cursor(info.doc.line, info.doc.col) |
||||
else |
||||
call cursor(info.func.line, info.func.col) |
||||
endif |
||||
|
||||
normal! v |
||||
call cursor(info.rbrace.line, info.rbrace.col) |
||||
return |
||||
endif |
||||
|
||||
" rest is inner mode, a:mode == 'i' |
||||
|
||||
" if the function is a one liner we need to select only that portion |
||||
if info.lbrace.line == info.rbrace.line |
||||
call cursor(info.lbrace.line, info.lbrace.col+1) |
||||
normal! v |
||||
call cursor(info.rbrace.line, info.rbrace.col-1) |
||||
return |
||||
endif |
||||
|
||||
call cursor(info.lbrace.line+1, 1) |
||||
normal! V |
||||
call cursor(info.rbrace.line-1, 1) |
||||
endfunction |
||||
|
||||
function! go#textobj#FunctionJump(mode, direction) |
||||
" get count of the motion. This should be done before all the normal |
||||
" expressions below as those reset this value(because they have zero |
||||
" count!). We abstract -1 because the index starts from 0 in motion. |
||||
let l:cnt = v:count1 - 1 |
||||
|
||||
" set context mark so we can jump back with '' or `` |
||||
normal! m' |
||||
|
||||
" select already previously selected visual content and continue from there. |
||||
" If it's the first time starts with the visual mode. This is needed so |
||||
" after selecting something in visual mode, every consecutive motion |
||||
" continues. |
||||
if a:mode == 'v' |
||||
normal! gv |
||||
endif |
||||
|
||||
let offset = go#util#OffsetCursor() |
||||
|
||||
let fname = expand("%:p") |
||||
if &modified |
||||
" Write current unsaved buffer to a temp file and use the modified content |
||||
let l:tmpname = tempname() |
||||
call writefile(getline(1, '$'), l:tmpname) |
||||
let fname = l:tmpname |
||||
endif |
||||
|
||||
let bin_path = go#path#CheckBinPath('motion') |
||||
if empty(bin_path) |
||||
return |
||||
endif |
||||
|
||||
let command = printf("%s -format vim -file %s -offset %s", bin_path, fname, offset) |
||||
let command .= ' -shift ' . l:cnt |
||||
|
||||
if a:direction == 'next' |
||||
let command .= ' -mode next' |
||||
else " 'prev' |
||||
let command .= ' -mode prev' |
||||
endif |
||||
|
||||
if g:go_textobj_include_function_doc |
||||
let command .= " -parse-comments" |
||||
endif |
||||
|
||||
let out = system(command) |
||||
if v:shell_error != 0 |
||||
call go#util#EchoError(out) |
||||
return |
||||
endif |
||||
|
||||
" if exists, delete it as we don't need it anymore |
||||
if exists("l:tmpname") |
||||
call delete(l:tmpname) |
||||
endif |
||||
|
||||
" convert our string dict representation into native Vim dictionary type |
||||
let result = eval(out) |
||||
if type(result) != 4 || !has_key(result, 'fn') |
||||
return |
||||
endif |
||||
|
||||
" we reached the end and there are no functions. The usual [[ or ]] jumps to |
||||
" the top or bottom, we'll do the same. |
||||
if type(result) == 4 && has_key(result, 'err') && result.err == "no functions found" |
||||
if a:direction == 'next' |
||||
keepjumps normal! G |
||||
else " 'prev' |
||||
keepjumps normal! gg |
||||
endif |
||||
return |
||||
endif |
||||
|
||||
let info = result.fn |
||||
|
||||
" if we select something ,select all function |
||||
if a:mode == 'v' && a:direction == 'next' |
||||
keepjumps call cursor(info.rbrace.line, 1) |
||||
return |
||||
endif |
||||
|
||||
if a:mode == 'v' && a:direction == 'prev' |
||||
if has_key(info, 'doc') && g:go_textobj_include_function_doc |
||||
keepjumps call cursor(info.doc.line, 1) |
||||
else |
||||
keepjumps call cursor(info.func.line, 1) |
||||
endif |
||||
return |
||||
endif |
||||
|
||||
keepjumps call cursor(info.func.line, 1) |
||||
endfunction |
||||
|
||||
" vim:ts=2:sw=2:et |
||||
|
Loading…
Reference in new issue