465 lines
12 KiB
VimL
465 lines
12 KiB
VimL
if exists( "g:__AL_XPT_SNIPFUNC_VIM__" ) && g:__AL_XPT_SNIPFUNC_VIM__ >= XPT#ver
|
|
finish
|
|
endif
|
|
let g:__AL_XPT_SNIPFUNC_VIM__ = XPT#ver
|
|
let s:oldcpo = &cpo
|
|
set cpo-=< cpo+=B
|
|
let s:log = xpt#debug#Logger( 'warn' )
|
|
let s:log = xpt#debug#Logger( 'debug' )
|
|
fun! xpt#snipfunc#Extend(container)
|
|
call extend( a:container, s:f, 'keep' )
|
|
endfunction
|
|
let s:f = {}
|
|
fun! s:f.Pre(a)
|
|
return a:a
|
|
endfunction
|
|
fun! s:f.SnipObject()
|
|
return self.phFilterContext isnot 0 ? self.phFilterContext.snipObject : self.renderContext.snipObject
|
|
endfunction
|
|
fun! s:f.PHs(snipText)
|
|
let so = self.SnipObject()
|
|
let slave = xpt#snip#NewSlave(so,a:snipText)
|
|
call xpt#snip#CompileAndParse(slave)
|
|
return slave.parsedSnip
|
|
endfunction
|
|
fun! s:f.Inline(snipText)
|
|
return { 'action' : 'embed', 'phs' : self.PHs( a:snipText ) }
|
|
endfunction
|
|
fun! s:f.Inc(targetName,keepCursor,params)
|
|
let so = self.SnipObject()
|
|
let snipDict = so.ftScope.allTemplates
|
|
if has_key(snipDict,a:targetName)
|
|
let tsnip = snipDict[a:targetName]
|
|
call xpt#snip#CompileAndParse(tsnip)
|
|
let phs = xpt#phfilter#Filter( tsnip, 'xpt#phfilter#ReplacePH', { 'replParams' : a:params } )
|
|
if !a:keepCursor
|
|
call xpt#snip#DumbCursorInPlace(tsnip,phs)
|
|
endif
|
|
call xpt#st#Merge(so.setting,tsnip.setting)
|
|
return { 'action' : 'embed', 'nIndent' : 0, 'phs' : phs }
|
|
else
|
|
return 0
|
|
endif
|
|
endfunction
|
|
fun! s:f.GetDict(...)
|
|
return
|
|
endfunction
|
|
fun! s:f.GetVar(name)
|
|
if a:name =~# '\V\^$_x'
|
|
let n = a:name[1 :]
|
|
if has_key(self,n)
|
|
return self[n]()
|
|
endif
|
|
endif
|
|
let varScopes = []
|
|
if has_key( self, 'evalContext' )
|
|
call add(varScopes,self.evalContext.variables)
|
|
endif
|
|
if has_key( self, 'renderContext' )
|
|
call add( varScopes, get( self.renderContext.snipSetting, 'variables', {} ) )
|
|
endif
|
|
call add(varScopes,self)
|
|
for sc in varScopes
|
|
let val = get(sc,a:name)
|
|
if val isnot 0
|
|
return val
|
|
endif
|
|
endfor
|
|
return a:name
|
|
endfunction
|
|
fun! s:f._xSnipName()
|
|
return self.renderContext.snipObject.name
|
|
endfunction
|
|
fun! s:f.EmbedWrappedText()
|
|
let wrapData = self.renderContext.userWrapped
|
|
if !has_key( wrapData, 'text' )
|
|
return 0
|
|
endif
|
|
let ph = self.phFilterContext.ph
|
|
if has_key( ph, 'isKey' )
|
|
let n = len(wrapData.lines)
|
|
let nIndent = self.phFilterContext.phEvalContext.pos[1] - self.phFilterContext.phEvalContext.nIndAdd
|
|
if self.phFilterContext.phEvalContext.pos[0] == 0
|
|
let nIndent += self.phFilterContext.phEvalContext.offset
|
|
endif
|
|
let sep = "\n"
|
|
let ph = extend(deepcopy(ph),{ 'name':'', 'value':1, }, 'force' )
|
|
unlet ph.isKey
|
|
let newPHs = []
|
|
let i = 0
|
|
while i < n
|
|
let newph = extend(deepcopy(ph),{ 'displayText':wrapData.lines[ i ], }, 'force' )
|
|
call extend(newPHs,[newph,sep])
|
|
let i += 1
|
|
endwhile
|
|
call remove(newPHs,-1)
|
|
return { 'action' : 'embed', 'nIndent' : nIndent, 'phs' : newPHs }
|
|
else
|
|
return { 'nIndent' : wrapData.indent, 'text':wrapData.text }
|
|
endif
|
|
endfunction
|
|
fun! s:f.WrapAlignAfter(min)
|
|
let userWrapped = self.renderContext.userWrapped
|
|
let n = max([a:min,userWrapped.max]) - len(userWrapped.curline)
|
|
return repeat( ' ', n )
|
|
endfunction
|
|
fun! s:f.WrapAlignBefore(min)
|
|
let userWrapped = self.renderContext.userWrapped
|
|
let n = max([a:min,userWrapped.max]) - len(userWrapped.lines[0])
|
|
return repeat( ' ', n )
|
|
endfunction
|
|
fun! s:f.Item()
|
|
return get( self.renderContext, 'item', {} )
|
|
endfunction
|
|
fun! s:f.ItemName()
|
|
return get( self.Item(), 'name', '' )
|
|
endfunction
|
|
fun! s:f.ItemFullname()
|
|
return get( self.Item(), 'fullname', '')
|
|
endfunction
|
|
fun! s:f.ItemValue() dict
|
|
return get( self.evalContext, 'userInput', '' )
|
|
endfunction
|
|
fun! s:f.PrevItem(n)
|
|
let hist = get( self.renderContext, 'history', [] )
|
|
return get(hist,a:n,{})
|
|
endfunction
|
|
fun! s:f.ItemInitValue()
|
|
return get( self.Item(), 'initValue', '' )
|
|
endfunction
|
|
fun! s:f.ItemInitValueWithEdge()
|
|
let [l,r] = self.ItemEdges()
|
|
return l . self.ItemInitValue() . r
|
|
endfunction
|
|
fun! s:f.ItemValueStripped(...)
|
|
let ptn = a:0 == 0 || a:1 =~ 'lr' ? '\V\^\s\*\|\s\*\$' : ( a:1 == 'l' ? '\V\^\s\*' : '\V\s\*\$' )
|
|
return substitute( self.ItemValue(), ptn, '', 'g' )
|
|
endfunction
|
|
fun! s:f.ItemPos()
|
|
return XPMposStartEnd(self.renderContext.leadingPlaceHolder.mark)
|
|
endfunction
|
|
fun! s:f.Vmatch(...)
|
|
let v = self.V()
|
|
for reg in a:000
|
|
if match(v,reg) != -1
|
|
return 1
|
|
endif
|
|
endfor
|
|
return 0
|
|
endfunction
|
|
fun! s:f.VMS(reg)
|
|
return matchstr(self.V(),a:reg)
|
|
endfunction
|
|
fun! s:f.ItemStrippedValue()
|
|
let v = self.V()
|
|
let [edgeLeft,edgeRight] = self.ItemEdges()
|
|
let v = substitute( v, '\V\^' . edgeLeft, '', '' )
|
|
let v = substitute( v, '\V' . edgeRight . '\$', '', '' )
|
|
return v
|
|
endfunction
|
|
fun! s:f.Phase() dict
|
|
return get( self.renderContext, 'phase', '' )
|
|
endfunction
|
|
fun! s:f.E(s)
|
|
return expand(a:s)
|
|
endfunction
|
|
fun! s:f.Context()
|
|
return self.renderContext
|
|
endfunction
|
|
fun! s:f.S(str,ptn,rep,...)
|
|
let flg = a:0 >= 1 ? a:1 : 'g'
|
|
return substitute(a:str,a:ptn,a:rep,flg)
|
|
endfunction
|
|
fun! s:f.SubstituteWithValue(ptn,rep,...)
|
|
let flg = a:0 >= 1 ? a:1 : 'g'
|
|
return substitute(self.V(),a:ptn,a:rep,flg)
|
|
endfunction
|
|
fun! s:f.HasStep(name)
|
|
let namedStep = get( self.renderContext, 'namedStep', {} )
|
|
return has_key(namedStep,a:name)
|
|
endfunction
|
|
fun! s:f.Reference(name)
|
|
let namedStep = get( self.renderContext, 'namedStep', {} )
|
|
return get( namedStep, a:name, '' )
|
|
endfunction
|
|
fun! s:f.Snippet(name)
|
|
return get( self.renderContext.ftScope.allTemplates, a:name, { 'tmpl' : '' } )[ 'tmpl' ]
|
|
endfunction
|
|
fun! s:f.Void(...)
|
|
return ""
|
|
endfunction
|
|
fun! s:f.Echo(...)
|
|
if a:0 > 0
|
|
return a:1
|
|
else
|
|
return ''
|
|
endif
|
|
endfunction
|
|
fun! s:f.EchoIf(isTrue,...)
|
|
if a:isTrue
|
|
return join( a:000, '' )
|
|
else
|
|
return self.V()
|
|
endif
|
|
endfunction
|
|
fun! s:f.EchoIfEq(expected,...)
|
|
if self.V() ==# a:expected
|
|
return join( a:000, '' )
|
|
else
|
|
return self.V()
|
|
endif
|
|
endfunction
|
|
fun! s:f.EchoIfNoChange(...)
|
|
if self.V0() ==# self.ItemName()
|
|
return join( a:000, '' )
|
|
else
|
|
return self.V()
|
|
endif
|
|
endfunction
|
|
fun! s:f.Commentize(text)
|
|
if has_key( self, '$CL' )
|
|
return self[ '$CL' ] . ' ' . a:text . ' ' . self[ '$CR' ]
|
|
elseif has_key( self, '$CS' )
|
|
return self[ '$CS' ] . ' ' . a:text
|
|
endif
|
|
return a:text
|
|
endfunction
|
|
fun! s:f.VoidLine()
|
|
return self.Commentize( 'void' )
|
|
endfunction
|
|
fun! s:f.Empty()
|
|
return self.ItemValue() == ''
|
|
endfunction
|
|
fun! s:f.IsChanged()
|
|
let initFull = self.ItemInitValueWithEdge()
|
|
let v = self.ItemValue()
|
|
return initFull !=# v
|
|
endfunction
|
|
fun! s:f.EmbedPHs(phsID)
|
|
let snipObject = self.renderContext.snipObject
|
|
return { 'action' : 'embed', 'phs':xpt#ftsc#GetPHPieces( snipObject.ftScope, a:phsID ) }
|
|
endfunction
|
|
fun! s:f.Build(...)
|
|
return { 'action' : 'build', 'text' : join( a:000, '' ) }
|
|
endfunction
|
|
fun! s:f.BuildIfChanged(...)
|
|
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
|
|
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
|
|
if v ==# fn || v == ''
|
|
return ''
|
|
else
|
|
return { 'action' : 'build', 'text' : join( a:000, '' ) }
|
|
endif
|
|
endfunction
|
|
fun! s:f.BuildIfNoChange(...)
|
|
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
|
|
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
|
|
if v ==# fn
|
|
return { 'action' : 'build', 'text' : join( a:000, '' ) }
|
|
else
|
|
return 0
|
|
endif
|
|
endfunction
|
|
fun! s:f.Trigger(name)
|
|
return {'action' : 'expandTmpl', 'tmplName' : a:name}
|
|
endfunction
|
|
fun! s:f.Finish(...)
|
|
return self.FinishPH( a:0 > 0 ? { 'text' : a:1 } : {} )
|
|
endfunction
|
|
fun! s:f.FinishOuter(...)
|
|
return self.FinishPH(a:0 > 0 ? { 'text' : a:1, 'marks' : 'mark' } : { 'marks' : 'mark' } )
|
|
endfunction
|
|
fun! s:f.FinishPH(opt)
|
|
let opt = a:opt
|
|
if empty(self.renderContext.groupList)
|
|
let o = { 'action' : g:XPTact.finishPH }
|
|
call extend( o, opt, 'keep' )
|
|
return o
|
|
else
|
|
return get( opt, 'text', 0 )
|
|
endif
|
|
endfunction
|
|
fun! s:f.Embed(snippetText)
|
|
return { 'action' : g:XPTact.embed, 'text' : a:snippetText }
|
|
endfunction
|
|
fun! s:f.Next(...)
|
|
let rst = { 'action' : 'next' }
|
|
if a:0 > 0
|
|
let phs = deepcopy(a:000)
|
|
call filter( phs, 'type(v:val)==' . type( '' ) )
|
|
if len(phs) < len(a:000)
|
|
let rst.phs = a:000
|
|
else
|
|
let text = join( a:000, '' )
|
|
let so = self.SnipObject()
|
|
if match(text,so.ptn.lft) >= 0
|
|
let rst.phs = self.PHs(text)
|
|
else
|
|
let rst.text = text
|
|
endif
|
|
endif
|
|
endif
|
|
return rst
|
|
endfunction
|
|
fun! s:f.Remove()
|
|
return { 'action' : 'remove' }
|
|
endfunction
|
|
fun! s:f.Choose(lst,...)
|
|
let val = { 'action' : 'pum', 'pum' : a:lst }
|
|
if a:0 == 1
|
|
let val.acceptEmpty = a:1 != 0
|
|
endif
|
|
return val
|
|
endfunction
|
|
fun! s:f.ChooseStr(...)
|
|
return copy(a:000)
|
|
endfunction
|
|
fun! s:f.Complete(key,...)
|
|
let val = { 'action' : 'complete', 'pum' : a:key }
|
|
if a:0 == 1
|
|
let val.acceptEmpty = a:1 != 0
|
|
endif
|
|
return val
|
|
endfunction
|
|
fun! s:f.xptFinishTemplateWith(postType) dict
|
|
endfunction
|
|
fun! s:f.xptFinishItemWith(postType) dict
|
|
endfunction
|
|
fun! s:f.UnescapeMarks(string) dict
|
|
let patterns = self.renderContext.snipObject.ptn
|
|
let charToEscape = '\(\[' . patterns.l . patterns.r . ']\)'
|
|
let r = substitute( a:string, '\v(\\*)\1\\?\V' . charToEscape, '\1\2', 'g')
|
|
return r
|
|
endfunction
|
|
fun! s:f.headerSymbol(...)
|
|
let h = expand('%:t')
|
|
let h = substitute(h, '\.', '_', 'g') " replace . with _
|
|
let h = substitute(h, '.', '\U\0', 'g') " make all characters upper case
|
|
return '__'.h.'__'
|
|
endfunction
|
|
fun! s:f.date(...)
|
|
return strftime( self.GetVar( '$DATE_FMT' ) )
|
|
endfunction
|
|
fun! s:f.datetime(...)
|
|
return strftime( self.GetVar( '$DATETIME_FMT' ) )
|
|
endfunction
|
|
fun! s:f.time(...)
|
|
return strftime( self.GetVar( '$TIME_FMT' ) )
|
|
endfunction
|
|
fun! s:f.file(...)
|
|
return expand("%:t")
|
|
endfunction
|
|
fun! s:f.fileRoot(...)
|
|
return expand("%:t:r")
|
|
endfunction
|
|
fun! s:f.fileExt(...)
|
|
return expand("%:t:e")
|
|
endfunction
|
|
fun! s:f.path(...)
|
|
return expand("%:p")
|
|
endfunction
|
|
fun! s:f.UpperCase(v)
|
|
return substitute(a:v, '.', '\u&', 'g')
|
|
endfunction
|
|
fun! s:f.LowerCase(v)
|
|
return substitute(a:v, '.', '\l&', 'g')
|
|
endfunction
|
|
fun! s:f.ItemEdges()
|
|
let leader = get( self.renderContext, 'leadingPlaceHolder', {} )
|
|
if has_key( leader, 'leftEdge' )
|
|
return [leader.leftEdge,leader.rightEdge]
|
|
else
|
|
return [ '', '' ]
|
|
endif
|
|
endfunction
|
|
fun! s:f.ItemCreate(name,edges,filters)
|
|
let [ml,mr] = XPTmark()
|
|
let item = ml . a:name
|
|
if has_key( a:edges, 'left' )
|
|
let item = ml . a:edges.left . item
|
|
endif
|
|
if has_key( a:edges, 'right' )
|
|
let item .= ml . a:edges.right
|
|
endif
|
|
let item .= mr
|
|
if has_key( a:filters, 'post' )
|
|
let item .= a:filters.post . mr . mr
|
|
endif
|
|
return item
|
|
endfunction
|
|
fun! s:f.ExpandIfNotEmpty(sep,item,...)
|
|
let v = self.V()
|
|
let [ml,mr] = XPTmark()
|
|
if a:0 != 0
|
|
let r = a:1
|
|
else
|
|
let r = ''
|
|
endif
|
|
let t = ( v == '' || v =~ '\V' . a:item ) ? '' : self.Build(v . ml . a:sep . ml . a:item . ml . r . mr . 'ExpandIfNotEmpty(' . string( a:sep ) . ', ' . string( a:item ) . ')' . mr . mr )
|
|
return t
|
|
endfunction
|
|
fun! s:f.ExpandInsideEdge(newLeftEdge,newRightEdge)
|
|
let v = self.V()
|
|
let fullname = self.ItemFullname()
|
|
let [el,er] = self.ItemEdges()
|
|
if v ==# fullname || v == ''
|
|
return ''
|
|
endif
|
|
return substitute( v, '\V' . er . '\$' , '' , '' ) . self.ItemCreate( self.ItemName(), { 'left' : a:newLeftEdge, 'right' : a:newRightEdge }, {} ) . er
|
|
endfunction
|
|
fun! s:f.NIndent()
|
|
return &shiftwidth
|
|
endfunction
|
|
fun! s:f.ResetIndent(nIndent,text)
|
|
return { 'action' : 'resetIndent', 'resetIndent':1, 'nIndent' : a:nIndent, 'text' : a:text }
|
|
endfunction
|
|
fun! s:f.CmplQuoter_pre() dict
|
|
if !g:xptemplate_brace_complete
|
|
return ''
|
|
endif
|
|
let v = substitute( self.ItemStrippedValue(), '\V\^\s\*', '', '' )
|
|
let first = matchstr( v, '\V\^\[''"]' )
|
|
if first == ''
|
|
return ''
|
|
endif
|
|
let v = substitute( v, '\V\[^' . first . ']', '', 'g' )
|
|
if v == first
|
|
return first
|
|
else
|
|
return ''
|
|
endif
|
|
endfunction
|
|
fun! s:f.AutoCmpl(keepInPost,list,...)
|
|
if !a:keepInPost && self.Phase() == 'post'
|
|
return ''
|
|
endif
|
|
if type(a:list) == type([])
|
|
let list = a:list
|
|
else
|
|
let list = [a:list] + a:000
|
|
endif
|
|
let v = self.V0()
|
|
if v == ''
|
|
return ''
|
|
endif
|
|
for word in list
|
|
if word =~ '\V\^' . v
|
|
return word[len(v) :]
|
|
endif
|
|
endfor
|
|
return ''
|
|
endfunction
|
|
let s:f.Edges = s:f.ItemEdges
|
|
let s:f.UE = s:f.UnescapeMarks
|
|
let s:f.VOID = s:f.Void
|
|
let s:f.R = s:f.Reference
|
|
let s:f.SV = s:f.SubstituteWithValue
|
|
let s:f.C = s:f.Context
|
|
let s:f.V0 = s:f.ItemStrippedValue
|
|
let s:f.IVE = s:f.ItemInitValueWithEdge
|
|
let s:f.VS = s:f.ItemValueStripped
|
|
let s:f.IV = s:f.ItemInitValue
|
|
let s:f.V = s:f.ItemValue
|
|
let s:f.NN = s:f.ItemFullname
|
|
let s:f.N = s:f.ItemName
|
|
let &cpo = s:oldcpo
|