Commits

ZyX_I committed 08a6c14

@aurum/edit: *Cmd events are now nested
Added “requiresbvar” aurum://command option
@aurum/log: Some procinput improvements:
- Made it possible to create syntax before creating templatefunc, thus made it
possible to move some code to @aurum/edit
- Improved behavior after switching to another buffer while generating (change
shared with @aurum/edit)

  • Participants
  • Parent commits f3a2107

Comments (0)

Files changed (3)

File doc/aurum.txt

     0.1: Added :AuBranch and :AuName
 @aurum/edit:
     1.0: Removed setlines function (moved it to @aurum/repo)
+    1.1: Added “requiresbvar” _f.newcommand option
 @aurum/vimdiff:
     0.1: Added full, untracked, onlymodified and files options to |:AuVimDiff|
 @aurum/log:

File plugin/aurum/edit.vim

 "▶1
 scriptencoding utf-8
 if !exists('s:_pluginloaded')
-    execute frawor#Setup('1.0', {'@/autocommands': '0.0',
+    execute frawor#Setup('1.1', {'@/autocommands': '0.0',
                 \                   '@/functions': '0.0',
                 \                   '@/resources': '0.0',
                 \                   '@aurum/repo': '2.0',
     call FraworLoad('@/functions')
     let s:auefunc={}
     call s:_f.augroup.add('Aurum',
-                \[['BufReadCmd',   'aurum://*', 0, [s:auefunc,  0]],
-                \ ['FileReadCmd',  'aurum://*', 0, [s:auefunc,  1]],
-                \ ['SourceCmd',    'aurum://*', 0, [s:auefunc,  2]],
-                \ ['BufWriteCmd',  'aurum://*', 0, [s:auefunc, -1]],
-                \ ['FileWriteCmd', 'aurum://*', 0, [s:auefunc, -2]],
+                \[['BufReadCmd',   'aurum://*', 1, [s:auefunc,  0]],
+                \ ['FileReadCmd',  'aurum://*', 1, [s:auefunc,  1]],
+                \ ['SourceCmd',    'aurum://*', 1, [s:auefunc,  2]],
+                \ ['BufWriteCmd',  'aurum://*', 1, [s:auefunc, -1]],
+                \ ['FileWriteCmd', 'aurum://*', 1, [s:auefunc, -2]],
                 \])
     finish
 elseif s:_pluginloaded
     endfor
     return [repo]+strings+[opts]
 endfunction
-"▶1 runcmd
-function s:F.runcmd(cdescr, amatch, args)
-    let bvar=call(a:cdescr.function, a:args, {})
-    let buf=bufnr('%')
-    if has_key(s:_r.bufvars, buf) &&
-                \has_key(s:_r.bufvars[buf], 'prevbuf')
-        let bvar.prevbuf=s:_r.bufvars[buf].prevbuf
+"▶1 patchbvar
+function s:F.patchbvar(cdescr, amatch, args, bvar, buf)
+    if has_key(s:_r.bufvars, a:buf) &&
+                \has_key(s:_r.bufvars[a:buf], 'prevbuf')
+        let a:bvar.prevbuf=s:_r.bufvars[a:buf].prevbuf
     endif
-    if !get(a:cdescr, 'modifiable', 0)
-        setlocal buftype=nofile nomodifiable readonly
+    let a:bvar.amatch=a:amatch
+    let a:bvar.command=a:cdescr.id
+    let a:bvar.repo=a:args[1]
+    if has_key(a:cdescr, 'options')
+        let a:bvar.opts=a:args[-1]
     endif
-    let bvar.amatch=a:amatch
-    let bvar.command=a:cdescr.id
-    let bvar.repo=a:args[1]
-    if has_key(a:cdescr, 'options')
-        let bvar.opts=a:args[-1]
-    endif
-    let s:_r.bufvars[buf]=bvar
+    return a:bvar
+endfunction
+"▶1 setfiletype
+function s:F.setfiletype(cdescr)
     if has_key(a:cdescr, 'filetype')
         let &l:filetype=a:cdescr.filetype
         execute 'runtime! ftplugin/'.a:cdescr.filetype.'.vim'
     endif
+endfunction
+"▶1 runcmd
+function s:F.runcmd(cdescr, amatch, args)
+    let buf=bufnr('%')
+    if has_key(a:cdescr, 'write')
+        setlocal buftype=acwrite
+    else
+        setlocal buftype=nofile
+    endif
+    if get(a:cdescr, 'requiresbvar', 0)
+        let bvar=s:F.patchbvar(a:cdescr, a:amatch, a:args, {}, buf)
+        let args=a:args+[bvar]
+        let s:_r.bufvars[buf]=bvar
+        call s:F.setfiletype(a:cdescr)
+        call call(a:cdescr.function, args, {})
+    else
+        let bvar=call(a:cdescr.function, a:args, {})
+        call s:F.patchbvar(a:cdescr, a:amatch, a:args, bvar, buf)
+        let s:_r.bufvars[buf]=bvar
+        call s:F.setfiletype(a:cdescr)
+    endif
+    if bufnr('%')!=buf
+        return
+    endif
+    if !get(a:cdescr, 'modifiable', 0)
+        setlocal nomodifiable readonly
+    endif
     file
 endfunction
 "▶1 checkcmd :: command → _ + :throw?
         endif
         let cdescr[key]=a:cdescr[key]
     endfor
-    "▶2 Boolean keys: modifiable, sourceable
-    for key in ['modifiable', 'sourceable']
+    "▶2 Boolean keys: modifiable, sourceable, requiresbvar
+    for key in ['modifiable', 'sourceable', 'requiresbvar']
         if has_key(a:cdescr, key)
             if type(a:cdescr[key])!=type(0)
                 call s:_f.throw('nbl')

File plugin/aurum/log.vim

     execute frawor#Setup('0.2', {'@/table': '0.1',
                 \        '@aurum/cmdutils': '0.0',
                 \         '@aurum/bufvars': '0.0',
-                \            '@aurum/edit': '1.0',
+                \            '@aurum/edit': '1.1',
                 \                  '@/fwc': '0.3',
                 \            '@aurum/repo': '2.2',
                 \             '@/commands': '0.0',
             \'mapping_size':      0,
             \'skipchangesets':    {},
         \}
