Mercurial > vim
comparison runtime/autoload/phpcomplete.vim @ 856:8cd729851562 v7.0g
updated for version 7.0g
author | vimboss |
---|---|
date | Sun, 30 Apr 2006 18:54:39 +0000 |
parents | 5117153003bd |
children | c5c164b4c95c |
comparison
equal
deleted
inserted
replaced
855:d2a4f08396fe | 856:8cd729851562 |
---|---|
1 " Vim completion script | 1 " Vim completion script |
2 " Language: PHP | 2 " Language: PHP |
3 " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) | 3 " Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) |
4 " Last Change: 2006 Apr 15 | 4 " Last Change: 2006 Apr 30 |
5 " | 5 " |
6 " TODO: | 6 " TODO: |
7 " - Class aware completion: | 7 " - Class aware completion: |
8 " a) caching? | 8 " a) caching? |
9 " - Switching to HTML (XML?) completion (SQL) inside of phpStrings | 9 " - Switching to HTML (XML?) completion (SQL) inside of phpStrings |
70 | 70 |
71 if scontext =~ '\(=\s*new\|extends\)\s\+$' | 71 if scontext =~ '\(=\s*new\|extends\)\s\+$' |
72 " Complete class name | 72 " Complete class name |
73 " Internal solution for finding classes in current file. | 73 " Internal solution for finding classes in current file. |
74 let file = getline(1, '$') | 74 let file = getline(1, '$') |
75 call filter(file, | 75 call filter(file, |
76 \ 'v:val =~ "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') | 76 \ 'v:val =~ "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') |
77 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | 77 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) |
78 let jfile = join(file, ' ') | 78 let jfile = join(file, ' ') |
79 let int_values = split(jfile, 'class\s\+') | 79 let int_values = split(jfile, 'class\s\+') |
80 let int_classes = {} | 80 let int_classes = {} |
151 " :(, but all of them have differences. To squeeze them into | 151 " :(, but all of them have differences. To squeeze them into |
152 " one implementation would require many additional arguments | 152 " one implementation would require many additional arguments |
153 " and ifs. No good solution | 153 " and ifs. No good solution |
154 " Functions declared with public keyword or without any | 154 " Functions declared with public keyword or without any |
155 " keyword are public | 155 " keyword are public |
156 let functions = filter(deepcopy(sccontent), | 156 let functions = filter(deepcopy(sccontent), |
157 \ 'v:val =~ "^\\s*\\(public\\s\\*\\)\\?function"') | 157 \ 'v:val =~ "^\\s*\\(public\\s\\*\\)\\?function"') |
158 let jfuncs = join(functions, ' ') | 158 let jfuncs = join(functions, ' ') |
159 let sfuncs = split(jfuncs, 'function\s\+') | 159 let sfuncs = split(jfuncs, 'function\s\+') |
160 let c_functions = {} | 160 let c_functions = {} |
161 for i in sfuncs | 161 for i in sfuncs |
162 let f_name = matchstr(i, | 162 let f_name = matchstr(i, |
163 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') | 163 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') |
164 let f_args = matchstr(i, | 164 let f_args = matchstr(i, |
165 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') | 165 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') |
166 if f_name != '' | 166 if f_name != '' |
167 let c_functions[f_name.'('] = f_args | 167 let c_functions[f_name.'('] = f_args |
168 endif | 168 endif |
169 endfor | 169 endfor |
170 " Variables declared with var or with public keyword are | 170 " Variables declared with var or with public keyword are |
171 " public | 171 " public |
172 let variables = filter(deepcopy(sccontent), | 172 let variables = filter(deepcopy(sccontent), |
173 \ 'v:val =~ "^\\s*\\(public\\|var\\)\\s\\+\\$"') | 173 \ 'v:val =~ "^\\s*\\(public\\|var\\)\\s\\+\\$"') |
174 let jvars = join(variables, ' ') | 174 let jvars = join(variables, ' ') |
175 let svars = split(jvars, '\$') | 175 let svars = split(jvars, '\$') |
176 let c_variables = {} | 176 let c_variables = {} |
177 for i in svars | 177 for i in svars |
178 let c_var = matchstr(i, | 178 let c_var = matchstr(i, |
179 \ '^\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') | 179 \ '^\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') |
180 if c_var != '' | 180 if c_var != '' |
181 let c_variables[c_var] = '' | 181 let c_variables[c_var] = '' |
182 endif | 182 endif |
183 endfor | 183 endfor |
202 if has_key(c_variables, i) | 202 if has_key(c_variables, i) |
203 let class = ' ' | 203 let class = ' ' |
204 if all_values[i] != '' | 204 if all_values[i] != '' |
205 let class = i.' class ' | 205 let class = i.' class ' |
206 endif | 206 endif |
207 let final_list += | 207 let final_list += |
208 \ [{'word':i, | 208 \ [{'word':i, |
209 \ 'info':class.all_values[i], | 209 \ 'info':class.all_values[i], |
210 \ 'kind':'v'}] | 210 \ 'kind':'v'}] |
211 else | 211 else |
212 let final_list += | 212 let final_list += |
213 \ [{'word':substitute(i, '.*::', '', ''), | 213 \ [{'word':substitute(i, '.*::', '', ''), |
214 \ 'info':i.all_values[i].')', | 214 \ 'info':i.all_values[i].')', |
215 \ 'kind':'f'}] | 215 \ 'kind':'f'}] |
216 endif | 216 endif |
217 endfor | 217 endfor |
218 | 218 |
239 endif | 239 endif |
240 if val !~ '' | 240 if val !~ '' |
241 let int_vars[adddollar.val] = '' | 241 let int_vars[adddollar.val] = '' |
242 endif | 242 endif |
243 endfor | 243 endfor |
244 | 244 |
245 " ctags has good support for PHP, use tags file for external | 245 " ctags has good support for PHP, use tags file for external |
246 " variables | 246 " variables |
247 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | 247 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) |
248 let ext_vars = {} | 248 let ext_vars = {} |
249 if fnames != '' | 249 if fnames != '' |
254 let item = matchstr(field['text'], '^[^[:space:]]\+') | 254 let item = matchstr(field['text'], '^[^[:space:]]\+') |
255 " Add -> if it is possible object declaration | 255 " Add -> if it is possible object declaration |
256 let classname = '' | 256 let classname = '' |
257 if field['text'] =~ item.'\s*=\s*new\s\+' | 257 if field['text'] =~ item.'\s*=\s*new\s\+' |
258 let item = item.'->' | 258 let item = item.'->' |
259 let classname = matchstr(field['text'], | 259 let classname = matchstr(field['text'], |
260 \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') | 260 \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') |
261 endif | 261 endif |
262 let ext_vars[adddollar.item] = classname | 262 let ext_vars[adddollar.item] = classname |
263 endfor | 263 endfor |
264 endif | 264 endif |
266 " Now we have all variables in int_vars dictionary | 266 " Now we have all variables in int_vars dictionary |
267 call extend(int_vars, ext_vars) | 267 call extend(int_vars, ext_vars) |
268 | 268 |
269 " Internal solution for finding functions in current file. | 269 " Internal solution for finding functions in current file. |
270 let file = getline(1, '$') | 270 let file = getline(1, '$') |
271 call filter(file, | 271 call filter(file, |
272 \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') | 272 \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') |
273 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | 273 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) |
274 let jfile = join(file, ' ') | 274 let jfile = join(file, ' ') |
275 let int_values = split(jfile, 'function\s\+') | 275 let int_values = split(jfile, 'function\s\+') |
276 let int_functions = {} | 276 let int_functions = {} |
277 for i in int_values | 277 for i in int_values |
278 let f_name = matchstr(i, | 278 let f_name = matchstr(i, |
279 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') | 279 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') |
280 let f_args = matchstr(i, | 280 let f_args = matchstr(i, |
281 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') | 281 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') |
282 let int_functions[f_name.'('] = f_args.')' | 282 let int_functions[f_name.'('] = f_args.')' |
283 endfor | 283 endfor |
284 | 284 |
285 " Prepare list of functions from tags file | 285 " Prepare list of functions from tags file |
289 let qflist = getqflist() | 289 let qflist = getqflist() |
290 for field in qflist | 290 for field in qflist |
291 " File name | 291 " File name |
292 let item = matchstr(field['text'], '^[^[:space:]]\+') | 292 let item = matchstr(field['text'], '^[^[:space:]]\+') |
293 let fname = matchstr(field['text'], '\t\zs\f\+\ze') | 293 let fname = matchstr(field['text'], '\t\zs\f\+\ze') |
294 let prototype = matchstr(field['text'], | 294 let prototype = matchstr(field['text'], |
295 \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') | 295 \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') |
296 let ext_functions[item.'('] = prototype.') - '.fname | 296 let ext_functions[item.'('] = prototype.') - '.fname |
297 endfor | 297 endfor |
298 endif | 298 endif |
299 | 299 |
318 if all_values[i] != '' | 318 if all_values[i] != '' |
319 let class = i.' class ' | 319 let class = i.' class ' |
320 endif | 320 endif |
321 let final_list += [{'word':i, 'info':class.all_values[i], 'kind':'v'}] | 321 let final_list += [{'word':i, 'info':class.all_values[i], 'kind':'v'}] |
322 else | 322 else |
323 let final_list += | 323 let final_list += |
324 \ [{'word':substitute(i, '.*::', '', ''), | 324 \ [{'word':substitute(i, '.*::', '', ''), |
325 \ 'info':i.all_values[i], | 325 \ 'info':i.all_values[i], |
326 \ 'kind':'f'}] | 326 \ 'kind':'f'}] |
327 endif | 327 endif |
328 endfor | 328 endfor |
329 | 329 |
359 let jfile = join(file, ' ') | 359 let jfile = join(file, ' ') |
360 let int_vals = split(jfile, '\ze\$') | 360 let int_vals = split(jfile, '\ze\$') |
361 let int_vars = {} | 361 let int_vars = {} |
362 for i in int_vals | 362 for i in int_vals |
363 if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new' | 363 if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new' |
364 let val = matchstr(i, | 364 let val = matchstr(i, |
365 \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->' | 365 \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->' |
366 else | 366 else |
367 let val = matchstr(i, | 367 let val = matchstr(i, |
368 \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*') | 368 \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*') |
369 endif | 369 endif |
370 if val != '' | 370 if val != '' |
371 let int_vars[val] = '' | 371 let int_vars[val] = '' |
372 endif | 372 endif |
373 endfor | 373 endfor |
374 | 374 |
375 call extend(int_vars,g:php_builtin_vars) | 375 call extend(int_vars,g:php_builtin_vars) |
376 | 376 |
377 " ctags has support for PHP, use tags file for external variables | 377 " ctags has support for PHP, use tags file for external variables |
378 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | 378 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) |
379 let ext_vars = {} | 379 let ext_vars = {} |
380 if fnames != '' | 380 if fnames != '' |
381 let sbase = substitute(a:base, '^\$', '', '') | 381 let sbase = substitute(a:base, '^\$', '', '') |
385 let item = '$'.matchstr(field['text'], '^[^[:space:]]\+') | 385 let item = '$'.matchstr(field['text'], '^[^[:space:]]\+') |
386 let m_menu = '' | 386 let m_menu = '' |
387 " Add -> if it is possible object declaration | 387 " Add -> if it is possible object declaration |
388 if field['text'] =~ item.'\s*=\s*new\s\+' | 388 if field['text'] =~ item.'\s*=\s*new\s\+' |
389 let item = item.'->' | 389 let item = item.'->' |
390 let m_menu = matchstr(field['text'], | 390 let m_menu = matchstr(field['text'], |
391 \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') | 391 \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') |
392 endif | 392 endif |
393 let ext_vars[item] = m_menu | 393 let ext_vars[item] = m_menu |
394 endfor | 394 endfor |
395 endif | 395 endif |
419 endfor | 419 endfor |
420 | 420 |
421 return int_dict | 421 return int_dict |
422 | 422 |
423 else | 423 else |
424 " Complete everything else - | 424 " Complete everything else - |
425 " + functions, DONE | 425 " + functions, DONE |
426 " + keywords of language DONE | 426 " + keywords of language DONE |
427 " + defines (constant definitions), DONE | 427 " + defines (constant definitions), DONE |
428 " + extend keywords for predefined constants, DONE | 428 " + extend keywords for predefined constants, DONE |
429 " + classes (after new), DONE | 429 " + classes (after new), DONE |
430 " + limit choice after -> and :: to funcs and vars DONE | 430 " + limit choice after -> and :: to funcs and vars DONE |
431 | 431 |
432 " Internal solution for finding functions in current file. | 432 " Internal solution for finding functions in current file. |
433 let file = getline(1, '$') | 433 let file = getline(1, '$') |
434 call filter(file, | 434 call filter(file, |
435 \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') | 435 \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') |
436 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | 436 let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) |
437 let jfile = join(file, ' ') | 437 let jfile = join(file, ' ') |
438 let int_values = split(jfile, 'function\s\+') | 438 let int_values = split(jfile, 'function\s\+') |
439 let int_functions = {} | 439 let int_functions = {} |
440 for i in int_values | 440 for i in int_values |
441 let f_name = matchstr(i, | 441 let f_name = matchstr(i, |
442 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') | 442 \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') |
443 let f_args = matchstr(i, | 443 let f_args = matchstr(i, |
444 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\s*\zs.\{-}\ze\s*)\_s*{') | 444 \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\s*\zs.\{-}\ze\s*)\_s*{') |
445 let int_functions[f_name.'('] = f_args.')' | 445 let int_functions[f_name.'('] = f_args.')' |
446 endfor | 446 endfor |
447 | 447 |
448 " Prepare list of functions from tags file | 448 " Prepare list of functions from tags file |
452 let qflist = getqflist() | 452 let qflist = getqflist() |
453 for field in qflist | 453 for field in qflist |
454 " File name | 454 " File name |
455 let item = matchstr(field['text'], '^[^[:space:]]\+') | 455 let item = matchstr(field['text'], '^[^[:space:]]\+') |
456 let fname = matchstr(field['text'], '\t\zs\f\+\ze') | 456 let fname = matchstr(field['text'], '\t\zs\f\+\ze') |
457 let prototype = matchstr(field['text'], | 457 let prototype = matchstr(field['text'], |
458 \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') | 458 \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') |
459 let ext_functions[item.'('] = prototype.') - '.fname | 459 let ext_functions[item.'('] = prototype.') - '.fname |
460 endfor | 460 endfor |
461 endif | 461 endif |
462 | 462 |
470 let jfile = join(file, ' ') | 470 let jfile = join(file, ' ') |
471 let int_values = split(jfile, 'define\s*(\s*') | 471 let int_values = split(jfile, 'define\s*(\s*') |
472 let int_constants = {} | 472 let int_constants = {} |
473 for i in int_values | 473 for i in int_values |
474 let c_name = matchstr(i, '\(["'']\)\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze\1') | 474 let c_name = matchstr(i, '\(["'']\)\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze\1') |
475 " let c_value = matchstr(i, | 475 " let c_value = matchstr(i, |
476 " \ '\(["'']\)[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\1\s*,\s*\zs.\{-}\ze\s*)') | 476 " \ '\(["'']\)[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\1\s*,\s*\zs.\{-}\ze\s*)') |
477 if c_name != '' | 477 if c_name != '' |
478 let int_constants[c_name] = '' " c_value | 478 let int_constants[c_name] = '' " c_value |
479 endif | 479 endif |
480 endfor | 480 endfor |
514 let int_list = res | 514 let int_list = res |
515 | 515 |
516 let final_list = [] | 516 let final_list = [] |
517 for i in int_list | 517 for i in int_list |
518 if has_key(int_functions, i) | 518 if has_key(int_functions, i) |
519 let final_list += | 519 let final_list += |
520 \ [{'word':i, | 520 \ [{'word':i, |
521 \ 'info':i.int_functions[i], | 521 \ 'info':i.int_functions[i], |
522 \ 'kind':'f'}] | 522 \ 'kind':'f'}] |
523 elseif has_key(int_constants, i) | 523 elseif has_key(int_constants, i) |
524 let final_list += [{'word':i, 'kind':'d'}] | 524 let final_list += [{'word':i, 'kind':'d'}] |
525 else | 525 else |
597 endfunction | 597 endfunction |
598 " }}} | 598 " }}} |
599 | 599 |
600 function! phpcomplete#GetClassContents(file, name) " {{{ | 600 function! phpcomplete#GetClassContents(file, name) " {{{ |
601 let cfile = join(a:file, "\n") | 601 let cfile = join(a:file, "\n") |
602 " We use new buffer and (later) normal! because | 602 " We use new buffer and (later) normal! because |
603 " this is the most efficient way. The other way | 603 " this is the most efficient way. The other way |
604 " is to go through the looong string looking for | 604 " is to go through the looong string looking for |
605 " matching {} | 605 " matching {} |
606 below 1new | 606 below 1new |
607 0put =cfile | 607 0put =cfile |
608 call search('class\s\+'.a:name) | 608 call search('class\s\+'.a:name) |
609 let cfline = line('.') | 609 let cfline = line('.') |
610 " Catch extends | 610 " Catch extends |
611 if getline('.') =~ 'extends' | 611 if getline('.') =~ 'extends' |
612 let extends_class = matchstr(getline('.'), | 612 let extends_class = matchstr(getline('.'), |
613 \ 'class\s\+'.a:name.'\s\+extends\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') | 613 \ 'class\s\+'.a:name.'\s\+extends\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') |
614 else | 614 else |
615 let extends_class = '' | 615 let extends_class = '' |
616 endif | 616 endif |
617 normal! % | 617 normal! % |
963 \ } | 963 \ } |
964 " }}} | 964 " }}} |
965 " PHP builtin functions {{{ | 965 " PHP builtin functions {{{ |
966 " To create from scratch list of functions: | 966 " To create from scratch list of functions: |
967 " 1. Download multi html file PHP documentation | 967 " 1. Download multi html file PHP documentation |
968 " 2. run for i in `ls | grep "^function\."`; do grep -A4 Description $i >> funcs; done | 968 " 2. run for i in `ls | grep "^function\."`; do grep -A4 Description $i >> funcs; done |
969 " 3. Open funcs in Vim and | 969 " 3. Open funcs in Vim and |
970 " a) g/Description/normal! 5J | 970 " a) g/Description/normal! 5J |
971 " b) remove all html tags (it will require few s/// and g//) | 971 " b) remove all html tags (it will require few s/// and g//) |
972 " c) :%s/^\([^[:space:]]\+\) \([^[:space:]]\+\) ( \(.*\))/\\ '\2(': '\3| \1', | 972 " c) :%s/^\([^[:space:]]\+\) \([^[:space:]]\+\) ( \(.*\))/\\ '\2(': '\3| \1', |
973 " This will create Dictionary | 973 " This will create Dictionary |
974 " d) remove all /^[^\\] lines | 974 " d) remove all /^[^\\] lines |