diff --git a/autoload/neosnippet/handlers.vim b/autoload/neosnippet/handlers.vim index 9bcdacf..38a07bd 100644 --- a/autoload/neosnippet/handlers.vim +++ b/autoload/neosnippet/handlers.vim @@ -33,7 +33,8 @@ function! neosnippet#handlers#_complete_done() "{{{ return endif - let snippet = neosnippet#parser#_get_completed_snippet(v:completed_item) + let snippet = neosnippet#parser#_get_completed_snippet( + \ v:completed_item, neosnippet#util#get_next_text()) if snippet == '' return endif diff --git a/autoload/neosnippet/parser.vim b/autoload/neosnippet/parser.vim index 1313dfe..3b34dd8 100644 --- a/autoload/neosnippet/parser.vim +++ b/autoload/neosnippet/parser.vim @@ -292,37 +292,51 @@ function! neosnippet#parser#_initialize_snippet_options() "{{{ \ } endfunction"}}} -function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{ - let pairs = { '(' : ')', '{' : '}', '"' : '"' } - if index(keys(pairs), a:completed_item.word[-1:]) < 0 - return '' - endif - let key = a:completed_item.word[-1:] - let pair = pairs[key] - +function! neosnippet#parser#_get_completed_snippet(completed_item, next_text) "{{{ let item = a:completed_item + " Set abbr let abbr = (item.abbr != '') ? item.abbr : item.word if len(item.menu) > 5 " Combine menu. let abbr .= ' ' . item.menu endif - if item.info != '' let abbr = split(item.info, '\n')[0] endif + let pairs = { '(' : ')', '{' : '}', '"' : '"' } + let word_pattern = neosnippet#util#escape_pattern(item.word) + let angle_pattern = word_pattern . '<.\+>(.*)' + let no_key = index(keys(pairs), item.word[-1:]) < 0 + if no_key && abbr !~# word_pattern . '\%(<.\+>\)\?(.*)' + return '' + endif + + let key = no_key ? '(' : item.word[-1:] + if a:next_text[:0] ==# key + " Disable auto pair + return '' + endif + + let pair = pairs[key] + " Make snippet arguments let cnt = 1 let snippet = '' + if no_key && abbr !~# angle_pattern + " Auto key + let snippet .= key + endif + if empty(filter(values(pairs), 'stridx(abbr, v:val) > 0')) " Pairs not found pattern let snippet .= '${' . cnt . '}' let cnt += 1 endif - if abbr =~ '<.\+>(.*)' + if abbr =~# angle_pattern " Add angle analysis let snippet .= '<' @@ -340,6 +354,10 @@ function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{ endfor let snippet .= args let snippet .= '>' + + if no_key + let snippet .= key + endif endif let args = '' @@ -361,9 +379,10 @@ function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{ endfor let snippet .= args - let snippet .= pair - - let snippet .= '${' . cnt . '}' + if a:next_text[:0] !=# pair + let snippet .= pair + let snippet .= '${' . cnt . '}' + endif return snippet endfunction"}}} diff --git a/autoload/neosnippet/util.vim b/autoload/neosnippet/util.vim index d678715..c84e38e 100644 --- a/autoload/neosnippet/util.vim +++ b/autoload/neosnippet/util.vim @@ -109,6 +109,9 @@ function! neosnippet#util#get_cur_text() "{{{ \ matchstr(getline('.'), \ '^.*\%' . col('.') . 'c' . (mode() ==# 'i' ? '' : '.')) endfunction"}}} +function! neosnippet#util#get_next_text() "{{{ + return getline('.')[len(neosnippet#util#get_cur_text()) :] +endfunction"}}} function! neosnippet#util#print_error(string) "{{{ echohl Error | echomsg '[neosnippet] ' . a:string | echohl None endfunction"}}} diff --git a/test/functions.vim b/test/functions.vim index d39a5b6..29612ea 100644 --- a/test/functions.vim +++ b/test/functions.vim @@ -36,71 +36,92 @@ function! s:suite.get_completed_snippet() call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo()', \ 'menu' : '', 'info' : '' - \ }), ')${1}') + \ }, ''), ')${1}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : '', \ 'menu' : '', 'info' : '' - \ }), '${1})${2}') + \ }, ''), '${1})${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(hoge)', \ 'menu' : '', 'info' : '' - \ }), '${1:#:hoge})${2}') + \ }, ''), '${1:#:hoge})${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo', 'abbr' : 'foo(hoge)', \ 'menu' : '', 'info' : '' - \ }), '') + \ }, ''), '(${1:#:hoge})${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo)', \ 'menu' : '', 'info' : '' - \ }), '${1:#:hoge}, ${2:#:piyo})${3}') + \ }, ''), '${1:#:hoge}, ${2:#:piyo})${3}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo(foobar))', \ 'menu' : '', 'info' : '' - \ }), '${1:#:hoge}, ${2:#:piyo()})${3}') + \ }, ''), '${1:#:hoge}, ${2:#:piyo()})${3}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(hoge[, abc])', \ 'menu' : '', 'info' : '' - \ }), '${1:#:hoge[, abc]})${2}') + \ }, ''), '${1:#:hoge[, abc]})${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(...)', \ 'menu' : '', 'info' : '' - \ }), '${1:#:...})${2}') + \ }, ''), '${1:#:...})${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo(', 'abbr' : 'foo(hoge, ...)', \ 'menu' : '', 'info' : '' - \ }), '${1:#:hoge}${2:#:, ...})${3}') + \ }, ''), '${1:#:hoge}${2:#:, ...})${3}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo{', 'abbr' : 'foo{}', \ 'menu' : '', 'info' : '' - \ }), '}${1}') + \ }, ''), '}${1}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo{', 'abbr' : 'foo{', \ 'menu' : '', 'info' : '' - \ }), '${1}}${2}') + \ }, ''), '${1}}${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ \ 'word' : 'foo{', 'abbr' : 'foo{piyo}', \ 'menu' : '', 'info' : '' - \ }), '${1:#:piyo}}${2}') + \ }, ''), '${1:#:piyo}}${2}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ - \ 'word' : 'Dictionary(', 'abbr' : 'Dictionary(foo)', + \ 'word' : 'Dictionary', 'abbr' : 'Dictionary(foo)', \ 'menu' : '', 'info' : '' - \ }), '<${1:#:Key}, ${2:#:Value}>${3:#:foo})${4}') + \ }, ''), '<${1:#:Key}, ${2:#:Value}>(${3:#:foo})${4}') call s:assert.equals(neosnippet#parser#_get_completed_snippet({ - \ 'word' : 'Dictionary(', 'abbr' : 'Dictionary (foo)', + \ 'word' : 'Dictionary(', + \ 'abbr' : 'Dictionary Dictionary(foo)', \ 'menu' : '', 'info' : '' - \ }), '${1:#:foo})${2}') + \ }, ''), '${1:#:foo})${2}') + + call s:assert.equals(neosnippet#parser#_get_completed_snippet({ + \ 'word' : 'Dictionary(', 'abbr' : '', + \ 'menu' : '', 'info' : '' + \ }, '('), '') + + call s:assert.equals(neosnippet#parser#_get_completed_snippet({ + \ 'word' : 'Dictionary(', 'abbr' : 'Dictionary(foo)', + \ 'menu' : '', 'info' : '' + \ }, '('), '') + + call s:assert.equals(neosnippet#parser#_get_completed_snippet({ + \ 'word' : 'Dictionary(', 'abbr' : 'Dictionary(foo)', + \ 'menu' : '', 'info' : '' + \ }, ')'), '${1:#:foo}') + + call s:assert.equals(neosnippet#parser#_get_completed_snippet({ + \ 'word' : 'Dictionary', 'abbr' : 'Dictionary(foo)', + \ 'menu' : '', 'info' : '' + \ }, ''), '(${1:#:foo})${2}') endfunction