1
0
mirror of https://github.com/amix/vimrc synced 2025-07-12 22:24:59 +08:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Mirosław Pragłowski
2014-10-13 21:54:40 +02:00
266 changed files with 11284 additions and 3954 deletions

View File

@ -9,6 +9,7 @@ Weber](marco-oweber@gmx.de), and [Adnan Zafar](https://github.com/ajzafar) with
additional contributions from:
* [907th](https://github.com/907th)
* [adkron](https://github.com/adkron)
* [alderz](https://github.com/alderz)
* [asymmetric](https://github.com/asymmetric)
* [bpugh](https://github.com/bpugh)

View File

@ -44,6 +44,30 @@ looking at the [vim-snippets][vim-snippets] repository.
" Optional:
Bundle "honza/vim-snippets"
## FAQ ##
> How does SnipMate determine which snippets to load? How can I separate, for
> example, my Rails snippets from my Ruby snippets?
Primarily SnipMate looks at the `'filetype'` and `'syntax'` settings. Taking
"scopes" from these options, it looks in each `snippets/` directory in
`'runtimepath'` for files named `scope.snippets`, `scope/*.snippets`, or
`scope_*.snippets`.
However we understand this may not allow for the flexibility desired by some
languages. For this we provide two options: scope aliases and the
`:SnipMateLoadScope` command. Scope aliases simply say "whenever this scope is
loaded, also load this other scope:
let g:snipMate = {}
let g:snipMate.scope_aliases = {}
let g:snipMate.scope_aliases['ruby'] = 'ruby,rails'
will load the `ruby-rails` scope whenever the `ruby` scope is active. The
`:SnipMateLoadScope foo` command will always load the foo scope in the current
buffer. The [vim-rails](https://github.com/tpope/vim-rails) plugin automatically
does `:SnipMateLoadScope rails` when editing a Rails project for example.
## Release Notes ##
### Master ###
@ -53,6 +77,10 @@ looking at the [vim-snippets][vim-snippets] repository.
* Fix bug with mirrors in the first column
* Fix bug with tabs in indents ([#143][143])
* Fix bug with mirrors in placeholders
* Fix reading single snippet files
* Fix the use of the visual map at the end of a line
* Add `:SnipMateLoadScope` command and buffer-local scope aliases
* Load `<scope>_*.snippets` files
### 0.87 - 2014-01-04 ###

View File

@ -41,11 +41,6 @@ if !exists('g:snips_no_mappings') || !g:snips_no_mappings
call s:map_if_not_mapped('<C-R><Tab>', '<Plug>snipMateShow', 'i')
endif
" FIXME: Without this map, <BS> 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 <unique> <BS> b<BS><Esc>
let &cpo = s:save_cpo
" vim:noet:

View File

@ -2,7 +2,6 @@
if !exists('g:snipMate')
let g:snipMate = {}
endif
let s:c = g:snipMate
try
call tlib#input#List('mi', '', [])
@ -11,27 +10,7 @@ catch /.*/
endtry
" match $ which doesn't follow a \
let s:d = '\%([\\]\@<!\$\)'
" if filetype is objc, cpp, cs or cu also append snippets from scope 'c'
" you can add multiple by separating scopes by ',', see s:AddScopeAliases
let s:c.scope_aliases = get(s:c, 'scope_aliases', {})
if !exists('g:snipMate_no_default_aliases') || !g:snipMate_no_default_aliases
let s:c.scope_aliases.objc = get(s:c.scope_aliases, 'objc', 'c')
let s:c.scope_aliases.cpp = get(s:c.scope_aliases, 'cpp', 'c')
let s:c.scope_aliases.cu = get(s:c.scope_aliases, 'cu', 'c')
let s:c.scope_aliases.xhtml = get(s:c.scope_aliases, 'xhtml', 'html')
let s:c.scope_aliases.html = get(s:c.scope_aliases, 'html', 'javascript')
let s:c.scope_aliases.php = get(s:c.scope_aliases, 'php', 'php,html,javascript')
let s:c.scope_aliases.ur = get(s:c.scope_aliases, 'ur', 'html,javascript')
let s:c.scope_aliases.mxml = get(s:c.scope_aliases, 'mxml', 'actionscript')
let s:c.scope_aliases.eruby = get(s:c.scope_aliases, 'eruby', 'eruby-rails,html')
endif
" set this to "\<tab>" to make snipmate not swallow tab (make sure to not have
" expandtab set). Remember that you can always enter tabs by <c-v> <tab> then
" you don't need this
let s:c['no_match_completion_feedkeys_chars'] = get(s:c, 'no_match_completion_feedkeys_chars', "\t")
let s:d = nr2char(31)
fun! Filename(...)
let filename = expand('%:t:r')
@ -85,11 +64,20 @@ fun! snipMate#expandSnip(snip, col)
if b:snip_state.stop_count
aug snipmate_changes
au CursorMoved,CursorMovedI <buffer> call b:snip_state.update_changes()
au CursorMoved,CursorMovedI <buffer> if exists('b:snip_state') |
\ call b:snip_state.update_changes() |
\ else |
\ silent! au! snipmate_changes * <buffer> |
\ endif
aug END
call b:snip_state.set_stop(0)
let ret = b:snip_state.select_word()
return b:snip_state.select_word()
if b:snip_state.stop_count == 1
call b:snip_state.remove()
endif
return ret
else
unlet b:snip_state
" Place cursor at end of snippet if no tab stop is given
@ -115,6 +103,7 @@ endfunction
" Prepare snippet to be processed by s:BuildTabStops
fun! s:ProcessSnippet(snip)
let snippet = a:snip
let esc_bslash = '\%(\\\@<!\%(\\\\\)*\)\@<='
if exists('b:snipmate_content_visual')
let visual = b:snipmate_content_visual
@ -130,7 +119,7 @@ fun! s:ProcessSnippet(snip)
" Using a loop here instead of a regex fixes a bug with nested "\=".
if stridx(snippet, '`') != -1
let new = []
let snip = split(snippet, '\%(\\\@<!\%(\\\\\)*\)\@<=`', 1)
let snip = split(snippet, esc_bslash . '`', 1)
let isexp = 0
for i in snip
if isexp
@ -143,13 +132,15 @@ fun! s:ProcessSnippet(snip)
let snippet = join(new, '')
let snippet = substitute(snippet, "\r", "\n", 'g')
let snippet = substitute(snippet, '\\`', "`", 'g')
let snippet = substitute(snippet, '\\\\', "\\", 'g')
endif
" Place all text after a colon in a tab stop after the tab stop
" (e.g. "${#:foo}" becomes "${:foo}foo").
" This helps tell the position of the tab stops later.
let snippet = substitute(snippet, s:d.'{\d\+:\(.\{-}\)}', '&\1', 'g')
let snippet = substitute(snippet, esc_bslash . '\$\({\d\+:\(.\{-}\)}\|{\d\+}\)', s:d . '\1\2', 'g')
let snippet = substitute(snippet, esc_bslash . '\$\(\d\+\)', s:d . '\1', 'g')
let snippet = substitute(snippet, esc_bslash . '\\\$', '$', 'g')
let snippet = substitute(snippet, '\\\\', "\\", 'g')
" Update the a:snip so that all the $# become the text after
" the colon in their associated ${#}.
@ -165,14 +156,14 @@ fun! s:ProcessSnippet(snip)
" Add ${0} tab stop if found
if snippet =~ s:d . '{0'
let snippet = substitute(snippet, s:d.'{0', '${'.i, '')
let snippet = substitute(snippet, s:d.'{0', s:d . '{' . i, '')
let s = matchstr(snippet, s:d.'{'.i.':\zs.\{-}\ze}')
if s != ''
let snippet = substitute(snippet, s:d.'0', '$'.i, 'g')
let snippet = substitute(snippet, s:d.'0', s:d . i, 'g')
let snippet = substitute(snippet, s:d.i, s.'&', 'g')
endif
else
let snippet .= '${'.i.'}'
let snippet .= s:d . '{'.i.'}'
endif
if &et " Expand tabs to spaces if 'expandtab' is set.
@ -206,7 +197,7 @@ endf
fun! s:BuildTabStops(snip, lnum, col, indent)
let snipPos = []
let i = 1
let withoutVars = substitute(a:snip, '$\d\+', '', 'g')
let withoutVars = substitute(a:snip, s:d . '\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')
@ -255,13 +246,12 @@ function! s:state_proto.jump_stop(backwards)
" 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 ''
endif
call self.set_stop(self.stop_no)
return self.select_word()
let ret = self.select_word()
if self.stop_no == self.stop_count - 1
call self.remove()
endif
return ret
endfunction
" Updates tab stops/vars
@ -274,7 +264,7 @@ function! s:state_proto.update_stops()
for pos in self.stops
if pos == self.cur_stop | continue | endif
let changed = pos[0] == curLine && pos[1] > self.start_col
let changed = pos[0] == curLine && pos[1] > self.cur_stop[1]
let changedVars = 0
let endPlaceholder = pos[2] - 1 + pos[1]
" Subtract changeLen from each tab stop that was after any of
@ -333,10 +323,13 @@ function! s:state_proto.update_changes()
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)
if mode() == 'i'
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
endif
let self.prev_len = col('$')
@ -348,6 +341,7 @@ function! s:state_proto.update_vars(change)
let newWord = strpart(getline('.'), self.start_col - 1, newWordLen)
let changeLen = a:change
let curLine = line('.')
let curCol = col('.')
let oldStartSnip = self.start_col
let updateTabStops = changeLen != 0
let i = 0
@ -386,7 +380,7 @@ function! s:state_proto.update_vars(change)
" Reposition the cursor in case a var updates on the same line but before
" the current tabstop
if oldStartSnip != self.start_col || mode() == 'i'
call cursor(0, col('.') + self.start_col - oldStartSnip)
call cursor(0, curCol + self.start_col - oldStartSnip)
endif
endfunction
@ -394,12 +388,16 @@ endfunction
" returns list of
" ['triggername', 'name', 'contents']
" if triggername is not set 'default' is assumed
" TODO: better error checking
fun! snipMate#ReadSnippetsFile(file)
let result = []
let new_scopes = []
if !filereadable(a:file) | return [result, new_scopes] | endif
let inSnip = 0
let line_no = 0
for line in readfile(a:file) + ["\n"]
let line_no += 1
if inSnip && (line[0] == "\t" || line == '')
let content .= strpart(line, 1)."\n"
continue
@ -418,6 +416,10 @@ fun! snipMate#ReadSnippetsFile(file)
let trigger = strpart(trigger, 0, space - 1)
endif
let content = ''
if trigger =~ '^\s*$' " discard snippets with empty triggers
echom 'Invalid snippet in' a:file 'near line' line_no
let inSnip = 0
endif
elseif line[:6] == 'extends'
call extend(new_scopes, map(split(strpart(line, 8)),
\ "substitute(v:val, ',*$', '', '')"))
@ -426,12 +428,26 @@ fun! snipMate#ReadSnippetsFile(file)
return [result, new_scopes]
endf
function! s:GetScopes()
let ret = exists('b:snipMate.scope_aliases') ? copy(b:snipMate.scope_aliases) : {}
let global = get(g:snipMate, 'scope_aliases', {})
for alias in keys(global)
if has_key(ret, alias)
let ret[alias] = join(split(ret[alias], ',')
\ + split(global[alias], ','), ',')
else
let ret[alias] = global[alias]
endif
endfor
return ret
endfunction
" 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 scope_aliases = s:GetScopes()
let new = a:list
let new2 = []
while !empty(new)
@ -447,16 +463,22 @@ fun! s:AddScopeAliases(list)
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
if v:version < 704 || has('win32')
function! s:Glob(path, expr)
let res = []
for p in split(a:path, ',')
let h = split(fnamemodify(a:expr, ':h'), '/')[0]
if isdirectory(p . '/' . h)
call extend(res, split(glob(p . '/' . a:expr), "\n"))
endif
endfor
return filter(res, 'filereadable(v:val)')
endfunction
else
function! s:Glob(path, expr)
return split(globpath(a:path, a:expr), "\n")
endfunction
endif
" returns dict of
" { path: { 'type': one of 'snippet' 'snippets',
@ -466,12 +488,11 @@ endfunction
" '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 paths = join(funcref#Call(g:snipMate.snippet_dirs), ',')
let result = {}
let scopes = s:AddScopeAliases(a:scopes)
let trigger = escape(a:trigger, "*[]?{}`'$")
@ -480,19 +501,22 @@ function! snipMate#GetSnippetFiles(mustExist, scopes, trigger)
for scope in scopes
for f in s:Glob(paths, 'snippets/' . scope . '.snippets') +
\ 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')
" We check for trigger* in the next two loops. In the case of an exact
" match, that'll be handled in snipMate#GetSnippetsForWordBelowCursor.
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 }
\ 'trigger': fnamemodify(f, ':t:r'), 'name_prefix' : scope }
endfor
for f in s:Glob(paths, 'snippets/'.scope.'/'.trigger.'/*.snippet')
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 }
\ 'trigger': fnamemodify(f, ':h:t'), 'name_prefix' : scope }
endfor
if !a:mustExist
@ -507,21 +531,12 @@ function! snipMate#GetSnippetFiles(mustExist, scopes, trigger)
endfunction
" should be moved to utils or such?
function! snipMate#SetByPath(dict, path, value)
function! snipMate#SetByPath(dict, trigger, path, snippet) abort
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
endfunction
function! s:ReadFile(file)
if a:file =~ '\.snippet$'
return [['', '', readfile(a:file), '1']]
else
return snipMate#ReadSnippetsFile(a:file)
if !has_key(d, a:trigger)
let d[a:trigger] = {}
endif
let d[a:trigger][a:path] = a:snippet
endfunction
function! s:CachedSnips(file)
@ -545,13 +560,13 @@ function! snipMate#DefaultPool(scopes, trigger, result)
call extend(extra_scopes, new_scopes)
for [trigger, name, contents] in snippets
if trigger =~ '\V\^' . escape(a:trigger, '\')
call snipMate#SetByPath(a:result,
\ [trigger, opts.name_prefix . ' ' . name],
\ contents)
call snipMate#SetByPath(a:result, trigger,
\ opts.name_prefix . ' ' . name, contents)
endif
endfor
elseif opts.type == 'snippet'
call snipMate#SetByPath(a:result, [opts.trigger, opts.name_prefix.' '.opts.name], readfile(f))
call snipMate#SetByPath(a:result, opts.trigger,
\ opts.name_prefix . ' ' . opts.name, readfile(f))
else
throw "unexpected"
endif
@ -636,7 +651,7 @@ endf
fun! snipMate#ScopesByFile()
" duplicates are removed in AddScopeAliases
return filter(funcref#Call(s:c.get_scopes), "v:val != ''")
return filter(funcref#Call(g:snipMate.get_scopes), "v:val != ''")
endf
" used by both: completion and insert snippet
@ -669,8 +684,8 @@ fun! snipMate#GetSnippetsForWordBelowCursor(word, exact)
let snippet = ''
" prefer longest word
for word in lookups
let s:c.word = word
for [k,snippetD] in items(funcref#Call(s:c['get_snippets'], [snipMate#ScopesByFile(), word]))
let g:snipMate.word = word
for [k,snippetD] in items(funcref#Call(g:snipMate['get_snippets'], [snipMate#ScopesByFile(), word]))
" hack: require exact match
if a:exact && k !=# word
continue
@ -730,7 +745,7 @@ fun! snipMate#ShowAvailableSnips()
" Pretty hacky, but really can't have the tab swallowed!
if len(matches) == 0
call feedkeys(s:c['no_match_completion_feedkeys_chars'], 'n')
call feedkeys(g:snipMate['no_match_completion_feedkeys_chars'], 'n')
return ""
endif

View File

@ -74,6 +74,14 @@ Commands~
files will be shown, with the existing files
shown first.
:SnipMateLoadScope[!] scope [scope ...]
Load snippets from additional scopes. Without
[!] the additional scopes are loaded only in
the current buffer. For example >
:SnipMateLoadScopes rails
< will load all rails.snippets in the current
buffer.
*SnipMate-options*
Options~
@ -103,9 +111,13 @@ g:snipMate.scope_aliases A |Dictionary| associating certain filetypes
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.
case of dotted filetypes. A buffer local
variant b:snipMate_scope_aliases is merged
with the global variant.
g:snipMate_no_default_aliases
g:snipMate_no_default_aliases Note: This has been renamed to the following.
g:snipMate.no_default_aliases
When set to 1, prevents SnipMate from loading
default scope aliases. The defaults are:
Filetype Alias ~
@ -118,6 +130,10 @@ g:snipMate_no_default_aliases
php php,html,javascript
ur html,javascript
xhtml html
Individual defaults can be disabled by setting
them to an empty value: >
let g:snipMate.scope_aliases.php = ''
< will disable the default PHP alias.
Note: Setting this option does not disable
scope aliases entirely, only those made by
SnipMate itself. Any scope aliases created by
@ -178,6 +194,7 @@ settings (taking into account the dotted syntax), the following files are read
for snippets: >
.../snippets/<scope>.snippets
.../snippets/<scope>_<name>.snippets
.../snippets/<scope>/<name>.snippets
.../snippets/<scope>/<trigger>.snippet
.../snippets/<scope>/<trigger>/<description>.snippet

View File

@ -11,8 +11,8 @@ 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'
" Save and reset 'cpo'
let s:save_cpo = &cpo
set cpo&vim
@ -24,7 +24,7 @@ endtry
if (!exists('g:snipMateSources'))
let g:snipMateSources = {}
" default source: get snippets based on runtimepath:
" Default source: get snippets based on runtimepath
let g:snipMateSources['default'] = funcref#Function('snipMate#DefaultPool')
endif
@ -40,52 +40,89 @@ inoremap <silent> <Plug>snipMateTrigger <C-R>=snipMate#TriggerSnippet(1)<
inoremap <silent> <Plug>snipMateBack <C-R>=snipMate#BackwardsSnippet()<CR>
snoremap <silent> <Plug>snipMateBack <Esc>a<C-R>=snipMate#BackwardsSnippet()<CR>
inoremap <silent> <Plug>snipMateShow <C-R>=snipMate#ShowAvailableSnips()<CR>
xnoremap <silent> <Plug>snipMateVisual :<C-U>call <SID>grab_visual()<CR>i
xnoremap <silent> <Plug>snipMateVisual :<C-U>call <SID>grab_visual()<CR>gv"_c
" config which can be overridden (shared lines)
if !exists('g:snipMate')
let g:snipMate = {}
" config variables
if !exists('g:snips_author')
let g:snips_author = 'Me'
endif
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"))
" SnipMate inserts this string when no snippet expansion can be done
let g:snipMate['no_match_completion_feedkeys_chars'] =
\ get(g:snipMate, 'no_match_completion_feedkeys_chars', "\t")
" 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)')
" Add default scope aliases, without overriding user settings
let g:snipMate.scope_aliases = get(g:snipMate, 'scope_aliases', {})
if exists('g:snipMate_no_default_aliases')
echom 'The g:snipMate_no_default_aliases option has been renamed.'
\ 'See :h snipMate-options.'
endif
if (!exists('g:snipMate_no_default_aliases') || !g:snipMate_no_default_aliases)
\ && (!exists('g:snipMate.no_default_aliases')
\ || !g:snipMate.no_default_aliases)
let g:snipMate.scope_aliases.objc =
\ get(g:snipMate.scope_aliases, 'objc', 'c')
let g:snipMate.scope_aliases.cpp =
\ get(g:snipMate.scope_aliases, 'cpp', 'c')
let g:snipMate.scope_aliases.cu =
\ get(g:snipMate.scope_aliases, 'cu', 'c')
let g:snipMate.scope_aliases.xhtml =
\ get(g:snipMate.scope_aliases, 'xhtml', 'html')
let g:snipMate.scope_aliases.html =
\ get(g:snipMate.scope_aliases, 'html', 'javascript')
let g:snipMate.scope_aliases.php =
\ get(g:snipMate.scope_aliases, 'php', 'php,html,javascript')
let g:snipMate.scope_aliases.ur =
\ get(g:snipMate.scope_aliases, 'ur', 'html,javascript')
let g:snipMate.scope_aliases.mxml =
\ get(g:snipMate.scope_aliases, 'mxml', 'actionscript')
let g:snipMate.scope_aliases.eruby =
\ get(g:snipMate.scope_aliases, 'eruby', 'eruby-rails,html')
endif
let g:snipMate['get_snippets'] = get(g:snipMate, 'get_snippets', funcref#Function("snipMate#GetSnippets"))
" List of paths where snippets/ dirs are located, or a function returning such
" a list
let g:snipMate['snippet_dirs'] = get(g:snipMate, 'snippet_dirs', funcref#Function('return split(&runtimepath,",")'))
if type(g:snipMate['snippet_dirs']) == type([])
call map(g: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
let g:snipMate['get_scopes'] = get(g:snipMate, 'get_scopes', funcref#Function('return split(&ft,"\\.")+[&syntax, "_"]'))
" Modified from Luc Hermitte's function on StackOverflow
" <http://stackoverflow.com/a/1534347>
function! s:grab_visual()
let a_save = @a
try
normal! gv"ad
normal! gv"ay
let b:snipmate_content_visual = @a
finally
let @a = a_save
endtry
endfunction
" TODO: Allow specifying an arbitrary snippets file
function! s:load_scopes(bang, ...)
let gb = a:bang ? g: : b:
let gb.snipMate = get(gb, 'snipMate', {})
let gb.snipMate.scope_aliases = get(gb.snipMate, 'scope_aliases', {})
let gb.snipMate.scope_aliases['_'] = join(split(get(gb.snipMate.scope_aliases, '_', ''), ',') + a:000, ',')
endfunction
command! -bang -bar -nargs=+ SnipMateLoadScope
\ call s:load_scopes(<bang>0, <f-args>)
" Edit snippet files
command! SnipMateOpenSnippetFiles call snipMate#OpenSnippetFiles()
" restore 'cpo'
let &cpo = s:save_cpo