decls.vim 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. let s:go_decls_var = {
  2. \ 'init': 'ctrlp#decls#init()',
  3. \ 'exit': 'ctrlp#decls#exit()',
  4. \ 'enter': 'ctrlp#decls#enter()',
  5. \ 'accept': 'ctrlp#decls#accept',
  6. \ 'lname': 'declarations',
  7. \ 'sname': 'decls',
  8. \ 'type': 'tabs',
  9. \}
  10. if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars)
  11. let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var)
  12. else
  13. let g:ctrlp_ext_vars = [s:go_decls_var]
  14. endif
  15. function! ctrlp#decls#init() abort
  16. cal s:enable_syntax()
  17. return s:decls
  18. endfunction
  19. function! ctrlp#decls#exit() abort
  20. unlet! s:decls s:current_dir s:target
  21. endfunction
  22. " The action to perform on the selected string
  23. " Arguments:
  24. " a:mode the mode that has been chosen by pressing <cr> <c-v> <c-t> or <c-x>
  25. " the values are 'e', 'v', 't' and 'h', respectively
  26. " a:str the selected string
  27. function! ctrlp#decls#accept(mode, str) abort
  28. let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
  29. let dir = getcwd()
  30. try
  31. " we jump to the file directory so we can get the fullpath via fnamemodify
  32. " below
  33. execute cd . s:current_dir
  34. let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|')
  35. " i.e: main.go
  36. let filename = vals[1]
  37. let line = vals[2]
  38. let col = vals[3]
  39. " i.e: /Users/fatih/vim-go/main.go
  40. let filepath = fnamemodify(filename, ":p")
  41. " acceptile is a very versatile method,
  42. call ctrlp#acceptfile(a:mode, filepath)
  43. call cursor(line, col)
  44. silent! norm! zvzz
  45. finally
  46. "jump back to old dir
  47. execute cd . fnameescape(dir)
  48. endtry
  49. endfunction
  50. function! ctrlp#decls#enter() abort
  51. let s:current_dir = fnameescape(expand('%:p:h'))
  52. let s:decls = []
  53. let bin_path = go#path#CheckBinPath('motion')
  54. if empty(bin_path)
  55. return
  56. endif
  57. let command = printf("%s -format vim -mode decls", bin_path)
  58. let command .= " -include ". get(g:, "go_decls_includes", "func,type")
  59. call go#cmd#autowrite()
  60. if s:mode == 0
  61. " current file mode
  62. let fname = expand("%:p")
  63. if exists('s:target')
  64. let fname = s:target
  65. endif
  66. let command .= printf(" -file %s", fname)
  67. else
  68. " all functions mode
  69. let dir = expand("%:p:h")
  70. if exists('s:target')
  71. let dir = s:target
  72. endif
  73. let command .= printf(" -dir %s", dir)
  74. endif
  75. let out = go#util#System(command)
  76. if go#util#ShellError() != 0
  77. call go#util#EchoError(out)
  78. return
  79. endif
  80. let result = eval(out)
  81. if type(result) != 4 || !has_key(result, 'decls')
  82. return
  83. endif
  84. let decls = result.decls
  85. " find the maximum function name
  86. let max_len = 0
  87. for decl in decls
  88. if len(decl.ident)> max_len
  89. let max_len = len(decl.ident)
  90. endif
  91. endfor
  92. for decl in decls
  93. " paddings
  94. let space = " "
  95. for i in range(max_len - len(decl.ident))
  96. let space .= " "
  97. endfor
  98. call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s",
  99. \ decl.ident . space,
  100. \ decl.keyword,
  101. \ fnamemodify(decl.filename, ":t"),
  102. \ decl.line,
  103. \ decl.col,
  104. \ decl.full,
  105. \))
  106. endfor
  107. endfunc
  108. function! s:enable_syntax() abort
  109. if !(has('syntax') && exists('g:syntax_on'))
  110. return
  111. endif
  112. syntax match CtrlPIdent '\zs\h\+\ze\s'
  113. syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|'
  114. syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|'
  115. syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename
  116. highlight link CtrlPIdent Function
  117. highlight link CtrlPKeyword Keyword
  118. highlight link CtrlPFilename SpecialComment
  119. highlight link CtrlPSignature Comment
  120. endfunction
  121. let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
  122. function! ctrlp#decls#cmd(mode, ...) abort
  123. let s:mode = a:mode
  124. if a:0 && !empty(a:1)
  125. let s:target = a:1
  126. endif
  127. return s:id
  128. endfunction
  129. " vim: sw=2 ts=2 et