diff options
author | Karel Kočí <cynerd@email.cz> | 2016-06-30 16:03:25 +0200 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2016-06-30 16:03:25 +0200 |
commit | e573b3020c032400eed60b649a2cbf55266e6bb0 (patch) | |
tree | 8f572394ac8433529c7a8e70d160a2fbe8268b4e /vim/bundle/vim-snipmate/autoload/snipMate.vim | |
parent | b8c667bd64b3edd38d56c63c5bd1db53a23b4499 (diff) | |
download | myconfigs-e573b3020c032400eed60b649a2cbf55266e6bb0.tar.gz myconfigs-e573b3020c032400eed60b649a2cbf55266e6bb0.tar.bz2 myconfigs-e573b3020c032400eed60b649a2cbf55266e6bb0.zip |
Add current configurations from old repository
Diffstat (limited to 'vim/bundle/vim-snipmate/autoload/snipMate.vim')
-rw-r--r-- | vim/bundle/vim-snipmate/autoload/snipMate.vim | 603 |
1 files changed, 603 insertions, 0 deletions
diff --git a/vim/bundle/vim-snipmate/autoload/snipMate.vim b/vim/bundle/vim-snipmate/autoload/snipMate.vim new file mode 100644 index 0000000..74366fa --- /dev/null +++ b/vim/bundle/vim-snipmate/autoload/snipMate.vim @@ -0,0 +1,603 @@ +" config which can be overridden (shared lines) +if !exists('g:snipMate') + let g:snipMate = {} +endif + +try + call tlib#input#List('mi', '', []) +catch /.*/ + echoe "you're missing tlib. See install instructions at ".expand('<sfile>:h:h').'/README.md' +endtry + +fun! Filename(...) abort + let filename = expand('%:t:r') + if filename == '' | return a:0 == 2 ? a:2 : '' | endif + return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') +endf + +let s:cache = {} + +function! snipMate#expandSnip(snip, version, col) abort + let lnum = line('.') + let col = a:col + let line = getline(lnum) + let indent = match(line, '\S\|$') + 1 + let b:snip_state = snipmate#jumping#state() + + if a:version == 1 + let [snippet, b:snip_state.stops] = snipmate#parse#snippet(a:snip) + " Build stop/mirror info + let b:snip_state.stop_count = s:build_stops(snippet, b:snip_state.stops, lnum, col, indent) + let snipLines = map(copy(snippet), + \ 'snipMate#sniplist_str(v:val, b:snip_state.stops)') + else + let snippet = snipmate#legacy#process_snippet(a:snip) + let [b:snip_state.stops, b:snip_state.stop_count] = snipmate#legacy#build_stops(snippet, lnum, col - indent, indent) + let snipLines = split(substitute(snippet, printf('%s\d\+\|%s{\d\+.\{-}}', + \ g:snipmate#legacy#sigil, g:snipmate#legacy#sigil), '', 'g'), "\n", 1) + endif + + " Abort if the snippet is empty + if empty(snippet) + return '' + endif + + " Expand snippet onto current position + let afterCursor = strpart(line, col - 1) + " Keep text after the cursor + if afterCursor != "\t" && afterCursor != ' ' + let line = strpart(line, 0, col - 1) + let snipLines[-1] .= afterCursor + else + let afterCursor = '' + " For some reason the cursor needs to move one right after this + if line != '' && col == 1 && &ve != 'all' && &ve != 'onemore' + let col += 1 + endif + endif + + " Insert snippet with proper indentation + call setline(lnum, line . snipLines[0]) + call append(lnum, map(snipLines[1:], "empty(v:val) ? v:val : '" . strpart(line, 0, indent - 1) . "' . v:val")) + + " Open any folds snippet expands into + if &foldenable + silent! exec lnum . ',' . (lnum + len(snipLines) - 1) . 'foldopen' + endif + + aug snipmate_changes + au CursorMoved,CursorMovedI <buffer> if exists('b:snip_state') | + \ call b:snip_state.update_changes() | + \ else | + \ silent! au! snipmate_changes * <buffer> | + \ endif + aug END + + let b:snip_state.stop_no = 0 + return b:snip_state.set_stop(0) +endfunction + +function! snipMate#placeholder_str(num, stops) abort + return snipMate#sniplist_str(a:stops[a:num].placeholder, a:stops) +endfunction + +function! snipMate#sniplist_str(snippet, stops) abort + let str = '' + let pos = 0 + let add_to = 1 + let seen_stops = [] + + while pos < len(a:snippet) + let item = a:snippet[pos] + + if type(item) == type('') + let str .= item + elseif type(item) == type([]) + let str .= snipMate#placeholder_str(item[0], a:stops) + endif + + let pos += 1 + unlet item " avoid E706 + endwhile + + return str +endfunction + +function! s:build_stops(snippet, stops, lnum, col, indent) abort + let stops = a:stops + let lnum = a:lnum + let col = a:col + + for line in a:snippet + let col = s:build_loc_info(line, stops, lnum, col, []) + if line isnot a:snippet[-1] + let lnum += 1 + let col = a:indent + endif + endfor + + " add zero tabstop if it doesn't exist and then link it to the highest stop + " number + let stops[0] = get(stops, 0, + \ { 'placeholder' : [], 'line' : lnum, 'col' : col }) + let stop_count = max(keys(stops)) + 2 + let stops[stop_count - 1] = stops[0] + + return stop_count +endfunction + +function! s:build_loc_info(snippet, stops, lnum, col, seen_items) abort + let stops = a:stops + let lnum = a:lnum + let col = a:col + let pos = 0 + let in_text = 0 + let seen_items = a:seen_items + + for item in a:snippet + if type(item) == type('') + let col += len(item) + elseif type(item) == type([]) + let id = item[0] + let stub = item[-1] + let stub.line = lnum + let stub.col = col + call s:add_update_objects(stub, seen_items) + + if len(item) > 2 && type(item[1]) != type({}) + let col = s:build_loc_info(item[1:-2], stops, lnum, col, seen_items) + else + let col += len(snipMate#placeholder_str(id, stops)) + endif + + let in_text = 0 + endif + unlet item " avoid E706 + endfor + + return col +endfunction + +function! s:add_update_objects(object, targets) abort + let targets = a:targets + + for item in targets + let item.update_objects = get(item, 'update_objects', []) + call add(item.update_objects, a:object) + endfor + + call add(targets, a:object) +endfunction + +" reads a .snippets file +" returns list of +" ['triggername', 'name', 'contents'] +" if triggername is not set 'default' is assumed +" TODO: better error checking +fun! snipMate#ReadSnippetsFile(file) abort + let result = [] + let new_scopes = [] + if !filereadable(a:file) | return [result, new_scopes] | endif + let inSnip = 0 + let line_no = 0 + let snipversion = get(g:snipMate, 'snippet_version', 0) + for line in readfile(a:file) + ["\n"] + let line_no += 1 + + if inSnip && (line[0] == "\t" || line == '') + let content .= strpart(line, 1)."\n" + continue + elseif inSnip + call add(result, [trigger, name, + \ content[:-2], bang, snipversion]) + let inSnip = 0 + endif + + if line[:6] == 'snippet' + let inSnip = 1 + let bang = (line[7] == '!') + if bang + let bang += line[8] == '!' + endif + let trigger = strpart(line, 8 + bang) + let name = '' + let space = stridx(trigger, ' ') + 1 + if space " Process multi snip + let name = strpart(trigger, space) + let trigger = strpart(trigger, 0, space - 1) + endif + let content = '' + if trigger =~ '^\s*$' " discard snippets with empty triggers + echom 'Invalid snippet in' a:file 'near line' line_no + let inSnip = 0 + endif + elseif line[:6] == 'extends' + call extend(new_scopes, map(split(strpart(line, 8)), + \ "substitute(v:val, ',*$', '', '')")) + elseif line[:6] == 'version' + let snipversion = +strpart(line, 8) + endif + endfor + return [result, new_scopes] +endf + +function! s:GetScopes() abort + let ret = exists('b:snipMate.scope_aliases') ? copy(b:snipMate.scope_aliases) : {} + let global = get(g:snipMate, 'scope_aliases', {}) + for alias in keys(global) + if has_key(ret, alias) + let ret[alias] = join(split(ret[alias], ',') + \ + split(global[alias], ','), ',') + else + let ret[alias] = global[alias] + endif + endfor + return ret +endfunction + +" adds scope aliases to list. +" returns new list +" the aliases of aliases are added recursively +fun! s:AddScopeAliases(list) abort + let did = {} + let scope_aliases = s:GetScopes() + let new = a:list + let new2 = [] + while !empty(new) + for i in new + if !has_key(did, i) + let did[i] = 1 + call extend(new2, split(get(scope_aliases,i,''),',')) + endif + endfor + let new = new2 + let new2 = [] + endwhile + return keys(did) +endf + +augroup SnipMateSource + au SourceCmd *.snippet,*.snippets call s:source_snippet() +augroup END + +function! s:info_from_filename(file) abort + let parts = split(fnamemodify(a:file, ':r'), '/') + let snipidx = len(parts) - index(reverse(copy(parts)), 'snippets') - 1 + let rtp_prefix = join(parts[(snipidx - + \ (parts[snipidx - 1] == 'after' ? 3 : 2)):snipidx - 1], '/') + let trigger = get(parts, snipidx + 2, '') + let desc = get(parts, snipidx + 3, get(g:snipMate, 'override', 0) ? + \ '' : fnamemodify(a:file, ':t')) + return [rtp_prefix, trigger, desc] +endfunction + +function! s:source_snippet() abort + let file = expand('<afile>:p') + let [rtp_prefix, trigger, desc] = s:info_from_filename(file) + let new_snips = [] + if fnamemodify(file, ':e') == 'snippet' + call add(new_snips, [trigger, desc, join(readfile(file), "\n"), 0, + \ get(g:snipMate, 'snippet_version', 0)]) + else + let [snippets, extends] = s:CachedSnips(file) + let new_snips = deepcopy(snippets) + call extend(s:lookup_state.extends, extends) + endif + for snip in new_snips + if get(g:snipMate, 'override', 0) + let snip[1] = join([s:lookup_state.scope, snip[1]]) + else + let snip[1] = join([s:lookup_state.scope, rtp_prefix, + \ empty(snip[1]) ? desc : snip[1]]) + endif + endfor + call extend(s:lookup_state.snips, new_snips) +endfunction + +function! s:CachedSnips(file) abort + let mtime = getftime(a:file) + if has_key(s:cache, a:file) && s:cache[a:file].mtime >= mtime + return s:cache[a:file].contents + endif + let s:cache[a:file] = {} + let s:cache[a:file].mtime = mtime + let s:cache[a:file].contents = snipMate#ReadSnippetsFile(a:file) + return s:cache[a:file].contents +endfunction + +function! s:snippet_filenames(scope, trigger) abort + let mid = ['', '_*', '/*'] + let mid += map(copy(mid), "'/' . a:trigger . '*' . v:val") + call map(mid, "'snippets/' . a:scope . v:val . '.snippet'") + return map(mid[:2], 'v:val . "s"') + mid[3:] +endfunction + +function! snipMate#SetByPath(dict, trigger, path, snippet, bang, snipversion) abort + let d = a:dict + if a:bang == 2 + unlet! d[a:trigger] + return + elseif !has_key(d, a:trigger) || a:bang == 1 + let d[a:trigger] = {} + endif + let d[a:trigger][a:path] = [a:snippet, a:snipversion] +endfunction + +if v:version < 704 || has('win32') + function! s:Glob(path, expr) + let res = [] + for p in split(a:path, ',') + let h = split(fnamemodify(a:expr, ':h'), '/')[0] + if isdirectory(p . '/' . h) + call extend(res, split(glob(p . '/' . a:expr), "\n")) + endif + endfor + return filter(res, 'filereadable(v:val)') + endfunction +else + function! s:Glob(path, expr) + return split(globpath(a:path, a:expr), "\n") + endfunction +endif + +" default triggers based on paths +function! snipMate#DefaultPool(scopes, trigger, result) abort + let scopes = s:AddScopeAliases(a:scopes) + let scopes_done = [] + let s:lookup_state = {} + let s:lookup_state.snips = [] + + while !empty(scopes) + let scope = remove(scopes, 0) + let s:lookup_state.scope = scope + let s:lookup_state.extends = [] + + for expr in s:snippet_filenames(scope, escape(a:trigger, "*[]?{}`'$|#%")) + for path in g:snipMate.snippet_dirs + for file in s:Glob(path, expr) + source `=file` + endfor + endfor + endfor + + call add(scopes_done, scope) + call extend(scopes, s:lookup_state.extends) + call filter(scopes, 'index(scopes_done, v:val) == -1') + endwhile + + for [trigger, desc, contents, bang, snipversion] in s:lookup_state.snips + if trigger =~ '\V\^' . escape(a:trigger, '\') + call snipMate#SetByPath(a:result, trigger, desc, contents, bang, snipversion) + endif + endfor +endfunction + +" return a dict of snippets found in runtimepath matching trigger +" scopes: list of scopes. usually this is the filetype. eg ['c','cpp'] +" trigger may contain glob patterns. Thus use '*' to get all triggers +" +fun! snipMate#GetSnippets(scopes, trigger) abort + let result = {} + + for F in values(g:snipMateSources) + call funcref#Call(F, [a:scopes, a:trigger, result]) + endfor + return result +endf + +function! snipMate#OpenSnippetFiles() abort + let files = [] + let scopes_done = [] + let exists = [] + let notexists = [] + for scope in s:AddScopeAliases(snipMate#ScopesByFile()) + let files += s:snippet_filenames(scope, '') + endfor + call filter(files, "v:val !~# '\\*'") + for path in g:snipMate.snippet_dirs + let fullpaths = map(copy(files), 'printf("%s/%s", path, v:val)') + let exists += filter(copy(fullpaths), 'filereadable(v:val)') + let notexists += map(filter(copy(fullpaths), + \ 'v:val =~# "\.snippets" && !filereadable(v:val)'), + \ '"does not exist: " . v:val') + endfor + let all = exists + notexists + let select = tlib#input#List('mi', 'select files to be opened in splits', all) + for idx in select + exec 'sp' all[idx - 1] + endfor +endfunction + +fun! snipMate#ScopesByFile() abort + " duplicates are removed in AddScopeAliases + return filter(funcref#Call(g:snipMate.get_scopes), "v:val != ''") +endf + +" used by both: completion and insert snippet +fun! snipMate#GetSnippetsForWordBelowCursor(word, exact) abort + " Split non-word characters into their own piece + " so 'foo.bar..baz' becomes ['foo', '.', 'bar', '.', '.', 'baz'] + " First split just after a \W and then split each resultant string just + " before a \W + let parts = filter(tlib#list#Flatten( + \ map(split(a:word, '\W\zs'), 'split(v:val, "\\ze\\W")')), + \ '!empty(v:val)') + " Only look at the last few possibilities. Too many can be slow. + if len(parts) > 5 + let parts = parts[-5:] + endif + let lookups = [a:word] + let lookup = '' + for w in reverse(parts) + let lookup = w . lookup + if index(lookups, lookup) == -1 + call add(lookups, lookup) + endif + endfor + + " Remove empty lookup entries, but only if there are other nonempty lookups + if len(lookups) > 1 + call filter(lookups, 'v:val != ""') + endif + + let matching_snippets = [] + let snippet = '' + " prefer longest word + for word in lookups + let g:snipMate.word = word + for [k,snippetD] in items(funcref#Call(g:snipMate['get_snippets'], [snipMate#ScopesByFile(), word])) + " hack: require exact match + if a:exact && k !=# word + continue + endif + call add(matching_snippets, [k, snippetD]) + if a:exact + break + endif + endfor + endfor + return matching_snippets +endf + +" snippets: dict containing snippets by name +" usually this is just {'default' : snippet_contents } +fun! s:ChooseSnippet(snippets) abort + let snippet = [] + let keys = keys(a:snippets) + let i = 1 + for snip in keys + let snippet += [i.'. '.snip] + let i += 1 + endfor + if len(snippet) == 1 + " there's only a single snippet, choose it + let idx = 0 + else + let idx = tlib#input#List('si','select snippet by name',snippet) -1 + if idx == -1 + return '' + endif + endif + " if a:snippets[..] is a String Call returns it + " If it's a function or a function string the result is returned + return funcref#Call(a:snippets[keys(a:snippets)[idx]]) +endf + +fun! snipMate#WordBelowCursor() abort + return matchstr(getline('.'), '\S\+\%' . col('.') . 'c') +endf + +fun! snipMate#GetSnippetsForWordBelowCursorForComplete(word) abort + let snippets = map(snipMate#GetSnippetsForWordBelowCursor(a:word, 0), 'v:val[0]') + return filter(snippets, 'v:val =~# "\\V\\^' . escape(a:word, '"\') . '"') +endf + +fun! snipMate#CanBeTriggered() abort + let word = snipMate#WordBelowCursor() + let matches = snipMate#GetSnippetsForWordBelowCursorForComplete(word) + return len(matches) > 0 +endf + +fun! snipMate#ShowAvailableSnips() abort + let col = col('.') + let word = snipMate#WordBelowCursor() + let matches = snipMate#GetSnippetsForWordBelowCursorForComplete(word) + + " Pretty hacky, but really can't have the tab swallowed! + if len(matches) == 0 + call feedkeys(g:snipMate['no_match_completion_feedkeys_chars'], 'n') + return "" + endif + + call complete(col - len(word), sort(matches)) + return '' +endf + +" Pass an argument to force snippet expansion instead of triggering or jumping +function! snipMate#TriggerSnippet(...) abort + if exists('g:SuperTabMappingForward') + if g:SuperTabMappingForward == "<tab>" + let SuperTabPlug = maparg('<Plug>SuperTabForward', 'i') + if SuperTabPlug == "" + let SuperTabKey = "\<c-n>" + else + exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" + endif + elseif g:SuperTabMappingBackward == "<tab>" + let SuperTabPlug = maparg('<Plug>SuperTabBackward', 'i') + if SuperTabPlug == "" + let SuperTabKey = "\<c-p>" + else + exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" + endif + endif + endif + + if pumvisible() " Update snippet if completion is used, or deal with supertab + if exists('SuperTabKey') + call feedkeys(SuperTabKey) | return '' + endif + call feedkeys("\<esc>a", 'n') " Close completion menu + call feedkeys("\<tab>") | return '' + endif + + if exists('b:snip_state') && a:0 == 0 " Jump only if no arguments + let jump = b:snip_state.jump_stop(0) + if type(jump) == 1 " returned a string + return jump + endif + endif + + let word = matchstr(getline('.'), '\S\+\%'.col('.').'c') + let list = snipMate#GetSnippetsForWordBelowCursor(word, 1) + if empty(list) + let snippet = '' + else + let [trigger, snippetD] = list[0] + let snippet = s:ChooseSnippet(snippetD) + " Before expanding snippet, create new undo point |i_CTRL-G| + let &undolevels = &undolevels + let col = col('.') - len(trigger) + sil exe 's/\V'.escape(trigger, '/\.').'\%#//' + return snipMate#expandSnip(snippet[0], snippet[1], col) + endif + + " should allow other plugins to register hooks instead (duplicate code) + if exists('SuperTabKey') + call feedkeys(SuperTabKey) + return '' + endif + return word == '' + \ ? "\<tab>" + \ : "\<c-r>=snipMate#ShowAvailableSnips()\<cr>" +endfunction + +fun! snipMate#BackwardsSnippet() abort + if exists('b:snip_state') | return b:snip_state.jump_stop(1) | endif + + if exists('g:SuperTabMappingForward') + if g:SuperTabMappingForward == "<s-tab>" + let SuperTabPlug = maparg('<Plug>SuperTabForward', 'i') + if SuperTabPlug == "" + let SuperTabKey = "\<c-n>" + else + exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" + endif + elseif g:SuperTabMappingBackward == "<s-tab>" + let SuperTabPlug = maparg('<Plug>SuperTabBackward', 'i') + if SuperTabPlug == "" + let SuperTabKey = "\<c-p>" + else + exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" + endif + endif + endif + " should allow other plugins to register hooks instead (duplicate code) + if exists('SuperTabKey') + call feedkeys(SuperTabKey) + return '' + endif + return "\<s-tab>" +endf + +" vim:noet:sw=4:ts=4:ft=vim |