Fix #203 add g:neosnippet#scope_aliases

This commit is contained in:
Shougo Matsushita 2014-01-01 11:00:43 +09:00
parent 622a691785
commit bc7969afb2
7 changed files with 336 additions and 14 deletions

View File

@ -1,7 +1,7 @@
"=============================================================================
" FILE: neosnippet.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" Last Modified: 21 Nov 2013.
" Last Modified: 01 Jan 2014.
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
@ -30,6 +30,8 @@ set cpo&vim
" Global options definition. "{{{
call neosnippet#util#set_default(
\ 'g:neosnippet#disable_runtime_snippets', {})
call neosnippet#util#set_default(
\ 'g:neosnippet#scope_aliases', {})
call neosnippet#util#set_default(
\ 'g:neosnippet#snippets_directory', '')
call neosnippet#util#set_default(

View File

@ -34,6 +34,13 @@ let s:edit_options = [
\]
"}}}
function! s:get_list() "{{{
if !exists('s:List')
let s:List = unite#util#get_vital().import('Data.List')
endif
return s:List
endfunction"}}}
function! neosnippet#commands#_edit(args) "{{{
if neosnippet#util#is_sudo()
call neosnippet#util#print_error(
@ -101,8 +108,11 @@ function! neosnippet#commands#_make_cache(filetype) "{{{
let path = join(neosnippet#helpers#get_snippets_directory(), ',')
let snippets_files = []
for glob in [filetype.'.snip*', filetype.'_*.snip*',
\ filetype . '/**/*.snip*']
for glob in call(s:get_list().flatten,
\ map(split(get(g:neosnippet#scope_aliases,
\ filetype, filetype), '\s*,\s*'), "
\ [v:val . '.snip*', v:val . '/**/*.snip*']
\ + (v:val ==# filetype ? [v:val . '_*.snip*'] : [])"))
let snippets_files += split(globpath(path, glob), '\n')
endfor

View File

@ -145,14 +145,9 @@ function! s:_build_module(sid)
if has_key(s:loaded, a:sid)
return copy(s:loaded[a:sid])
endif
let prefix = '<SNR>' . a:sid . '_'
let funcs = s:_redir('function')
let filter_pat = '^\s*function ' . prefix
let map_pat = prefix . '\zs\w\+'
let functions = map(filter(split(funcs, "\n"),
\ 'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'),
\ 'matchstr(v:val, map_pat)')
let functions = s:_get_functions(a:sid)
let prefix = '<SNR>' . a:sid . '_'
let module = {}
for func in functions
let module[func] = function(prefix . func)
@ -175,6 +170,24 @@ function! s:_build_module(sid)
return copy(module)
endfunction
if exists('+regexpengine')
function! s:_get_functions(sid)
let funcs = s:_redir(printf("function /\\%%#=2^\<SNR>%d_", a:sid))
let map_pat = '<SNR>' . a:sid . '_\zs\w\+'
return map(split(funcs, "\n"), 'matchstr(v:val, map_pat)')
endfunction
else
function! s:_get_functions(sid)
let prefix = '<SNR>' . a:sid . '_'
let funcs = s:_redir('function')
let filter_pat = '^\s*function ' . prefix
let map_pat = prefix . '\zs\w\+'
return map(filter(split(funcs, "\n"),
\ 'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'),
\ 'matchstr(v:val, map_pat)')
endfunction
endif
function! s:_redir(cmd)
let [save_verbose, save_verbosefile] = [&verbose, &verbosefile]
set verbose=0 verbosefile=

View File

@ -0,0 +1,285 @@
" Utilities for list.
let s:save_cpo = &cpo
set cpo&vim
function! s:pop(list)
return remove(a:list, -1)
endfunction
function! s:push(list, val)
call add(a:list, a:val)
return a:list
endfunction
function! s:shift(list)
return remove(a:list, 0)
endfunction
function! s:unshift(list, val)
return insert(a:list, a:val)
endfunction
function! s:cons(x, xs)
return [a:x] + a:xs
endfunction
" TODO spec
function! s:conj(xs, x)
return a:xs + [a:x]
endfunction
" Removes duplicates from a list.
function! s:uniq(list, ...)
let list = a:0 ? map(copy(a:list), printf('[v:val, %s]', a:1)) : copy(a:list)
let i = 0
let seen = {}
while i < len(list)
let key = string(a:0 ? list[i][1] : list[i])
if has_key(seen, key)
call remove(list, i)
else
let seen[key] = 1
let i += 1
endif
endwhile
return a:0 ? map(list, 'v:val[0]') : list
endfunction
function! s:clear(list)
if !empty(a:list)
unlet! a:list[0 : len(a:list) - 1]
endif
return a:list
endfunction
" Concatenates a list of lists.
" XXX: Should we verify the input?
function! s:concat(list)
let list = []
for Value in a:list
let list += Value
endfor
return list
endfunction
" Flattens a list.
function! s:flatten(list, ...)
let limit = a:0 > 0 ? a:1 : -1
let list = []
if limit == 0
return a:list
endif
let limit -= 1
for Value in a:list
if type(Value) == type([])
let list += s:flatten(Value, limit)
else
call add(list, Value)
endif
unlet! Value
endfor
return list
endfunction
" Sorts a list with expression to compare each two values.
" a:a and a:b can be used in {expr}.
function! s:sort(list, expr)
if type(a:expr) == type(function('function'))
return sort(a:list, a:expr)
endif
let s:expr = a:expr
return sort(a:list, 's:_compare')
endfunction
function! s:_compare(a, b)
return eval(s:expr)
endfunction
" Sorts a list using a set of keys generated by mapping the values in the list
" through the given expr.
" v:val is used in {expr}
function! s:sort_by(list, expr)
let pairs = map(a:list, printf('[v:val, %s]', a:expr))
return map(s:sort(pairs,
\ 'a:a[1] ==# a:b[1] ? 0 : a:a[1] ># a:b[1] ? 1 : -1'), 'v:val[0]')
endfunction
function! s:max(list, expr)
echoerr 'Data.List.max() is obsolete. Use its max_by() instead.'
return s:max_by(a:list, a:expr)
endfunction
" Returns a maximum value in {list} through given {expr}.
" Returns 0 if {list} is empty.
" v:val is used in {expr}
function! s:max_by(list, expr)
if empty(a:list)
return 0
endif
let list = map(copy(a:list), a:expr)
return a:list[index(list, max(list))]
endfunction
function! s:min(list, expr)
echoerr 'Data.List.min() is obsolete. Use its min_by() instead.'
return s:min_by(a:list, a:expr)
endfunction
" Returns a minimum value in {list} through given {expr}.
" Returns 0 if {list} is empty.
" v:val is used in {expr}
" FIXME: -0x80000000 == 0x80000000
function! s:min_by(list, expr)
return s:max_by(a:list, '-(' . a:expr . ')')
endfunction
" Returns List of character sequence between [a:from, a:to]
" e.g.: s:char_range('a', 'c') returns ['a', 'b', 'c']
function! s:char_range(from, to)
return map(
\ range(char2nr(a:from), char2nr(a:to)),
\ 'nr2char(v:val)'
\)
endfunction
" Returns true if a:list has a:value.
" Returns false otherwise.
function! s:has(list, value)
return index(a:list, a:value) isnot -1
endfunction
" Returns true if a:list[a:index] exists.
" Returns false otherwise.
" NOTE: Returns false when a:index is negative number.
function! s:has_index(list, index)
" Return true when negative index?
" let index = a:index >= 0 ? a:index : len(a:list) + a:index
return 0 <= a:index && a:index < len(a:list)
endfunction
" similar to Haskell's Data.List.span
function! s:span(f, xs)
let border = len(a:xs)
for i in range(len(a:xs))
if !eval(substitute(a:f, 'v:val', string(a:xs[i]), 'g'))
let border = i
break
endif
endfor
return border == 0 ? [[], copy(a:xs)] : [a:xs[: border - 1], a:xs[border :]]
endfunction
" similar to Haskell's Data.List.break
function! s:break(f, xs)
return s:span(printf('!(%s)', a:f), a:xs)
endfunction
" similar to Haskell's Data.List.takeWhile
function! s:take_while(f, xs)
return s:span(a:f, a:xs)[0]
endfunction
" similar to Haskell's Data.List.partition
function! s:partition(f, xs)
return [filter(copy(a:xs), a:f), filter(copy(a:xs), '!(' . a:f . ')')]
endfunction
" similar to Haskell's Prelude.all
function! s:all(f, xs)
return !s:any(printf('!(%s)', a:f), a:xs)
endfunction
" similar to Haskell's Prelude.any
function! s:any(f, xs)
return !empty(filter(map(copy(a:xs), a:f), 'v:val'))
endfunction
" similar to Haskell's Prelude.and
function! s:and(xs)
return s:all('v:val', a:xs)
endfunction
" similar to Haskell's Prelude.or
function! s:or(xs)
return s:any('v:val', a:xs)
endfunction
" similar to Haskell's Prelude.foldl
function! s:foldl(f, init, xs)
let memo = a:init
for x in a:xs
let expr = substitute(a:f, 'v:val', string(x), 'g')
let expr = substitute(expr, 'v:memo', string(memo), 'g')
unlet memo
let memo = eval(expr)
endfor
return memo
endfunction
" similar to Haskell's Prelude.foldl1
function! s:foldl1(f, xs)
if len(a:xs) == 0
throw 'foldl1'
endif
return s:foldl(a:f, a:xs[0], a:xs[1:])
endfunction
" similar to Haskell's Prelude.foldr
function! s:foldr(f, init, xs)
return s:foldl(a:f, a:init, reverse(copy(a:xs)))
endfunction
" similar to Haskell's Prelude.fold11
function! s:foldr1(f, xs)
if len(a:xs) == 0
throw 'foldr1'
endif
return s:foldr(a:f, a:xs[-1], a:xs[0:-2])
endfunction
" similar to python's zip()
function! s:zip(...)
return map(range(min(map(copy(a:000), 'len(v:val)'))), "map(copy(a:000), 'v:val['.v:val.']')")
endfunction
" similar to zip(), but goes until the longer one.
function! s:zip_fill(xs, ys, filler)
if empty(a:xs) && empty(a:ys)
return []
elseif empty(a:ys)
return s:cons([a:xs[0], a:filler], s:zip_fill(a:xs[1 :], [], a:filler))
elseif empty(a:xs)
return s:cons([a:filler, a:ys[0]], s:zip_fill([], a:ys[1 :], a:filler))
else
return s:cons([a:xs[0], a:ys[0]], s:zip_fill(a:xs[1 :], a:ys[1: ], a:filler))
endif
endfunction
" Inspired by Ruby's with_index method.
function! s:with_index(list, ...)
let base = a:0 > 0 ? a:1 : 0
return s:zip(a:list, range(base, len(a:list)+base-1))
endfunction
" similar to Ruby's detect or Haskell's find.
" TODO spec and doc
function! s:find(list, default, f)
for x in a:list
if eval(substitute(a:f, 'v:val', string(x), 'g'))
return x
endif
endfor
return a:default
endfunction
" Return non-zero if a:list1 and a:list2 have any common item(s).
" Return zero otherwise.
function! s:has_common_items(list1, list2)
return !empty(filter(copy(a:list1), 'index(a:list2, v:val) isnot -1'))
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:set et ts=2 sts=2 sw=2 tw=0:

View File

@ -1,3 +1,3 @@
897c317
9bfba96
Prelude
Data.List

View File

@ -195,11 +195,23 @@ g:neosnippet#enable_snipmate_compatibility
The default value is 0.
g:neosnippet#enable_preview *g:neosnippet#enable_preview*
If this variable is not 0, neosnippet will enable the preview window
feature.
If this variable is not 0, neosnippet will enable the preview
window feature in neocomplcache/neocomplete sources.
The default value is 0.
*g:neosnippet#scope_aliases*
g:neosnippet#scope_aliases
It is a dictionary that associating certain filetypes with
other snippet files.
The key is filetype, and the value is comma separated snippet
filenames excluded extensions.
It works like |g:snipMate.scope_aliases|.
The default value is {}. >
let g:neosnippet#scope_aliases = {}
let g:neosnippet#scope_aliases['ruby'] = 'ruby,ruby-rails'
------------------------------------------------------------------------------
KEY MAPPINGS *neosnippet-key-mappings*