-function s:F.glog.graph_init(showparents, opts)
+function s:F.glog.graph_init(showparents, opts, repo)
     let graph=deepcopy(s:defgraph)
-    let graph.repo=a:opts.repo
+    let graph.repo=a:repo
     let graph.workcss=a:showparents
     let graph.skipchangesets=a:opts.skipchangesets
     call extend(graph, s:F.graph)
 " TODO Fix skipping changesets if possible
 let s:iterfuncs.git={}
 function s:iterfuncs.git.start(repo, opts, ...)
-    let graph=s:F.glog.graph_init(get(a:000, 0, []), a:opts)
-    return {'graph': graph, 'opts': a:opts}
+    let graph=s:F.glog.graph_init(get(a:000, 0, []), a:opts, a:repo)
+    return {'graph': graph, 'opts': a:opts, 'repo': a:repo}
 endfunction
 function s:iterfuncs.git.proccs(d, cs)
     if has_key(a:d.opts.skipchangesets, a:cs.hex)
         return [[], 0, 0]
     endif
-    let text=a:d.opts.templatefunc(a:cs, a:d.opts)
+    let text=a:d.opts.templatefunc(a:cs, a:d.opts, a:d.repo)
     let text.block_r=[[0, 0],
                 \     [len(text.text)-1,
                 \      max(map(copy(text.text), 'len(v:val)'))]]
 let s:iterfuncs.hg={}
 function s:iterfuncs.hg.start(repo, opts, ...)
     return {'seen': [], 'state': [0, 0], 'opts': a:opts,
-                \'showparents': get(a:000, 0, [])}
+                \'showparents': get(a:000, 0, []), 'repo': a:repo}
 endfunction
 function s:iterfuncs.hg.proccs(d, cs)
     let char=((index(a:d.showparents, a:cs.hex)==-1)?('o'):('@'))
         let text={'skip': 1}
         let skip=1
     else
-        let text=a:d.opts.templatefunc(a:cs, a:d.opts)
+        let text=a:d.opts.templatefunc(a:cs, a:d.opts, a:d.repo)
         let skip=0
     endif
     call s:F.glog.utf(a:d.state, 'C', char, text,
             \                                   '@<@, @0@)', ' to ']
 let s:kwmarg={}
 let s:kwmarg.summary='matchstr(a:cs.description, "\\\\v^[^\\n]*")'
