1
0
mirror of https://github.com/gryf/snipmate.vim.git synced 2025-12-19 12:28:11 +01:00

added support for <shift-tab> to go back a tab stop, and cleaned up the code a bit

This commit is contained in:
Michael Sanders
2009-07-12 19:59:04 -04:00
parent c9d9d3a85d
commit 9e11b093d4
4 changed files with 132 additions and 74 deletions

View File

@@ -7,6 +7,8 @@ let s:did_snips_mappings = 1
ino <silent> <tab> <c-r>=TriggerSnippet()<cr> ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr> snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
ino <silent> <s-tab> <c-r>=BackwardsSnippet()<cr>
snor <silent> <s-tab> <esc>i<right><c-r>=BackwardsSnippet()<cr>
ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr> ino <silent> <c-r><tab> <c-r>=ShowAvailableSnips()<cr>
" The default mappings for these are annoying & sometimes break snipMate. " The default mappings for these are annoying & sometimes break snipMate.

View File

@@ -5,7 +5,12 @@ fun! Filename(...)
endf endf
fun s:RemoveSnippet() fun s:RemoveSnippet()
unl g:snipPos s:curPos s:snipLen s:endSnip s:endSnipLine s:prevLen s:lastBuf unl! g:snipPos s:curPos s:snipLen s:endCol s:endLine s:prevLen
\ s:lastBuf s:oldWord
if exists('s:update')
unl s:startCol s:origWordLen s:update
if exists('s:oldVars') | unl s:oldVars s:oldEndCol | endif
endif
aug! snipMateAutocmds aug! snipMateAutocmds
endf endf
@@ -13,12 +18,15 @@ fun snipMate#expandSnip(snip, col)
let lnum = line('.') | let col = a:col let lnum = line('.') | let col = a:col
let snippet = s:ProcessSnippet(a:snip) let snippet = s:ProcessSnippet(a:snip)
" Avoid error if eval evaluates to nothing
if snippet == '' | return '' | endif if snippet == '' | return '' | endif
" Expand snippet onto current position with the tab stops removed
let snipLines = split(substitute(snippet, '$\d\+\|${\d\+.\{-}}', '', 'g'), "\n", 1) let snipLines = split(substitute(snippet, '$\d\+\|${\d\+.\{-}}', '', 'g'), "\n", 1)
let line = getline(lnum) let line = getline(lnum)
let afterCursor = strpart(line, col - 1) let afterCursor = strpart(line, col - 1)
" Keep text after the cursor
if afterCursor != "\t" && afterCursor != ' ' if afterCursor != "\t" && afterCursor != ' '
let line = strpart(line, 0, col - 1) let line = strpart(line, 0, col - 1)
let snipLines[-1] .= afterCursor let snipLines[-1] .= afterCursor
@@ -35,6 +43,8 @@ fun snipMate#expandSnip(snip, col)
" Autoindent snippet according to previous indentation " Autoindent snippet according to previous indentation
let indent = matchend(line, '^.\{-}\ze\(\S\|$\)') + 1 let indent = matchend(line, '^.\{-}\ze\(\S\|$\)') + 1
call append(lnum, map(snipLines[1:], "'".strpart(line, 0, indent - 1)."'.v:val")) call append(lnum, map(snipLines[1:], "'".strpart(line, 0, indent - 1)."'.v:val"))
" Open any folds snippet expands into
if &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif if &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif
let [g:snipPos, s:snipLen] = s:BuildTabStops(snippet, lnum, col - indent, indent) let [g:snipPos, s:snipLen] = s:BuildTabStops(snippet, lnum, col - indent, indent)
@@ -44,11 +54,10 @@ fun snipMate#expandSnip(snip, col)
au CursorMovedI * call s:UpdateChangedSnip(0) au CursorMovedI * call s:UpdateChangedSnip(0)
au InsertEnter * call s:UpdateChangedSnip(1) au InsertEnter * call s:UpdateChangedSnip(1)
aug END aug END
let s:lastBuf = bufnr(0) let s:lastBuf = bufnr(0) " Only expand snippet while in current buffer
let s:curPos = 0
let s:curPos = 0 let s:endCol = g:snipPos[s:curPos][1]
let s:endSnip = g:snipPos[s:curPos][1] let s:endLine = g:snipPos[s:curPos][0]
let s:endSnipLine = g:snipPos[s:curPos][0]
call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1])
let s:prevLen = [line('$'), col('$')] let s:prevLen = [line('$'), col('$')]
@@ -63,6 +72,7 @@ fun snipMate#expandSnip(snip, col)
return '' return ''
endf endf
" Prepare snippet to be processed by s:BuildTabStops
fun s:ProcessSnippet(snip) fun s:ProcessSnippet(snip)
let snippet = a:snip let snippet = a:snip
" Evaluate eval (`...`) expressions. " Evaluate eval (`...`) expressions.
@@ -99,6 +109,7 @@ fun s:ProcessSnippet(snip)
return snippet return snippet
endf endf
" Counts occurences of haystack in needle
fun s:Count(haystack, needle) fun s:Count(haystack, needle)
let counter = 0 let counter = 0
let index = stridx(a:haystack, a:needle) let index = stridx(a:haystack, a:needle)
@@ -109,8 +120,7 @@ fun s:Count(haystack, needle)
return counter return counter
endf endf
" This function builds a list of a list of each tab stop in the " Builds a list of a list of each tab stop in the snippet containing:
" snippet containing:
" 1.) The tab stop's line number. " 1.) The tab stop's line number.
" 2.) The tab stop's column number " 2.) The tab stop's column number
" (by getting the length of the string between the last "\n" and the " (by getting the length of the string between the last "\n" and the
@@ -156,45 +166,65 @@ fun s:BuildTabStops(snip, lnum, col, indent)
return [snipPos, i - 1] return [snipPos, i - 1]
endf endf
fun snipMate#jumpTabStop() fun snipMate#jumpTabStop(backwards)
let leftPlaceholder = exists('s:origWordLen')
\ && s:origWordLen != g:snipPos[s:curPos][2]
if leftPlaceholder && exists('s:oldEndCol')
let startPlaceholder = s:oldEndCol + 1
endif
if exists('s:update') if exists('s:update')
call s:UpdatePlaceholderTabStops() call s:UpdatePlaceholderTabStops()
else else
call s:UpdateTabStops() call s:UpdateTabStops()
endif endif
let s:curPos += 1 " Don't reselect placeholder if it has been modified
if leftPlaceholder && g:snipPos[s:curPos][2] != -1
if exists('startPlaceholder')
let g:snipPos[s:curPos][1] = startPlaceholder
else
let g:snipPos[s:curPos][1] = col('.')
let g:snipPos[s:curPos][2] = 0
endif
endif
let s:curPos += a:backwards ? -1 : 1
" Loop over the snippet when going backwards from the beginning
if s:curPos < 0 | let s:curPos = s:snipLen - 1 | endif
if s:curPos == s:snipLen if s:curPos == s:snipLen
let sMode = s:endSnip == g:snipPos[s:curPos-1][1]+g:snipPos[s:curPos-1][2] let sMode = s:endCol == g:snipPos[s:curPos-1][1]+g:snipPos[s:curPos-1][2]
call s:RemoveSnippet() call s:RemoveSnippet()
return sMode ? "\<tab>" : TriggerSnippet() return sMode ? "\<tab>" : TriggerSnippet()
endif endif
call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1])
let s:endSnipLine = g:snipPos[s:curPos][0] let s:endLine = g:snipPos[s:curPos][0]
let s:endSnip = g:snipPos[s:curPos][1] let s:endCol = g:snipPos[s:curPos][1]
let s:prevLen = [line('$'), col('$')] let s:prevLen = [line('$'), col('$')]
return g:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord() return g:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord()
endf endf
fun s:UpdatePlaceholderTabStops() fun s:UpdatePlaceholderTabStops()
let changeLen = s:origWordLen - g:snipPos[s:curPos][2] let changeLen = s:origWordLen - g:snipPos[s:curPos][2]
unl s:startSnip s:origWordLen s:update unl s:startCol s:origWordLen s:update
if !exists('s:origPos') | return | endif if !exists('s:oldVars') | return | endif
" Update tab stops in snippet if text has been added via "$#" " Update tab stops in snippet if text has been added via "$#"
" (e.g., in "${1:foo}bar$1${2}"). " (e.g., in "${1:foo}bar$1${2}").
if changeLen != 0 if changeLen != 0
let curLine = line('.') let curLine = line('.')
for pos in g:snipPos[s:curPos + 1:] for pos in g:snipPos
let changed = pos[0] == curLine && pos[1] > s:origSnipPos if pos == g:snipPos[s:curPos] | continue | endif
let changed = pos[0] == curLine && pos[1] > s:oldEndCol
let changedVars = 0 let changedVars = 0
let endPlaceholder = pos[2] - 1 + pos[1] let endPlaceholder = pos[2] - 1 + pos[1]
" Subtract changeLen from each tab stop that was after any of " Subtract changeLen from each tab stop that was after any of
" the current tab stop's placeholders. " the current tab stop's placeholders.
for [lnum, col] in s:origPos for [lnum, col] in s:oldVars
if lnum > pos[0] | break | endif if lnum > pos[0] | break | endif
if pos[0] == lnum if pos[0] == lnum
if pos[1] > col || (pos[2] == -1 && pos[1] == col) if pos[1] > col || (pos[2] == -1 && pos[1] == col)
@@ -211,8 +241,8 @@ fun s:UpdatePlaceholderTabStops()
if pos[2] == -1 | continue | endif if pos[2] == -1 | continue | endif
" Do the same to any placeholders in the other tab stops. " Do the same to any placeholders in the other tab stops.
for nPos in pos[3] for nPos in pos[3]
let changed = nPos[0] == curLine && nPos[1] > s:origSnipPos let changed = nPos[0] == curLine && nPos[1] > s:oldEndCol
for [lnum, col] in s:origPos for [lnum, col] in s:oldVars
if lnum > nPos[0] | break | endif if lnum > nPos[0] | break | endif
if nPos[0] == lnum && nPos[1] > col if nPos[0] == lnum && nPos[1] > col
let changed += 1 let changed += 1
@@ -222,23 +252,23 @@ fun s:UpdatePlaceholderTabStops()
endfor endfor
endfor endfor
endif endif
unl s:endSnip s:origPos s:origSnipPos unl s:endCol s:oldVars s:oldEndCol
endf endf
fun s:UpdateTabStops() fun s:UpdateTabStops()
let changeLine = s:endSnipLine - g:snipPos[s:curPos][0] let changeLine = s:endLine - g:snipPos[s:curPos][0]
let changeCol = s:endSnip - g:snipPos[s:curPos][1] let changeCol = s:endCol - g:snipPos[s:curPos][1]
if exists('s:origWordLen') if exists('s:origWordLen')
let changeCol -= s:origWordLen let changeCol -= s:origWordLen
unl s:origWordLen unl s:origWordLen
endif endif
let lnum = g:snipPos[s:curPos][0] let lnum = g:snipPos[s:curPos][0]
let col = g:snipPos[s:curPos][1] let col = g:snipPos[s:curPos][1]
" Update the line number of all proceeding tab stops if <cr> has " Update the line number of all proceeding tab stops if <cr> has
" been inserted. " been inserted.
if changeLine != 0 if changeLine != 0
let changeLine -= 1 let changeLine -= 1
for pos in g:snipPos[s:curPos + 1:] for pos in g:snipPos
if pos[0] >= lnum if pos[0] >= lnum
if pos[0] == lnum | let pos[1] += changeCol | endif if pos[0] == lnum | let pos[1] += changeCol | endif
let pos[0] += changeLine let pos[0] += changeLine
@@ -254,7 +284,7 @@ fun s:UpdateTabStops()
elseif changeCol != 0 elseif changeCol != 0
" Update the column of all proceeding tab stops if text has " Update the column of all proceeding tab stops if text has
" been inserted/deleted in the current line. " been inserted/deleted in the current line.
for pos in g:snipPos[s:curPos + 1:] for pos in g:snipPos
if pos[1] >= col && pos[0] == lnum if pos[1] >= col && pos[0] == lnum
let pos[1] += changeCol let pos[1] += changeCol
endif endif
@@ -271,13 +301,13 @@ endf
fun s:SelectWord() fun s:SelectWord()
let s:origWordLen = g:snipPos[s:curPos][2] let s:origWordLen = g:snipPos[s:curPos][2]
let s:oldWord = strpart(getline('.'), g:snipPos[s:curPos][1] - 1, let s:oldWord = strpart(getline('.'), g:snipPos[s:curPos][1] - 1,
\ s:origWordLen) \ s:origWordLen)
let s:prevLen[1] -= s:origWordLen let s:prevLen[1] -= s:origWordLen
if !empty(g:snipPos[s:curPos][3]) if !empty(g:snipPos[s:curPos][3])
let s:update = 1 let s:update = 1
let s:endSnip = -1 let s:endCol = -1
let s:startSnip = g:snipPos[s:curPos][1] - 1 let s:startCol = g:snipPos[s:curPos][1] - 1
endif endif
if !s:origWordLen | return '' | endif if !s:origWordLen | return '' | endif
let l = col('.') != 1 ? 'l' : '' let l = col('.') != 1 ? 'l' : ''
@@ -300,49 +330,53 @@ fun s:UpdateChangedSnip(entering)
if exists('g:snipPos') && bufnr(0) != s:lastBuf if exists('g:snipPos') && bufnr(0) != s:lastBuf
call s:RemoveSnippet() call s:RemoveSnippet()
elseif exists('s:update') " If modifying a placeholder elseif exists('s:update') " If modifying a placeholder
if !exists('s:origPos') && s:curPos + 1 < s:snipLen if !exists('s:oldVars') && s:curPos + 1 < s:snipLen
" Save the old snippet & word length before it's updated " Save the old snippet & word length before it's updated
" s:startSnip must be saved too, in case text is added " s:startCol must be saved too, in case text is added
" before the snippet (e.g. in "foo$1${2}bar${1:foo}"). " before the snippet (e.g. in "foo$1${2}bar${1:foo}").
let s:origSnipPos = s:startSnip let s:oldEndCol = s:startCol
let s:origPos = deepcopy(g:snipPos[s:curPos][3]) let s:oldVars = deepcopy(g:snipPos[s:curPos][3])
endif endif
let col = col('.') - 1 let col = col('.') - 1
if s:endSnip != -1 if s:endCol != -1
let changeLen = col('$') - s:prevLen[1] let changeLen = col('$') - s:prevLen[1]
let s:endSnip += changeLen let s:endCol += changeLen
else " When being updated the first time, after leaving select mode else " When being updated the first time, after leaving select mode
if a:entering | return | endif if a:entering | return | endif
let s:endSnip = col - 1 let s:endCol = col - 1
endif endif
" If the cursor moves outside the snippet, quit it " If the cursor moves outside the snippet, quit it
if line('.') != g:snipPos[s:curPos][0] || col < s:startSnip || if line('.') != g:snipPos[s:curPos][0] || col < s:startCol ||
\ col - 1 > s:endSnip \ col - 1 > s:endCol
unl! s:startSnip s:origWordLen s:origPos s:update unl! s:startCol s:origWordLen s:oldVars s:update
return s:RemoveSnippet() return s:RemoveSnippet()
endif endif
call s:UpdateVars() call s:UpdateVars()
let s:prevLen[1] = col('$') let s:prevLen[1] = col('$')
elseif exists('g:snipPos') elseif exists('g:snipPos')
let col = col('.') if !a:entering && g:snipPos[s:curPos][2] != -1
let lnum = line('.') let g:snipPos[s:curPos][2] = -2
endif
let col = col('.')
let lnum = line('.')
let changeLine = line('$') - s:prevLen[0] let changeLine = line('$') - s:prevLen[0]
if lnum == s:endSnipLine if lnum == s:endLine
let s:endSnip += col('$') - s:prevLen[1] let s:endCol += col('$') - s:prevLen[1]
let s:prevLen = [line('$'), col('$')] let s:prevLen = [line('$'), col('$')]
endif endif
if changeLine != 0 if changeLine != 0
let s:endSnipLine += changeLine let s:endLine += changeLine
let s:endSnip = col let s:endCol = col
endif endif
" Delete snippet if cursor moves out of it in insert mode " Delete snippet if cursor moves out of it in insert mode
if (lnum == s:endSnipLine && (col > s:endSnip || col < g:snipPos[s:curPos][1])) if (lnum == s:endLine && (col > s:endCol || col < g:snipPos[s:curPos][1]))
\ || lnum > s:endSnipLine || lnum < g:snipPos[s:curPos][0] \ || lnum > s:endLine || lnum < g:snipPos[s:curPos][0]
call s:RemoveSnippet() call s:RemoveSnippet()
endif endif
endif endif
@@ -351,25 +385,25 @@ endf
" This updates the variables in a snippet when a placeholder has been edited. " This updates the variables in a snippet when a placeholder has been edited.
" (e.g., each "$1" in "${1:foo} $1bar $1bar") " (e.g., each "$1" in "${1:foo} $1bar $1bar")
fun s:UpdateVars() fun s:UpdateVars()
let newWordLen = s:endSnip - s:startSnip + 1 let newWordLen = s:endCol - s:startCol + 1
let newWord = strpart(getline('.'), s:startSnip, newWordLen) let newWord = strpart(getline('.'), s:startCol, newWordLen)
if newWord == s:oldWord || empty(g:snipPos[s:curPos][3]) if newWord == s:oldWord || empty(g:snipPos[s:curPos][3])
return return
endif endif
let changeLen = g:snipPos[s:curPos][2] - newWordLen let changeLen = g:snipPos[s:curPos][2] - newWordLen
let curLine = line('.') let curLine = line('.')
let startCol = col('.') let startCol = col('.')
let oldStartSnip = s:startSnip let oldStartSnip = s:startCol
let updateTabStops = changeLen != 0 let updateTabStops = changeLen != 0
let i = 0 let i = 0
for [lnum, col] in g:snipPos[s:curPos][3] for [lnum, col] in g:snipPos[s:curPos][3]
if updateTabStops if updateTabStops
let start = s:startSnip let start = s:startCol
if lnum == curLine && col <= start if lnum == curLine && col <= start
let s:startSnip -= changeLen let s:startCol -= changeLen
let s:endSnip -= changeLen let s:endCol -= changeLen
endif endif
for nPos in g:snipPos[s:curPos][3][(i):] for nPos in g:snipPos[s:curPos][3][(i):]
" This list is in ascending order, so quit if we've gone too far. " This list is in ascending order, so quit if we've gone too far.
@@ -389,8 +423,8 @@ fun s:UpdateVars()
call setline(lnum, substitute(getline(lnum), '\%'.col.'c\V'. call setline(lnum, substitute(getline(lnum), '\%'.col.'c\V'.
\ escape(s:oldWord, '\'), escape(newWord, '\&'), '')) \ escape(s:oldWord, '\'), escape(newWord, '\&'), ''))
endfor endfor
if oldStartSnip != s:startSnip if oldStartSnip != s:startCol
call cursor(0, startCol + s:startSnip - oldStartSnip) call cursor(0, startCol + s:startCol - oldStartSnip)
endif endif
let s:oldWord = newWord let s:oldWord = newWord

View File

@@ -1,7 +1,7 @@
*snipMate.txt* Plugin for using TextMate-style snippets in Vim. *snipMate.txt* Plugin for using TextMate-style snippets in Vim.
snipMate *snippet* *snippets* *snipMate* snipMate *snippet* *snippets* *snipMate*
Last Change: May 8, 2009 Last Change: July 12, 2009
|snipMate-description| Description |snipMate-description| Description
|snipMate-syntax| Snippet syntax |snipMate-syntax| Snippet syntax
@@ -33,7 +33,7 @@ you type "for<tab>" in insert mode, it will expand a typical for loop in C: >
To go to the next item in the loop, simply <tab> over to it; if there is To go to the next item in the loop, simply <tab> over to it; if there is
repeated code, such as the "i" variable in this example, you can simply repeated code, such as the "i" variable in this example, you can simply
start typing once it's highlighted and all the matches specified in the start typing once it's highlighted and all the matches specified in the
snippet will be updated. snippet will be updated. To go in reverse, use <shift-tab>.
============================================================================== ==============================================================================
SYNTAX *snippet-syntax* SYNTAX *snippet-syntax*
@@ -62,7 +62,7 @@ only be used outside of a snippet declaration. E.g.: >
snippet trigger snippet trigger
expanded text expanded text
snippet another_trigger snippet another_trigger
# this doesn't work! # this isn't a comment!
expanded text expanded text
< <
This should hopefully be obvious with the included syntax highlighting. This should hopefully be obvious with the included syntax highlighting.
@@ -221,14 +221,14 @@ spaces. If 'softtabstop' is not set, 'shiftwidth' is used instead.
snipMate does not come with a setting to customize the trigger key, but you snipMate does not come with a setting to customize the trigger key, but you
can remap it easily in the two lines it's defined in the 'after' directory can remap it easily in the two lines it's defined in the 'after' directory
under 'plugin/snipMate.vim'. For instance, to change the trigger key under 'plugin/snipMate.vim'. For instance, to change the trigger key
to shift-tab, just change this: > to CTRL-J, just change this: >
ino <tab> <c-r>=TriggerSnippet()<cr> ino <tab> <c-r>=TriggerSnippet()<cr>
snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr> snor <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
to this: > to this: >
ino <s-tab> <c-r>=TriggerSnippet()<cr> ino <c-j> <c-r>=TriggerSnippet()<cr>
snor <s-tab> <esc>i<right><c-r>=TriggerSnippet()<cr> snor <c-j> <esc>i<right><c-r>=TriggerSnippet()<cr>
============================================================================== ==============================================================================
FEATURES *snipMate-features* FEATURES *snipMate-features*
@@ -243,15 +243,15 @@ snipMate.vim has the following features among others:
- Snippets can have multiple matches. - Snippets can have multiple matches.
- Snippets can be out of order. For instance, in a do...while loop, the - Snippets can be out of order. For instance, in a do...while loop, the
condition can be added before the code. condition can be added before the code.
- (New) File-based snippets are supported. - [New] File-based snippets are supported.
- (New) Triggers after non-word delimiters are expanded, e.g. "foo" - [New] Triggers after non-word delimiters are expanded, e.g. "foo"
in "bar.foo". in "bar.foo".
- [New] <shift-tab> can now be used to jump tab stops in reverse order.
============================================================================== ==============================================================================
DISADVANTAGES *snipMate-disadvantages* DISADVANTAGES *snipMate-disadvantages*
snipMate.vim currently has the following disadvantages to TextMate's snippets: snipMate.vim currently has the following disadvantages to TextMate's snippets:
- There is no way to go back a tab stop, like shift-tab in TextMate.
- There is no $0; the order of tab stops must be explicitly stated. - There is no $0; the order of tab stops must be explicitly stated.
- Placeholders within placeholders are not possible. E.g.: > - Placeholders within placeholders are not possible. E.g.: >
@@ -276,4 +276,6 @@ To contact the author (Michael Sanders), please email:
I greatly appreciate any suggestions or improvements offered for the script. I greatly appreciate any suggestions or improvements offered for the script.
==============================================================================
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View File

@@ -1,6 +1,6 @@
" File: snipMate.vim " File: snipMate.vim
" Author: Michael Sanders " Author: Michael Sanders
" Version: 0.82 " Version: 0.83
" Description: snipMate.vim implements some of TextMate's snippets features in " Description: snipMate.vim implements some of TextMate's snippets features in
" Vim. A snippet is a piece of often-typed text that you can " Vim. A snippet is a piece of often-typed text that you can
" insert into your document using a trigger word followed by a "<tab>". " insert into your document using a trigger word followed by a "<tab>".
@@ -138,7 +138,7 @@ fun! TriggerSnippet()
call feedkeys("\<tab>") | return '' call feedkeys("\<tab>") | return ''
endif endif
if exists('g:snipPos') | return snipMate#jumpTabStop() | endif if exists('g:snipPos') | return snipMate#jumpTabStop(0) | endif
let word = matchstr(getline('.'), '\S\+\%'.col('.').'c') let word = matchstr(getline('.'), '\S\+\%'.col('.').'c')
for scope in [bufnr('%')] + split(&ft, '\.') + ['_'] for scope in [bufnr('%')] + split(&ft, '\.') + ['_']
@@ -147,7 +147,7 @@ fun! TriggerSnippet()
" the snippet. " the snippet.
if snippet != '' if snippet != ''
let col = col('.') - len(trigger) let col = col('.') - len(trigger)
sil exe 's/\V'.escape(trigger, '/').'\%#//' sil exe 's/\V'.escape(trigger, '/.').'\%#//'
return snipMate#expandSnip(snippet, col) return snipMate#expandSnip(snippet, col)
endif endif
endfor endfor
@@ -159,6 +159,23 @@ fun! TriggerSnippet()
return "\<tab>" return "\<tab>"
endf endf
fun! BackwardsSnippet()
if exists('g:snipPos') | return snipMate#jumpTabStop(1) | endif
if exists('g:SuperTabMappingForward')
if g:SuperTabMappingBackward == "<s-tab>"
let SuperTabKey = "\<c-p>"
elseif g:SuperTabMappingForward == "<s-tab>"
let SuperTabKey = "\<c-n>"
endif
endif
if exists('SuperTabKey')
call feedkeys(SuperTabKey)
return ''
endif
return "\<s-tab>"
endf
" Check if word under cursor is snippet trigger; if it isn't, try checking if " Check if word under cursor is snippet trigger; if it isn't, try checking if
" the text after non-word characters is (e.g. check for "foo" in "bar.foo") " the text after non-word characters is (e.g. check for "foo" in "bar.foo")
fun s:GetSnippet(word, scope) fun s:GetSnippet(word, scope)
@@ -174,6 +191,9 @@ fun s:GetSnippet(word, scope)
let word = substitute(word, '.\{-}\W', '', '') let word = substitute(word, '.\{-}\W', '', '')
endif endif
endw endw
if word == '' && a:word != '.' && stridx(a:word, '.') != -1
let [word, snippet] = s:GetSnippet('.', a:scope)
endif
return [word, snippet] return [word, snippet]
endf endf