mirror of
https://github.com/gryf/snipmate.vim.git
synced 2025-12-29 01:42:36 +01:00
fixed some bugs, and added support for nested snippets (!)
This commit is contained in:
@@ -1,23 +1,24 @@
|
|||||||
" These are the mappings for snipMate.vim. Putting it here ensures that it
|
" These are the mappings for snipMate.vim. Putting it here ensures that it
|
||||||
" will be mapped after other plugins such as supertab.vim.
|
" will be mapped after other plugins such as supertab.vim.
|
||||||
if exists('s:did_snips_mappings') || &cp || version < 700
|
if exists('s:did_snips_mappings') || &cp || version < 700
|
||||||
fini
|
finish
|
||||||
en
|
endif
|
||||||
let s:did_snips_mappings = 1
|
let s:did_snips_mappings = 1
|
||||||
|
|
||||||
ino <tab> <c-r>=TriggerSnippet()<cr>
|
ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
|
||||||
snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
|
snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
|
||||||
snor <bs> b<bs>
|
snor <bs> b<bs>
|
||||||
snor ' b<bs>'
|
snor ' b<bs>'
|
||||||
snor <right> <esc>a
|
snor <right> <esc>a
|
||||||
snor <left> <esc>bi
|
snor <left> <esc>bi
|
||||||
|
|
||||||
" By default load snippets in ~/.vim/snippets/<filetype>
|
" 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')
|
||||||
if isdirectory($HOME.'/.vim/snippets/_')
|
if isdirectory($HOME.'/.vim/snippets/_')
|
||||||
call ExtractSnips($HOME.'/.vim/snippets/_', '_')
|
call ExtractSnips($HOME.'/.vim/snippets/_', '_')
|
||||||
endif
|
endif
|
||||||
au FileType * if !exists('s:did_'.&ft) &&
|
au FileType * if !exists('s:did_'.&ft) &&
|
||||||
\ isdirectory($HOME.'/.vim/snippets/'.&ft)
|
\ isdirectory($HOME.'/.vim/snippets/'.&ft)
|
||||||
\| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en
|
\| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fun s:MakeSnippet(text, ft, multisnip)
|
|||||||
let name = strpart(a:text, space, quote-space)
|
let name = strpart(a:text, space, quote-space)
|
||||||
let space = stridx(a:text, ' ', quote)
|
let space = stridx(a:text, ' ', quote)
|
||||||
let var = 's:multi_snips'
|
let var = 's:multi_snips'
|
||||||
else " evaluating a regular snippet
|
else
|
||||||
let var = 's:snippets'
|
let var = 's:snippets'
|
||||||
endif
|
endif
|
||||||
if !has_key({var}, a:ft) | let {var}[a:ft] = {} | 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')
|
for path in split(globpath(a:dir, '*'), '\n')
|
||||||
if isdirectory(path)
|
if isdirectory(path)
|
||||||
for snipFile in split(globpath(path, '*.snippet'), '\n')
|
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
|
endfor
|
||||||
continue
|
else
|
||||||
|
call s:ProcessFile(path, a:ft)
|
||||||
endif
|
endif
|
||||||
call s:ProcessFile(path, a:ft)
|
|
||||||
endfor
|
endfor
|
||||||
unl s:slash
|
unl s:slash
|
||||||
let s:did_{a:ft} = 1
|
let s:did_{a:ft} = 1
|
||||||
@@ -114,24 +115,22 @@ fun! TriggerSnippet()
|
|||||||
call feedkeys("\<esc>a", 'n') | call s:UpdateChangedSnip(0)
|
call feedkeys("\<esc>a", 'n') | call s:UpdateChangedSnip(0)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if exists('s:snipPos')
|
|
||||||
return s:JumpTabStop()
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists('s:sid') && exists('g:SuperTabMappingForward')
|
if !exists('s:sid') && exists('g:SuperTabMappingForward')
|
||||||
\ && g:SuperTabMappingForward == "<tab>"
|
\ && g:SuperTabMappingForward == "<tab>"
|
||||||
call s:GetSuperTabSID()
|
call s:GetSuperTabSID()
|
||||||
endif
|
endif
|
||||||
let word = s:GetSnippet()
|
|
||||||
|
|
||||||
|
let word = s:GetSnippet()
|
||||||
" if word is a trigger for a snippet, delete the trigger & expand the snippet
|
" if word is a trigger for a snippet, delete the trigger & expand the snippet
|
||||||
if exists('s:snippet')
|
if exists('s:snippet')
|
||||||
if s:snippet == ''
|
if s:snippet == '' " if user cancelled a multi snippet, quit
|
||||||
return unl s:snippet " if user cancelled multi snippet, quit
|
return unl s:snippet
|
||||||
endif
|
endif
|
||||||
let col = col('.')-len(word)
|
let col = col('.')-len(word)
|
||||||
sil exe 's/'.escape(word, '/\*[]').'\%#//'
|
sil exe 's/'.escape(word, '/\*[]').'\%#//'
|
||||||
return s:ExpandSnippet(col)
|
return s:ExpandSnippet(col)
|
||||||
|
elseif exists('s:snipPos')
|
||||||
|
return s:JumpTabStop()
|
||||||
endif
|
endif
|
||||||
return exists('s:sid') ? {s:sid}_SuperTab('n') : "\<tab>"
|
return exists('s:sid') ? {s:sid}_SuperTab('n') : "\<tab>"
|
||||||
endf
|
endf
|
||||||
@@ -195,18 +194,22 @@ fun s:ExpandSnippet(col)
|
|||||||
unl s:snippet
|
unl s:snippet
|
||||||
|
|
||||||
if snipLen
|
if snipLen
|
||||||
let s:curPos = 0
|
if exists('s:snipLen')
|
||||||
let s:snipLen = snipLen
|
let s:snipLen += snipLen-1 | let s:curPos += 1
|
||||||
let s:endSnip = s:snipPos[0][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]
|
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('$')]
|
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
|
else
|
||||||
|
if !exists('s:snipLen') | unl s:snipPos | endif
|
||||||
" place cursor at end of snippet if no tab stop is given
|
" place cursor at end of snippet if no tab stop is given
|
||||||
unl s:snipPos | let newlines = len(snip)-1
|
let newlines = len(snip)-1
|
||||||
call cursor(lnum + newlines, tab + len(snip[-1]) - len(afterCursor)
|
call cursor(lnum + newlines, indent + len(snip[-1]) - len(afterCursor)
|
||||||
\ + (newlines ? 0: col))
|
\ + (newlines ? 0: col))
|
||||||
endif
|
endif
|
||||||
return ''
|
return ''
|
||||||
@@ -274,29 +277,28 @@ endf
|
|||||||
" second is the position (column) of the "$#" tab stop on the line.
|
" 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
|
" If there are none of these tab stop, an empty list ([]) is returnrned
|
||||||
fun s:BuildTabStops(lnum, col, indent)
|
fun s:BuildTabStops(lnum, col, indent)
|
||||||
let s:snipPos = []
|
let snipPos = [] | let i = 1
|
||||||
let i = 1
|
|
||||||
" temporarily delete placeholders
|
" temporarily delete placeholders
|
||||||
let cut_snip = substitute(s:snippet, '$\d', '', 'g')
|
let cut_snip = substitute(s:snippet, '$\d', '', 'g')
|
||||||
wh stridx(s:snippet, '${'.i) != -1
|
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'),
|
\ a:indent+len(matchstr(substitute(cut_snip, '${'.i.'\@!\d.\{-}}', '', 'g'),
|
||||||
\ "^.*\\(\n\\|^\\)\\zs.*\\ze${".i.'.\{-}}')), -1]]
|
\ "^.*\\(\n\\|^\\)\\zs.*\\ze${".i.'.\{-}}')), -1]]
|
||||||
if s:snipPos[i-1][0] == a:lnum
|
if snipPos[i-1][0] == a:lnum
|
||||||
let s:snipPos[i-1][1] += a:col
|
let snipPos[i-1][1] += a:col
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" get all $# matches in another list, if ${#:name} is given
|
" get all $# matches in another list, if ${#:name} is given
|
||||||
if stridx(cut_snip, '${'.i.':') != -1
|
if stridx(cut_snip, '${'.i.':') != -1
|
||||||
let j = i-1
|
let j = i-1
|
||||||
let s:snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}'))
|
let snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}'))
|
||||||
let s:snipPos[j] += [[]]
|
let snipPos[j] += [[]]
|
||||||
" temporarily delete all other tab stops/placeholders
|
" temporarily delete all other tab stops/placeholders
|
||||||
let tempstr = substitute(s:snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g')
|
let tempstr = substitute(s:snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g')
|
||||||
wh stridx(tempstr, '$'.i) != -1
|
wh stridx(tempstr, '$'.i) != -1
|
||||||
let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i)
|
let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i)
|
||||||
let linecount = a:lnum+s:Count(beforeMark, "\n")
|
let linecount = a:lnum+s:Count(beforeMark, "\n")
|
||||||
let s:snipPos[j][3] += [[linecount,
|
let snipPos[j][3] += [[linecount,
|
||||||
\ a:indent+(linecount > a:lnum ?
|
\ a:indent+(linecount > a:lnum ?
|
||||||
\ len(matchstr(beforeMark, "^.*\n\\zs.*"))
|
\ len(matchstr(beforeMark, "^.*\n\\zs.*"))
|
||||||
\ : a:col+len(beforeMark))]]
|
\ : a:col+len(beforeMark))]]
|
||||||
@@ -305,6 +307,11 @@ fun s:BuildTabStops(lnum, col, indent)
|
|||||||
endif
|
endif
|
||||||
let i += 1
|
let i += 1
|
||||||
endw
|
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
|
return i-1
|
||||||
endf
|
endf
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user