]> ruderich.org/simon Gitweb - config/dotfiles.git/blob - vim/plugin/qname.vim
securemodelines: Allow disabling of the plugin.
[config/dotfiles.git] / vim / plugin / qname.vim
1 if !exists("g:qname_hotkey") || g:qname_hotkey == ""
2         let g:qname_hotkey = "<F3>"
3 endif
4 exe "nmap" g:qname_hotkey ":cal QNameInit(1)<cr>:~"
5 let s:qname_hotkey = eval('"\'.g:qname_hotkey.'"')
6
7 if exists("g:qname_loaded") && g:qname_loaded
8         finish
9 endif
10 let g:qname_loaded = 1
11
12 function! QNameRun()
13         cal s:colPrinter.print()
14         echo "\rMatch" len(s:n)."/".len(s:ls) "names:" s:inp
15         call inputsave()
16         let _key = getchar()
17         if !type(_key)
18                 let _key = nr2char(_key)
19         endif
20
21         if _key == "\<BS>"
22                 let s:inp = s:inp[:-2]
23         elseif strlen(_key) == 1 && char2nr(_key) > 31
24                 let s:inp = s:inp._key
25         endif
26         if _key == "\<ESC>" || _key == "\<CR>"
27                 let _sel = s:colPrinter.sel
28                 if _key == "\<CR>" && _sel < len(s:n) && _sel >= 0
29                         call s:swb(matchstr(s:s[_sel], '<\zs\d\+\ze>'),"")
30                 endif
31                 cal QNameInit(0)
32         elseif _key == "\<Up>"
33                 cal s:colPrinter.vert(-1)
34         elseif _key == "\<Down>"
35                 cal s:colPrinter.vert(1)
36         elseif _key == "\<Left>"
37                 cal s:colPrinter.horz(-1)
38         elseif _key == "\<Right>"
39                 cal s:colPrinter.horz(1)
40         elseif _key == s:qname_hotkey
41                 cal QNameInit(0)
42         else
43                 cal s:build()
44         endif
45         redraws
46         call inputrestore()
47 endfunc
48
49 function! QNameInit(start)
50         if a:start
51                 cmap ~ cal QNameRun()<CR>:~
52                 let s:pro = "Prompt: "
53                 let s:cmdh = &cmdheight
54                 if a:start != -1
55                         let s:inp = ""
56                 endif
57                 call s:baselist()
58                 call s:build()
59                 exe "set cmdheight=".(s:colPrinter.trow+1)
60         else
61                 cmap ~ exe "cunmap \x7E"<cr>
62                 exe "set cmdheight=".s:cmdh
63          endif
64 endfunc
65
66 function! s:build()
67         let s:s = []
68         let s:n = []
69         let s:blen = 0
70         let _cmp = tolower(tr(s:inp, '\', '/'))
71         for _line in s:ls
72                 let _name = matchstr(_line, '^.\{-}\ze \+<')
73                 if s:fmatch(tolower(_name), _cmp)
74                         cal add(s:s, _line)
75                         cal add(s:n, _name)
76                 endif
77         endfor
78         if len(s:n) > s:colPrinter.trow
79                 cal s:colPrinter.put(s:n)
80         else
81                 cal s:colPrinter.put(s:s)
82         endif
83 endfunc
84
85 function! s:swb(bno,mod)
86         if bufwinnr(a:bno) == -1
87                 exe "hid b".a:mod a:bno
88         else
89                 exe bufwinnr(a:bno) . "winc w"
90         endif
91 endfunc 
92
93 function! s:fmatch(src,pat)
94         let _si = strlen(a:src)-1
95         let _pi = strlen(a:pat)-1
96         while _si>=0 && _pi>=0
97                 if a:src[_si] == a:pat[_pi]
98                         let _pi -= 1
99                 endif
100                 let _si -= 1
101         endwhile
102         return _pi < 0
103 endfunc
104
105 function! s:baselist()
106         let s:ls = []
107         redir @y | silent ls! | redir END
108         for _line in split(@y,"\n")
109                 if _line[3]!='u' || _line[6]!='-'
110                         let _bno = matchstr(_line, '^ *\zs\d*')+0
111                         let _fname = substitute(expand("#"._bno.":p"), '\', '/', 'g')
112                         if _fname == ""
113                                 let _fname = "\xA0".matchstr(_line, '"\zs[^"]*')
114                         endif
115                         let _name = fnamemodify(_fname,":t")
116                         cal add(s:ls, _name." <"._bno."> ".fnamemodify(_fname,":h"))
117                 endif
118         endfor
119         let _align = max(map(copy(s:ls),'stridx(v:val,">")'))
120         call map(s:ls, 'substitute(v:val, " <", repeat(" ",_align-stridx(v:val,">"))." <", "")')
121         cal sort(s:ls, 1)
122 endfunc
123
124 let s:colPrinter = {"trow": 4}
125 function! s:colPrinter.put(its) dict
126         let _cols = []
127         let _trow = self.trow
128
129         let _its = copy(a:its)
130         let _len = len(_its)
131         let _i = 0
132         while _i < _len
133                 if _i+_trow <= _len
134                         cal add(_cols, remove(_its,0,_trow-1))
135                 else
136                         cal add(_cols, _its)
137                 endif
138                 let _i += _trow
139         endwhile
140
141         let _cpos = [0]
142         let _cw = []
143         let _t = 0
144         for _li in _cols
145                 let _w = max(map(copy(_li),'strlen(v:val)'))+4
146                 let _t += _w
147                 cal add(_cpos,_t)
148                 cal add(_cw,_w)
149         endfor
150
151         let _rows = []
152         for _i in range(_trow)
153                 let _row = []
154                 for _j in range(len(_cols))
155                         if _j*_trow+_i < _len
156                                 cal add(_row,_cols[_j][_i])
157                         endif
158                 endfor
159                 cal add(_rows, _row)
160         endfor
161
162         let self.cols = _cols
163         let self.cw = _cw
164         let self.rows = _rows
165         let self.cpos = _cpos
166         let self.len = _len
167         let self.lcol = 0
168         let self.sel = 0
169 endfunc
170
171 function! s:colPrinter.horz(mv) dict
172         let _t = self.sel + a:mv*self.trow
173         if _t >= 0 && _t < self.len
174                 let self.sel = _t
175         endif
176 endfunc
177
178 function! s:colPrinter.vert(mv) dict
179         let _t = self.sel + a:mv
180         let _len = self.len
181         if _t < 0 && _len > 0
182                 let self.sel = _len-1
183         elseif _t >= _len
184                 let self.sel = 0
185         else
186                 let self.sel = _t
187         endif
188 endfunc
189
190 function! s:colPrinter.print() dict
191         let _len = self.len
192         let _trow = self.trow
193         if !_len
194                 echo "  [...NO MATCH...]" repeat("\n",_trow)
195                 return
196         endif
197         let _sel = self.sel
198         let _t = _sel/_trow
199         let _cpos = self.cpos
200         let _lcol = self.lcol
201         let _tcol = &columns
202         if _cpos[_lcol]+_tcol < _cpos[_t+1]
203                 let _rcol = _t
204                 let _pos = _cpos[_t+1]-_tcol-2
205                 while _cpos[_lcol] < _pos
206                         let _lcol += 1
207                 endwhile
208                 let _lcol -= _lcol > _t
209         else
210                 if _t < _lcol
211                         let _lcol = _t
212                 endif
213                 let _rcol = len(_cpos)-1
214                 let _pos = _cpos[_lcol]+_tcol+2
215                 while _cpos[_rcol] > _pos
216                         let _rcol -= 1
217                 endwhile
218                 let _rcol -= _rcol > _lcol
219         endif
220         let _cw = self.cw
221         let _pos = _cpos[_lcol]+_tcol
222         let self.lcol = _lcol
223         for _i in range(_trow)
224                 let _row = self.rows[_i]
225                 for _j in range(_lcol,_rcol)
226                         if _j*_trow+_i < _len
227                                 let _txt = "  " . _row[_j]
228                                 let _txt .= repeat(" ", _cw[_j] - strlen(_txt))
229                                 let _txt = _txt[:_pos-_cpos[_j]-2]
230                                 if _j*_trow + _i == _sel
231                                         echoh Search|echon _txt|echoh None
232                                 else
233                                         echon _txt
234                                 endif
235                         endif
236                 endfor
237                 echon "\n"
238         endfor
239 endfunc