diff options
Diffstat (limited to 'runtime/autoload')
-rw-r--r-- | runtime/autoload/phpcomplete.vim | 74 | ||||
-rw-r--r-- | runtime/autoload/provider/clipboard.vim | 14 | ||||
-rw-r--r-- | runtime/autoload/provider/script_host.py | 25 | ||||
-rw-r--r-- | runtime/autoload/tutor.vim | 346 |
4 files changed, 435 insertions, 24 deletions
diff --git a/runtime/autoload/phpcomplete.vim b/runtime/autoload/phpcomplete.vim index b014b4cdcf..5ddad88873 100644 --- a/runtime/autoload/phpcomplete.vim +++ b/runtime/autoload/phpcomplete.vim @@ -3,7 +3,7 @@ " Maintainer: Dávid Szabó ( complex857 AT gmail DOT com ) " Previous Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl ) " URL: https://github.com/shawncplus/phpcomplete.vim -" Last Change: 2014 Oct 02 +" Last Change: 2014 Dec 01 " " OPTIONS: " @@ -1172,11 +1172,11 @@ function! phpcomplete#GetCurrentInstruction(line_number, col_number, phpbegin) " " break if we are on a "naked" stop_char (operators, colon, openparent...) if index(stop_chars, current_char) != -1 let do_break = 1 - " dont break does not look like a "->" + " dont break if it does look like a "->" if (prev_char == '-' && current_char == '>') || (current_char == '-' && next_char == '>') let do_break = 0 endif - " dont break if its looks like a "::" + " dont break if it does look like a "::" if (prev_char == ':' && current_char == ':') || (current_char == ':' && next_char == ':') let do_break = 0 endif @@ -1356,8 +1356,12 @@ function! phpcomplete#GetCallChainReturnType(classname_candidate, class_candidat endif " make @return self, static, $this the same way " (not exactly what php means by these) - if returnclass == 'self' || returnclass == 'static' || returnclass == '$this' - let classname_candidate = a:classname_candidate + if returnclass == 'self' || returnclass == 'static' || returnclass == '$this' || returnclass == 'self[]' || returnclass == 'static[]' || returnclass == '$this[]' + if returnclass =~ '\[\]$' + let classname_candidate = a:classname_candidate.'[]' + else + let classname_candidate = a:classname_candidate + endif let class_candidate_namespace = a:class_candidate_namespace else let [classname_candidate, class_candidate_namespace] = phpcomplete#ExpandClassName(returnclass, fullnamespace, a:imports) @@ -1527,7 +1531,7 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor let function_boundary = phpcomplete#GetCurrentFunctionBoundaries() let search_end_line = max([1, function_boundary[0][0]]) " -1 makes us ignore the current line (where the completion was invoked - let lines = reverse(getline(search_end_line, line('.') - 1)) + let lines = reverse(getline(search_end_line, a:start_line - 1)) " check Constant lookup let constant_object = matchstr(a:context, '\zs'.class_name_pattern.'\ze::') @@ -1638,9 +1642,32 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor " assignment for the variable in question with a variable on the right hand side if line =~# '^\s*'.object.'\s*=&\?\s*'.variable_name_pattern - let tailing_semicolon = match(line, ';\s*$') - let tailing_semicolon = tailing_semicolon != -1 ? tailing_semicolon : strlen(getline(a:start_line - i)) - let prev_context = phpcomplete#GetCurrentInstruction(a:start_line - i, tailing_semicolon - 1, b:phpbegin) + + " try to find the next non-comment or string ";" char + let start_col = match(line, '^\s*'.object.'\C\s*=\zs&\?\s*'.variable_name_pattern) + let filelines = reverse(lines) + let [pos, char] = s:getNextCharWithPos(filelines, [a:start_line - i - 1, start_col]) + let chars_read = 1 + " read while end of the file + while char != 'EOF' && chars_read < 1000 + let last_pos = pos + let [pos, char] = s:getNextCharWithPos(filelines, pos) + let chars_read += 1 + " we got a candidate + if char == ';' + let synIDName = synIDattr(synID(pos[0] + 1, pos[1] + 1, 0), 'name') + " it's not a comment or string, end search + if synIDName !~? 'comment\|string' + break + endif + endif + endwhile + + let prev_context = phpcomplete#GetCurrentInstruction(last_pos[0] + 1, last_pos[1], b:phpbegin) + if prev_context == '' + " cannot get previous context give up + return + endif let prev_class = phpcomplete#GetClassName(a:start_line - i, prev_context, a:current_namespace, a:imports) if stridx(prev_class, '\') != -1 @@ -1656,9 +1683,32 @@ function! phpcomplete#GetClassName(start_line, context, current_namespace, impor " assignment for the variable in question with a function on the right hand side if line =~# '^\s*'.object.'\s*=&\?\s*'.function_invocation_pattern - let tailing_semicolon = match(line, ';\s*$') - let tailing_semicolon = tailing_semicolon != -1 ? tailing_semicolon : strlen(getline(a:start_line - i)) - let prev_context = phpcomplete#GetCurrentInstruction(a:start_line - i, tailing_semicolon - 1, b:phpbegin) + + " try to find the next non-comment or string ";" char + let start_col = match(line, '\C^\s*'.object.'\s*=\zs&\?\s*'.function_invocation_pattern) + let filelines = reverse(lines) + let [pos, char] = s:getNextCharWithPos(filelines, [a:start_line - i - 1, start_col]) + let chars_read = 1 + " read while end of the file + while char != 'EOF' && chars_read < 1000 + let last_pos = pos + let [pos, char] = s:getNextCharWithPos(filelines, pos) + let chars_read += 1 + " we got a candidate + if char == ';' + let synIDName = synIDattr(synID(pos[0] + 1, pos[1] + 1, 0), 'name') + " it's not a comment or string, end search + if synIDName !~? 'comment\|string' + break + endif + endif + endwhile + + let prev_context = phpcomplete#GetCurrentInstruction(last_pos[0] + 1, last_pos[1], b:phpbegin) + if prev_context == '' + " cannot get previous context give up + return + endif let function_name = matchstr(prev_context, '^'.function_invocation_pattern.'\ze') let function_name = matchstr(function_name, '^\zs.\+\ze\s*($') " strip the trailing ( diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index d20b3a9bf1..5d1ce7896d 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -55,13 +55,21 @@ endif let s:clipboard = {} function! s:clipboard.get(reg) - if s:selections[a:reg].owner > 0 - return s:selections[a:reg].data + let reg = a:reg == '"' ? '+' : a:reg + if s:selections[reg].owner > 0 + return s:selections[reg].data end - return s:try_cmd(s:paste[a:reg]) + return s:try_cmd(s:paste[reg]) endfunction function! s:clipboard.set(lines, regtype, reg) + if a:reg == '"' + call s:clipboard.set(a:lines,a:regtype,'+') + if s:copy['*'] != s:copy['+'] + call s:clipboard.set(a:lines,a:regtype,'*') + end + return 0 + end if s:cache_enabled == 0 call s:try_cmd(s:copy[a:reg], a:lines) return 0 diff --git a/runtime/autoload/provider/script_host.py b/runtime/autoload/provider/script_host.py index 0a7eb53a0e..96d70e0330 100644 --- a/runtime/autoload/provider/script_host.py +++ b/runtime/autoload/provider/script_host.py @@ -17,6 +17,9 @@ IS_PYTHON3 = sys.version_info >= (3, 0) if IS_PYTHON3: basestring = str + if sys.version_info >= (3, 4): + from importlib.machinery import PathFinder + @neovim.plugin class ScriptHost(object): @@ -190,31 +193,35 @@ def path_hook(nvim): name = oldtail[:idx] tail = oldtail[idx+1:] fmr = imp.find_module(name, path) - module = imp.load_module(fullname[:-len(oldtail)] + name, *fmr) + module = imp.find_module(fullname[:-len(oldtail)] + name, *fmr) return _find_module(fullname, tail, module.__path__) else: - fmr = imp.find_module(fullname, path) - return imp.load_module(fullname, *fmr) + return imp.find_module(fullname, path) class VimModuleLoader(object): def __init__(self, module): self.module = module def load_module(self, fullname, path=None): - return self.module + # Check sys.modules, required for reload (see PEP302). + if fullname in sys.modules: + return sys.modules[fullname] + return imp.load_module(fullname, *self.module) class VimPathFinder(object): - @classmethod - def find_module(cls, fullname, path=None): + @staticmethod + def find_module(fullname, path=None): + "Method for Python 2.7 and 3.3." try: return VimModuleLoader( _find_module(fullname, fullname, path or _get_paths())) except ImportError: return None - @classmethod - def load_module(cls, fullname, path=None): - return _find_module(fullname, fullname, path or _get_paths()) + @staticmethod + def find_spec(fullname, path=None, target=None): + "Method for Python 3.4+." + return PathFinder.find_spec(fullname, path or _get_paths(), target) def hook(path): if path == nvim.VIM_SPECIAL_PATH: diff --git a/runtime/autoload/tutor.vim b/runtime/autoload/tutor.vim new file mode 100644 index 0000000000..d2881f7f34 --- /dev/null +++ b/runtime/autoload/tutor.vim @@ -0,0 +1,346 @@ +" vim: fdm=marker et ts=4 sw=4 + +" Setup: {{{1 +function! tutor#SetupVim() + if has('syntax') + if !exists('g:syntax_on') || g:syntax_on == 0 + syntax on + endif + endif +endfunction + +" Mappings: {{{1 + +function! s:CheckMaps() + nmap +endfunction + +function! s:MapKeyWithRedirect(key, cmd) + if maparg(a:key) !=# '' + redir => l:keys + silent call s:CheckMaps() + redir END + let l:key_list = split(l:keys, '\n') + + let l:raw_map = filter(copy(l:key_list), "v:val =~# '\\* ".a:key."'") + if len(l:raw_map) == 0 + exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd + return + endif + let l:map_data = split(l:raw_map[0], '\s*') + + exe "nnoremap <buffer> <expr> ".l:map_data[0]." ".a:cmd + else + exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd + endif +endfunction + +function! tutor#MouseDoubleClick() + if foldclosed(line('.')) > -1 + normal! zo + else + if match(getline('.'), '^#\{1,} ') > -1 + normal! zc + else + call tutor#FollowLink(0) + endif + endif +endfunction + +function! tutor#InjectCommand() + let l:cmd = substitute(getline('.'), '^\s*', '', '') + exe l:cmd + redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd +endfunction + +function! tutor#SetNormalMappings() + call s:MapKeyWithRedirect('l', 'tutor#ForwardSkipConceal(v:count1)') + call s:MapKeyWithRedirect('h', 'tutor#BackwardSkipConceal(v:count1)') + call s:MapKeyWithRedirect('<right>', 'tutor#ForwardSkipConceal(v:count1)') + call s:MapKeyWithRedirect('<left>', 'tutor#BackwardSkipConceal(v:count1)') + + nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr> + nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr> + nnoremap <buffer> >> :call tutor#InjectCommand()<cr> +endfunction + +function! tutor#SetSampleTextMappings() + noremap <silent> <buffer> A :if match(getline('.'), '^--->') > -1 \| call search('\s{\@=', 'Wc') \| startinsert \| else \| startinsert! \| endif<cr> + noremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr> + onoremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr> + noremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr> + onoremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr> + nmap <silent> <buffer> 0 ^<esc> + nmap <silent> <buffer> <Home> ^<esc> + nmap <silent> <buffer> <End> $ + imap <silent> <buffer> <Home> <esc>^<esc>:startinsert<cr> + imap <silent> <buffer> <End> <esc>$:startinsert<cr> + noremap <silent> <buffer> I :exe "normal! 0" \| startinsert<cr> +endfunction + +" Navigation: {{{1 + +" taken from http://stackoverflow.com/a/24224578 + +function! tutor#ForwardSkipConceal(count) + let cnt=a:count + let mvcnt=0 + let c=col('.') + let l=line('.') + let lc=col('$') + let line=getline('.') + while cnt + if c>=lc + let mvcnt+=cnt + break + endif + if stridx(&concealcursor, 'n')==-1 + let isconcealed=0 + else + let [isconcealed, cchar, group] = synconcealed(l, c) + endif + if isconcealed + let cnt-=strchars(cchar) + let oldc=c + let c+=1 + while c < lc + let [isconcealed2, cchar2, group2] = synconcealed(l, c) + if !isconcealed2 || cchar2 != cchar + break + endif + let c+= 1 + endwhile + let mvcnt+=strchars(line[oldc-1:c-2]) + else + let cnt-=1 + let mvcnt+=1 + let c+=len(matchstr(line[c-1:], '.')) + endif + endwhile + return mvcnt.'l' +endfunction + +function! tutor#BackwardSkipConceal(count) + let cnt=a:count + let mvcnt=0 + let c=col('.') + let l=line('.') + let lc=0 + let line=getline('.') + while cnt + if c<=1 + let mvcnt+=cnt + break + endif + if stridx(&concealcursor, 'n')==-1 || c == 0 + let isconcealed=0 + else + let [isconcealed, cchar, group]=synconcealed(l, c-1) + endif + if isconcealed + let cnt-=strchars(cchar) + let oldc=c + let c-=1 + while c>1 + let [isconcealed2, cchar2, group2] = synconcealed(l, c-1) + if !isconcealed2 || cchar2 != cchar + break + endif + let c-=1 + endwhile + let c = max([c, 1]) + let mvcnt+=strchars(line[c-1:oldc-2]) + else + let cnt-=1 + let mvcnt+=1 + let c-=len(matchstr(line[:c-2], '.$')) + endif + endwhile + return mvcnt.'h' +endfunction + +" Hypertext: {{{1 + +function! tutor#FollowLink(force) + let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '') + if l:stack_s =~# 'tutorLink' + let l:link_start = searchpairpos('\[', '', ')', 'nbcW') + let l:link_end = searchpairpos('\[', '', ')', 'ncW') + if l:link_start[0] == l:link_end[0] + let l:linkData = getline(l:link_start[0])[l:link_start[1]-1:l:link_end[1]-1] + else + return + endif + let l:target = matchstr(l:linkData, '(\@<=.*)\@=') + if a:force != 1 && match(l:target, '\*.\+\*') > -1 + call cursor(l:link_start[0], l:link_end[1]) + call search(l:target, '') + normal! ^ + elseif a:force != 1 && match(l:target, '^@tutor:') > -1 + let l:tutor = matchstr(l:target, '@tutor:\zs.*') + exe "Tutor ".l:tutor + else + exe "help ".l:target + endif + endif +endfunction + +" Folding And Info: {{{1 + +function! tutor#TutorFolds() + if getline(v:lnum) =~# '^#\{1,6}' + return ">". len(matchstr(getline(v:lnum), '^#\{1,6}')) + else + return "=" + endif +endfunction + +function! tutor#InfoText() + let l:info_parts = [] + if exists('b:tutor_infofunc') + call add(l:info_parts, eval(b:tutor_infofunc.'()')) + endif + return join(l:info_parts, " ") +endfunction + +" Marks {{{1 +function! tutor#PlaceXMarks() + call cursor(1, 1) + let b:tutor_sign_id = 1 + while search('^--->', 'W') > 0 + call tutor#CheckText(getline('.')) + let b:tutor_sign_id+=1 + endwhile + call cursor(1, 1) +endfunction + +function! tutor#CheckText(text) + if match(a:text, '{expect:ANYTHING}\s*$') == -1 + if match(getline('.'), '^--->\s*$') > -1 + exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') + else + if match(getline('.'), '|expect:.\+|') == -1 + let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze {expect:') + let l:expected_text = matchstr(a:text, '{expect:\zs.*\ze}\s*$') + else + let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze |expect:') + let l:expected_text = matchstr(a:text, '|expect:\zs.*\ze|\s*$') + endif + if l:cur_text ==# l:expected_text + exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorok buffer=".bufnr('%') + else + exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') + endif + endif + endif +endfunction + +function! tutor#OnTextChanged() + let l:text = getline('.') + if match(l:text, '^--->') > -1 + call tutor#CheckText(l:text) + endif +endfunction + +" Tutor Cmd: {{{1 + +function! s:Locale() + let l:lang = "" + if exists('v:lang') && v:lang =~ '\a\a' + let l:lang = v:lang + elseif $LC_ALL =~ '\a\a' + let l:lang = $LC_ALL + elseif $LANG =~ '\a\a' + let l:lang = $LANG + endif + return split(l:lang, '_') +endfunction + +function! s:GlobPath(lp, pat) + if version >= 704 && has('patch279') + return globpath(a:lp, a:pat, 1, 1) + else + return split(globpath(a:lp, a:pat, 1), '\n') + endif +endfunction + +function! s:Sort(a, b) + let mod_a = fnamemodify(a:a, ':t') + let mod_b = fnamemodify(a:b, ':t') + if mod_a == mod_b + let retval = 0 + elseif mod_a > mod_b + if match(mod_a, '^vim-') > -1 && match(mod_b, '^vim-') == -1 + let retval = -1 + else + let retval = 1 + endif + else + if match(mod_b, '^vim-') > -1 && match(mod_a, '^vim-') == -1 + let retval = 1 + else + let retval = -1 + endif + endif + return retval +endfunction + +function! s:GlobTutorials(name) + " search for tutorials: + " 1. non-localized + let l:tutors = s:GlobPath(&rtp, 'tutor/'.a:name.'.tutor') + " 2. localized for current locale + let l:locale_tutors = s:GlobPath(&rtp, 'tutor/'.s:Locale()[0].'/'.a:name.'.tutor') + " 3. fallback to 'en' + if len(l:locale_tutors) == 0 + let l:locale_tutors = s:GlobPath(&rtp, 'tutor/en/'.a:name.'.tutor') + endif + call extend(l:tutors, l:locale_tutors) + return uniq(sort(l:tutors, 's:Sort'), 's:Sort') +endfunction + +function! tutor#TutorCmd(tutor_name) + if match(a:tutor_name, '[[:space:]]') > 0 + echom "Only one argument accepted (check spaces)" + return + endif + + if a:tutor_name == '' + let l:tutor_name = 'vim-01-beginner.tutor' + else + let l:tutor_name = a:tutor_name + endif + + if match(l:tutor_name, '\.tutor$') > 0 + let l:tutor_name = fnamemodify(l:tutor_name, ':r') + endif + + let l:tutors = s:GlobTutorials(l:tutor_name) + + if len(l:tutors) == 0 + echom "No tutorial with that name found" + return + endif + + if len(l:tutors) == 1 + let l:to_open = l:tutors[0] + else + let l:idx = 0 + let l:candidates = ['Several tutorials with that name found. Select one:'] + for candidate in map(copy(l:tutors), + \'fnamemodify(v:val, ":h:h:t")."/".s:Locale()[0]."/".fnamemodify(v:val, ":t")') + let l:idx += 1 + call add(l:candidates, l:idx.'. '.candidate) + endfor + let l:tutor_to_open = inputlist(l:candidates) + let l:to_open = l:tutors[l:tutor_to_open-1] + endif + + exe "edit ".l:to_open +endfunction + +function! tutor#TutorCmdComplete(lead,line,pos) + let l:tutors = s:GlobTutorials('*') + let l:names = uniq(sort(map(l:tutors, 'fnamemodify(v:val, ":t:r")'), 's:Sort')) + return join(l:names, "\n") +endfunction |