<commit_before>" Vim completion script
" Language:	PHP
" Maintainer:	<NAME> ( mikmach AT wp DOT pl )
" Maintainer:	<NAME> ( shawn AT shawnbiddle DOT com )
" Maintainer:	<NAME> ( <EMAIL> AT <EMAIL> DOT <EMAIL> )
" 维护人： 吕海涛 ( vim AT lvht DOT net )

let s:script_path = fnamemodify(resolve(expand('<sfile>:p')), ':h')
let s:cache_classstructures = {}

function! phpcd#CompletePHP(findstart, base) " {{{
	" we need to wait phpcd {{{
	if g:phpcd_channel_id < 0
		return
	endif " }}}

	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 compl_begin = col('.') - 2
			while start >= 0 && line[start - 1] =~ '[\\a-zA-Z_0-9\x7f-\xff$]'
				let start -= 1
			endwhile
			let b:phpbegin = phpbegin
			let b:compl_context = phpcd#GetCurrentInstruction(line('.'), max([0, col('.') - 2]), phpbegin)

			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 " }}}

	" a:base is very short - we need context {{{
	if exists("b:compl_context")
		let context = b:compl_context
		unlet! b:compl_context
		" chop of the "base" from the end of the current instruction
		if a:base != ""
			let context = substitute(context, '\s*[$a-zA-Z_0-9\x7f-\xff]*$', '', '')
		end
	else
		let context = ''
	end " }}}

	try " {{{
		let winheight = winheight(0)
		let winnr = winnr()

		let [current_namespace, imports] = phpcd#GetCurrentNameSpace(getline(0, line('.')))

		if context =~? '^use\s' || context ==? 'use' " {{{
			" TODO complete use
		endif " }}}

		if context =~ '\(->\|::\)$' " {{{
			let classname = phpcd#GetClassName(line('.'), context, current_namespace, imports)
			return rpcrequest(g:phpcd_channel_id, 'info', classname, a:base)
		elseif context =~? 'implements'
			" TODO complete class Foo implements
		elseif context =~? 'extends\s\+.\+$' && a:base == ''
			" TODO complete class Foo extends
		elseif context =~? 'extends'
			" TODO complete class Foo extends Prefix..
		elseif context =~? 'class [a-zA-Z_\x7f-\xff\\][a-zA-Z_0-9\x7f-\xff\\]*'
			" special case when you've typed the class keyword and the name too,
			" only extends and implements allowed there
			return filter(['extends', 'implements'], 'stridx(v:val, a:base) == 0')
		elseif context =~? 'new'
			" TODO complete $foo = new
		endif " }}}

		if a:base =~ '^\$' " {{{
			return phpcd#CompleteVariable(a:base)
		else
			return phpcd#CompleteGeneral(a:base, current_namespace, imports)
		endif " }}}
	finally
		silent! exec winnr.'resize '.winheight
	endtry " }}}
endfunction
" }}}

function! phpcd#CompleteGeneral(base, current_namespace, imports) " {{{
	" Complete everything
	"  + 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.

	if a:base =~? '^\'
		let leading_slash = '\'
	else
		let leading_slash = ''
	endif
<commit_msg>初步支持注释元标记<commit_after>" Vim completion script
" Language:	PHP
" Maintainer:	<NAME> ( mikmach AT wp DOT pl )
" Maintainer:	<NAME> ( shawn AT shawnbiddle DOT com )
" Maintainer:	<NAME> ( complex857 AT gmail DOT com )
" 维护人： 吕海涛 ( vim AT lvht DOT net )

let s:script_path = fnamemodify(resolve(expand('<sfile>:p')), ':h')
let s:cache_classstructures = {}

function! phpcd#CompletePHP(findstart, base) " {{{
	" we need to wait phpcd {{{
	if g:phpcd_channel_id < 0
		return
	endif " }}}

	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 compl_begin = col('.') - 2
			while start >= 0 && line[start - 1] =~ '[\\a-zA-Z_0-9\x7f-\xff$]'
				let start -= 1
			endwhile
			let b:phpbegin = phpbegin
			let b:compl_context = phpcd#GetCurrentInstruction(line('.'), max([0, col('.') - 2]), phpbegin)

			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 " }}}

	" a:base is very short - we need context {{{
	if exists("b:compl_context")
		let context = b:compl_context
		unlet! b:compl_context
		" chop of the "base" from the end of the current instruction
		if a:base != ""
			let context = substitute(context, '\s*[$a-zA-Z_0-9\x7f-\xff]*$', '', '')
		end
	else
		let context = ''
	end " }}}

	try " {{{
		let winheight = winheight(0)
		let winnr = winnr()

		let [current_namespace, imports] = phpcd#GetCurrentNameSpace(getline(0, line('.')))

		if context =~? '^use\s' || context ==? 'use' " {{{
			" TODO complete use
		endif " }}}

		if context =~ '\(->\|::\)$' " {{{
			let classname = phpcd#GetClassName(line('.'), context, current_namespace, imports)
			return rpcrequest(g:phpcd_channel_id, 'info', classname, a:base)
		elseif context =~? 'implements'
			" TODO complete class Foo implements
		elseif context =~? 'extends\s\+.\+$' && a:base == ''
			" TODO complete class Foo extends
		elseif context =~? 'extends'
			" TODO complete class Foo extends Prefix..
		elseif context =~? 'class [a-zA-Z_\x7f-\xff\\][a-zA-Z_0-9\x7f-\xff\\]*'
			" special case when you've typed the class keyword and the name too,
			" only extends and implements allowed there
			return filter(['extends', 'implements'], 'stridx(v:val, a:base) == 0')
		elseif context =~? 'new'
			" TODO complete $foo = new
		endif " }}}

		let line = getline('.')
		if line =~ '* @$'
			" TODO 根据输入过滤
			return phpcd#CompleteDoc()
		endif

		if a:base =~ '^\$' " {{{
			return phpcd#CompleteVariable(a:base)
		else
			return phpcd#CompleteGeneral(a:base, current_namespace, imports)
		endif " }}}
	finally " {{{
		silent! exec winnr.'resize '.winheight
	endtry " }}}
endfunction
" }}}

function! phpcd#CompleteDoc() " {{{
	return [
				\ 'api',
				\ 'author',
				\ 'category',
				\ 'copyright',
				\ 'deprecated',
				\ 'example',
				\ 'filesource',
				\ 'global',
				\ 'ignore',
				\ 'internal',
				\ 'license',
				\ 'link',
				\ 'method',
				\ 'package',
				\ 'param',
				\ 'property',
				\ 'property-read',
				\ 'property-write',
				\ 'return',
				\ 'see',
				\ 'since',
				\ 'source',
				\ 'subpackage',
				\ 'throws',
				\ 'todo',
				\ 'uses',
				\ 'var',
				\ 'version'
				\]
endfunction

function! phpcd#CompleteGeneral(base, current_namespace, imports) " {{{
	" Complete everything
	"  + 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.

	if a:base =~? '^\'
		let leading_slash = '\'
	else
		let leading_slash = ''
	endif

{'fraction_non_alphanumeric': 0.17083580320094843, 'fraction_numerical': 0.007468879668049793, 'mean_word_length': 3.3596899224806203, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4966218', 'n_tokens_mistral': 3429, 'n_tokens_neox': 3039, 'n_words': 834}