let s:sigil = nr2char(31) let snipmate#legacy#sigil = s:sigil " Prepare snippet to be processed by s:BuildTabStops function! snipmate#legacy#process_snippet(snip) let snippet = a:snip let esc_bslash = '\%(\\\@ 0) ? &sts : &sw), 'g') endif return snippet endfunction " 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. function! snipmate#legacy#build_stops(snip, lnum, col, indent) let stops = {} let i = 0 let withoutVars = substitute(a:snip, s:sigil . '\d\+', '', 'g') while a:snip =~ s:sigil . '{' . i let beforeTabStop = matchstr(withoutVars, '^.*\ze'.s:sigil .'{'.i.'\D') let withoutOthers = substitute(withoutVars, ''.s:sigil .'{\('.i.'\D\)\@!\d\+.\{-}}', '', 'g') let stops[i] = {} let stops[i].line = a:lnum + s:count(beforeTabStop, "\n") let stops[i].col = a:indent + len(matchstr(withoutOthers, '.*\(\n\|^\)\zs.*\ze'.s:sigil .'{'.i.'\D')) let stops[i].placeholder = 0 let stops[i].mirrors = [] if stops[i].line == a:lnum let stops[i].col += a:col endif " Get all $# matches in another list, if ${#:name} is given if withoutVars =~ printf('%s{%d:', s:sigil, i) let stops[i].placeholder = len(matchstr(withoutVars, ''.s:sigil .'{'.i.':\zs.\{-}\ze}')) let withoutOthers = substitute(a:snip, ''.s:sigil .'{\d\+.\{-}}\|'.s:sigil .''.i.'\@!\d\+', '', 'g') while match(withoutOthers, ''.s:sigil .''.i.'\(\D\|$\)') != -1 let stops[i].mirrors = get(stops[i], 'mirrors', []) let beforeMark = matchstr(withoutOthers, \ printf('^.\{-}\ze%s%s%d\(\D\|$\)', \ repeat('.', stops[i].placeholder), s:sigil, i)) let line = a:lnum + s:count(beforeMark, "\n") let col = a:indent + (line > a:lnum \ ? len(matchstr(beforeMark, '.*\n\zs.*')) \ : a:col + len(beforeMark)) call add(stops[i].mirrors, { 'line' : line, 'col' : col }) let withoutOthers = substitute(withoutOthers, ''.s:sigil .''.i.'\ze\(\D\|$\)', '', '') endw endif let i += 1 endw let stops[i] = stops[0] return [stops, i + 1] endfunction " Counts occurences of haystack in needle function! 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 endfunction