diff options
| author | Christian Hammond <christian@beanbaginc.com> | 2016-11-04 16:57:38 -0700 |
|---|---|---|
| committer | Christian Hammond <christian@beanbaginc.com> | 2016-11-04 16:57:38 -0700 |
| commit | 6ded9db39463372e5205a36bea72d6de516ece69 (patch) | |
| tree | 1d1f497cc99dd44d2ee7e2c3daa35965157ff924 /tests/examplefiles/phpcomplete.vim | |
| download | pygments-git-6ded9db39463372e5205a36bea72d6de516ece69.tar.gz | |
Add support for partials and path segments for Handlebars.
This introduces support for some missing features to the Handlebars lexer:
Partials and path segments. Partials mostly appeared to work before, but the
`>` in `{{> ... }}` would appear as a syntax error, as could other
components of the partial. This change introduces support for:
* Standard partials: `{{> partialName}}`
* Partials with parameters: `{{> partialName varname="value"}}`
* Ddynamic partials: `{{> (partialFunc)}}`
* Ddynamic partials with lookups: `{{> (lookup ../path "partialName")}}`
* Partial blocks: `{{> @partial-block}}`
* Inline partials: `{{#*inline}}..{{/inline}}`
It also introduces support for path segments, which can reference content in
the current context or in a parent context. For instance, `this.name`,
`this/name`, `./name`, `../name`, `this/name`, etc. These are all now tracked
as variables.
Diffstat (limited to 'tests/examplefiles/phpcomplete.vim')
| -rw-r--r-- | tests/examplefiles/phpcomplete.vim | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/tests/examplefiles/phpcomplete.vim b/tests/examplefiles/phpcomplete.vim new file mode 100644 index 00000000..17d74fd8 --- /dev/null +++ b/tests/examplefiles/phpcomplete.vim @@ -0,0 +1,567 @@ +" Vim completion script +" Language: PHP +" Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) +" Last Change: 2006 May 9 +" +" TODO: +" - Class aware completion: +" a) caching? +" - Switching to HTML (XML?) completion (SQL) inside of phpStrings +" - allow also for XML completion <- better do html_flavor for HTML +" completion +" - outside of <?php?> getting parent tag may cause problems. Heh, even in +" perfect conditions GetLastOpenTag doesn't cooperate... Inside of +" phpStrings this can be even a bonus but outside of <?php?> it is not the +" best situation + +function! phpcomplete#CompletePHP(findstart, base) + if a:findstart + unlet! b:php_menu + " Check if we are inside of PHP markup + let pos = getpos('.') + let phpbegin = searchpairpos('<?', '', '?>', 'bWn', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"') + let phpend = searchpairpos('<?', '', '?>', 'Wn', + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\|comment"') + + if phpbegin == [0,0] && phpend == [0,0] + " We are outside of any PHP markup. Complete HTML + let htmlbegin = htmlcomplete#CompleteTags(1, '') + let cursor_col = pos[2] + let base = getline('.')[htmlbegin : cursor_col] + let b:php_menu = htmlcomplete#CompleteTags(0, base) + return htmlbegin + else + " locate the start of the word + let line = getline('.') + let start = col('.') - 1 + let curline = line('.') + let compl_begin = col('.') - 2 + while start >= 0 && line[start - 1] =~ '[a-zA-Z_0-9\x7f-\xff$]' + let start -= 1 + endwhile + let b:compl_context = getline('.')[0:compl_begin] + return start + + " We can be also inside of phpString with HTML tags. Deal with + " it later (time, not lines). + endif + + endif + " If exists b:php_menu it means completion was already constructed we + " don't need to do anything more + if exists("b:php_menu") + return b:php_menu + endif + " Initialize base return lists + let res = [] + let res2 = [] + " a:base is very short - we need context + if exists("b:compl_context") + let context = b:compl_context + unlet! b:compl_context + endif + + if !exists('g:php_builtin_functions') + call phpcomplete#LoadData() + endif + + let scontext = substitute(context, '\$\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*$', '', '') + + if scontext =~ '\(=\s*new\|extends\)\s\+$' + " Complete class name + " Internal solution for finding classes in current file. + let file = getline(1, '$') + call filter(file, + \ 'v:val =~ "class\\s\\+[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let jfile = join(file, ' ') + let int_values = split(jfile, 'class\s\+') + let int_classes = {} + for i in int_values + let c_name = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*') + if c_name != '' + let int_classes[c_name] = '' + endif + endfor + + " Prepare list of classes from tags file + let ext_classes = {} + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + if fnames != '' + exe 'silent! vimgrep /^'.a:base.'.*\tc\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + " [:space:] thing: we don't have to be so strict when + " dealing with tags files - entries there were already + " checked by ctags. + let item = matchstr(field['text'], '^[^[:space:]]\+') + let ext_classes[item] = '' + endfor + endif + endif + + " Prepare list of built in classes from g:php_builtin_functions + if !exists("g:php_omni_bi_classes") + let g:php_omni_bi_classes = {} + for i in keys(g:php_builtin_object_functions) + let g:php_omni_bi_classes[substitute(i, '::.*$', '', '')] = '' + endfor + endif + + let classes = sort(keys(int_classes)) + let classes += sort(keys(ext_classes)) + let classes += sort(keys(g:php_omni_bi_classes)) + + for m in classes + if m =~ '^'.a:base + call add(res, m) + endif + endfor + + let final_menu = [] + for i in res + let final_menu += [{'word':i, 'kind':'c'}] + endfor + + return final_menu + + elseif scontext =~ '\(->\|::\)$' + " Complete user functions and variables + " Internal solution for current file. + " That seems as unnecessary repeating of functions but there are + " few not so subtle differences as not appending of $ and addition + " of 'kind' tag (not necessary in regular completion) + + if scontext =~ '->$' && scontext !~ '\$this->$' + + " Get name of the class + let classname = phpcomplete#GetClassName(scontext) + + " Get location of class definition, we have to iterate through all + " tags files separately because we need relative path from current + " file to the exact file (tags file can be in different dir) + if classname != '' + let classlocation = phpcomplete#GetClassLocation(classname) + else + let classlocation = '' + endif + + if classlocation == 'VIMPHP_BUILTINOBJECT' + + for object in keys(g:php_builtin_object_functions) + if object =~ '^'.classname + let res += [{'word':substitute(object, '.*::', '', ''), + \ 'info': g:php_builtin_object_functions[object]}] + endif + endfor + + return res + + endif + + if filereadable(classlocation) + let classfile = readfile(classlocation) + let classcontent = '' + let classcontent .= "\n".phpcomplete#GetClassContents(classfile, classname) + let sccontent = split(classcontent, "\n") + + " YES, YES, YES! - we have whole content including extends! + " Now we need to get two elements: public functions and public + " vars + " NO, NO, NO! - third separate filtering looking for content + " :(, but all of them have differences. To squeeze them into + " one implementation would require many additional arguments + " and ifs. No good solution + " Functions declared with public keyword or without any + " keyword are public + let functions = filter(deepcopy(sccontent), + \ 'v:val =~ "^\\s*\\(static\\s\\+\\|public\\s\\+\\)*function"') + let jfuncs = join(functions, ' ') + let sfuncs = split(jfuncs, 'function\s\+') + let c_functions = {} + for i in sfuncs + let f_name = matchstr(i, + \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') + let f_args = matchstr(i, + \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') + if f_name != '' + let c_functions[f_name.'('] = f_args + endif + endfor + " Variables declared with var or with public keyword are + " public + let variables = filter(deepcopy(sccontent), + \ 'v:val =~ "^\\s*\\(public\\|var\\)\\s\\+\\$"') + let jvars = join(variables, ' ') + let svars = split(jvars, '\$') + let c_variables = {} + for i in svars + let c_var = matchstr(i, + \ '^\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') + if c_var != '' + let c_variables[c_var] = '' + endif + endfor + + let all_values = {} + call extend(all_values, c_functions) + call extend(all_values, c_variables) + + for m in sort(keys(all_values)) + if m =~ '^'.a:base && m !~ '::' + call add(res, m) + elseif m =~ '::'.a:base + call add(res2, m) + endif + endfor + + let start_list = res + res2 + + let final_list = [] + for i in start_list + if has_key(c_variables, i) + let class = ' ' + if all_values[i] != '' + let class = i.' class ' + endif + let final_list += + \ [{'word':i, + \ 'info':class.all_values[i], + \ 'kind':'v'}] + else + let final_list += + \ [{'word':substitute(i, '.*::', '', ''), + \ 'info':i.all_values[i].')', + \ 'kind':'f'}] + endif + endfor + + return final_list + + endif + + endif + + if a:base =~ '^\$' + let adddollar = '$' + else + let adddollar = '' + endif + let file = getline(1, '$') + let jfile = join(file, ' ') + let sfile = split(jfile, '\$') + let int_vars = {} + for i in sfile + if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new' + let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->' + else + let val = matchstr(i, '^[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*') + endif + if val !~ '' + let int_vars[adddollar.val] = '' + endif + endfor + + " ctags has good support for PHP, use tags file for external + " variables + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let ext_vars = {} + if fnames != '' + let sbase = substitute(a:base, '^\$', '', '') + exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + let item = matchstr(field['text'], '^[^[:space:]]\+') + " Add -> if it is possible object declaration + let classname = '' + if field['text'] =~ item.'\s*=\s*new\s\+' + let item = item.'->' + let classname = matchstr(field['text'], + \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') + endif + let ext_vars[adddollar.item] = classname + endfor + endif + endif + + " Now we have all variables in int_vars dictionary + call extend(int_vars, ext_vars) + + " Internal solution for finding functions in current file. + let file = getline(1, '$') + call filter(file, + \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let jfile = join(file, ' ') + let int_values = split(jfile, 'function\s\+') + let int_functions = {} + for i in int_values + let f_name = matchstr(i, + \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') + let f_args = matchstr(i, + \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\zs.\{-}\ze)\_s*{') + let int_functions[f_name.'('] = f_args.')' + endfor + + " Prepare list of functions from tags file + let ext_functions = {} + if fnames != '' + exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + " File name + let item = matchstr(field['text'], '^[^[:space:]]\+') + let fname = matchstr(field['text'], '\t\zs\f\+\ze') + let prototype = matchstr(field['text'], + \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') + let ext_functions[item.'('] = prototype.') - '.fname + endfor + endif + endif + + let all_values = {} + call extend(all_values, int_functions) + call extend(all_values, ext_functions) + call extend(all_values, int_vars) " external variables are already in + call extend(all_values, g:php_builtin_object_functions) + + for m in sort(keys(all_values)) + if m =~ '\(^\|::\)'.a:base + call add(res, m) + endif + endfor + + let start_list = res + + let final_list = [] + for i in start_list + if has_key(int_vars, i) + let class = ' ' + if all_values[i] != '' + let class = i.' class ' + endif + let final_list += [{'word':i, 'info':class.all_values[i], 'kind':'v'}] + else + let final_list += + \ [{'word':substitute(i, '.*::', '', ''), + \ 'info':i.all_values[i], + \ 'kind':'f'}] + endif + endfor + + return final_list + endif + + if a:base =~ '^\$' + " Complete variables + " Built-in variables {{{ + let g:php_builtin_vars = {'$GLOBALS':'', + \ '$_SERVER':'', + \ '$_GET':'', + \ '$_POST':'', + \ '$_COOKIE':'', + \ '$_FILES':'', + \ '$_ENV':'', + \ '$_REQUEST':'', + \ '$_SESSION':'', + \ '$HTTP_SERVER_VARS':'', + \ '$HTTP_ENV_VARS':'', + \ '$HTTP_COOKIE_VARS':'', + \ '$HTTP_GET_VARS':'', + \ '$HTTP_POST_VARS':'', + \ '$HTTP_POST_FILES':'', + \ '$HTTP_SESSION_VARS':'', + \ '$php_errormsg':'', + \ '$this':'' + \ } + " }}} + + " Internal solution for current file. + let file = getline(1, '$') + let jfile = join(file, ' ') + let int_vals = split(jfile, '\ze\$') + let int_vars = {} + for i in int_vals + if i =~ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*=\s*new' + let val = matchstr(i, + \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*').'->' + else + let val = matchstr(i, + \ '^\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*') + endif + if val != '' + let int_vars[val] = '' + endif + endfor + + call extend(int_vars,g:php_builtin_vars) + + " ctags has support for PHP, use tags file for external variables + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let ext_vars = {} + if fnames != '' + let sbase = substitute(a:base, '^\$', '', '') + exe 'silent! vimgrep /^'.sbase.'.*\tv\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + let item = '$'.matchstr(field['text'], '^[^[:space:]]\+') + let m_menu = '' + " Add -> if it is possible object declaration + if field['text'] =~ item.'\s*=\s*new\s\+' + let item = item.'->' + let m_menu = matchstr(field['text'], + \ '=\s*new\s\+\zs[a-zA-Z_0-9\x7f-\xff]\+\ze') + endif + let ext_vars[item] = m_menu + endfor + endif + endif + + call extend(int_vars, ext_vars) + let g:a0 = keys(int_vars) + + for m in sort(keys(int_vars)) + if m =~ '^\'.a:base + call add(res, m) + endif + endfor + + let int_list = res + + let int_dict = [] + for i in int_list + if int_vars[i] != '' + let class = ' ' + if int_vars[i] != '' + let class = i.' class ' + endif + let int_dict += [{'word':i, 'info':class.int_vars[i], 'kind':'v'}] + else + let int_dict += [{'word':i, 'kind':'v'}] + endif + endfor + + return int_dict + + else + " Complete everything else - + " + functions, DONE + " + keywords of language DONE + " + defines (constant definitions), DONE + " + extend keywords for predefined constants, DONE + " + classes (after new), DONE + " + limit choice after -> and :: to funcs and vars DONE + + " Internal solution for finding functions in current file. + let file = getline(1, '$') + call filter(file, + \ 'v:val =~ "function\\s\\+&\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*\\s*("') + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let jfile = join(file, ' ') + let int_values = split(jfile, 'function\s\+') + let int_functions = {} + for i in int_values + let f_name = matchstr(i, + \ '^&\?\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze') + let f_args = matchstr(i, + \ '^&\?[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\s*(\s*\zs.\{-}\ze\s*)\_s*{') + let int_functions[f_name.'('] = f_args.')' + endfor + + " Prepare list of functions from tags file + let ext_functions = {} + if fnames != '' + exe 'silent! vimgrep /^'.a:base.'.*\tf\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + " File name + let item = matchstr(field['text'], '^[^[:space:]]\+') + let fname = matchstr(field['text'], '\t\zs\f\+\ze') + let prototype = matchstr(field['text'], + \ 'function\s\+&\?[^[:space:]]\+\s*(\s*\zs.\{-}\ze\s*)\s*{\?') + let ext_functions[item.'('] = prototype.') - '.fname + endfor + endif + endif + + " All functions + call extend(int_functions, ext_functions) + call extend(int_functions, g:php_builtin_functions) + + " Internal solution for finding constants in current file + let file = getline(1, '$') + call filter(file, 'v:val =~ "define\\s*("') + let jfile = join(file, ' ') + let int_values = split(jfile, 'define\s*(\s*') + let int_constants = {} + for i in int_values + let c_name = matchstr(i, '\(["'']\)\zs[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\ze\1') + " let c_value = matchstr(i, + " \ '\(["'']\)[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*\1\s*,\s*\zs.\{-}\ze\s*)') + if c_name != '' + let int_constants[c_name] = '' " c_value + endif + endfor + + " Prepare list of constants from tags file + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let ext_constants = {} + if fnames != '' + exe 'silent! vimgrep /^'.a:base.'.*\td\(\t\|$\)/j '.fnames + let qflist = getqflist() + if len(qflist) > 0 + for field in qflist + let item = matchstr(field['text'], '^[^[:space:]]\+') + let ext_constants[item] = '' + endfor + endif + endif + + " All constants + call extend(int_constants, ext_constants) + " Treat keywords as constants + + let all_values = {} + + " One big dictionary of functions + call extend(all_values, int_functions) + + " Add constants + call extend(all_values, int_constants) + " Add keywords + call extend(all_values, g:php_keywords) + + for m in sort(keys(all_values)) + if m =~ '^'.a:base + call add(res, m) + endif + endfor + + let int_list = res + + let final_list = [] + for i in int_list + if has_key(int_functions, i) + let final_list += + \ [{'word':i, + \ 'info':i.int_functions[i], + \ 'kind':'f'}] + elseif has_key(int_constants, i) + let final_list += [{'word':i, 'kind':'d'}] + else + let final_list += [{'word':i}] + endif + endfor + + return final_list + + endif + +endfunction +" vim:set foldmethod=marker: |
