1
0
mirror of https://github.com/gryf/snipmate.vim.git synced 2026-01-06 13:54:18 +01:00

fixed some bugs, and added support for nested snippets (!)

This commit is contained in:
Michael Sanders
2009-02-26 18:22:05 -05:00
parent 8db937bb3b
commit 2e5caabf53
2 changed files with 39 additions and 31 deletions

View File

@@ -1,23 +1,24 @@
" These are the mappings for snipMate.vim. Putting it here ensures that it
" will be mapped after other plugins such as supertab.vim.
if exists('s:did_snips_mappings') || &cp || version < 700
fini
en
finish
endif
let s:did_snips_mappings = 1
ino <tab> <c-r>=TriggerSnippet()<cr>
snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
snor <bs> b<bs>
snor ' b<bs>'
snor <right> <esc>a
snor <left> <esc>bi
" By default load snippets in ~/.vim/snippets/<filetype>
" NOTE: I need to make sure this works on Windows
if isdirectory($HOME.'/.vim/snippets')
if isdirectory($HOME.'/.vim/snippets/_')
call ExtractSnips($HOME.'/.vim/snippets/_', '_')
endif
au FileType * if !exists('s:did_'.&ft) &&
\ isdirectory($HOME.'/.vim/snippets/'.&ft)
\| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en
\| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en
endif

View File

@@ -41,7 +41,7 @@ fun s:MakeSnippet(text, ft, multisnip)
let name = strpart(a:text, space, quote-space)
let space = stridx(a:text, ' ', quote)
let var = 's:multi_snips'
else " evaluating a regular snippet
else
let var = 's:snippets'
endif
if !has_key({var}, a:ft) | let {var}[a:ft] = {} | endif
@@ -64,11 +64,12 @@ fun! ExtractSnips(dir, ft)
for path in split(globpath(a:dir, '*'), '\n')
if isdirectory(path)
for snipFile in split(globpath(path, '*.snippet'), '\n')
call s:ProcessFile(snipFile, a:ft, strpart(path, strridx(path, s:slash)+1))
call s:ProcessFile(snipFile, a:ft,
\ strpart(path, strridx(path, s:slash)+1))
endfor
continue
else
call s:ProcessFile(path, a:ft)
endif
call s:ProcessFile(path, a:ft)
endfor
unl s:slash
let s:did_{a:ft} = 1
@@ -114,24 +115,22 @@ fun! TriggerSnippet()
call feedkeys("\<esc>a", 'n') | call s:UpdateChangedSnip(0)
endif
if exists('s:snipPos')
return s:JumpTabStop()
endif
if !exists('s:sid') && exists('g:SuperTabMappingForward')
\ && g:SuperTabMappingForward == "<tab>"
call s:GetSuperTabSID()
endif
let word = s:GetSnippet()
let word = s:GetSnippet()
" if word is a trigger for a snippet, delete the trigger & expand the snippet
if exists('s:snippet')
if s:snippet == ''
return unl s:snippet " if user cancelled multi snippet, quit
if s:snippet == '' " if user cancelled a multi snippet, quit
return unl s:snippet
endif
let col = col('.')-len(word)
sil exe 's/'.escape(word, '/\*[]').'\%#//'
return s:ExpandSnippet(col)
elseif exists('s:snipPos')
return s:JumpTabStop()
endif
return exists('s:sid') ? {s:sid}_SuperTab('n') : "\<tab>"
endf
@@ -195,18 +194,22 @@ fun s:ExpandSnippet(col)
unl s:snippet
if snipLen
let s:curPos = 0
let s:snipLen = snipLen
let s:endSnip = s:snipPos[0][1]
if exists('s:snipLen')
let s:snipLen += snipLen-1 | let s:curPos += 1
else
let s:snipLen = snipLen | let s:curPos = 0
endif
let s:endSnip = s:snipPos[s:curPos][1]
let s:endSnipLine = s:snipPos[s:curPos][0]
call cursor(s:snipPos[0][0], s:snipPos[0][1])
call cursor(s:snipPos[s:curPos][0], s:snipPos[s:curPos][1])
let s:prevLen = [line('$'), col('$')]
if s:snipPos[0][2] != -1 | return s:SelectWord() | endif
if s:snipPos[s:curPos][2] != -1 | return s:SelectWord() | endif
else
if !exists('s:snipLen') | unl s:snipPos | endif
" place cursor at end of snippet if no tab stop is given
unl s:snipPos | let newlines = len(snip)-1
call cursor(lnum + newlines, tab + len(snip[-1]) - len(afterCursor)
let newlines = len(snip)-1
call cursor(lnum + newlines, indent + len(snip[-1]) - len(afterCursor)
\ + (newlines ? 0: col))
endif
return ''
@@ -274,29 +277,28 @@ endf
" second is the position (column) of the "$#" tab stop on the line.
" If there are none of these tab stop, an empty list ([]) is returnrned
fun s:BuildTabStops(lnum, col, indent)
let s:snipPos = []
let i = 1
let snipPos = [] | let i = 1
" temporarily delete placeholders
let cut_snip = substitute(s:snippet, '$\d', '', 'g')
wh stridx(s:snippet, '${'.i) != -1
let s:snipPos += [[a:lnum+s:Count(matchstr(cut_snip, '^.*\ze${'.i), "\n"),
let snipPos += [[a:lnum+s:Count(matchstr(cut_snip, '^.*\ze${'.i), "\n"),
\ a:indent+len(matchstr(substitute(cut_snip, '${'.i.'\@!\d.\{-}}', '', 'g'),
\ "^.*\\(\n\\|^\\)\\zs.*\\ze${".i.'.\{-}}')), -1]]
if s:snipPos[i-1][0] == a:lnum
let s:snipPos[i-1][1] += a:col
if snipPos[i-1][0] == a:lnum
let snipPos[i-1][1] += a:col
endif
" get all $# matches in another list, if ${#:name} is given
if stridx(cut_snip, '${'.i.':') != -1
let j = i-1
let s:snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}'))
let s:snipPos[j] += [[]]
let snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}'))
let snipPos[j] += [[]]
" temporarily delete all other tab stops/placeholders
let tempstr = substitute(s:snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g')
wh stridx(tempstr, '$'.i) != -1
let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i)
let linecount = a:lnum+s:Count(beforeMark, "\n")
let s:snipPos[j][3] += [[linecount,
let snipPos[j][3] += [[linecount,
\ a:indent+(linecount > a:lnum ?
\ len(matchstr(beforeMark, "^.*\n\\zs.*"))
\ : a:col+len(beforeMark))]]
@@ -305,6 +307,11 @@ fun s:BuildTabStops(lnum, col, indent)
endif
let i += 1
endw
if exists('s:snipPos') " allow nested snippets
let s:snipPos = extend(s:snipPos, snipPos, s:curPos+1)
else
let s:snipPos = snipPos
endif
return i-1
endf