- Refactored parse routine.

This commit is contained in:
Shougo Matsushita 2012-11-03 14:08:11 +09:00
parent 2aed9fa34d
commit ff8b6f19c3
2 changed files with 92 additions and 65 deletions

View File

@ -212,7 +212,7 @@ function! s:initialize_snippet(dict, path, line, pattern, name)"{{{
let abbr = a:dict.abbr let abbr = a:dict.abbr
endif endif
let dict = { let snippet = {
\ 'word' : a:dict.name, 'snip' : a:dict.word, \ 'word' : a:dict.name, 'snip' : a:dict.word,
\ 'filter_str' : a:dict.abbr, \ 'filter_str' : a:dict.abbr,
\ 'description' : a:dict.word, \ 'description' : a:dict.word,
@ -221,7 +221,12 @@ function! s:initialize_snippet(dict, path, line, pattern, name)"{{{
\ 'action__path' : a:path, 'action__line' : a:line, \ 'action__path' : a:path, 'action__line' : a:line,
\ 'action__pattern' : a:pattern, 'real_name' : a:name, \ 'action__pattern' : a:pattern, 'real_name' : a:name,
\} \}
return dict
if has_key(a:dict, 'regex')
let snippet.regex = a:dict.regex
endif
return snippet
endfunction"}}} endfunction"}}}
function! s:initialize_snippet_options()"{{{ function! s:initialize_snippet_options()"{{{
return { 'head' : 0, 'word' : 0, 'indent' : 0 } return { 'head' : 0, 'word' : 0, 'indent' : 0 }
@ -337,13 +342,15 @@ function! s:parse_snippets_file(snippets, snippets_file)"{{{
let line = substitute(line, '\s\+$', '', '') let line = substitute(line, '\s\+$', '', '')
endif endif
if line =~ '^include' if line =~ '^\s*#'
" Comment.
elseif line =~ '^include'
" Include snippets. " Include snippets.
let snippet_file = matchstr(line, '^include\s\+\zs.*$') let filename = matchstr(line, '^include\s\+\zs.*$')
for snippets_file in split(globpath(join( for snippets_file in split(globpath(join(
\ neosnippet#get_snippets_directory(), ','), \ neosnippet#get_snippets_directory(), ','),
\ snippet_file), '\n') \ filename), '\n')
call s:parse_snippets_file(a:snippets, snippets_file) call s:parse_snippets_file(a:snippets, snippets_file)
endfor endfor
elseif line =~ '^delete\s' elseif line =~ '^delete\s'
@ -358,67 +365,10 @@ function! s:parse_snippets_file(snippets, snippets_file)"{{{
\ a:snippets, dup_check, a:snippets_file) \ a:snippets, dup_check, a:snippets_file)
endif endif
" Initialize snippet dict. let snippet_dict = s:parse_snippet_name(
let snippet_dict = { 'word' : '', 'linenr' : linenr, \ line, linenr, dup_check)
\ 'options' : s:initialize_snippet_options() }
" Try using the name without the description (abbr).
let snippet_dict.name = matchstr(line, '^snippet\s\+\zs\S\+')
" Fall back to using the name and description (abbr) combined.
" SnipMate snippets may have duplicate names, but different
" descriptions (abbrs).
let description = matchstr(line, '^snippet\s\+\zs.*$')
if description !=# snippet_dict.name
" Convert description.
let snippet_dict.name =
\ substitute(description, '\W\+', '_', 'g')
endif
" Collect the description (abbr) of the snippet, if set on snippet line.
" This is for compatibility with SnipMate-style snippets.
let snippet_dict.abbr = matchstr(line, '^snippet\s\+\S\+\s\+\zs.*$')
" Check for duplicated names.
if has_key(dup_check, snippet_dict.name)
let dup = dup_check[snippet_dict.name]
call neosnippet#util#print_error(printf(
\ 'Warning: %s:%d is overriding `%s` from %s:%d',
\ a:snippets_file, linenr, snippet_dict.name,
\ dup.action__path, dup.action__line))
call neosnippet#util#print_error(printf(
\ 'Please rename the snippet name or use `delete %s`.',
\ snippet_dict.name))
endif
elseif !empty(snippet_dict) elseif !empty(snippet_dict)
" Allow overriding/setting of the description (abbr) of the snippet. if line =~ '^\s'
" This will override what was set via the snippet line.
if line =~ '^abbr\s'
let snippet_dict.abbr = matchstr(line, '^abbr\s\+\zs.*$')
elseif line =~ '^alias\s'
let snippet_dict.alias = split(matchstr(line,
\ '^alias\s\+\zs.*$'), '[,[:space:]]\+')
elseif line =~ '^prev_word\s'
let prev_word = matchstr(line,
\ '^prev_word\s\+[''"]\zs.*\ze[''"]$')
if prev_word == '^'
" For backward compatibility.
let snippet_dict.options.head = 1
else
call neosnippet#util#print_error(
\ 'prev_word must be "^" character.')
endif
elseif line =~ '^options\s\+'
for option in split(matchstr(line,
\ '^options\s\+\zs.*$'), '[,[:space:]]\+')
if !has_key(snippet_dict.options, option)
call neosnippet#util#print_error(
\ printf('invalid option name : %s is detected.', option))
else
let snippet_dict.options[option] = 1
endif
endfor
elseif line =~ '^\s'
if snippet_dict.word != '' if snippet_dict.word != ''
let snippet_dict.word .= "\n" let snippet_dict.word .= "\n"
else else
@ -431,6 +381,8 @@ function! s:parse_snippets_file(snippets, snippets_file)"{{{
elseif line =~ '^$' elseif line =~ '^$'
" Blank line. " Blank line.
let snippet_dict.word .= "\n" let snippet_dict.word .= "\n"
else
call s:add_snippet_attribute(line, linenr, snippet_dict)
endif endif
endif endif
@ -446,6 +398,80 @@ function! s:parse_snippets_file(snippets, snippets_file)"{{{
return a:snippets return a:snippets
endfunction"}}} endfunction"}}}
function! s:parse_snippet_name(line, linenr, dup_check)"{{{
" Initialize snippet dict.
let snippet_dict = { 'word' : '', 'linenr' : a:linenr,
\ 'options' : s:initialize_snippet_options() }
" Try using the name without the description (abbr).
let snippet_dict.name = matchstr(a:line, '^snippet\s\+\zs\S\+')
" Fall back to using the name and description (abbr) combined.
" SnipMate snippets may have duplicate names, but different
" descriptions (abbrs).
let description = matchstr(a:line, '^snippet\s\+\zs.*$')
if description !=# snippet_dict.name
" Convert description.
let snippet_dict.name =
\ substitute(description, '\W\+', '_', 'g')
endif
" Collect the description (abbr) of the snippet, if set on snippet line.
" This is for compatibility with SnipMate-style snippets.
let snippet_dict.abbr = matchstr(a:line,
\ '^snippet\s\+\S\+\s\+\zs.*$')
" Check for duplicated names.
if has_key(a:dup_check, snippet_dict.name)
let dup = a:dup_check[snippet_dict.name]
call neosnippet#util#print_error(printf(
\ 'Warning: %s:%d is overriding `%s` from %s:%d',
\ a:snippets_file, linenr, snippet_dict.name,
\ dup.action__path, dup.action__line))
call neosnippet#util#print_error(printf(
\ 'Please rename the snippet name or use `delete %s`.',
\ snippet_dict.name))
endif
return snippet_dict
endfunction"}}}
function! s:add_snippet_attribute(line, linenr, snippet_dict)"{{{
" Allow overriding/setting of the description (abbr) of the snippet.
" This will override what was set via the snippet line.
if a:line =~ '^abbr\s'
let a:snippet_dict.abbr = matchstr(a:line, '^abbr\s\+\zs.*$')
elseif a:line =~ '^alias\s'
let a:snippet_dict.alias = split(matchstr(a:line,
\ '^alias\s\+\zs.*$'), '[,[:space:]]\+')
elseif a:line =~ '^prev_word\s'
let prev_word = matchstr(a:line,
\ '^prev_word\s\+[''"]\zs.*\ze[''"]$')
if prev_word == '^'
" For backward compatibility.
let a:snippet_dict.options.head = 1
else
call neosnippet#util#print_error(
\ 'prev_word must be "^" character.')
endif
elseif a:line =~ '^regex\s'
let a:snippet_dict.regex = matchstr(a:line,
\ '^regex\s\+[''"]\zs.*\ze[''"]$')
elseif a:line =~ '^options\s\+'
for option in split(matchstr(a:line,
\ '^options\s\+\zs.*$'), '[,[:space:]]\+')
if !has_key(a:snippet_dict.options, option)
call neosnippet#util#print_error(
\ printf('Invalid option name : %s is detected.', option))
else
let a:snippet_dict.options[option] = 1
endif
endfor
else
call neosnippet#util#print_error(
\ printf('Invalid syntax : "%s" is detected.', a:line))
endif
endfunction"}}}
function! s:is_beginning_of_line(cur_text)"{{{ function! s:is_beginning_of_line(cur_text)"{{{
let keyword_pattern = '\S\+' let keyword_pattern = '\S\+'
let cur_keyword_str = matchstr(a:cur_text, keyword_pattern.'$') let cur_keyword_str = matchstr(a:cur_text, keyword_pattern.'$')

View File

@ -676,6 +676,7 @@ CHANGELOG *neosnippet-changelog*
2012-11-03 2012-11-03
- Refactored documentation. - Refactored documentation.
- Added :NeoSnippetSource. - Added :NeoSnippetSource.
- Refactored parse routine.
2012-11-02 2012-11-02
- Added g:neosnippet#enable_snipmate_compatibility option. - Added g:neosnippet#enable_snipmate_compatibility option.