2015-02-04 05:43:54 -05:00
|
|
|
describe 'snippet parser'
|
|
|
|
|
|
|
|
before
|
2024-10-06 04:25:50 -04:00
|
|
|
" two optional arguments:
|
|
|
|
" first one: whether or not to create the stop stubs
|
|
|
|
" second one: whether or not to return the stops
|
2015-02-04 05:43:54 -05:00
|
|
|
function! Parse(snippet, ...)
|
2016-06-11 09:56:50 -04:00
|
|
|
let [snip, stops] = snipmate#parse#snippet(a:snippet, (a:0 ? a:1 : 1))
|
|
|
|
return (a:0 > 1 && a:2) ? [snip, stops] : snip
|
2015-02-04 05:43:54 -05:00
|
|
|
endfunction
|
|
|
|
let b:snipmate_visual = 'testvisual'
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'parses numeric $id and ${id} vars as [id] lists'
|
2016-06-11 09:56:50 -04:00
|
|
|
let expect = [[[1234567890]]]
|
2015-02-04 05:43:54 -05:00
|
|
|
Expect Parse('$1234567890') == expect
|
|
|
|
Expect Parse('${1234567890}') == expect
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'disregards $ or ${ followed by a non-id'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse('$x1') == [['x1']]
|
|
|
|
Expect Parse('${x}1') == [['x}1']]
|
|
|
|
Expect Parse('$VISUA1') == [['VISUA1']]
|
|
|
|
Expect Parse('${VISUA}1') == [['VISUA}1']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'gathers references to each instance of each stop id'
|
2016-06-11 09:56:50 -04:00
|
|
|
let [snip, b:stops] = Parse('x$1x${2:x$1x}x$1x${1/a/b}x$VISUALx', 1, 1)
|
2015-02-04 05:43:54 -05:00
|
|
|
function! InstanceFound(list)
|
|
|
|
return !empty(filter(copy(b:stops[a:list[0]].instances),
|
|
|
|
\ 'v:val is a:list'))
|
|
|
|
endfunction
|
|
|
|
function! CheckList(list)
|
|
|
|
for item in a:list
|
|
|
|
if type(item) == type([])
|
|
|
|
Expect InstanceFound(item) to_be_true
|
|
|
|
call CheckList(item)
|
|
|
|
endif
|
|
|
|
unlet item " E732
|
|
|
|
endfor
|
|
|
|
endfunction
|
2016-06-11 09:56:50 -04:00
|
|
|
call CheckList(snip[0])
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'parses mirror substitutions ${n/pat/sub} as [n, {...}]'
|
2016-06-11 09:56:50 -04:00
|
|
|
let expect = [[[1, { 'pat' : 'abc', 'sub' : 'def' }]]]
|
2015-02-04 05:43:54 -05:00
|
|
|
Expect Parse('${1/abc/def}') == expect
|
2016-06-11 09:56:50 -04:00
|
|
|
let expect[0][0][1].flags = ''
|
2015-02-04 05:43:54 -05:00
|
|
|
Expect Parse('${1/abc/def/}') == expect
|
2016-06-11 09:56:50 -04:00
|
|
|
let expect[0][0][1].flags = 'g'
|
2015-02-04 05:43:54 -05:00
|
|
|
Expect Parse('${1/abc/def/g}') == expect
|
|
|
|
end
|
|
|
|
|
2016-06-11 09:56:50 -04:00
|
|
|
it 'reads patterns literally except for "\/"'
|
|
|
|
Expect Parse('${1/\a\/b/\c\/d\}}') == [[[1, { 'pat' : '\a/b', 'sub' : '\c/d}' }]]]
|
|
|
|
end
|
|
|
|
|
2015-02-04 05:43:54 -05:00
|
|
|
it 'parses vars with placeholders as [id, placeholder] lists'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse('${1:abc}') == [[[1, 'abc']]]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'evaluates backtick expressions'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse('`fnamemodify("x.y", ":r")`') == [['x']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'parses placeholders for vars and other specials'
|
|
|
|
let text = 'a `fnamemodify("x.y", ":r")` ${2:(${3/a/b})}'
|
|
|
|
let expect = ['a x ', [2, '(', [3, { 'pat' : 'a', 'sub' : 'b' }], ')']]
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse(text) == [expect]
|
|
|
|
Expect Parse(printf('${1:%s}', text)) == [[[1] + expect]]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
2016-04-12 04:31:09 -04:00
|
|
|
it 'converts tabs according to &et, &sts, &sw, &ts'
|
2015-02-04 05:43:54 -05:00
|
|
|
" &noet -> leave tabs alone
|
|
|
|
setl noet
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("abc\tdef\n\t\tghi") == [["abc\tdef"], ["\t\tghi"]]
|
2015-02-04 05:43:54 -05:00
|
|
|
|
|
|
|
" &et -> &sts or &sw
|
|
|
|
setl et sts=2 sw=3
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
|
2015-02-04 05:43:54 -05:00
|
|
|
|
|
|
|
setl et sts=0 sw=3
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
|
2015-02-04 05:43:54 -05:00
|
|
|
|
|
|
|
setl et sts=-1 sw=3
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
|
2016-04-12 04:31:09 -04:00
|
|
|
|
|
|
|
" See #227
|
|
|
|
if exists('*shiftwidth')
|
|
|
|
setl et sts=0 sw=0 ts=3
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("abc\tdef\n\t\tghi") == [["abc def"], [" ghi"]]
|
2016-04-12 04:31:09 -04:00
|
|
|
endif
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'parses backslashes as escaping the next character or joining lines'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse('x\x') == [['xx']]
|
|
|
|
Expect Parse('x\\x') == [['x\x']]
|
|
|
|
Expect Parse("x\\\nx") == [['xx']]
|
|
|
|
Expect Parse('x\$1') == [['x$1']]
|
|
|
|
Expect Parse('${1:\}}') == [[[1, '}']]]
|
|
|
|
Expect Parse('`fnamemodify("\`.x", ":r")`') == [['`']]
|
|
|
|
Expect Parse('\`x\`') == [['`x`']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'splits text at newlines'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("x\nx") == [['x'], ['x']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'joins evaluated expressions to surrounding text on the same line'
|
|
|
|
let g:foo = 'bar'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("x`g:foo`x") == [['xbarx']]
|
|
|
|
Expect Parse("x`g:foo`\nx") == [['xbar'], ['x']]
|
|
|
|
Expect Parse("x\n`g:foo`x") == [['x'], ['barx']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'expands $VISUAL placeholders with any indents'
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("x$VISUALx") == [['xtestvisualx']]
|
2015-02-04 05:43:54 -05:00
|
|
|
let b:snipmate_visual = " foo\nbar\n baz"
|
|
|
|
setl noet
|
2016-06-11 09:56:50 -04:00
|
|
|
Expect Parse("\tx\n\t$VISUAL\nx") == [["\tx"], ["\t foo"], ["\tbar"],
|
|
|
|
\ ["\t baz"], ["x"]]
|
|
|
|
end
|
|
|
|
|
2017-03-14 11:16:07 -04:00
|
|
|
it 'removes newlines from the end of VISUALs if before an end of line'
|
|
|
|
let b:snipmate_visual = "1\n2\n"
|
|
|
|
Expect Parse("x\n$VISUAL\nx") == [['x'], ['1'], ['2'], ['x']]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'splits the before and after a $VISUAL if it is multiline'
|
|
|
|
let b:snipmate_visual = "1\n2\n3"
|
|
|
|
Expect Parse("foo $VISUAL bar") == [['foo 1'], ['2'], ['3 bar']]
|
|
|
|
end
|
|
|
|
|
2016-06-11 09:56:50 -04:00
|
|
|
it 'determines which var with an id is the stop'
|
|
|
|
let [snip, stops] = Parse("$1$1$1", 0, 1)
|
|
|
|
Expect snip == [[[1, "", stops[1]], [1, {}], [1, {}]]]
|
|
|
|
|
|
|
|
let [snip, stops] = Parse("$1${1}$1", 0, 1)
|
|
|
|
Expect snip == [[[1, "", stops[1]], [1, {}], [1, {}]]]
|
|
|
|
|
|
|
|
let [snip, stops] = Parse("$1${1:}$1", 0, 1)
|
|
|
|
Expect snip == [[[1, {}], [1, "", stops[1]], [1, {}]]]
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'picks the first of many possible stops'
|
|
|
|
let [snip, stops] = Parse("$1${1:foo}${1:bar}", 0, 1)
|
|
|
|
Expect snip == [[[1, {}], [1, "foo", stops[1]], [1, {}]]]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'represents empty lines as an empty string'
|
|
|
|
Expect Parse("foo\n\nbar") == [['foo'], [''], ['bar']]
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|
|
|
|
|
2024-10-06 04:25:50 -04:00
|
|
|
it 'parses a selection as a special var named "select" with each item'
|
|
|
|
Expect Parse("${1|foo|bar|baz|select}") ==
|
|
|
|
\ [[[1, ['select', 'foo', 'bar', 'baz', 'select']]]]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'stores selection items in the var dictionary'
|
|
|
|
let [snip, stops] = Parse("${1|foo|bar|baz|select}", 0, 1)
|
|
|
|
Expect stops[1].items == ['foo', 'bar', 'baz', 'select']
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets a selections placeholder to the first item'
|
|
|
|
let [snip, stops] = Parse("${1|foo|bar|baz|select}", 0, 1)
|
|
|
|
Expect stops[1].placeholder == 'foo'
|
|
|
|
end
|
|
|
|
|
2015-02-04 05:43:54 -05:00
|
|
|
end
|