582 lines
18 KiB
VimL
582 lines
18 KiB
VimL
exec xpt#once#init
|
|
let s:oldcpo = &cpo
|
|
set cpo-=< cpo+=B
|
|
let s:log = xpt#debug#Logger( 'debug' )
|
|
exe XPT#importConst
|
|
let s:KEYTYPE_MAP = { '.':'onfocus', '.def':'onfocus', '.ontype':'live', '.onchange':'live', }
|
|
let s:KEYTYPE_TO_DICT = { 'pre':'preValues', 'live':'liveFilters', 'onfocus':'onfocusFilters', }
|
|
runtime plugin/xptemplate.vim
|
|
fun s:CompileSnippetFile(fn)
|
|
if a:fn =~ '\V.xpt.vimc\$' || !filereadable( a:fn )
|
|
return
|
|
endif
|
|
let lines = readfile(a:fn)
|
|
let lines = xpt#parser#Compact(lines)
|
|
let lines = xpt#parser#CompileCompacted(lines)
|
|
call writefile( lines, a:fn . 'c' )
|
|
endfunction
|
|
fun! xpt#parser#Compile(fn)
|
|
let compiledFn = a:fn . 'c'
|
|
let ctime = getftime(a:fn)
|
|
if !filereadable(compiledFn) || getftime(compiledFn) < ctime || g:xptemplate_always_compile
|
|
call s:CompileSnippetFile(a:fn)
|
|
else
|
|
endif
|
|
endfunction
|
|
fun! xpt#parser#Compact(lines)
|
|
let compacted = []
|
|
let iSnipPart = match( a:lines, '\V\^XPT\s' )
|
|
if iSnipPart < 0
|
|
let iSnipPart = len(a:lines)
|
|
endif
|
|
let [i,len] = [0 - 1,iSnipPart - 1]
|
|
while i < len | let i += 1
|
|
let l = a:lines[i]
|
|
if l != '' && l !~ '\v^"[^"]*$'
|
|
call add(compacted,l)
|
|
endif
|
|
endwhile
|
|
let [s,e,lastNonblank] = [-1,-1,100000]
|
|
let [i,len] = [iSnipPart - 1,len(a:lines) - 1]
|
|
while i < len | let i += 1
|
|
let l = a:lines[i]
|
|
if l == '' || l =~ '\v^"[^"]*$'
|
|
let lastNonblank = min([lastNonblank,i - 1])
|
|
continue
|
|
endif
|
|
if l =~# '\V\^..XPT\>'
|
|
if s == -1
|
|
let [s,e,lastNonblank] = [-1,-1,100000]
|
|
continue
|
|
else
|
|
let compacted += a:lines[s : i - 1]
|
|
let [s,e,lastNonblank] = [-1,-1,100000]
|
|
endif
|
|
elseif l =~# '\V\^XPT\>'
|
|
if s == -1
|
|
let [s,lastNonblank] = [i,i]
|
|
else
|
|
let e = min([i - 1,lastNonblank])
|
|
let compacted += a:lines[s : e]
|
|
let [s,e,lastNonblank] = [i,-1,100000]
|
|
endif
|
|
else
|
|
let lastNonblank = i
|
|
endif
|
|
endwhile
|
|
if s != -1
|
|
let compacted += a:lines[s : min([lastNonblank,i])]
|
|
endif
|
|
return compacted
|
|
endfunction
|
|
fun! xpt#parser#CompileCompacted(lines)
|
|
let rst = []
|
|
let lines = a:lines
|
|
let iSnipPart = match( lines, '\V\^XPT\s' )
|
|
if iSnipPart < 0
|
|
return lines
|
|
endif
|
|
if iSnipPart > 0
|
|
let rst += lines[: iSnipPart - 1]
|
|
let lines = lines[iSnipPart :]
|
|
endif
|
|
let [i,len] = [0,len(lines)]
|
|
call xpt#indent#IndentToTab(lines)
|
|
let s = i
|
|
while i < len-1 | let i += 1
|
|
let v = lines[i]
|
|
if v =~# '\V\^XPT\>'
|
|
let ll = xpt#parser#CompileSnippet(lines[s : i - 1])
|
|
let rst += [ll]
|
|
let s = i
|
|
elseif v =~# '\V\^\\XPT'
|
|
let lines[i] = v[1 :]
|
|
endif
|
|
endwhile
|
|
if i >= s
|
|
let ll = xpt#parser#CompileSnippet(lines[s : i])
|
|
let rst += [ll]
|
|
endif
|
|
return rst
|
|
endfunction
|
|
fun! xpt#parser#CompileSnippet(lines)
|
|
let lines = a:lines
|
|
let snippetLines = []
|
|
let setting = xpt#st#New()
|
|
let l0 = lines[0]
|
|
let pos = match( l0, '\VXPT\s\+\S\+\.\{-}\zs\s' . s:nonEscaped . '"' )
|
|
if pos >= 0
|
|
let [setting.rawHint, lines[0]] = [ matchstr( l0[ pos + 1 + 1 : ], '\v\S.*' ), l0[ : pos ] ]
|
|
endif
|
|
let [ x, snippetName; snippetParameters ] = split(lines[0], '\V'.s:nonEscaped.'\s\+')
|
|
for pair in snippetParameters
|
|
let name = matchstr(pair, '\V\^\[^=]\*')
|
|
let value = pair[len(name) :]
|
|
let value = value[0:0] == '=' ? xpt#util#UnescapeChar(value[1:], ' ') : 1
|
|
let setting[name] = value
|
|
endfor
|
|
let start = 1
|
|
let len = len(lines)
|
|
while start < len
|
|
let command = matchstr( lines[ start ], '\V\^XSETm\?\ze\s' )
|
|
if command != ''
|
|
let [key,val,start] = s:GetXSETkeyAndValue(lines,start)
|
|
if key == ''
|
|
let start += 1
|
|
continue
|
|
endif
|
|
let [keyname,keytype] = xpt#parser#GetKeyType(key)
|
|
call s:HandleXSETcommand(setting,command,[keyname,keytype,val])
|
|
elseif lines[start] =~# '^\\XSET' " escaped XSET or XSETm
|
|
let snippetLines += [lines[start][1:]]
|
|
else
|
|
call add(snippetLines,lines[start])
|
|
endif
|
|
let start += 1
|
|
endwhile
|
|
call xpt#st#Simplify(setting)
|
|
if has_key( setting, 'alias' )
|
|
return printf( 'call XPTemplateAlias(%s,%s,%s)', string(snippetName),string(setting.alias),string(setting))
|
|
else
|
|
return printf( 'call XPTdefineSnippet(%s,%s,%s)', string(snippetName),string(setting),string(snippetLines))
|
|
endif
|
|
endfunction
|
|
fun! xpt#parser#Include(...)
|
|
call xpt#parser#Load(a:000,1)
|
|
endfunction
|
|
fun! xpt#parser#Embed(...)
|
|
call xpt#parser#Load(a:000,0)
|
|
endfunction
|
|
fun! xpt#parser#Load(fns,inherit)
|
|
let scope = b:xptemplateData.snipFileScope
|
|
let ftscope = b:xptemplateData.filetypes[scope.filetype]
|
|
let saved_inherit = scope.inheritFT
|
|
let scope.inheritFT = a:inherit
|
|
let fns = xpt#util#Flatten(a:fns)
|
|
for f in fns
|
|
if a:inherit && xpt#ftscope#IsSnippetLoaded(ftscope,f)
|
|
continue
|
|
endif
|
|
call xpt#snipfile#Push()
|
|
exe 'runtime! ftplugin/' . f . '.xpt.vim'
|
|
call xpt#snipfile#Pop()
|
|
endfor
|
|
let scope.inheritFT = saved_inherit
|
|
endfunction
|
|
fun! xpt#parser#SetVar(nameSpaceValue)
|
|
let x = b:xptemplateData
|
|
let ftScope = x.filetypes[x.snipFileScope.filetype]
|
|
let name = matchstr(a:nameSpaceValue, '^\S\+\ze')
|
|
if name == ''
|
|
return
|
|
endif
|
|
let val = matchstr(a:nameSpaceValue, '\s\+\zs.*')
|
|
if val =~ '^''.*''$'
|
|
let val = val[1:-2]
|
|
else
|
|
let val = substitute( val, '\\ ', " ", 'g' )
|
|
endif
|
|
let val = substitute( val, '\\n', "\n", 'g' )
|
|
let priority = x.snipFileScope.priority
|
|
if !has_key(ftScope.varPriority,name) || priority <= ftScope.varPriority[name]
|
|
let [ftScope.funcs[name],ftScope.varPriority[name]] = [val,priority]
|
|
endif
|
|
endfunction
|
|
fun! xpt#parser#SnipSet(dictNameValue)
|
|
let x = b:xptemplateData
|
|
let snipScope = x.snipFileScope
|
|
let [ dict, nameValue ] = split( a:dictNameValue, '\V.', 1 )
|
|
let name = matchstr( nameValue, '^.\{-}\ze=' )
|
|
let value = nameValue[len(name) + 1 :]
|
|
let snipScope[dict][name] = value
|
|
endfunction
|
|
fun! xpt#parser#loadSpecialFiletype(ft)
|
|
let x = b:xptemplateData
|
|
let ft = a:ft
|
|
if has_key(x.filetypes,ft)
|
|
return
|
|
endif
|
|
if ft == 'unknown'
|
|
call xpt#parser#loadSnippetFile( 'unknown/unknown' )
|
|
else
|
|
call xpt#parser#InitSnippetFile( '~~/xpt/pseudo/ftplugin/' . ft . '/' . ft . '.xpt.vim' )
|
|
call XPTinclude( '_common/common' )
|
|
call XPTfiletypeInit()
|
|
endif
|
|
call XPTparseSnippets()
|
|
endfunction
|
|
fun! xpt#parser#loadSnippetFile(rel_snip)
|
|
exe 'runtime! ftplugin/' . a:rel_snip . '.xpt.vim'
|
|
call XPTfiletypeInit()
|
|
endfunction
|
|
fun! s:AssignSnipFT(filename)
|
|
let x = b:xptemplateData
|
|
let filename = substitute( a:filename, '\\', '/', 'g' )
|
|
if filename =~ 'unknown.xpt.vim$'
|
|
return 'unknown'
|
|
endif
|
|
let ftFolder = matchstr( filename, '\V/ftplugin/\zs\[^\\]\+\ze/' )
|
|
if empty(x.snipFileScopeStack)
|
|
if filename =~ '\V\<pseudo\>/'
|
|
return ftFolder
|
|
endif
|
|
if &filetype =~ '\<' . ftFolder . '\>' " sub type like 'xpt.vim'
|
|
let ft = &filetype
|
|
else
|
|
let ft = 'not allowed'
|
|
endif
|
|
else
|
|
if x.snipFileScopeStack[-1].inheritFT || ftFolder =~ '\V\^_'
|
|
if !has_key( x.snipFileScopeStack[ -1 ], 'filetype' )
|
|
throw 'parent may has no XPTemplate command called :' . a:filename
|
|
endif
|
|
let ft = x.snipFileScopeStack[-1].filetype
|
|
else
|
|
let ft = ftFolder
|
|
endif
|
|
endif
|
|
return ft
|
|
endfunction
|
|
fun! xpt#parser#InitSnippetFile(filename,...)
|
|
if ! xpt#option#lib_filter#Match(a:filename)
|
|
return 'finish'
|
|
endif
|
|
if !exists("b:xptemplateData")
|
|
call XPTemplateInit()
|
|
endif
|
|
let x = b:xptemplateData
|
|
let filetypes = x.filetypes
|
|
let snipScope = xpt#snipfile#New(a:filename)
|
|
let snipScope.filetype = s:AssignSnipFT(a:filename)
|
|
let x.snipFileScope = snipScope
|
|
let ft = snipScope.filetype
|
|
if ft == 'not allowed'
|
|
call s:log.Info( "not allowed:" . a:filename )
|
|
return 'finish'
|
|
endif
|
|
if ! has_key(filetypes,ft)
|
|
let filetypes[ft] = xpt#ftscope#New()
|
|
endif
|
|
let ftScope = filetypes[ft]
|
|
if xpt#ftscope#CheckAndSetSnippetLoaded(ftScope,a:filename)
|
|
return 'finish'
|
|
endif
|
|
for pair in a:000
|
|
let kv = split( pair, '=', 1 )
|
|
let key = kv[0]
|
|
let val = join( kv[ 1 : ], '=' )
|
|
if key =~ 'prio\%[rity]'
|
|
call XPTemplatePriority(val)
|
|
elseif key =~ 'mark'
|
|
call XPTemplateMark(val[0 : 0],val[1 : 1])
|
|
elseif key =~ 'key\%[word]'
|
|
call XPTemplateKeyword(val)
|
|
endif
|
|
endfor
|
|
return 'doit'
|
|
endfunction
|
|
fun! xpt#parser#SnippetFileInit_for_compiled(filename,...)
|
|
if !filereadable(a:filename)
|
|
return call( function( 'xpt#parser#InitSnippetFile' ), [ a:filename ] + a:000 )
|
|
endif
|
|
if a:filename =~ '\V.xpt.vim\$'
|
|
call xpt#parser#Compile(a:filename)
|
|
exe 'so' a:filename . 'c'
|
|
return 'finish'
|
|
else
|
|
return call( function( 'xpt#parser#InitSnippetFile' ), [ a:filename ] + a:000 )
|
|
endif
|
|
endfunction
|
|
fun! xpt#parser#LoadSnippets()
|
|
let fts = split( &filetype, '\V.', 1 )
|
|
call filter( fts, 'v:val!=""' )
|
|
for ft in fts
|
|
call xpt#parser#LoadFTSnippets(ft)
|
|
endfor
|
|
endfunction
|
|
fun! s:RTP()
|
|
let rtps = split( &runtimepath, ',' )
|
|
call filter( rtps, 'v:val!=""' )
|
|
let rtps += [ g:XPT_PATH . '/xptsnippets', g:XPT_PATH . '/personal' ]
|
|
let rtpath = join( rtps, ',' )
|
|
return rtpath
|
|
endfunction
|
|
fun! xpt#parser#LoadFtDetectors(ft)
|
|
let namePattern = a:ft =~ '/' ? a:ft : a:ft . '/*'
|
|
let rtpath = s:RTP()
|
|
let ftdetectfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.ftdetect.vim' ), "\n" )
|
|
for fn in ftdetectfiles
|
|
exe 'so' fn
|
|
endfor
|
|
endfunction
|
|
fun! xpt#parser#LoadFTSnippets(ft)
|
|
let namePattern = a:ft =~ '/' ? a:ft : a:ft . '/*'
|
|
let rtpath = s:RTP()
|
|
let ftdetectfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.ftdetect.vim' ), "\n" )
|
|
for fn in ftdetectfiles
|
|
exe 'so' fn
|
|
endfor
|
|
let snipfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.xpt.vim' ), "\n" )
|
|
for fn in snipfiles
|
|
let compiled = fn . 'c'
|
|
if !filereadable(compiled) || getftime(compiled) < getftime(fn) || g:xptemplate_always_compile
|
|
call xpt#parser#Compile(fn)
|
|
exe 'so' compiled
|
|
endif
|
|
endfor
|
|
endfunction
|
|
fun! xpt#parser#GetKeyType(rawKey)
|
|
let keytype = matchstr(a:rawKey, '\V'.s:nonEscaped.'|\zs\.\{-}\$')
|
|
if keytype == ""
|
|
let keytype = matchstr(a:rawKey, '\V'.s:nonEscaped.'.\zs\.\{-}\$')
|
|
endif
|
|
let keyname = keytype == "" ? a:rawKey : a:rawKey[ 0 : - len(keytype) - 2 ]
|
|
let keyname = substitute(keyname, '\V\\\(\[.|\\]\)', '\1', 'g')
|
|
return [keyname,keytype]
|
|
endfunction
|
|
let s:KEY_NAME = 0
|
|
let s:KEY_TYPE = 1
|
|
let s:VALUE = 2
|
|
let s:stHandler = {}
|
|
fun! s:stHandler.ComeFirst(setting,cmdArgs)
|
|
let a:setting.comeFirst = xpt#util#SplitWith( a:cmdArgs[ s:VALUE ], ' ' )
|
|
endfunction
|
|
fun! s:stHandler.ComeLast(setting,cmdArgs)
|
|
let a:setting.comeLast = xpt#util#SplitWith( a:cmdArgs[ s:VALUE ], ' ' )
|
|
endfunction
|
|
fun! s:stHandler.postQuoter(setting,cmdArgs)
|
|
let pq = split( a:cmdArgs[ s:VALUE ], ',' )
|
|
let a:setting.postQuoter = { 'start' : pq[0], 'end' : pq[1] }
|
|
endfunction
|
|
let s:stHandler.PostQuoter = s:stHandler.postQuoter
|
|
let s:keytypeHandler = {}
|
|
fun! s:keytypeHandler.repl(setting,cmdArgs)
|
|
let a:setting.replacements[a:cmdArgs[s:KEY_NAME]] = a:cmdArgs[s:VALUE]
|
|
endfunction
|
|
fun! s:keytypeHandler.map(setting,cmdArgs)
|
|
let [kn,kt,val] = a:cmdArgs
|
|
let mp = a:setting.mappings
|
|
if !has_key(mp,kn)
|
|
let mp[ kn ] = { 'saver' : xpt#msvr#New( 1 ), 'keys' : {} }
|
|
endif
|
|
let key = matchstr( val, '\V\^\S\+\ze\s' )
|
|
let mapping = matchstr( val, '\V\s\+\zs\.\*' )
|
|
call xpt#msvr#Add( mp[ kn ].saver, 'i', key )
|
|
let mp[kn].keys[key] = xpt#flt#NewSimple(0,mapping)
|
|
endfunction
|
|
fun! s:keytypeHandler.post(setting,cmdArgs)
|
|
let [kn,kt,val] = a:cmdArgs
|
|
let val = xpt#ph#AlterFilterByPHName(kn,val)
|
|
let a:setting.postFilters[kn] = xpt#flt#NewSimple(0,val)
|
|
endfunction
|
|
fun! s:HandleXSETcommand(setting,command,cmdArgs)
|
|
let [kn,kt,val] = a:cmdArgs
|
|
let kt = get( s:KEYTYPE_MAP, '.' . kt, kt )
|
|
let fcon = {}
|
|
if has_key(s:stHandler,kn)
|
|
let fcon.f = s:stHandler[kn]
|
|
call fcon.f(a:setting,[kn,kt,val])
|
|
elseif has_key(s:KEYTYPE_TO_DICT,kt)
|
|
let dicName = s:KEYTYPE_TO_DICT[kt]
|
|
let a:setting[dicName][kn] = xpt#flt#NewSimple(0,val)
|
|
elseif kn =~ '\V\^$'
|
|
let a:setting.variables[kn] = val
|
|
elseif has_key(s:keytypeHandler,kt)
|
|
let fcon.f = s:keytypeHandler[kt]
|
|
call fcon.f(a:setting,[kn,kt,val])
|
|
else
|
|
throw "unknown key name or type:" . kn . ' ' . kt
|
|
endif
|
|
endfunction
|
|
fun! xpt#parser#LoadSnippetToParseList(fn)
|
|
let lines = readfile(a:fn)
|
|
let i = match( lines, '\V\^XPTemplateDef' )
|
|
if i == -1
|
|
let i = match( lines, '\V\^XPT\s' ) - 1
|
|
endif
|
|
if i < 0
|
|
return
|
|
endif
|
|
let lines = lines[i :]
|
|
let x = b:xptemplateData
|
|
let x.snippetToParse += [ { 'snipFileScope' : x.snipFileScope, 'lines' : lines } ]
|
|
endfunction
|
|
fun! xpt#parser#ParseSnippet(p)
|
|
call xpt#snipfile#Push()
|
|
let x = b:xptemplateData
|
|
let x.snipFileScope = a:p.snipFileScope
|
|
let lines = a:p.lines
|
|
let [i,len] = [0,len(lines)]
|
|
let [s,e,blk] = [-1,-1,10000]
|
|
while i < len-1 | let i += 1
|
|
let v = lines[i]
|
|
if v =~ '^\s*$' || v =~ '^"[^"]*$'
|
|
let blk = min([blk,i - 1])
|
|
continue
|
|
endif
|
|
if v =~# '^\.\.XPT'
|
|
let e = i - 1
|
|
call s:XPTemplateParseSnippet(lines[s : e])
|
|
let [s,e,blk] = [-1,-1,10000]
|
|
elseif v =~# '^XPT\>'
|
|
if s != -1
|
|
let e = min([i - 1,blk])
|
|
call s:XPTemplateParseSnippet(lines[s : e])
|
|
let [s,e,blk] = [i,-1,10000]
|
|
else
|
|
let s = i
|
|
let blk = i
|
|
endif
|
|
elseif v =~# '^\\XPT'
|
|
let lines[i] = v[1 :]
|
|
else
|
|
let blk = i
|
|
endif
|
|
endwhile
|
|
if s != -1
|
|
call s:XPTemplateParseSnippet(lines[s : min([blk,i])])
|
|
endif
|
|
call xpt#snipfile#Pop()
|
|
endfunction
|
|
fun! s:XPTemplateParseSnippet(lines)
|
|
let lines = a:lines
|
|
let snipScope = XPTsnipScope()
|
|
let snipScope.loadedSnip = get( snipScope, 'loadedSnip', {} )
|
|
let snippetLines = []
|
|
let setting = deepcopy(g:XPTemplateSettingPrototype)
|
|
let [hint,lines[0]] = s:GetSnipCommentHint(lines[0])
|
|
if hint != ''
|
|
let setting.rawHint = hint
|
|
endif
|
|
let snippetParameters = split(lines[0], '\V'.s:nonEscaped.'\s\+')
|
|
let snippetName = snippetParameters[1]
|
|
let snippetParameters = snippetParameters[2:]
|
|
for pair in snippetParameters
|
|
let name = matchstr(pair, '\V\^\[^=]\*')
|
|
let value = pair[len(name) :]
|
|
let value = value[0:0] == '=' ? xpt#util#UnescapeChar(value[1:], ' ') : 1
|
|
let setting[name] = value
|
|
endfor
|
|
let start = 1
|
|
let len = len(lines)
|
|
while start < len
|
|
let command = matchstr( lines[ start ], '\V\^XSETm\?\ze\s' )
|
|
if command != ''
|
|
let [key,val,start] = s:GetXSETkeyAndValue(lines,start)
|
|
if key == ''
|
|
let start += 1
|
|
continue
|
|
endif
|
|
let [keyname,keytype] = xpt#parser#GetKeyType(key)
|
|
call s:HandleXSETcommandOld(setting,command,keyname,keytype,val)
|
|
elseif lines[start] =~# '^\\XSET' " escaped XSET or XSETm
|
|
let snippetLines += [lines[start][1:]]
|
|
else
|
|
let snippetLines += [lines[start]]
|
|
endif
|
|
let start += 1
|
|
endwhile
|
|
let setting.fromXPT = 1
|
|
if has_key( setting, 'alias' )
|
|
call XPTemplateAlias(snippetName,setting.alias,setting)
|
|
else
|
|
call XPTdefineSnippet(snippetName,setting,snippetLines)
|
|
endif
|
|
if has_key(snipScope.loadedSnip,snippetName)
|
|
call XPT#info( "XPT: warn : duplicate snippet:" . snippetName . ' in file:' . snipScope.filename )
|
|
endif
|
|
let snipScope.loadedSnip[snippetName] = 1
|
|
if has_key( setting, 'synonym' )
|
|
let synonyms = split( setting.synonym, '|' )
|
|
for synonym in synonyms
|
|
call XPTemplateAlias(synonym,snippetName,{})
|
|
if has_key(snipScope.loadedSnip,synonym)
|
|
call XPT#warn( "XPT: warn : duplicate synonym:" . synonym . ' in file:' . snipScope.filename )
|
|
endif
|
|
let snipScope.loadedSnip[synonym] = 1
|
|
endfor
|
|
endif
|
|
endfunction
|
|
fun! s:GetSnipCommentHint(str)
|
|
let pos = match(a:str, '\V' . s:nonEscaped . '\shint=')
|
|
if pos != -1
|
|
return [a:str[pos + 6 :],a:str[: pos - 1]]
|
|
endif
|
|
let pos = match( a:str, '\VXPT\s\+\S\+\.\{-}\zs\s' . s:nonEscaped . '"' )
|
|
if pos == -1
|
|
return [ '', a:str ]
|
|
else
|
|
return [ matchstr( a:str[ pos + 1 + 1 : ], '\S.*' ), a:str[ : pos ] ]
|
|
endif
|
|
endfunction
|
|
fun! s:GetXSETkeyAndValue(lines,start)
|
|
let start = a:start
|
|
let XSETparam = matchstr(a:lines[start], '\V\^XSET\%[m]\s\+\zs\.\*')
|
|
let isMultiLine = a:lines[ start ] =~# '\V\^XSETm'
|
|
if isMultiLine
|
|
let key = XSETparam
|
|
let [start,val] = s:ParseMultiLineValues(a:lines,start)
|
|
else
|
|
let key = matchstr(XSETparam, '\V\[^=]\*\ze=')
|
|
if key == ''
|
|
return [ '', '', start + 1 ]
|
|
endif
|
|
let val = matchstr(XSETparam, '\V=\s\*\zs\.\*')
|
|
let val = substitute(val, '\\n', "\n", 'g')
|
|
endif
|
|
return [key,val,start]
|
|
endfunction
|
|
fun! s:ParseMultiLineValues(lines,start)
|
|
let lines = a:lines
|
|
let start = a:start
|
|
let endPattern = '\V\^XSETm\s\+END\$'
|
|
let start += 1
|
|
let multiLineValues = []
|
|
while start < len(lines)
|
|
let line = lines[start]
|
|
if line =~# endPattern
|
|
break
|
|
endif
|
|
if line =~# '^\V\\\+XSET\%[m]'
|
|
let slashes = matchstr( line, '^\\\+' )
|
|
let nrSlashes = len(slashes + 1) / 2
|
|
let line = line[nrSlashes :]
|
|
endif
|
|
let multiLineValues += [line]
|
|
let start += 1
|
|
endwhile
|
|
let val = join(multiLineValues, "\n")
|
|
return [start,val]
|
|
endfunction
|
|
fun! s:HandleXSETcommandOld(setting,command,keyname,keytype,value)
|
|
if a:keyname ==# 'ComeFirst'
|
|
let a:setting.comeFirst = xpt#util#SplitWith( a:value, ' ' )
|
|
elseif a:keyname ==# 'ComeLast'
|
|
let a:setting.comeLast = xpt#util#SplitWith( a:value, ' ' )
|
|
elseif a:keyname ==# 'postQuoter'
|
|
let a:setting.postQuoter = a:value
|
|
elseif a:keyname =~ '\V\^$'
|
|
let a:setting.variables[a:keyname] = a:value
|
|
elseif a:keytype == "" || a:keytype ==# 'def'
|
|
let a:setting.defaultValues[a:keyname] = xpt#flt#New(0,a:value)
|
|
elseif a:keytype ==# 'map'
|
|
let a:setting.mappings[a:keyname] = get( a:setting.mappings, a:keyname, { 'saver' : xpt#msvr#New(1), 'keys' : {} } )
|
|
let key = matchstr( a:value, '\V\^\S\+\ze\s' )
|
|
let mapping = matchstr( a:value, '\V\s\+\zs\.\*' )
|
|
call xpt#msvr#Add( a:setting.mappings[ a:keyname ].saver, 'i', key )
|
|
let a:setting.mappings[a:keyname].keys[key] = xpt#flt#New(0,mapping)
|
|
elseif a:keytype ==# 'pre'
|
|
let a:setting.preValues[a:keyname] = xpt#flt#New(0,a:value)
|
|
elseif a:keytype ==# 'ontype'
|
|
let a:setting.ontypeFilters[a:keyname] = xpt#flt#New(0,a:value)
|
|
elseif a:keytype ==# 'post'
|
|
if a:keyname =~ '\V...'
|
|
let a:setting.postFilters[a:keyname] = xpt#flt#New( 0, 'BuildIfNoChange(' . string(a:value) . ')' )
|
|
else
|
|
let a:setting.postFilters[a:keyname] = xpt#flt#New(0,a:value)
|
|
endif
|
|
else
|
|
throw "unknown key name or type:" . a:keyname . ' ' . a:keytype
|
|
endif
|
|
endfunction
|
|
let &cpo = s:oldcpo
|