-let s:kwmarg.stat='a:opts.repo.functions.getstats(a:opts.repo, diff, a:opts)'
+let s:kwmarg.stat='a:repo.functions.getstats(a:repo, diff, a:opts)'
 let s:kwmarg.patch='diff'
 let s:kwmarg.empty=''''''
 let s:kwpempt=['parents', 'children', 'tags', 'bookmarks']
         endif
         let astr=matchstr(s, '\v^\#(\\.|[^#])+\#')
         let arg=s:F.temp.parsearg(astr[1:-2])
+        let j=0
+        for a in s:kwexpr[kw][2:]
+            let a=get(arg, j, a)
+            if a is 0
+                call s:_f.throw('argmis', j, kw)
+            endif
+            let arg[j]=a
+            let j+=1
+        endfor
         if s:kwexpr[kw][0] && !empty(filter(lr[1:], 's:kwexpr[v:val[0]][0]'))
             call s:_f.throw('2multl')
         endif
     endfor
     return 0
 endfunction
+"▶2 temp.getcid
+function s:F.temp.getcid(template, opts)
+    let r=''
+    for o in ['patch', 'stat', 'showfiles', 'showrenames', 'showcopies']
+        let r.=get(a:opts, o, 0)
+    endfor
+    let r.=has_key(a:opts, 'files')
+    let r.=string(a:template)[2:-3]
+    return r
+endfunction
 "▶2 temp.compile :: template, opts → Fref
 let s:compilecache={}
-function s:F.temp.compile(template, opts)
+function s:F.temp.compile(template, opts, repo)
     "▶3 Cache
-    let cid=''
-    for o in ['patch', 'stat', 'showfiles', 'showrenames', 'showcopies']
-        let cid.=get(a:opts, o, 0)
-    endfor
-    let cid.=has_key(a:opts, 'files')
-    let cid.=string(a:template)[2:-3]
+    let cid=s:F.temp.getcid(a:template, a:opts)
     if has_key(s:compilecache, cid)
         return s:compilecache[cid]
     endif
     "▶3 Define variables
