-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsymfind.vim
183 lines (170 loc) · 4.07 KB
/
symfind.vim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
let s:bufname = '__SYMFIND__'
let s:sp = "------------------------------------------"
let s:help = ['f xxx - find file xxx', 's xxx - find symbol xxx', 'g xxx - grep pattern xxx' ]
let s:exname = ''
"===== toolkit {{{
let s:match = []
function! s:mymatch(expr, pat)
let s:match = matchlist(a:expr, a:pat)
return len(s:match) >0
endf
"}}}
func! s:openSymfind(exname)
let instno = 0
if a:exname != ''
let s:exname = a:exname
endif
let bufname = s:bufname . s:exname
let defcmd = 'f'
if s:mymatch(a:exname, '\v:(\d+)$')
let instno = s:match[1] +0
endif
if a:exname[0] == 'f' || a:exname[0] == 's'
let defcmd = a:exname[0]
endif
let wnr = bufwinnr(bufname)
let bnr = bufnr(bufname)
if wnr != -1
exe wnr . 'wincmd w'
elseif bnr != -1
new
exe 'b' . bnr
else
exe 'new ' . bufname
let b:preview = 0
endif
if bnr == -1
let b:sf_instno = instno
setl buftype=nofile
setl noswapfile
setl hidden
setl nowrap
setl cursorline
setl nonumber
" setl winfixheight
" setl winfixwidth
call setline(1, defcmd . ' ')
call setline(2, s:sp)
call setline(3, s:help)
call s:setSyntax()
endif
inoremap <silent> <buffer> <cr> <c-o>:call SF_call('')<cr>
nnoremap <silent> <buffer> <cr> :call SF_go('')<cr>
nnoremap <silent> <buffer> <s-cr> :call SF_go(1)<cr>
nnoremap <silent> <buffer> s<cr> :call SF_go(1)<cr>
nmap <silent> <buffer> <2-leftmouse> <cr>
nnoremap <silent> <buffer> q :hide<cr>
nnoremap <silent> <buffer> <c-w>H :call SF_setPreview(1)<cr>
1
starti!
endfunc
func! SF_setPreview(force)
if !a:force && exists('b:preview') && b:preview
return
endif
let b:preview = 1
wincmd H
vert res 40
endf
func! SF_call(cmd)
if a:cmd != ''
call s:openSymfind('')
1
call setline(1, a:cmd)
endif
if line('.') > 2
call SF_go('')
return
endif
let s = getline(1)
if s:mymatch(s, '^\v(\d+)\w')
let b:sf_ses = s:match[1]
elseif exists('b:sf_ses')
let s = b:sf_ses . s
endif
let cmd = 'symsvr.pl -c "' . s . '"'
if exists('b:sf_instno') && b:sf_instno != 0
let cmd .= ' :' . b:sf_instno
endif
" NOTE: since gvim 7.4, default shellxquote=() for cmd.exe, which causes
" system("xx.pl") cannot return anything.
if has('win32')
set shellxquote=
endif
let rv = split(system(cmd), "\n")
call setline(2, s:sp)
silent! 3,$d
call setline(3, rv)
" for 'g' command
if s =~ '\v^(\d*)g\s+'
" exec grep command (returned by server) at client-side.
exec "!" . rv[0] . "|tee 1.out"
if winnr('$') != 1
q
endif
lgetfile 1.out
lopen
stopi
else
" in symfind window
1
starti!
endif
endf
func! SF_go(splitwnd)
if line('.') <= 2
return
endif
let ls = split(getline('.'), "\t")
if ls[0] !~ '^\d\+:'
return
endif
let f = ls[-1] . '/' . ls[-2]
if f =~ '\s'
" process space
let f = substitute(f, '\s', '\\\0', 'g')
endif
if a:splitwnd || b:preview
call SF_setPreview(0)
exe (winnr()+1) . 'wincmd w'
endif
let cmd = 'e ' . substitute(f, '\v(.+):(\d+)$', '+\2 \1', '')
" call confirm(cmd)
exec cmd
if has('folding')
silent! foldopen!
endif
endf
command! -nargs=? Symfind :call s:openSymfind(<q-args>)
" symfind
nmap <leader>sf :Symfind<cr>
nmap <leader>1sf :Symfind :1<cr>
nmap <leader>g] :exe "call SF_call('s <c-r><c-w>')"<cr>
vmap <leader>g] y:exe "call SF_call('s <c-r>0')"<cr>
nmap <leader><c-]> \g]
vmap <leader><c-]> \g]
nmap <leader>gf :exe "call SF_call('f <c-r><c-f>')"<cr>
vmap <leader>gf y:exe "call SF_call('f <c-r>0')"<cr>
" find file
" nmap <leader>ff :Symfind f<cr>
" find symbol
" nmap <leader>fs :Symfind s<cr>
func! s:setSyntax ()
" sfLineNr sfKind sfKeyword sfExtra sfFile sfFolder
" sfLineNr sfFile sfFolder
syn match sfLineNr /^\v\d+:/ nextgroup=sfKind,sfFile
syn match sfKind /\t[a-z]\>/ contained nextgroup=sfKeyword
syn match sfKeyword /\t[^\t]\+/ contained nextgroup=sfExtra
syn match sfExtra /\t[^\t]*/ contained nextgroup=sfFile
syn match sfFile /\v\t[^\t]{2,}/ contained nextgroup=sfFolder
syn match sfFolder /\t\S*[/\\]\S*/ contained
hi link sfLineNr LineNr
hi link sfKind Type
hi link sfKeyword Identifier
hi link sfExtra Special
hi link sfFile Macro
" hi link sfFolder Special
endf
" TODO
func! SF_complete()
endf