aboutsummaryrefslogtreecommitdiff
path: root/runtime/autoload
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/autoload')
-rw-r--r--runtime/autoload/phpcomplete.vim74
-rw-r--r--runtime/autoload/provider/clipboard.vim14
-rw-r--r--runtime/autoload/provider/script_host.py25
-rw-r--r--runtime/autoload/tutor.vim346
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