pax_global_header00006660000000000000000000000064122620761450014517gustar00rootroot0000000000000052 comment=c7fe3e84ef163ce4bd7a4d9ee54a7f83afec5dd5 vim-snipmate-0.87/000077500000000000000000000000001226207614500140665ustar00rootroot00000000000000vim-snipmate-0.87/.gitignore000066400000000000000000000000311226207614500160500ustar00rootroot00000000000000doc/tags *.swp .DS_Store vim-snipmate-0.87/Contributors.md000066400000000000000000000031541226207614500171100ustar00rootroot00000000000000# Contributors # SnipMate was originally authored by Michael Sanders ([Vim](http://www.vim.org/account/profile.php?user_id=16544), [GitHub](https://github.com/msanders)). It is currently maintained by [Rok Garbas](rok@garbas.si), [Marc Weber](marco-oweber@gmx.de), and [Adnan Zafar](https://github.com/ajzafar) with additional contributions from: * [907th](https://github.com/907th) * [alderz](https://github.com/alderz) * [asymmetric](https://github.com/asymmetric) * [bpugh](https://github.com/bpugh) * [bruno-](https://github.com/bruno-) * [darkwise](https://github.com/darkwise) * [henrik](https://github.com/henrik) * [holizz](https://github.com/holizz) * [honza](https://github.com/honza) * [hpesoj](https://github.com/hpesoj) * [ironcamel](https://github.com/ironcamel) * [jb55](https://github.com/jb55) * [jbernard](https://github.com/jbernard) * [jherdman](https://github.com/jherdman) * [kozo2](https://github.com/kozo2) * [lilydjwg](https://github.com/lilydjwg) * [marutanm](https://github.com/marutanm) * [MicahElliott](https://github.com/MicahElliott) * [muffinresearch](https://github.com/muffinresearch) * [pielgrzym](https://github.com/pielgrzym) * [pose](https://github.com/pose) * [r00k](https://github.com/r00k) * [radicalbit](https://github.com/radicalbit) * [redpill](https://github.com/redpill) * [robhudson](https://github.com/robhudson) * [Shraymonks](https://github.com/shraymonks) * [sickill](https://github.com/sickill) * [statik](https://github.com/statik) * [steveno](https://github.com/steveno) * [taq](https://github.com/taq) * [thisgeek](https://github.com/thisgeek) * [Xandaros](https://github.com/Xandaros) vim-snipmate-0.87/README.md000066400000000000000000000046311226207614500153510ustar00rootroot00000000000000# SnipMate # SnipMate aims to provide support for textual snippets, similar to TextMate or other Vim plugins like [UltiSnips][ultisnips]. For example, in C, typing `for` could be expanded to for (i = 0; i < count; i++) { /* code */ } with successive presses of tab jumping around the snippet. Originally authored by [Michael Sanders][msanders], SnipMate was forked in 2011 after a stagnation in development. This fork is currently maintained by [Rok Garbas][garbas], [Marc Weber][marcweber], and [Adnan Zafar][ajzafar]. ## Installing SnipMate ## We recommend one of the following methods for installing SnipMate and its dependencies. SnipMate depends on [vim-addon-mw-utils][mw-utils] and [tlib][tlib]. Since SnipMate does not ship with any snippets, we suggest looking at the [vim-snippets][vim-snippets] repository. * Using [Pathogen][pathogen], run the following commands: % cd ~/.vim/bundle % git clone https://github.com/tomtom/tlib_vim.git % git clone https://github.com/MarcWeber/vim-addon-mw-utils.git % git clone https://github.com/garbas/vim-snipmate.git # Optional: % git clone https://github.com/honza/vim-snippets.git * Using [VAM][vam], add `vim-snippets` to the list of packages to be installed. * Using [Vundle][vundle], add the following to your `vimrc` then run `:BundleInstall` Bundle "MarcWeber/vim-addon-mw-utils" Bundle "tomtom/tlib_vim" Bundle "garbas/vim-snipmate" " Optional: Bundle "honza/vim-snippets" # Release Notes # ## 0.87 - 2014-01-04 ## * Stop indenting empty lines when expanding snippets * Support extends keyword in .snippets files * Fix visual placeholder support * Add zero tabstop support * Support negative 'softtabstop' * Add g:snipMate_no_default_aliases option * Add snipMateTrigger for triggering an expansion inside a snippet * Add snipMate#CanBeTriggered() function [ultisnips]: https://github.com/sirver/ultisnips [msanders]: https://github.com/msanders [garbas]: https://github.com/garbas [marcweber]: https://github.com/marcweber [ajzafar]: https://github.com/ajzafar [mw-utils]: https://github.com/marcweber/vim-addon-mw-utils [tlib]: https://github.com/tomtom/tlib_vim [vim-snippets]: https://github.com/honza/vim-snippets [vam]: https://github.com/marcweber/vim-addon-manager [pathogen]: https://github.com/tpope/vim-pathogen [vundle]: https://github.com/gmarik/vundle vim-snipmate-0.87/addon-info.json000066400000000000000000000010131226207614500167720ustar00rootroot00000000000000{ "name" : "snipMate", "version" : "dev", "author" : "Michael Sanders -> original project http://github.com/msanders/snipmate.vim", "maintainer" : "Rok Garbas / Marc Weber", "repository" : {"type": "git", "url": "git://github.com/garbas/vim-snipmate.git"}, "dependencies" : { "vim-addon-mw-utils": {}, "tlib": {} }, "description" : "snipMate.vim aims to be a concise vim script that implements some of TextMate's snippets features in Vim. See README.md to learn about the features this fork adds" } vim-snipmate-0.87/after/000077500000000000000000000000001226207614500151675ustar00rootroot00000000000000vim-snipmate-0.87/after/plugin/000077500000000000000000000000001226207614500164655ustar00rootroot00000000000000vim-snipmate-0.87/after/plugin/snipMate.vim000066400000000000000000000036461226207614500207730ustar00rootroot00000000000000" snipMate maps " These maps are created here in order to make sure we can reliably create maps " after SuperTab. let s:save_cpo = &cpo set cpo&vim function! s:map_if_not_mapped(lhs, rhs, mode) let l:unique = s:overwrite ? '' : ' ' if !hasmapto(a:rhs, a:mode) silent! exe a:mode . 'map' . l:unique a:lhs a:rhs endif endfunction if !exists('g:snips_no_mappings') || !g:snips_no_mappings if exists('g:snips_trigger_key') echom 'g:snips_trigger_key is deprecated. See :h snipMate-mappings' exec 'imap ' g:snips_trigger_key 'snipMateTrigger' exec 'smap ' g:snips_trigger_key 'snipMateSNext' exec 'xmap ' g:snips_trigger_key 'snipMateVisual' else " Remove SuperTab map if it exists let s:overwrite = maparg('', 'i') ==? 'SuperTabForward' call s:map_if_not_mapped('', 'snipMateNextOrTrigger', 'i') call s:map_if_not_mapped('', 'snipMateNextOrTrigger', 's') let s:overwrite = 0 call s:map_if_not_mapped('', 'snipMateVisual', 'x') endif if exists('g:snips_trigger_key_backwards') echom 'g:snips_trigger_key_backwards is deprecated. See :h snipMate-mappings' exec 'imap ' g:snips_trigger_key_backwards 'snipMateIBack' exec 'smap ' g:snips_trigger_key_backwards 'snipMateSBack' else let s:overwrite = maparg('', 'i') ==? 'SuperTabBackward' call s:map_if_not_mapped('', 'snipMateBack', 'i') call s:map_if_not_mapped('', 'snipMateBack', 's') let s:overwrite = 0 endif call s:map_if_not_mapped('', 'snipMateShow', 'i') endif " FIXME: Without this map, in select mode deletes the current selection and " returns to normal mode. This doesn't update placeholders. Ideally there's some " way to update the placeholders without this otherwise useless map. silent! snoremap b let &cpo = s:save_cpo " vim:noet: vim-snipmate-0.87/autoload/000077500000000000000000000000001226207614500156765ustar00rootroot00000000000000vim-snipmate-0.87/autoload/snipMate.vim000066400000000000000000000632331226207614500202020ustar00rootroot00000000000000" config which can be overridden (shared lines) if !exists('g:snipMate') let g:snipMate = {} endif let s:c = g:snipMate try call tlib#input#List('mi', '', []) catch /.*/ echoe "you're missing tlib. See install instructions at ".expand(':h:h').'/README.md' endtry " match $ which doesn't follow a \ let s:d = '\%([\\]\@" to make snipmate not swallow tab (make sure to not have " expandtab set). Remember that you can always enter tabs by then " you don't need this let s:c['no_match_completion_feedkeys_chars'] = get(s:c, 'no_match_completion_feedkeys_chars', "\t") fun! Filename(...) 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:state_proto = {} fun! s:state_proto.remove() unlet! b:snip_state " Remove all buffer-local autocommands in the snipmate_changes group au! snipmate_changes * endf fun! snipMate#expandSnip(snip, col) let lnum = line('.') | let col = a:col let snippet = s:ProcessSnippet(a:snip) " Avoid error if eval evaluates to nothing if snippet == '' | return '' | endif " Expand snippet onto current position with the tab stops removed let snipLines = split(substitute(snippet, ''.s:d .'\d\+\|'.s:d .'{\d\+.\{-}}', '', 'g'), "\n", 1) let line = getline(lnum) 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 let indent = indent(lnum) + 1 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 &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif let b:snip_state = copy(s:state_proto) let [b:snip_state.stops, b:snip_state.stop_count] = s:BuildTabStops(snippet, lnum, col - indent, indent) if b:snip_state.stop_count aug snipmate_changes au CursorMovedI,InsertEnter call b:snip_state.update_changes() aug END call b:snip_state.set_stop(0) return b:snip_state.select_word() else unlet b:snip_state " Place cursor at end of snippet if no tab stop is given let newlines = len(snipLines) - 1 call cursor(lnum + newlines, indent + len(snipLines[-1]) - len(afterCursor) \ + (newlines ? 0: col - 1)) endif return '' endf " Update state information to correspond to the given tab stop function! s:state_proto.set_stop(stop) let self.stop_no = a:stop let self.cur_stop = self.stops[self.stop_no] let self.end_col = self.cur_stop[1] + self.cur_stop[2] let self.start_col = self.cur_stop[1] call cursor(self.cur_stop[0], self.cur_stop[1]) let self.prev_len = col('$') let self.has_vars = exists('self.cur_stop[3]') let self.old_vars = self.has_vars ? deepcopy(self.cur_stop[3]) : [] endfunction " Prepare snippet to be processed by s:BuildTabStops fun! s:ProcessSnippet(snip) let snippet = a:snip if exists('b:snipmate_content_visual') let visual = b:snipmate_content_visual unlet b:snipmate_content_visual else let visual = '' endif let snippet = substitute(snippet,'{VISUAL}', escape(visual,'%\'), 'g') " Evaluate eval (`...`) expressions. " Backquotes prefixed with a backslash "\" are ignored. " And backslash can be escaped by doubling it. " Using a loop here instead of a regex fixes a bug with nested "\=". if stridx(snippet, '`') != -1 let new = [] let snip = split(snippet, '\%(\\\@ 0) ? &sts : &sw), 'g') endif return snippet endf " Counts occurences of haystack in needle fun! s:Count(haystack, needle) let counter = 0 let index = stridx(a:haystack, a:needle) while index != -1 let index = stridx(a:haystack, a:needle, index+1) let counter += 1 endw return counter endf " Builds a list of a list of each tab stop in the snippet containing: " 1.) The tab stop's line number. " 2.) The tab stop's column number " (by getting the length of the string between the last "\n" and the " tab stop). " 3.) The length of the text after the colon for the current tab stop " (e.g. "${1:foo}" would return 3). " 4.) If the "${#:}" construct is given, another list containing all " the matches of "$#", to be replaced with the placeholder. This list is " composed the same way as the parent; the first item is the line number, " and the second is the column. fun! s:BuildTabStops(snip, lnum, col, indent) let snipPos = [] let i = 1 let withoutVars = substitute(a:snip, '$\d\+', '', 'g') while a:snip =~ s:d.'{'.i let beforeTabStop = matchstr(withoutVars, '^.*\ze'.s:d .'{'.i.'\D') let withoutOthers = substitute(withoutVars, ''.s:d .'{\('.i.'\D\)\@!\d\+.\{-}}', '', 'g') let j = i - 1 call add(snipPos, [0, 0, 0]) let snipPos[j][0] = a:lnum + s:Count(beforeTabStop, "\n") let snipPos[j][1] = a:indent + len(matchstr(withoutOthers, '.*\(\n\|^\)\zs.*\ze'.s:d .'{'.i.'\D')) if snipPos[j][0] == a:lnum | let snipPos[j][1] += a:col | endif " Get all $# matches in another list, if ${#:name} is given if withoutVars =~ ''.s:d .'{'.i.':' let snipPos[j][2] = len(matchstr(withoutVars, ''.s:d .'{'.i.':\zs.\{-}\ze}')) let dots = repeat('.', snipPos[j][2]) call add(snipPos[j], []) let withoutOthers = substitute(a:snip, ''.s:d .'{\d\+.\{-}}\|'.s:d .''.i.'\@!\d\+', '', 'g') while match(withoutOthers, ''.s:d .''.i.'\(\D\|$\)') != -1 let beforeMark = matchstr(withoutOthers, '^.\{-}\ze'.dots.''.s:d .''.i.'\(\D\|$\)') call add(snipPos[j][3], [0, 0]) let snipPos[j][3][-1][0] = a:lnum + s:Count(beforeMark, "\n") let snipPos[j][3][-1][1] = a:indent + (snipPos[j][3][-1][0] > a:lnum \ ? len(matchstr(beforeMark, '.*\n\zs.*')) \ : a:col + len(beforeMark)) let withoutOthers = substitute(withoutOthers, ''.s:d .''.i.'\ze\(\D\|$\)', '', '') endw endif let i += 1 endw return [snipPos, i - 1] endf function! s:state_proto.jump_stop(backwards) " Update changes just in case " This seems to be only needed because insert completion does not trigger " the CursorMovedI event call self.update_changes() " Update stop and var locations call self.update_stops() " Store the changed col/length of the current stop let self.cur_stop[1] = self.start_col let self.cur_stop[2] = self.end_col - self.start_col let self.stop_no += a:backwards ? -1 : 1 " Loop over the snippet when going backwards from the beginning if self.stop_no < 0 | let self.stop_no = self.stop_count - 1 | endif if self.stop_no == self.stop_count call self.remove() return -1 endif call self.set_stop(self.stop_no) return self.select_word() endfunction " Updates tab stops/vars function! s:state_proto.update_stops() let changeLen = self.end_col - self.cur_stop[2] - self.start_col " Update tab stops in snippet if text has been added via "$#" " (e.g., in "${1:foo}bar$1${2}"). if changeLen != 0 let curLine = line('.') for pos in self.stops if pos == self.cur_stop | continue | endif let changed = pos[0] == curLine && pos[1] > self.start_col let changedVars = 0 let endPlaceholder = pos[2] - 1 + pos[1] " Subtract changeLen from each tab stop that was after any of " the current tab stop's placeholders. for [lnum, col] in self.old_vars if lnum > pos[0] | break | endif if pos[0] == lnum if pos[1] > col || (pos[2] == -1 && pos[1] == col) let changed += 1 elseif col < endPlaceholder let changedVars += 1 endif endif endfor let pos[1] += changeLen * changed " Parse variables within placeholders, e.g., "${1:foo} ${2:$1bar}" let pos[2] += changeLen * changedVars " Do the same to any placeholders in the other tab stops. if exists('pos[3]') for nPos in pos[3] let changed = nPos[0] == curLine && nPos[1] > self.start_col for [lnum, col] in self.old_vars if lnum > nPos[0] | break | endif if nPos[0] == lnum && nPos[1] > col let changed += 1 endif endfor let nPos[1] += changeLen * changed endfor endif endfor endif endfunction " Select the placeholder for the current tab stop function! s:state_proto.select_word() let len = self.cur_stop[2] if !len | return '' | endif let l = col('.') != 1 ? 'l' : '' if &sel == 'exclusive' return "\".l.'v'.len."l\" endif return len == 1 ? "\".l.'gh' : "\".l.'v'.(len - 1)."l\" endfunction " Update the snippet as text is typed. The self.update_vars() function does " the actual work. " If the cursor moves outside of a placeholder, call self.remove() function! s:state_proto.update_changes() let change_len = col('$') - self.prev_len let self.end_col += change_len let col = col('.') if line('.') != self.cur_stop[0] || col < self.start_col || col > self.end_col call self.remove() elseif self.has_vars call self.update_vars(change_len) endif let self.prev_len = col('$') endfunction " Actually update the vars for any changed text function! s:state_proto.update_vars(change) let newWordLen = self.end_col - self.start_col let newWord = strpart(getline('.'), self.start_col - 1, newWordLen) let changeLen = a:change let curLine = line('.') let oldStartSnip = self.start_col let updateTabStops = changeLen != 0 let i = 0 for [lnum, col] in self.cur_stop[3] if updateTabStops let start = self.start_col if lnum == curLine && col <= start let self.start_col += changeLen let self.end_col += changeLen endif for nPos in self.cur_stop[3][(i):] " This list is in ascending order, so quit if we've gone too far. if nPos[0] > lnum | break | endif if nPos[0] == lnum && nPos[1] > col let nPos[1] += changeLen endif endfor if lnum == curLine && col > start let col += changeLen let self.cur_stop[3][i][1] = col endif let i += 1 endif let theline = getline(lnum) " subtract -1 to go from column byte index to string byte index " subtract another -1 to exclude the col'th element call setline(lnum, theline[0:(col-2)] . newWord . theline[(col+self.end_col-self.start_col-a:change-1):]) endfor " Reposition the cursor in case a var updates on the same line but before " the current tabstop if oldStartSnip != self.start_col call cursor(0, col('.') + self.start_col - oldStartSnip) endif endfunction " should be moved to utils or such? fun! snipMate#SetByPath(dict, path, value) let d = a:dict for p in a:path[:-2] if !has_key(d,p) | let d[p] = {} | endif let d = d[p] endfor let d[a:path[-1]] = a:value endf " reads a .snippets file " returns list of " ['triggername', 'name', 'contents'] " if triggername is not set 'default' is assumed fun! snipMate#ReadSnippetsFile(file) let result = [] let new_scopes = [] if !filereadable(a:file) | return [result, new_scopes] | endif let r_guard = '^guard\s\+\zs.*' let inSnip = 0 let guard = 1 for line in readfile(a:file) + ["\n"] if inSnip == 2 && line =~ r_guard let guard = matchstr(line, r_guard) elseif inSnip && (line[0] == "\t" || line == '') let content .= strpart(line, 1)."\n" continue elseif inSnip call add(result, [trigger, name == '' ? 'default' : name, content[:-2], guard]) let inSnip = 0 let guard = "1" endif if inSnip == 2 let inSnip = 1 endif if line[:6] == 'snippet' " 2 signals first line let inSnip = 2 let trigger = strpart(line, 8) 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 = '' elseif line[:6] == 'extends' call extend(new_scopes, map(split(strpart(line, 8)), \ "substitute(v:val, ',*$', '', '')")) endif endfor return [result, new_scopes] endf " adds scope aliases to list. " returns new list " the aliases of aliases are added recursively fun! s:AddScopeAliases(list) let did = {} let scope_aliases = get(s:c,'scope_aliases', {}) 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 function! s:Glob(path, expr) let res = [] for p in split(a:path, ',') let h = fnamemodify(a:expr, ':h') if isdirectory(p . '/' . h) call extend(res, split(glob(p . '/' . a:expr), "\n")) endif endfor return filter(res, 'filereadable(v:val)') endfunction " returns dict of " { path: { 'type': one of 'snippet' 'snippets', " 'exists': 1 or 0 " " for single snippet files: " 'name': name of snippet " 'trigger': trigger of snippet " } " } " use trigger = '*' to match all snippet files " use mustExist = 1 to return existing files only " " mustExist = 0 is used by OpenSnippetFiles function! snipMate#GetSnippetFiles(mustExist, scopes, trigger) let paths = join(funcref#Call(s:c.snippet_dirs), ',') let result = {} let scopes = s:AddScopeAliases(a:scopes) let trigger = escape(a:trigger, "*[]?{}`'$") " collect existing files for scope in scopes for f in s:Glob(paths, 'snippets/' . scope . '.snippets') + \ s:Glob(paths, 'snippets/' . scope . '/*.snippets') let result[f] = { 'exists' : 1, 'type' : 'snippets', \ 'name_prefix' : fnamemodify(f, ':t:r') } endfor for f in s:Glob(paths, 'snippets/'.scope.'/'.trigger.'.snippet') let result[f] = {'exists': 1, 'type': 'snippet', 'name': 'default', \ 'trigger': a:trigger, 'name_prefix' : scope } endfor for f in s:Glob(paths, 'snippets/'.scope.'/'.trigger.'/*.snippet') let result[f] = {'exists': 1, 'type': 'snippet', 'name' : fnamemodify(f, ':t:r'), \ 'trigger': a:trigger, 'name_prefix' : scope } endfor if !a:mustExist for p in split(paths, ',') let p .= '/snippets/' . scope . '.snippets' let result[p] = get(result, p, {'exists': 0, 'type': 'snippets'}) endfor endif endfor return result endfunction fun! snipMate#EvalGuard(guard) " left: everything left of expansion " word: the expanded word " are guaranteed to be in scpe if a:guard == '1' | return 1 | endif let word = s:c.word " eval is evil, but backticks are allowed anyway. let left = getline('.')[:col('.')-3 - len(word)] exec 'return '.a:guard endf " default triggers based on paths fun! snipMate#DefaultPool(scopes, trigger, result) let triggerR = substitute(a:trigger,'*','.*','g') let extra_scopes = [] for [f,opts] in items(snipMate#GetSnippetFiles(1, a:scopes, a:trigger)) let opts.name_prefix = matchstr(f, '\v[^/]+\ze/snippets') . ' ' . opts.name_prefix if opts.type == 'snippets' let [snippets, extension] = cached_file_contents#CachedFileContents(f, s:c.read_snippets_cached, 0) for [trigger, name, contents, guard] in snippets if trigger !~ escape(triggerR,'~') | continue | endif if snipMate#EvalGuard(guard) call snipMate#SetByPath(a:result, [trigger, opts.name_prefix.' '.name], contents) endif endfor call extend(extra_scopes, extension) elseif opts.type == 'snippet' call snipMate#SetByPath(a:result, [opts.trigger, opts.name_prefix.' '.opts.name], funcref#Function('return readfile('.string(f).')')) else throw "unexpected" endif endfor if !empty(extra_scopes) call snipMate#DefaultPool(extra_scopes, a:trigger, a:result) endif endf " 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) let result = {} let triggerR = escape(substitute(a:trigger,'*','.*','g'), '~') " escape '~' for use as regexp " let scopes = s:AddScopeAliases(a:scopes) for F in values(g:snipMateSources) call funcref#Call(F, [a:scopes, a:trigger, result]) endfor return result endf " adds leading tab " and replaces leading spaces by tabs " see ftplugin/snippet.vim fun! snipMate#RetabSnip() range let leadingTab = expand('%:e') == 'snippets' let lines = getline(a:firstline, a:lastline) " remove leading "\t" let allIndented = 1 for l in lines if l[0] != '\t' | let allIndented = 0 | endif endfor " retab if allIndented call map(lines, 'v:val[1:]') endif let leadingSp = filter(map(copy(lines),'matchstr(v:val,"^\\s*") '),'v:val !=""') if !empty(leadingSp) " lines containing leading spaces found let smallestInd = len(sort(leadingSp)[-1]) let ind = input('retab, spaces per tab: ', smallestInd) for i in range(0, len(lines)-1) let ml = matchlist(lines[i], '^\(\s*\)\(.*\)') let lines[i] = repeat("\t", len(ml[1]) / ind) \ . repeat( " ", len(ml[1]) % ind) \ . ml[2] endfor endif " readd tab let tab = leadingTab ? "\t" : "" for i in range(0,len(lines)-1) call setline(a:firstline + i, tab.lines[i]) endfor endf fun! snipMate#OpenSnippetFiles() let dict = snipMate#GetSnippetFiles(0, snipMate#ScopesByFile(), '*') " sort by files wether they exist - put existing files first let exists = [] let notExists = [] for [file, v] in items(dict) let v['file'] = file if v['exists'] call add(exists, v) else call add(notExists, v) endif endfor let all = exists + notExists let show = map(copy(all),'(v:val["exists"] ? "exists:" : "does not exist yet:")." ".v:val["file"]') let select = tlib#input#List('mi', 'select files to be opened in splits', show) for idx in select exec 'sp '.all[idx - 1]['file'] endfor endf fun! snipMate#ScopesByFile() " duplicates are removed in AddScopeAliases return filter(funcref#Call(s:c.get_scopes), "v:val != ''") endf " used by both: completion and insert snippet fun! snipMate#GetSnippetsForWordBelowCursor(word, suffix, break_on_first_match) " Setup lookups: '1.2.3' becomes [1.2.3] + [3, 2.3] let parts = split(a:word, '\W\zs') if len(parts) > 2 let parts = parts[-2:] " max 2 additional items, this might become a setting endif let lookups = [a:word.a:suffix] let lookup = '' for w in reverse(parts) let lookup = w . lookup if index(lookups, lookup) == -1 call add(lookups, lookup.a:suffix) endif endfor " allow matching '.' if a:word =~ '\.$' call add(lookups, '.'.a:suffix) endif call filter(lookups, 'v:val != ""') " echo lookups let matching_snippets = [] let snippet = '' " prefer longest word for word in lookups let s:c.word = word " echomsg string(lookups).' current: '.word for [k,snippetD] in items(funcref#Call(s:c['get_snippets'], [snipMate#ScopesByFile(), word])) if a:suffix == '' " hack: require exact match if k !=# word | continue | endif endif call add(matching_snippets, [k, snippetD]) if a:break_on_first_match | 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) 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() return matchstr(getline('.'), '\S\+\%' . col('.') . 'c') endf fun! snipMate#GetSnippetsForWordBelowCursorForComplete(word) let snippets = map(snipMate#GetSnippetsForWordBelowCursor(a:word, '*', 0), 'v:val[0]') return filter(snippets, "v:val =~# '\\V\\^" . escape(a:word, '\') . "'") endf fun! snipMate#CanBeTriggered() let word = snipMate#WordBelowCursor() let matches = snipMate#GetSnippetsForWordBelowCursorForComplete(word) return len(matches) > 0 endf fun! snipMate#ShowAvailableSnips() 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(s:c['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(...) if exists('g:SuperTabMappingForward') if g:SuperTabMappingForward == "" let SuperTabPlug = maparg('SuperTabForward', 'i') if SuperTabPlug == "" let SuperTabKey = "\" else exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" endif elseif g:SuperTabMappingBackward == "" let SuperTabPlug = maparg('SuperTabBackward', 'i') if SuperTabPlug == "" let SuperTabKey = "\" 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("\a", 'n') " Close completion menu call feedkeys("\") | 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 s = s:ChooseSnippet(snippetD) if type(s) == type([]) let snippet = join(s, "\n") else let snippet = s end " 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, col) endif " should allow other plugins to register hooks instead (duplicate code) if exists('SuperTabKey') call feedkeys(SuperTabKey) return '' endif return word == '' \ ? "\" \ : "\=snipMate#ShowAvailableSnips()\" endfunction fun! snipMate#BackwardsSnippet() if exists('b:snip_state') | return b:snip_state.jump_stop(1) | endif if exists('g:SuperTabMappingForward') if g:SuperTabMappingForward == "" let SuperTabPlug = maparg('SuperTabForward', 'i') if SuperTabPlug == "" let SuperTabKey = "\" else exec "let SuperTabKey = \"" . escape(SuperTabPlug, '<') . "\"" endif elseif g:SuperTabMappingBackward == "" let SuperTabPlug = maparg('SuperTabBackward', 'i') if SuperTabPlug == "" let SuperTabKey = "\" 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 "\" endf " vim:noet:sw=4:ts=4:ft=vim vim-snipmate-0.87/autoload/snipMate_python_demo.vim000066400000000000000000000027731226207614500226110ustar00rootroot00000000000000" This file demonstrates " - how to register your own snippet sources (call snipMate_python_demo#Activate() in ftplugin/python.vim) " - implents a source which creates snippets based on python function " definitions found in the current file " " Example: " " def abc(a,b,c=None) " will create a snippet on the fly which looks like this: " abc(${1:a}, ${2:b}, ${3:c=None}) fun! snipMate_python_demo#Activate() if !exists('g:snipMateSources') let g:snipMateSources = {} endif let g:snipMateSources['python'] = funcref#Function('snipMate_python_demo#FunctionsFromCurrentFileAndTags') endf fun! s:Add(dict, line, source, trigger) let matched = matchlist(a:line,'def\s\+\([^( \t]\+\)[ \t]*(\([^)]*\)') if len(matched) > 2 let name = matched[1] " TODO: is this a glob? if name !~ a:trigger | return | endif let a:dict[name] = get(a:dict, name, {}) let sd = a:dict[name] let args = [] let nr=1 for arg in split(matched[2], '\s*,\s*') call add(args, '${'.nr.':'.arg.'}') let nr+=1 endfor let sd[a:source] = name.'('.join(args,', ').')' endif endf fun! snipMate_python_demo#FunctionsFromCurrentFileAndTags(scopes, trigger, result) " getting all might be too much if a:trigger == '*' | return | endif if index(a:scopes, 'python') < 0 | return | endif for t in taglist('^'.a:trigger) call s:Add(a:result, t.cmd, 'tags-' . t.filename, a:trigger) endfor for l in getline(0, line('$')) call s:Add(a:result, l, 'current-file', a:trigger) endfor endf vim-snipmate-0.87/doc/000077500000000000000000000000001226207614500146335ustar00rootroot00000000000000vim-snipmate-0.87/doc/SnipMate.txt000066400000000000000000000521631226207614500171230ustar00rootroot00000000000000*SnipMate.txt* Plugin for using TextMate-style snippets in Vim. SnipMate *snippet* *snippets* *SnipMate* Last Change: December 27, 2009 1. Description |SnipMate-description| 2. Usage |SnipMate-usage| 3. Interface and Settings |SnipMate-interface| |SnipMate-settings| 4. Snippet syntax |SnipMate-syntax| 5. Snippet sources |SnipMate-snippet-sources| 6. Disadvantages to TextMate |SnipMate-disadvantages| 7. Contact |SnipMate-contact| 8. License |SnipMate-license| For Vim version 7.0 or later. This plugin only works if 'compatible' is not set. {Vi does not have any of these features.} SnipMate depends on vim-addon-mw-utils and tlib. ============================================================================== DESCRIPTION *SnipMate-description* SnipMate implements snippet features in Vim. A snippet is like a template, reducing repetitive insertion of pieces of text. Snippets can contain placeholders for modifying the text if necessary or interpolated code for evaluation. For example, in C, typing "for" then pushing could expand to: > for (i = 0; i < count; i++) { /* code */ } SnipMate is inspired by TextMate's snippet features. ============================================================================== USAGE *SnipMate-usage* Every snippet consists of an expansion and a trigger. Typing a trigger into your buffer and then hitting your trigger key ( by default, see |SnipMate-mappings|) will replace the trigger with the expansion text. The expansion text can optionally include tab stops. When it does, upon expansion of the snippet, the cursor is placed at the first one, and the user can jump between each tab stop. Each of these tab stops can be represented by default placeholder text. If such a placeholder is provided, then the text of the placeholder can be repeated in the snippet at specified mirrors. Any edits to the placeholder are instantly updated at every mirror. SnipMate allows multiple snippets to use the same trigger. When triggered, a list of all snippets with that trigger is provided and prompts for which snippet to use. *SnipMate-scopes* SnipMate searches for snippets inside a directory named "snippets" inside each entry in 'runtimepath'. Which files are loaded depends on 'filetype' and 'syntax'; see |SnipMate-syntax| for more information. Snippets are loaded and refreshed automatically on demand. Note: SnipMate does not ship with any snippets. In order to use it, the user must either write their own snippets or obtain some from a repository like https://github.com/honza/vim-snippets ============================================================================== INTERFACE AND SETTINGS *SnipMate-interface* *SnipMate-settings* *SnipMate-commands* Commands~ *:SnipMateOpenSnippetFiles* :SnipMateOpenSnippetFiles Opens a list of all valid snippet locations based on the current scope |SnipMate-scopes|. Only existing files and non-existing .snippets files will be shown, with the existing files shown first. *SnipMate-options* Options~ g:snips_author A variable used in some snippets in place of the author's (your) name. Similar to $TM_FULLNAME in TextMate. For example, > snippet name `g:snips_author` < creates a snippet "name" that expands to your name. g:snipMate This |Dictionary| contains other SnipMate options. In short add > let g:snipMate = {} < to your .vimrc before setting other SnipMate options. g:snipMate.scope_aliases A |Dictionary| associating certain filetypes with other scopes |SnipMate-scopes|. The entries consist of a filetype as the key and a comma-separated list of aliases as the value. For example, > let g:snipMate.scope_aliases = {} let g:snipMate.scope_aliases['ruby'] \ = 'ruby,ruby-rails' < tells SnipMate that "ruby-rails" snippets in addition to "ruby" snippets should be loaded when editing files with 'filetype' set to "ruby" or contains "ruby" as an entry in the case of dotted filetypes. g:snipMate_no_default_aliases When set to 1, prevents SnipMate from loading default scope aliases. The defaults are: Filetype Alias ~ cpp c cu c eruby eruby-rails,html html javascript mxml actionscript objc c php php,html,javascript ur html,javascript xhtml html Note: Setting this option does not disable scope aliases entirely, only those made by SnipMate itself. Any scope aliases created by the user or someone else will still be in effect. g:snipMate['no_match_completion_feedkeys_chars'] A string inserted when no match for a trigger is found. By default a tab is inserted according to 'expandtab', 'tabstop', and 'softtabstop'. Set it to the empty string to prevent anything from being inserted. *SnipMate-mappings* Mappings~ The mappings SnipMate uses can be customized with the |:map| commands. For example, to change the key that triggers snippets and moves to the next tabstop, > :imap snipMateNextOrTrigger :smap snipMateNextOrTrigger The list of possible mappings is as follows: snipMateNextOrTrigger Default: Mode: Insert, Select Jumps to the next tab stop or, if none exists, try to expand a snippet. Use in both insert and select modes. snipMateTrigger Default: unmapped Mode: Insert Try to expand a snippet regardless of any existing snippet expansion. If done within an expanded snippet, the outer snippet's tab stops are lost, unless expansion failed. snipMateBack Default: Mode: Insert, Select Jump to the previous tab stop, if it exists. Use in both insert and select modes. snipMateShow Default: Mode: Insert Show all available snippets (that start with the previous text, if it exists). Use in insert mode. snipMateVisual Default: Mode: Visual See |SnipMate-visual|. Additionally, is mapped in visual mode in .snippets files for retabbing snippets. ============================================================================== SYNTAX *snippet-syntax* *SnipMate-syntax* SnipMate looks inside of each entry of 'rtp' (or |SnipMate-snippet-sources|) for a directory named /snippets/. Based on the 'filetype' and 'syntax' settings (taking into account the dotted syntax), the following files are read for snippets: > .../snippets/.snippets .../snippets//.snippets .../snippets//.snippet .../snippets///.snippet where is an entry in 'filetype' or 'syntax', is an arbitrary name, is the trigger for a snippet, and is a description used for |SnipMate-multisnip|. A .snippet file defines a single snippet with the trigger (and description) determined by the filename. The entire contents of the file are used as the snippet expansion text. Multiple snippets can be defined in *.snippets files. Each snippet definition looks something like: > snippet trigger optional description guard left_from_cursor='^\s*' expanded text more expanded text < *SnipMate-multisnip* The description is optional. If it is left out and a second snippet inside the same .snippets file uses the same trigger, the second one will overwrite the first. Otherwise multisnip is used. The guard condition line is also optional. It can be used to make a snippet available only in some cases. The value should be a VimL expression. Note: Hard tabs in the expansion text are required. When the snippet is expanded in the text and 'expandtab' is set, each tab will be replaced with spaces based on 'softtabstop' if nonzero or 'shiftwidth' otherwise. Comments can be made in .snippets files by starting a line with a # character. However these can't be used inside of snippet definitions: > # this is a correct comment snippet trigger expanded text snippet another_trigger # this isn't a comment! expanded text This should hopefully be clear with the included syntax highlighting. *snipMate-extends* Borrowing from UltiSnips, .snippets files can also contain an extends directive, for example: > extends html, javascript, css will tell SnipMate to also read html, javascript, and css snippets. *SnipMate-tabstops* Tab stops~ A tab stop, specified by ${#} where # is a number, tells SnipMate where to position the cursor next. The special tab stop ${0} denotes the last cursor position; in its absence, the cursor is placed at the end of the snippet. For example, to place the cursor first on the id of a
tag, allow the user to press to go to the middle of it, and finally end after
: > snippet div
${2}
< *SnipMate-placeholders* *SnipMate-mirrors* Placeholders and Mirrors~ Placeholder text can be supplied using "${#:text}", where # is the number of the tab stop. This text then can be copied throughout the snippet using "$#", given # is the same number as used before. So, to make a C for loop: > snippet for for (${2:i}; $2 < ${1:count}; $1++) { ${4} } This will cause "count" to first be selected and change if the user starts typing. When is pressed, the "i" in ${2}'s position will be selected; all $2 variables will default to "i" and automatically be updated if the user starts typing. NOTE: "$#" syntax is used only for mirrors, not for tab stops as in TextMate. Mirrors can also be used inside of placeholders. For instance: > snippet opt Will, as usual, cause "option" to first be selected and update all the $1 variables if the user starts typing. Since one of these variables is inside of ${2}, this text will then be used as a placeholder for the next tab stop, allowing the user to change it if he wishes. To copy a value throughout a snippet without supplying default text, simply use the "${#:}" construct without the text, e.g.: > snippet foo ${1:}bar$1 < *SnipMate-visual* There is a special placeholder called {VISUAL}. If you visually select text, then press Vim switches to insert mode. The next snippet you'll expand will replace {VISUAL} by the text which was selected previously. *SnipMate-eval* Interpolated Vim Script~ Snippets can also contain Vim script commands that are executed (via |eval()|) when the snippet is inserted. Commands are given inside backticks (`...`); for TextMates's functionality, use the |system()| function. E.g.: > snippet date `system("date +%Y-%m-%d")` will insert the current date, assuming you are on a Unix system. Note that you can also (and should) use |strftime()| for this example. Filename([{expr}] [, {defaultText}]) *SnipMate-Filename()* Since the current filename is used often in snippets, a default function has been defined for it in SnipMate.vim, appropriately called Filename(). With no arguments, the default filename without an extension is returned; the first argument specifies what to place before or after the filename, and the second argument supplies the default text to be used if the file has not been named. "$1" in the first argument is replaced with the filename; if you only want the filename to be returned, the first argument can be left blank. Examples: > snippet filename `Filename()` snippet filename_with_default `Filename('', 'name')` snippet filename_foo `Filename('$1_foo')` The first example returns the filename if it the file has been named, and an empty string if it hasn't. The second returns the filename if it's been named, and "name" if it hasn't. The third returns the filename followed by "_foo" if it has been named, and an empty string if it hasn't. ============================================================================== SNIPPET SOURCES *SnipMate-snippet-sources* SnipMate is configurable. plugin/SnipMate.vim assigns three important keys: > " default implementation collecting snippets by handlers let g:SnipMate['get_snippets'] = SnipMate#GetSnippets " default handler: let g:SnipMateSources['default'] = SnipMate#DefaultPool " default directories containing snippets: let g:SnipMate['snippet_dirs'] \ = funcref#Function('return split(&runtimepath,",")') You can override all of those settings. You can see that the default set of snippets is determined by Vim's 'rtp'. Example 1:~ autoload/SnipMate_python_demo.vim shows how you can register additional sources such as creating snippets on the fly representing python function definitions found in the current file. Example 2:~ Add to your ~/.vimrc: For each know snippet add a second version ending in _ adding folding markers > let g:commentChar = { \ 'vim': '"', \ 'c': '//', \ 'cpp': '//', \ 'sh': '#', \ 'python': '#' \ } " url https://github.com/garbas/vim-snipmate/issues/49 fun! AddFolding(text) return substitute(a:text,'\n'," ".g:commentChar[&ft]." {{{\n",1)."\n".g:commentChar[&ft]." }}}" endf fun! SnippetsWithFolding(scopes, trigger, result) " hacky: temporarely remove this function to prevent infinite recursion: call remove(g:SnipMateSources, 'with_folding') " get list of snippets: let result = SnipMate#GetSnippets(a:scopes, substitute(a:trigger,'_\(\*\)\?$','\1','')) let g:SnipMateSources['with_folding'] = funcref#Function('SnippetsWithFolding') " add folding: for k in keys(result) let a:result[k.'_'] = map(result[k],'AddFolding(v:val)') endfor endf " force setting default: runtime plugin/SnipMate.vim " add our own source let g:SnipMateSources['with_folding'] = funcref#Function('SnippetsWithFolding') See |SnipMate-syntax| for more details about all possible relative locations to 'rtp' can be found in. ============================================================================== DISADVANTAGES *SnipMate-disadvantages* SnipMate.vim currently has the following disadvantages to TextMate's snippets: - Nested placeholders are not currently possible. E.g.: > '${3}' < In TextMate this would first highlight ' id="some_id"', and if you hit delete it would automatically skip ${2} and go to ${3} on the next , but if you didn't delete it it would highlight "some_id" first. You cannot do this in SnipMate.vim. - Regex cannot be performed on variables, such as "${1/.*/\U&}" - Placeholders cannot span multiple lines. - Activating snippets in different scopes of the same file is not possible. Perhaps some of these features will be added in a later release. ============================================================================== CHANGELOG *SnipMate-changelog* 0.87 - 2014-01-04 ----------------- * Stop indenting empty lines when expanding snippets * Support extends keyword in .snippets files * Fix visual placeholder support * Add zero tabstop support * Support negative 'softtabstop' * Add g:snipMate_no_default_aliases option * Add snipMateTrigger for triggering an expansion inside a snippet * Add snipMate#CanBeTriggered() function 0.86 - 2013-06-15 ----------------- * Use more idiomatic maps * Remove most select mode mappings * Fix disappearing variables bug (hpesoj) * Fix cursor position bug when a variable is on the same line as the stop * Fix undo point creation causing problems with Supertab * Fix bug where SnipMate would use a typed trigger as a regular expression 0.85 - 2013-04-03 ----------------- * Allow trigger key customization * Enable undoing of snippet expansion * Support backslash escaping in snippets * Add support for {VISUAL} * Expand filetype extension with scope_aliases * Add expansion guards * Enable per-buffer expansion of snippets * Fix 'cpo' compatibility * Update supertab compatibility * Enable customization of various things through g:SnipMate * Disable spelling in snippet files * Highlight trigger names in .snippets files * Update many snippets * Separate sample snippets into separate repository 0.84 ---- * Unreleased version by Michael Sanders, available on his GitHub, 0.83 - 2009-07-13 ----------------- * Last release done by Michael Sanders, available at ============================================================================== CONTACT *SnipMate-contact* *SnipMate-author* SnipMate is currently maintained by: - Rok Garbas - Marc Weber (marco-oweber@gmx.de) - Adnan Zafar For bug reports, issues, or questions, check out the Issues page on GitHub: https://github.com/garbas/vim-snipmate/issues The original author, Michael Sanders, can be reached at: msanders42+snipmate gmail com ============================================================================== LICENSE *SnipMate-license* SnipMate is released under the MIT license: Copyright 2009-2010 Michael Sanders. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. ============================================================================== vim:tw=78:ts=8:ft=help:norl: vim-snipmate-0.87/ftplugin/000077500000000000000000000000001226207614500157165ustar00rootroot00000000000000vim-snipmate-0.87/ftplugin/html_snip_helper.vim000066400000000000000000000003711226207614500217700ustar00rootroot00000000000000" Helper function for (x)html snippets if exists('s:did_snip_helper') || &cp || !exists('loaded_snips') finish endif let s:did_snip_helper = 1 " Automatically closes tag if in xhtml fun! Close() return stridx(&ft, 'xhtml') == -1 ? '' : ' /' endf vim-snipmate-0.87/ftplugin/snippet.vim000066400000000000000000000003461226207614500201200ustar00rootroot00000000000000command! -buffer -range=% RetabSnip ,call snipMate#RetabSnip() vnoremap :RetabSnip if !exists('g:snippet_no_indentation_settings') setlocal sw=4 setlocal tabstop=4 setlocal noexpandtab endif vim-snipmate-0.87/ftplugin/snippets.vim000066400000000000000000000000361226207614500202770ustar00rootroot00000000000000runtime! ftplugin/snippet.vim vim-snipmate-0.87/plugin/000077500000000000000000000000001226207614500153645ustar00rootroot00000000000000vim-snipmate-0.87/plugin/snipMate.vim000066400000000000000000000064751226207614500176750ustar00rootroot00000000000000" File: snipMate.vim " Description: snipMate.vim implements some of TextMate's snippets features in " Vim. A snippet is a piece of often-typed text that you can " insert into your document using a trigger word followed by a "". " " For more help see snipMate.txt; you can do this by using: " :helptags ~/.vim/doc " :h SnipMate if exists('loaded_snips') || &cp || version < 700 finish endif let loaded_snips = 1 if !exists('snips_author') | let snips_author = 'Me' | endif " save and reset 'cpo' let s:save_cpo = &cpo set cpo&vim try call funcref#Function('') catch /.*/ echoe "you're missing vim-addon-mw-utils. See install instructions at ".expand(':h:h').'/README.md' endtry if (!exists('g:snipMateSources')) let g:snipMateSources = {} " default source: get snippets based on runtimepath: let g:snipMateSources['default'] = funcref#Function('snipMate#DefaultPool') endif au BufRead,BufNewFile *.snippet set ft=snippet au FileType snippet setl noet nospell au BufRead,BufNewFile *.snippets set ft=snippets au FileType snippets setl noet nospell fdm=expr fde=getline(v:lnum)!~'^\\t\\\\|^$'?'>1':1 inoremap snipMateNextOrTrigger =snipMate#TriggerSnippet() snoremap snipMateNextOrTrigger a=snipMate#TriggerSnippet() inoremap snipMateTrigger =snipMate#TriggerSnippet(1) inoremap snipMateBack =snipMate#BackwardsSnippet() snoremap snipMateBack a=snipMate#BackwardsSnippet() inoremap snipMateShow =snipMate#ShowAvailableSnips() xnoremap snipMateVisual :call grab_visual()i " config which can be overridden (shared lines) if !exists('g:snipMate') let g:snipMate = {} endif let s:snipMate = g:snipMate let s:snipMate['get_snippets'] = get(s:snipMate, 'get_snippets', funcref#Function("snipMate#GetSnippets")) " old snippets_dir: function returning list of paths which is used to read " snippets. You can replace it with your own implementation. Defaults to all " directories in &rtp/snippets/* let s:snipMate['snippet_dirs'] = get(s:snipMate, 'snippet_dirs', funcref#Function('return split(&runtimepath,",")')) if type(s:snipMate['snippet_dirs']) == type([]) call map(s:snipMate['snippet_dirs'], 'expand(v:val)') endif " _ is default scope added always " " &ft honors multiple filetypes and syntax such as in set ft=html.javascript syntax=FOO let s:snipMate['get_scopes'] = get(s:snipMate, 'get_scopes', funcref#Function('return split(&ft,"\\.")+[&syntax, "_"]')) " dummy for compatibility - will be removed " moving to autoload to improve loading speed and debugging fun! TriggerSnippet() echoe "replace TriggerSnippet by snipMate#TriggerSnippet, please!" return snipMate#TriggerSnippet() endf fun! BackwardSnippet() echoe "replace BackwardSnippet by snipMate#BackwardsSnippet, please!" return snipMate#BackwardsSnippet() endf " Modified from Luc Hermitte's function on StackOverflow " function! s:grab_visual() let a_save = @a try normal! gv"ad let b:snipmate_content_visual = @a finally let @a = a_save endtry endfunction " restore 'cpo' let &cpo = s:save_cpo " vim:noet:sw=4:ts=4:ft=vim vim-snipmate-0.87/plugin/snipMateInterface.vim000066400000000000000000000001321226207614500214760ustar00rootroot00000000000000" some useful commands command! SnipMateOpenSnippetFiles call snipMate#OpenSnippetFiles() vim-snipmate-0.87/syntax/000077500000000000000000000000001226207614500154145ustar00rootroot00000000000000vim-snipmate-0.87/syntax/snippet.vim000066400000000000000000000007111226207614500176120ustar00rootroot00000000000000" Syntax highlighting for .snippet files (used for snipMate.vim) " Hopefully this should make snippets a bit nicer to write! syn match placeHolder '\${\d\+\(:.\{-}\)\=}' contains=snipCommand syn match tabStop '\$\d\+' syn match snipEscape '\\\\\|\\`' syn match snipCommand '\%(\\\@