-    let func=['function d.template(cs, opts)',
+    let func=['function d.template(cs, opts, repo)',
                 \'let r={"text": [], "special": {}}',
                 \'let text=r.text',
                 \'let special=r.special',]
     if hasfiles
         let func+=['let files=a:opts.csfiles[a:cs.hex]']
     endif
-    let hasrevisions=get(a:opts.repo, 'hasrevisions', 1)
+    let hasrevisions=get(a:repo, 'hasrevisions', 1)
     if get(a:opts, 'patch', 0) || get(a:opts, 'stat', 0)
         let filesarg=((hasfiles && !has_key(a:opts.ignorefiles, 'patch'))?
                     \   ('files'):
                     \   ('[]'))
         let func+=['if !empty(a:cs.parents)',
-                    \'let diff=a:opts.repo.functions.diff(a:opts.repo, '.
-                    \                                    'a:cs.hex, '.
-                    \                                    'a:cs.parents[0], '.
-                    \                                     filesarg.', '.
-                    \                                    'a:opts)',
+                    \'let diff=a:repo.functions.diff(a:repo, '.
+                    \                               'a:cs.hex, '.
+                    \                               'a:cs.parents[0], '.
+                    \                                filesarg.', '.
+                    \                               'a:opts)',
                     \'endif']
     endif
     let reqs={}
                 endif
                 "▲4
                 let expr=substitute(expr, '@@@', marg, 'g')
-                "▶3 Get positional parameters if required
-                let j=0
-                for a in ke[2:]
-                    let s=get(arg, j, a)
-                    let arg[j]=s
-                    if s is 0
-                        call s:_f.throw('argmis', j, kw)
-                    endif
+                "▶3 Process positional parameters
+                for j in range(len(ke)-2)
                     let expr=substitute(expr, '@'.j.'@',
-                                \       escape(string(s), '&~\'), 'g')
-                    let j+=1
+                                \       escape(string(arg[j]), '&~\'), 'g')
                 endfor
                 "▶3 Skip meta if required
                 if kw is# 'rev' && !hasrevisions && arg.0 isnot# 'keep'
             \'%': '%',
         \}
 "▲3
-function s:F.temp.syntax(template, opts)
+function s:F.temp.syntax(template, opts, repo)
     "▶3 Cache
-    let cid=string(a:opts.templatefunc)[10:-3]
+    let cid=s:F.temp.getcid(a:template, a:opts)
     if has_key(s:syncache, cid)
         return s:syncache[cid]
     endif
     "▶3 Define variables
     let r=[]
     let topgroups=[]
-    let hasrevisions=get(a:opts.repo, 'hasrevisions', 1)
+    let hasrevisions=get(a:repo, 'hasrevisions', 1)
     "▲3
     let r+=['syn match auLogFirstLineStart =\v^[^ ]*[@o][^ ]* = '.
                 \'skipwhite nextgroup=']
     "▲3
     return 1
 endfunction
+"▶1 gettemplate :: bvar → + bvar
+function s:F.gettemplatelist(bvar)
+    if has_key(a:bvar, 'templatelist')
+        return
+    endif
+    if has_key(a:bvar.opts, 'template')
+        let template=eval(a:bvar.opts.template)
+    elseif has_key(a:bvar.opts, 'style')
+        let template=s:templates[a:bvar.opts.style]
+    else
+        let template=s:templates.default
+    endif
+    let a:bvar.templatelist=s:F.temp.parse(template)
+endfunction
 "▶1 setup
 "▶2 getkwreg
 function s:F.getkwreg(kw, nextlit)
     endif
 endfunction
 "▲2
-function s:F.setup(read, repo, opts)
+function s:F.setup(read, repo, opts, ...)
     let opts=a:opts
-    let bvar={}
+    let bvar=get(a:000, 0, {'opts': opts})
     "▶2 Add `ignorefiles'
     let ignorefiles=(has_key(opts, 'ignfiles')?
                 \               (opts.ignfiles):
                 \          ('changesets')))
     let csiterfuncs=a:repo.iterfuncs[csiterfuncsname]
     "▶2 Get template
-    if has_key(opts, 'template')
-        let template=eval(opts.template)
-    elseif has_key(opts, 'style')
-        let template=s:templates[opts.style]
-    else
-        let template=s:templates.default
-    endif
-    let opts.repo=a:repo
-    let bvar.templatelist=s:F.temp.parse(template)
-    let [opts.reqs, opts.templatefunc]=s:F.temp.compile(bvar.templatelist, opts)
+    call s:F.gettemplatelist(bvar)
+    let [opts.reqs, opts.templatefunc]=s:F.temp.compile(bvar.templatelist, opts,
+                \                                       a:repo)
     "▲2
     if !a:read
-        "▶ Required for setting syntax definitions and also for maps to work
-        " Is normally done by edit.vim, but in our case it is needed earlier
-        let bvar.opts=a:opts
-        let bvar.repo=a:repo
-        let s:_r.bufvars[bufnr('%')]=bvar
-        "▲
+        let buf=bufnr('%')
         let bvar.procinput=(has_key(a:opts, 'procinput')?
                     \           (2*a:opts.procinput):
                     \           s:_f.getoption('procinput'))
         if bvar.procinput==1 && getchar(1)
             let bvar.procinput=0
         endif
-        setlocal buftype=nofile filetype=aurumlog
         augroup AuLogNoInsert
             autocmd InsertEnter <buffer> :call feedkeys("\e", "n")
         augroup END
     let text=s:F.glog.graphlog(a:repo, opts, csiterfuncs, bvar, a:read)
     if a:read
         call s:_r.setlines(text, a:read)
-    else
+    elseif bufnr('%')==buf
         setlocal readonly nomodifiable
     endif
     return bvar
         return
     endif
     let bvar=s:_r.bufvars[buf]
-    let bvar.templatesyn=s:F.temp.syntax(bvar.templatelist, bvar.opts)
+    call s:F.gettemplatelist(bvar)
+    let bvar.templatesyn=s:F.temp.syntax(bvar.templatelist,bvar.opts,bvar.repo)
     for line in bvar.templatesyn
         execute line
     endfor
             \'\vrevrange\s+\Vtype "" type ""',
             \                         'revrange '.s:_r.comp.rev.' '.
             \                                     s:_r.comp.rev,            ''))
-"▶1 Post resource
+"▶1 Create aurum://log
 call s:_f.newcommand({
             \'function': s:F.setup,
             \ 'options': {'list': ['files', 'revrange', 'ignfiles'],
             \             'pats': ['files'],
             \            },
             \'filetype': 'aurumlog',
+            \'requiresbvar': 1,
             \})
 "▶1
 call frawor#Lockvar(s:, '_r,_pluginloaded,compilecache,parsecache,syncache')