I broke up with neovim....vim is my best friend now
This commit is contained in:
43
dot_vim/plugged/vim-vsnip/autoload/vsnip/snippet/node.vim
Normal file
43
dot_vim/plugged/vim-vsnip/autoload/vsnip/snippet/node.vim
Normal file
@@ -0,0 +1,43 @@
|
||||
let s:Placeholder = vsnip#snippet#node#placeholder#import()
|
||||
let s:Variable = vsnip#snippet#node#variable#import()
|
||||
let s:Text = vsnip#snippet#node#text#import()
|
||||
let s:Transform = vsnip#snippet#node#transform#import()
|
||||
|
||||
"
|
||||
" vsnip#snippet#node#create_from_ast
|
||||
"
|
||||
function! vsnip#snippet#node#create_from_ast(ast) abort
|
||||
if type(a:ast) == type([])
|
||||
return map(a:ast, 'vsnip#snippet#node#create_from_ast(v:val)')
|
||||
endif
|
||||
|
||||
if a:ast.type ==# 'placeholder'
|
||||
return s:Placeholder.new(a:ast)
|
||||
endif
|
||||
if a:ast.type ==# 'variable'
|
||||
return s:Variable.new(a:ast)
|
||||
endif
|
||||
if a:ast.type ==# 'text'
|
||||
return s:Text.new(a:ast)
|
||||
endif
|
||||
|
||||
throw 'vsnip: invalid node type'
|
||||
endfunction
|
||||
|
||||
"
|
||||
" vsnip#snippet#node#create_text
|
||||
"
|
||||
function! vsnip#snippet#node#create_text(text) abort
|
||||
return s:Text.new({
|
||||
\ 'type': 'text',
|
||||
\ 'raw': a:text,
|
||||
\ 'escaped': a:text
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
"
|
||||
" vsnip#snippet#node#create_transform
|
||||
"
|
||||
function! vsnip#snippet#node#create_transform(transform) abort
|
||||
return s:Transform.new(a:transform)
|
||||
endfunction
|
||||
@@ -0,0 +1,55 @@
|
||||
let s:max_tabstop = 1000000
|
||||
let s:uid = 0
|
||||
|
||||
function! vsnip#snippet#node#placeholder#import() abort
|
||||
return s:Placeholder
|
||||
endfunction
|
||||
|
||||
let s:Placeholder = {}
|
||||
|
||||
"
|
||||
" new.
|
||||
"
|
||||
function! s:Placeholder.new(ast) abort
|
||||
let s:uid += 1
|
||||
|
||||
let l:node = extend(deepcopy(s:Placeholder), {
|
||||
\ 'uid': s:uid,
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': a:ast.id,
|
||||
\ 'is_final': a:ast.id == 0,
|
||||
\ 'follower': v:false,
|
||||
\ 'choice': get(a:ast, 'choice', []),
|
||||
\ 'children': vsnip#snippet#node#create_from_ast(get(a:ast, 'children', [])),
|
||||
\ 'transform': vsnip#snippet#node#create_transform(get(a:ast, 'transform')),
|
||||
\ })
|
||||
|
||||
if l:node.is_final
|
||||
let l:node.id = s:max_tabstop
|
||||
endif
|
||||
|
||||
if len(l:node.children) == 0
|
||||
let l:node.children = [vsnip#snippet#node#create_text('')]
|
||||
endif
|
||||
|
||||
return l:node
|
||||
endfunction
|
||||
|
||||
"
|
||||
" text.
|
||||
"
|
||||
function! s:Placeholder.text() abort
|
||||
return join(map(copy(self.children), 'v:val.text()'), '')
|
||||
endfunction
|
||||
|
||||
"
|
||||
" to_string
|
||||
"
|
||||
function! s:Placeholder.to_string() abort
|
||||
return printf('%s(id=%s, follower=%s, choise=%s)',
|
||||
\ self.type,
|
||||
\ self.id,
|
||||
\ self.follower ? 'true' : 'false',
|
||||
\ self.choice
|
||||
\ )
|
||||
endfunction
|
||||
@@ -0,0 +1,38 @@
|
||||
let s:uid = 0
|
||||
|
||||
function! vsnip#snippet#node#text#import() abort
|
||||
return s:Text
|
||||
endfunction
|
||||
|
||||
let s:Text = {}
|
||||
|
||||
"
|
||||
" new.
|
||||
"
|
||||
function! s:Text.new(ast) abort
|
||||
let s:uid += 1
|
||||
|
||||
return extend(deepcopy(s:Text), {
|
||||
\ 'uid': s:uid,
|
||||
\ 'type': 'text',
|
||||
\ 'value': a:ast.escaped,
|
||||
\ 'children': [],
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
"
|
||||
" text.
|
||||
"
|
||||
function! s:Text.text() abort
|
||||
return self.value
|
||||
endfunction
|
||||
|
||||
"
|
||||
" to_string
|
||||
"
|
||||
function! s:Text.to_string() abort
|
||||
return printf('%s(%s)',
|
||||
\ self.type,
|
||||
\ self.value
|
||||
\ )
|
||||
endfunction
|
||||
@@ -0,0 +1,112 @@
|
||||
function! vsnip#snippet#node#transform#import() abort
|
||||
return s:Transform
|
||||
endfunction
|
||||
|
||||
let s:Transform = {}
|
||||
|
||||
"
|
||||
" new.
|
||||
"
|
||||
function! s:Transform.new(ast) abort
|
||||
let l:transform = empty(a:ast) ? {} : a:ast
|
||||
|
||||
let l:node = extend(deepcopy(s:Transform), {
|
||||
\ 'type': 'transform',
|
||||
\ 'regex': get(l:transform, 'regex', v:null),
|
||||
\ 'replacements': get(l:transform, 'format', []),
|
||||
\ 'options': get(l:transform, 'option', []),
|
||||
\ })
|
||||
|
||||
let l:node.is_noop = l:node.regex is v:null
|
||||
|
||||
return l:node
|
||||
endfunction
|
||||
|
||||
"
|
||||
" text.
|
||||
"
|
||||
function! s:Transform.text(input_text) abort
|
||||
if empty(a:input_text) || self.is_noop
|
||||
return a:input_text
|
||||
endif
|
||||
|
||||
if self.regex.pattern !=# '(.*)'
|
||||
" TODO: fully support regex
|
||||
return a:input_text
|
||||
endif
|
||||
|
||||
let l:text = ''
|
||||
|
||||
for l:replacement in self.replacements
|
||||
if l:replacement.type ==# 'format'
|
||||
if l:replacement.modifier ==# '/capitalize'
|
||||
let l:text .= s:capitalize(a:input_text)
|
||||
elseif l:replacement.modifier ==# '/downcase'
|
||||
let l:text .= s:downcase(a:input_text)
|
||||
elseif l:replacement.modifier ==# '/upcase'
|
||||
let l:text .= s:upcase(a:input_text)
|
||||
elseif l:replacement.modifier ==# '/camelcase'
|
||||
let l:text .= s:camelcase(a:input_text)
|
||||
elseif l:replacement.modifier ==# '/pascalcase'
|
||||
let l:text .= s:capitalize(s:camelcase(a:input_text))
|
||||
endif
|
||||
elseif l:replacement.type ==# 'text'
|
||||
let l:text .= l:replacement.escaped
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:text
|
||||
endfunction
|
||||
|
||||
"
|
||||
" to_string
|
||||
"
|
||||
function! s:Transform.to_string() abort
|
||||
if self.is_noop
|
||||
return
|
||||
end
|
||||
|
||||
return printf('%s(regex=%s, total_replacements=%s, options=%s)',
|
||||
\ self.type,
|
||||
\ get(self.regex, 'pattern', ''),
|
||||
\ len(self.replacements),
|
||||
\ join(self.options, ''),
|
||||
\ )
|
||||
endfunction
|
||||
|
||||
"
|
||||
" upcase
|
||||
"
|
||||
function! s:upcase(word) abort
|
||||
let word = toupper(a:word)
|
||||
return word
|
||||
endfunction
|
||||
|
||||
"
|
||||
" downcase
|
||||
"
|
||||
function! s:downcase(word) abort
|
||||
let word = tolower(a:word)
|
||||
return word
|
||||
endfunction
|
||||
|
||||
"
|
||||
" capitalize
|
||||
"
|
||||
function! s:capitalize(word) abort
|
||||
let word = s:upcase(strpart(a:word, 0, 1)) . strpart(a:word, 1)
|
||||
return word
|
||||
endfunction
|
||||
|
||||
"
|
||||
" camelcase
|
||||
" @see https://github.com/tpope/vim-abolish/blob/3f0c8faa/plugin/abolish.vim#L111-L118
|
||||
"
|
||||
function! s:camelcase(word) abort
|
||||
let word = substitute(a:word, '-', '_', 'g')
|
||||
if word !~# '_' && word =~# '\l'
|
||||
return substitute(word,'^.','\l&','')
|
||||
else
|
||||
return substitute(word,'\C\(_\)\=\(.\)','\=submatch(1)==""?tolower(submatch(2)) : toupper(submatch(2))','g')
|
||||
endif
|
||||
endfunction
|
||||
@@ -0,0 +1,63 @@
|
||||
let s:uid = 0
|
||||
|
||||
"
|
||||
" vsnip#snippet#node#variable#import
|
||||
"
|
||||
function! vsnip#snippet#node#variable#import() abort
|
||||
return s:Variable
|
||||
endfunction
|
||||
|
||||
let s:Variable = {}
|
||||
|
||||
"
|
||||
" new.
|
||||
"
|
||||
function! s:Variable.new(ast) abort
|
||||
let s:uid += 1
|
||||
|
||||
let l:resolver = vsnip#variable#get(a:ast.name)
|
||||
return extend(deepcopy(s:Variable), {
|
||||
\ 'uid': s:uid,
|
||||
\ 'type': 'variable',
|
||||
\ 'name': a:ast.name,
|
||||
\ 'unknown': empty(l:resolver),
|
||||
\ 'resolver': l:resolver,
|
||||
\ 'children': vsnip#snippet#node#create_from_ast(get(a:ast, 'children', [])),
|
||||
\ 'transform': vsnip#snippet#node#create_transform(get(a:ast, 'transform')),
|
||||
\ })
|
||||
endfunction
|
||||
|
||||
"
|
||||
" text.
|
||||
"
|
||||
function! s:Variable.text() abort
|
||||
return self.transform.text(join(map(copy(self.children), 'v:val.text()'), ''))
|
||||
endfunction
|
||||
|
||||
"
|
||||
" resolve.
|
||||
"
|
||||
function! s:Variable.resolve(context) abort
|
||||
if !self.unknown
|
||||
let l:resolved = self.transform.text(self.resolver.func({ 'node': self }))
|
||||
if l:resolved isnot v:null
|
||||
" Fix indent when one variable returns multiple lines
|
||||
let l:base_indent = vsnip#indent#get_base_indent(split(a:context.before_text, "\n", v:true)[-1])
|
||||
return substitute(l:resolved, "\n\\zs", l:base_indent, 'g')
|
||||
endif
|
||||
endif
|
||||
return v:null
|
||||
endfunction
|
||||
|
||||
"
|
||||
" to_string
|
||||
"
|
||||
function! s:Variable.to_string() abort
|
||||
return printf('%s(name=%s, unknown=%s, text=%s)',
|
||||
\ self.type,
|
||||
\ self.name,
|
||||
\ self.unknown ? 'true' : 'false',
|
||||
\ self.text()
|
||||
\ )
|
||||
endfunction
|
||||
|
||||
212
dot_vim/plugged/vim-vsnip/autoload/vsnip/snippet/parser.vim
Normal file
212
dot_vim/plugged/vim-vsnip/autoload/vsnip/snippet/parser.vim
Normal file
@@ -0,0 +1,212 @@
|
||||
let s:Combinator = vsnip#parser#combinator#import()
|
||||
|
||||
"
|
||||
" vsnip#snippet#parser#parse.
|
||||
" @see https://github.com/Microsoft/language-server-protocol/blob/master/snippetSyntax.md
|
||||
"
|
||||
function! vsnip#snippet#parser#parse(text) abort
|
||||
if strlen(a:text) == 0
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:parsed = s:parser.parse(a:text, 0)
|
||||
if !l:parsed[0]
|
||||
throw json_encode({ 'text': a:text, 'result': l:parsed })
|
||||
endif
|
||||
return l:parsed[1]
|
||||
endfunction
|
||||
|
||||
let s:skip = s:Combinator.skip
|
||||
let s:token = s:Combinator.token
|
||||
let s:many = s:Combinator.many
|
||||
let s:or = s:Combinator.or
|
||||
let s:seq = s:Combinator.seq
|
||||
let s:lazy = s:Combinator.lazy
|
||||
let s:option = s:Combinator.option
|
||||
let s:pattern = s:Combinator.pattern
|
||||
let s:map = s:Combinator.map
|
||||
|
||||
"
|
||||
" primitives.
|
||||
"
|
||||
let s:dollar = s:token('$')
|
||||
let s:open = s:token('{')
|
||||
let s:close = s:token('}')
|
||||
let s:colon = s:token(':')
|
||||
let s:slash = s:token('/')
|
||||
let s:comma = s:token(',')
|
||||
let s:pipe = s:token('|')
|
||||
let s:varname = s:pattern('[_[:alpha:]]\w*')
|
||||
let s:int = s:map(s:pattern('\d\+'), { value -> str2nr(value[0]) })
|
||||
let s:text = { stop, escape -> s:map(
|
||||
\ s:skip(stop, escape),
|
||||
\ { value -> {
|
||||
\ 'type': 'text',
|
||||
\ 'raw': value[0],
|
||||
\ 'escaped': value[1]
|
||||
\ }
|
||||
\ }) }
|
||||
let s:regex = s:map(s:text(['/'], []), { value -> {
|
||||
\ 'type': 'regex',
|
||||
\ 'pattern': value.raw
|
||||
\ } })
|
||||
|
||||
"
|
||||
" any (without text).
|
||||
"
|
||||
let s:any = s:or(
|
||||
\ s:lazy({ -> s:choice }),
|
||||
\ s:lazy({ -> s:variable }),
|
||||
\ s:lazy({ -> s:tabstop }),
|
||||
\ s:lazy({ -> s:placeholder }),
|
||||
\ )
|
||||
|
||||
"
|
||||
" format.
|
||||
"
|
||||
let s:format1 = s:map(s:seq(s:dollar, s:int), { value -> {
|
||||
\ 'type': 'format',
|
||||
\ 'id': value[1]
|
||||
\ } })
|
||||
let s:format2 = s:map(s:seq(s:dollar, s:open, s:int, s:close), { value -> {
|
||||
\ 'type': 'format',
|
||||
\ 'id': value[2]
|
||||
\ } })
|
||||
let s:format3 = s:map(
|
||||
\ s:seq(
|
||||
\ s:dollar,
|
||||
\ s:open,
|
||||
\ s:int,
|
||||
\ s:colon,
|
||||
\ s:or(
|
||||
\ s:token('/upcase'),
|
||||
\ s:token('/downcase'),
|
||||
\ s:token('/capitalize'),
|
||||
\ s:token('/camelcase'),
|
||||
\ s:token('/pascalcase'),
|
||||
\ s:token('+if'),
|
||||
\ s:token('?if:else'),
|
||||
\ s:token('-else'),
|
||||
\ s:token('else')
|
||||
\ ),
|
||||
\ s:close
|
||||
\ ), { value -> {
|
||||
\ 'type': 'format',
|
||||
\ 'id': value[2],
|
||||
\ 'modifier': value[4]
|
||||
\ } })
|
||||
let s:format = s:or(s:format1, s:format2, s:format3)
|
||||
|
||||
"
|
||||
" transform
|
||||
"
|
||||
let s:transform = s:map(s:seq(
|
||||
\ s:slash,
|
||||
\ s:regex,
|
||||
\ s:slash,
|
||||
\ s:many(s:or(s:format, s:text(['/', '$'], []))),
|
||||
\ s:slash,
|
||||
\ s:option(s:many(s:or(s:token('i'), s:token('g'))))
|
||||
\ ), { value -> {
|
||||
\ 'type': 'transform',
|
||||
\ 'regex': value[1],
|
||||
\ 'format': value[3],
|
||||
\ 'option': value[5]
|
||||
\ } })
|
||||
|
||||
"
|
||||
" variable
|
||||
"
|
||||
let s:variable1 = s:map(s:seq(s:dollar, s:varname), { value -> {
|
||||
\ 'type': 'variable',
|
||||
\ 'name': value[1],
|
||||
\ 'children': [],
|
||||
\ } })
|
||||
let s:variable2 = s:map(s:seq(s:dollar, s:open, s:varname, s:close), { value -> {
|
||||
\ 'type': 'variable',
|
||||
\ 'name': value[2],
|
||||
\ 'children': [],
|
||||
\ } })
|
||||
let s:variable3 = s:map(s:seq(
|
||||
\ s:dollar,
|
||||
\ s:open,
|
||||
\ s:varname,
|
||||
\ s:colon,
|
||||
\ s:many(s:or(s:any, s:text(['$', '}'], []))),
|
||||
\ s:close
|
||||
\ ), { value -> {
|
||||
\ 'type': 'variable',
|
||||
\ 'name': value[2],
|
||||
\ 'children': value[4]
|
||||
\ } })
|
||||
let s:variable4 = s:map(s:seq(s:dollar, s:open, s:varname, s:transform, s:close), { value -> {
|
||||
\ 'type': 'variable',
|
||||
\ 'name': value[2],
|
||||
\ 'transform': value[3],
|
||||
\ 'children': [],
|
||||
\ } })
|
||||
|
||||
let s:variable = s:or(s:variable1, s:variable2, s:variable3, s:variable4)
|
||||
|
||||
"
|
||||
" placeholder.
|
||||
"
|
||||
let s:placeholder = s:map(s:seq(
|
||||
\ s:dollar,
|
||||
\ s:open,
|
||||
\ s:int,
|
||||
\ s:colon,
|
||||
\ s:many(s:or(s:any, s:text(['$', '}'], []))),
|
||||
\ s:close
|
||||
\ ), { value -> {
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': value[2],
|
||||
\ 'children': value[4]
|
||||
\ } })
|
||||
|
||||
"
|
||||
" tabstop
|
||||
"
|
||||
let s:tabstop1 = s:map(s:seq(s:dollar, s:int), { value -> {
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': value[1],
|
||||
\ 'children': [],
|
||||
\ } })
|
||||
let s:tabstop2 = s:map(s:seq(s:dollar, s:open, s:int, s:option(s:colon), s:close), { value -> {
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': value[2],
|
||||
\ 'children': [],
|
||||
\ } })
|
||||
let s:tabstop3 = s:map(s:seq(s:dollar, s:open, s:int, s:transform, s:close), { value -> {
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': value[2],
|
||||
\ 'children': [],
|
||||
\ 'transform': value[3]
|
||||
\ } })
|
||||
let s:tabstop = s:or(s:tabstop1, s:tabstop2, s:tabstop3)
|
||||
|
||||
"
|
||||
" choice
|
||||
"
|
||||
let s:choice = s:map(s:seq(
|
||||
\ s:dollar,
|
||||
\ s:open,
|
||||
\ s:int,
|
||||
\ s:pipe,
|
||||
\ s:many(
|
||||
\ s:map(s:seq(s:text([',', '|'], []), s:option(s:comma)), { value -> value[0] }),
|
||||
\ ),
|
||||
\ s:pipe,
|
||||
\ s:close
|
||||
\ ), { value -> {
|
||||
\ 'type': 'placeholder',
|
||||
\ 'id': value[2],
|
||||
\ 'choice': value[4],
|
||||
\ 'children': [copy(value[4][0])],
|
||||
\ } })
|
||||
|
||||
"
|
||||
" parser.
|
||||
"
|
||||
let s:parser = s:many(s:or(s:any, s:text(['$'], ['}'])))
|
||||
|
||||
Reference in New Issue
Block a user