Improve completed snippet feature

This commit is contained in:
Shougo Matsushita 2016-01-04 12:13:47 +09:00
parent 57301f8a5d
commit ac6ac62a5b
4 changed files with 74 additions and 30 deletions

View File

@ -33,7 +33,8 @@ function! neosnippet#handlers#_complete_done() "{{{
return return
endif 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 == '' if snippet == ''
return return
endif endif

View File

@ -292,37 +292,51 @@ function! neosnippet#parser#_initialize_snippet_options() "{{{
\ } \ }
endfunction"}}} endfunction"}}}
function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{ function! neosnippet#parser#_get_completed_snippet(completed_item, next_text) "{{{
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]
let item = a:completed_item let item = a:completed_item
" Set abbr
let abbr = (item.abbr != '') ? item.abbr : item.word let abbr = (item.abbr != '') ? item.abbr : item.word
if len(item.menu) > 5 if len(item.menu) > 5
" Combine menu. " Combine menu.
let abbr .= ' ' . item.menu let abbr .= ' ' . item.menu
endif endif
if item.info != '' if item.info != ''
let abbr = split(item.info, '\n')[0] let abbr = split(item.info, '\n')[0]
endif 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 " Make snippet arguments
let cnt = 1 let cnt = 1
let snippet = '' let snippet = ''
if no_key && abbr !~# angle_pattern
" Auto key
let snippet .= key
endif
if empty(filter(values(pairs), 'stridx(abbr, v:val) > 0')) if empty(filter(values(pairs), 'stridx(abbr, v:val) > 0'))
" Pairs not found pattern " Pairs not found pattern
let snippet .= '${' . cnt . '}' let snippet .= '${' . cnt . '}'
let cnt += 1 let cnt += 1
endif endif
if abbr =~ '<.\+>(.*)' if abbr =~# angle_pattern
" Add angle analysis " Add angle analysis
let snippet .= '<' let snippet .= '<'
@ -340,6 +354,10 @@ function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{
endfor endfor
let snippet .= args let snippet .= args
let snippet .= '>' let snippet .= '>'
if no_key
let snippet .= key
endif
endif endif
let args = '' let args = ''
@ -361,9 +379,10 @@ function! neosnippet#parser#_get_completed_snippet(completed_item) "{{{
endfor endfor
let snippet .= args let snippet .= args
let snippet .= pair if a:next_text[:0] !=# pair
let snippet .= pair
let snippet .= '${' . cnt . '}' let snippet .= '${' . cnt . '}'
endif
return snippet return snippet
endfunction"}}} endfunction"}}}

View File

@ -109,6 +109,9 @@ function! neosnippet#util#get_cur_text() "{{{
\ matchstr(getline('.'), \ matchstr(getline('.'),
\ '^.*\%' . col('.') . 'c' . (mode() ==# 'i' ? '' : '.')) \ '^.*\%' . col('.') . 'c' . (mode() ==# 'i' ? '' : '.'))
endfunction"}}} endfunction"}}}
function! neosnippet#util#get_next_text() "{{{
return getline('.')[len(neosnippet#util#get_cur_text()) :]
endfunction"}}}
function! neosnippet#util#print_error(string) "{{{ function! neosnippet#util#print_error(string) "{{{
echohl Error | echomsg '[neosnippet] ' . a:string | echohl None echohl Error | echomsg '[neosnippet] ' . a:string | echohl None
endfunction"}}} endfunction"}}}

View File

@ -36,71 +36,92 @@ function! s:suite.get_completed_snippet()
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo()', \ 'word' : 'foo(', 'abbr' : 'foo()',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), ')${1}') \ }, ''), ')${1}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : '', \ 'word' : 'foo(', 'abbr' : '',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1})${2}') \ }, ''), '${1})${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(hoge)', \ 'word' : 'foo(', 'abbr' : 'foo(hoge)',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:hoge})${2}') \ }, ''), '${1:#:hoge})${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo', 'abbr' : 'foo(hoge)', \ 'word' : 'foo', 'abbr' : 'foo(hoge)',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '') \ }, ''), '(${1:#:hoge})${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo)', \ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo)',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:hoge}, ${2:#:piyo})${3}') \ }, ''), '${1:#:hoge}, ${2:#:piyo})${3}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo(foobar))', \ 'word' : 'foo(', 'abbr' : 'foo(hoge, piyo(foobar))',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:hoge}, ${2:#:piyo()})${3}') \ }, ''), '${1:#:hoge}, ${2:#:piyo()})${3}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(hoge[, abc])', \ 'word' : 'foo(', 'abbr' : 'foo(hoge[, abc])',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:hoge[, abc]})${2}') \ }, ''), '${1:#:hoge[, abc]})${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(...)', \ 'word' : 'foo(', 'abbr' : 'foo(...)',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:...})${2}') \ }, ''), '${1:#:...})${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo(', 'abbr' : 'foo(hoge, ...)', \ 'word' : 'foo(', 'abbr' : 'foo(hoge, ...)',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:hoge}${2:#:, ...})${3}') \ }, ''), '${1:#:hoge}${2:#:, ...})${3}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo{', 'abbr' : 'foo{}', \ 'word' : 'foo{', 'abbr' : 'foo{}',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '}${1}') \ }, ''), '}${1}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo{', 'abbr' : 'foo{', \ 'word' : 'foo{', 'abbr' : 'foo{',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1}}${2}') \ }, ''), '${1}}${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'foo{', 'abbr' : 'foo{piyo}', \ 'word' : 'foo{', 'abbr' : 'foo{piyo}',
\ 'menu' : '', 'info' : '' \ 'menu' : '', 'info' : ''
\ }), '${1:#:piyo}}${2}') \ }, ''), '${1:#:piyo}}${2}')
call s:assert.equals(neosnippet#parser#_get_completed_snippet({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'Dictionary(', 'abbr' : 'Dictionary<Key, Value>(foo)', \ 'word' : 'Dictionary', 'abbr' : 'Dictionary<Key, Value>(foo)',
\ 'menu' : '', 'info' : '' \ '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({ call s:assert.equals(neosnippet#parser#_get_completed_snippet({
\ 'word' : 'Dictionary(', 'abbr' : 'Dictionary<Key, Value> (foo)', \ 'word' : 'Dictionary(',
\ 'abbr' : 'Dictionary<Key, Value> Dictionary(foo)',
\ 'menu' : '', 'info' : '' \ '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 endfunction