Commits

ZyX_I committed 7dab100

More refactoring: move more code to tabutils from record

Comments (0)

Files changed (3)

autoload/aurum/record.vim

 "▶1 
 scriptencoding utf-8
-execute frawor#Setup('0.2', {'@/options': '0.0',
-            \                     '@/os': '0.0',
-            \               '@/mappings': '0.0',
-            \              '@/functions': '0.1',
-            \                    '@/fwc': '0.0',
-            \            '@%aurum/cache': '2.4',
-            \           '@%aurum/commit': '1.3',
-            \         '@%aurum/cmdutils': '4.3',
-            \         '@%aurum/tabutils': '0.0',
-            \        '@%aurum/lineutils': '0.0',
-            \             '@%aurum/edit': '1.5',
-            \             '@%aurum/undo': '1.0',
-            \          '@%aurum/bufvars': '0.0',})
-let s:_options={
-            \'recheight':    {'default': 0,
-            \                  'filter': '(if type "" earg _  range 0 inf)'},
-            \'recautowrite': {'default': 1,
-            \                  'filter': 'bool'},
-        \}
+execute frawor#Setup('0.2', {'@/os': '0.0',
+            \          '@/mappings': '0.0',
+            \         '@/functions': '0.1',
+            \               '@/fwc': '0.0',
+            \       '@%aurum/cache': '2.4',
+            \    '@%aurum/cmdutils': '4.3',
+            \    '@%aurum/tabutils': '1.0',
+            \   '@%aurum/lineutils': '0.0',
+            \        '@%aurum/edit': '1.5',
+            \        '@%aurum/undo': '1.0',
+            \     '@%aurum/bufvars': '0.0',})
 let s:_messages={
             \ 'bkpmis': 'Backup file %s not found',
             \'delfail': 'Failed to remove file %s',
             \ 'recnof': 'No files were selected for commiting',
             \   'norm': 'Can’t remove file %s as it was not added',
             \   'noad': 'Can’t add file %s as it is already included',
-            \ 'nsbvar': 'Internal error: sbvar key is present and sbuf '.
-            \           'is pointing to unknown buffer. If you can reproduce '.
-            \           'this file a bug report',
         \}
-"▶1 commitvimdiffcb
-function s:F.commitvimdiffcb(file, bvar, hex)
-    let [lwnr, rwnr, swnr]=s:F.getwnrs()
-
-    execute lwnr.'wincmd w'
-    let file=s:_r.os.path.join(a:bvar.repo.path, a:file)
-    let existed=bufexists(file)
-    execute 'silent edit' fnameescape(file)
-    if !existed
-        setlocal bufhidden=wipe
-    endif
-    diffthis
-
-    execute rwnr.'wincmd w'
-    let existed=s:_r.run('silent edit', 'file', a:bvar.repo, a:hex, a:file)
-    if !existed
-        setlocal bufhidden=wipe
-    endif
-    diffthis
-
-    execute lwnr.'wincmd w'
-endfunction
-"▶1 commitfindwindow
-function s:F.commitfindwindow()
-    let [lwnr, rwnr, swnr]=s:F.getwnrs()
-    execute lwnr.'wincmd w'
-    return 1
-endfunction
 "▶1 write
 function s:F.write(bvar)
     call feedkeys("\<C-\>\<C-n>:call ".
             endif
         endif
     endfor
-    let a:bvar.recopts.message = a:state.description
+    let a:bvar.copts.message = a:state.description
     call s:_r.undo.reset(a:bvar)
     call cursor(1, 1)
 endfunction
-"▶1 getswheight
-function s:F.getswheight()
-    let height=s:_f.getoption('recheight')
-    if height<=0
-        return (&lines-&cmdheight-(!!&laststatus))/5
-    endif
-    return height
-endfunction
 "▶1 run
 function s:F.run(cmd, opts, files, container)
     let files=copy(a:files)
     call s:_f.mapgroup.map('AuRecord', bufnr('%'))
     call extend(a:container, [state, repo])
 endfunction
+"▶1 _unload :: bvar
+function s:F._unload(bvar)
+    return s:_f.tab.unload(s:layoutname, a:bvar)
+endfunction
 "▶1 recfunc
 " TODO investigate why closing record tab is causing next character consumption
 "      under wine
     let bvar.filesbackup={}
     let bvar.newfiles={}
     let bvar.lines=map(copy(bvar.chars), 'v:val." ".bvar.files[v:key]')
-    let bvar.recopts=extend(copy(a:opts), {'repo': repo})
+    let bvar.copts=extend(copy(a:opts), {'repo': repo})
     let bvar.bufnr=bufnr('%')
     let bvar.oldbufs={}
-    let bvar.bwfunc=s:F.unload
+    let bvar.bwfunc=s:F._unload
     let bvar.switchwindow=s:F.switchwindow
     let bvar.openfiles=s:F.openfiles
     let bvar.foreignactions=s:foreignactions
     setglobal noautowrite noautowriteall noautoread
     setlocal noreadonly buftype=acwrite
     augroup AuRecordVimLeave
-        execute 'autocmd! VimLeave * '.
+        execute 'autocmd! VimLeave * nested '.
                     \   ':if has_key(s:_r.bufvars,'.bvar.bufnr.')'.
-                    \   '|  call s:F.unload(s:_r.bufvars.'.bvar.bufnr.')'.
+                    \   '|  call s:F._unload(s:_r.bufvars.'.bvar.bufnr.')'.
                     \   '|endif'
     augroup END
     if empty(bvar.chars)
         endif
     endif
 endfunction
-"▶1 tabunload
-function s:F.tabunload()
-    let [lwnr, rwnr, swnr]=s:F.getwnrs()
-    execute swnr.'wincmd w'
-    let bvar=s:_r.bufvars[bufnr('%')]
-    return s:F.unload(bvar)
-endfunction
 "▶1 unload
 function s:F.unload(bvar)
-    let sbvar=get(a:bvar, 'sbvar', a:bvar)
-    let sbuf=get(a:bvar, 'sbuf', -1)
-    if sbuf isnot 0 && bufexists(sbuf)
-        unlet sbvar.bwfunc
-        execute 'bwipeout!' sbuf
-    endif
-    for [o, val] in items(sbvar.savedopts)
-        execute 'let &g:'.o.'=val'
-    endfor
-    if bufexists(sbvar.bufnr)
-        call setbufvar(sbvar.bufnr, '&modified', 0)
-    endif
-    "▶2 Close tab
-    try
-        silent call s:_f.tab.close()
-    catch /\V\^Frawor:\[^:]\+:tidukn:/
-        if s:_f.tab.find(s:layoutname)
-            try
-                call s:_f.tab.close()
-            catch /\V\^Frawor:\[^:]\+:tidukn:/
-            endtry
-        endif
-    endtry
-    "▲2
-    let backupfiles=copy(sbvar.backupfiles)
-    let newfiles=copy(sbvar.newfiles)
+    let backupfiles=copy(a:bvar.backupfiles)
+    let newfiles=copy(a:bvar.newfiles)
     call filter(backupfiles, 'filereadable(v:key)')
     call filter(newfiles,    'filereadable(v:key)')
     call map(backupfiles, 's:F.restorebackup(v:val, v:key)')
     call map(newfiles,    's:F.restorebackup(v:key,   0  )')
-    for [buf, savedopts] in items(filter(sbvar.oldbufs, 'bufexists(v:key)'))
+    for [buf, savedopts] in items(filter(a:bvar.oldbufs, 'bufexists(v:key)'))
         for [opt, optval] in items(savedopts)
             call setbufvar(buf, '&'.opt, optval)
         endfor
 "▶1 register tab
 let s:layoutname='AuRecordTab'
 call s:_f.tab.new(s:layoutname, {
-            \   'top': ['AuRecordLeft', 'AuRecordRight'],
-            \'bottom': 'AuRecordStatus',
-        \}, s:F.getswheight, s:F.tabunload)
+            \    'top': ['AuRecordLeft', 'AuRecordRight'],
+            \ 'bottom': 'AuRecordStatus',
+            \'oprefix': 'rec',
+            \ 'unload': s:F.unload,
+        \})
 "▶1 edit
 let s:savedopts=['readonly', 'modifiable', 'scrollbind', 'cursorbind',
             \    'scrollopt', 'wrap', 'foldmethod', 'foldcolumn']
     endif
 endfunction
 let s:_augroups+=['AuRecordLeft']
-"▶1 srestore
-function s:F.srestore(bvar)
-    let sbuf=get(a:bvar, 'sbuf', -1)
-    "▶2 Check sbuf existence
-    if !bufexists(sbuf)
-        if has_key(a:bvar, 'sbvar')
-            return s:F.unload(a:bvar.sbvar)
-        elseif has_key(s:_r.bufvars, sbuf)
-            return s:F.unload(s:_r.bufvars[sbuf])
-        else
-            call s:_f.throw('nsbvar')
-        endif
-    endif
-    "▲2
-    let sbvar=a:bvar.sbvar
-    execute 'silent botright sbuffer' sbuf
-    execute 'resize' s:F.getswheight()
-    call winrestview(a:bvar.winview)
-    redraw!
-    let w:aurum_winid='AuRecordStatus'
-    setlocal bufhidden=wipe
-    return 1
-endfunction
 "▶1 restorefiles :: bvar, sline::UInt, eline::UInt → + FS
 function s:F.restorefiles(bvar, sline, eline)
     for file in map(range(a:sline, a:eline), 'a:bvar.lines[v:val-1][2:]')
 let s:F.sactions.vremove=s:F.sactions.remove
 "▶2 sactions.discard
 function s:F.sactions.discard(action, bvar, buf)
-    call s:F.unload(a:bvar)
+    call s:F._unload(a:bvar)
     return 0
 endfunction
 "▶2 sactions.undo
         endif
         execute lwnr.'wincmd w'
         call s:F.edit(a:bvar, 'aurum://edit:'.fullpath, 0)
-        if s:_f.getoption('recautowrite')
-            augroup AuRecordAutowrite
-                autocmd! BufLeave <buffer> nested write
-            augroup END
-        endif
+        call s:_f.tab.setautowrite()
         if a:bvar.undo_full
             let ebvar=s:_r.bufvars[bufnr('%')]
             let ebvar.undoleaf=undoleaf
     setlocal bufhidden=hide
     let winview=winsaveview()
     try
-        let r=s:_r.commit.commit(a:bvar.repo, a:bvar.recopts, files,
-                    \            a:bvar.status, keys(s:ntypes), 'silent edit',
-                    \            {'vimdiffcb':  s:F.commitvimdiffcb,
-                    \             'findwindow': s:F.commitfindwindow,
-                    \             'bwfunc':     s:F.srestore,
-                    \             'sbvar':      a:bvar,
-                    \             'sbuf':       a:buf,
-                    \             'winview':    winview,})
+        let r=s:_f.tab.copen(a:bvar, a:buf, s:ntypeskeys, {},
+                    \        a:bvar.status, files)
     finally
         if bufwinnr(a:buf)!=-1
             call setbufvar(a:buf, '&bufhidden', 'wipe')
         endif
     endtry
     if r
-        call s:F.unload(a:bvar)
+        call s:F._unload(a:bvar)
     endif
     return 0
 endfunction
             \'removed':  'r',
             \'deleted':  'r',
         \}
+let s:ntypeskeys=keys(s:ntypes)
 let s:uactions={
             \   'undo': 'undo',
             \   'redo': 'redo',

autoload/aurum/tabutils.vim

 "▶1 
 scriptencoding utf-8
-execute frawor#Setup('0.0', {})
+execute frawor#Setup('1.0', {'@/options': '0.0',
+            \                     '@/os': '0.0',
+            \             '@%aurum/edit': '1.0',
+            \          '@%aurum/bufvars': '0.0',
+            \           '@%aurum/commit': '1.3',})
 let s:_messages={
             \'tidnstr': 'Tab identifier must be a non-empty string',
             \'tidreg' : 'Tab identifier “%s” was already registered '.
             \           'by plugin %s',
             \'layinv' : "Invalid layout: it must\n".
             \           " - be a dictionary\n".
-            \           " - that has only “top” and “bottom” keys\n".
+            \           " - that has only “top”, “bottom”, “oprefix”, ".
+            \              "“unload” keys\n".
             \           " - with “top” key value being a non-empty ".
             \              "list of unique strings\n".
             \           " - and “bottom” key value being a string not present ".
-            \              "in “top” list",
-            \'bhfncal': 'botheightfun argument is not callable',
-            \'unlncal': 'unload argument is not callable',
+            \              "in “top” list\n".
+            \           " - ",
             \'tidukn' : 'Unknown tabid or tabid is not a string',
             \'botncal': 'botfun argument is not callable',
             \'barnlst': 'botargs argument is not a list',
             \  'tabex': 'There already is tab with id “%s”',
+            \ 'nsbvar': 'Internal error: sbvar key is present and sbuf '.
+            \           'is pointing to unknown buffer. If you can reproduce '.
+            \           'this file a bug report',
         \}
 let s:f={'cons': {}}
+"▶1 options
+let s:options={
+            \'height':    {'default': 0,
+            \               'filter': '(if type "" earg _  range 0 inf)'},
+            \'autowrite': {'default': 1,
+            \               'filter': 'bool'},
+        \}
+let s:_options={}
+"▶1 getswheight
+function s:F.getswheight(tabspec)
+    let height=s:_f.getoption(a:tabspec.oprefix . 'height')
+    if height<=0
+        return winheight(0)/5
+    endif
+    return height
+endfunction
 "▶1 getids
 function s:F.getids(layout)
     return a:layout.top + [a:layout.bottom]
 endfunction
-"▶1 f.cons.new :: {f}, tabid, layout, botheightfun, unload → + s:tabs, fdict
+"▶1 f.cons.new :: {f}, tabid, layout → + s:tabs, fdict
 let s:tabs={}
-function s:f.cons.new(plugdict, fdict, tabid, layout, botheightfun, unload)
+function s:f.cons.new(plugdict, fdict, tabid, tabdesc)
     "▶2 Check arguments
     if type(a:tabid)!=type('') || empty(a:tabid)
         call s:_f.throw('tidnstr')
     elseif has_key(s:tabs, a:tabid)
         call s:_f.throw('tidreg', a:tabid, s:tabs[a:tabid])
-    elseif          type(a:layout)!=type({})
-                \|| sort(keys(a:layout)) !=# ['bottom', 'top']
-                \|| type(a:layout.bottom)!=type('')
-                \|| type(a:layout.top)!=type([])
-                \|| empty(a:layout.top)
-                \|| !empty(filter(copy(a:layout.top), 'type(v:val)!='.type('')))
-                \|| !empty(filter(a:layout.top[1:],
-                \          'index(a:layout.top[:(v:key)], v:val)!=-1'))
-                \|| index(a:layout.top, a:layout.bottom)!=-1
+    elseif          type(a:tabdesc)!=type({})
+                \|| sort(keys(a:tabdesc)) !=#
+                \       ['bottom', 'oprefix', 'top', 'unload']
+                \|| type(a:tabdesc.bottom)!=type('')
+                \|| type(a:tabdesc.top)!=type([])
+                \|| empty(a:tabdesc.top)
+                \|| !empty(filter(copy(a:tabdesc.top),'type(v:val)!='.type('')))
+                \|| !empty(filter(a:tabdesc.top[1:],
+                \                 'index(a:tabdesc.top[:(v:key)], v:val)!=-1'))
+                \|| index(a:tabdesc.top, a:tabdesc.bottom)!=-1
+                \|| !exists('*a:tabdesc.unload')
+                \|| !(type(a:tabdesc.oprefix) == type(0)
+                \  || type(a:tabdesc.oprefix) == type(''))
         call s:_f.throw('layinv')
-    elseif !exists('*a:botheightfun')
-        call s:_f.throw('gshncal')
-    elseif !exists('*a:unload')
-        call s:_f.throw('unlncal')
     endif
     "▶2 tabdesc
     let a:fdict[a:tabid]={
-                \'layout': deepcopy(a:layout),
-                \'botheightfun': a:botheightfun,
-                \'unload': a:unload,
-                \'ids': s:F.getids(a:layout),
+                \'layout': {'bottom': a:tabdesc.bottom,
+                \              'top': copy(a:tabdesc.top),},
+                \'oprefix': a:tabdesc.oprefix,
+                \'unload': a:tabdesc.unload,
+                \'ids': s:F.getids(a:tabdesc),
                 \'id': a:tabid,
             \}
+    let oprefix=a:tabdesc.oprefix
+    let s:_options[oprefix.'height']=s:options.height
+    let s:_options[oprefix.'autowrite']=s:options.autowrite
     let s:tabs[a:tabid]=a:plugdict.id
 endfunction
 "▶1 settoplayout
                 \'extend(curids, {v:val[0]: v:val[1]})')
     return map(copy(a:ids), 'get(curids, v:val, 0)')
 endfunction
-"▶1 f.cons.getwnrs :: {f} → ([topid] + bottomids)
-function s:f.cons.getwnrs(plugdict, fdict)
+"▶1 getswnr
+function s:F.getswnr(tabspec)
+    return s:F.getwinnrs([a:tabspec.layout.bottom])[0]
+endfunction
+"▶1 getlwnr
+function s:F.getlwnr(tabspec)
+    return s:F.getwinnrs([a:tabspec.layout.top[0]])[0]
+endfunction
+"▶1 getlrwnrs
+function s:F.getlrwnrs(tabspec)
+    return s:F.getwinnrs(a:tabspec.layout.top[0:1])
+endfunction
+"▶1 tabunload :: {f}
+function s:F.tabunload(tabspec)
+    let swnr=s:F.getswnr(a:tabspec)
+    if !swnr
+        tabclose
+        return -1
+    endif
+    execute swnr.'wincmd w'
+    let bvar=s:_r.bufvars[bufnr('%')]
+    return a:tabspec.unload(bvar)
+endfunction
+"▶1 gettabspec :: fdict[, nothrow] → (tabid, tabspec)
+function s:F.gettabspec(fdict, ...)
     let tabid=gettabvar(tabpagenr(), 'aurum_tabid')
     "▶2 Check tabid
     if type(tabid)!=type('') || !has_key(a:fdict, tabid)
-        call s:_f.throw('tidukn')
+        if !a:0 || !a:1
+            call s:_f.throw('tidukn')
+        else
+            return [0, 0]
+        endif
     endif
     "▲2
     let tabspec=a:fdict[tabid]
+    return [tabid, tabspec]
+endfunction
+"▶1 f.cons.getwnrs :: {f} → ([topid] + bottomids)
+function s:f.cons.getwnrs(plugdict, fdict)
+    let [tabid, tabspec]=s:F.gettabspec(a:fdict)
     let ids=tabspec.ids
     let winnrs=s:F.getwinnrs(ids)
     if winnrs[0] is 0 || index(winnrs, 0)==-1
         topleft new
         call s:F.settoplayout(tabspec.layout)
         wincmd j
-        execute 'resize' call(tabspec.botheightfun, [], {})
+        execute 'resize' s:F.getswheight(tabspec)
         return s:F.getwinnrs(ids)
     endif
 endfunction
     setlocal bufhidden=wipe
     let t:aurum_tabid=tabspec.id
     call s:F.settoplayout(tabspec.layout)
-    let height=call(tabspec.botheightfun, [], {})
+    let height=s:F.getswheight(tabspec)
     call call(a:botfun, ['silent botright '.height.'split'] + a:botargs,
                 \{})
     setlocal bufhidden=wipe
     let w:aurum_winid=tabspec.layout.bottom
     let s:prevtabs[tabspec.id]=tabmark
 endfunction
-"▶1 f.cons.find :: {f}, tabid
-function s:f.cons.find(plugdict, fdict, tabid)
-    "▶2 Check argument
-    if type(a:tabid)!=type('') || !has_key(a:fdict, a:tabid)
-        call s:_f.throw('tidukn')
-    endif
-    "▲2
+"▶1 find :: tabid → tabnr + tab
+function s:F.find(tabid)
     for tabnr in range(1, tabpagenr('$'))
         if gettabvar(tabnr, 'aurum_tabid') is# a:tabid
             execute 'tabnext' tabnr
     endfor
     return 0
 endfunction
-"▶1 f.cons.close :: {f}
-function s:f.cons.close(plugdict, fdict)
-    let tabid=gettabvar(tabpagenr(), 'aurum_tabid')
-    "▶2 Check tabid
-    if type(tabid)!=type('') || !has_key(a:fdict, tabid)
-        call s:_f.throw('tidukn')
-    endif
-    "▲2
-    let tabspec=a:fdict[tabid]
+"▶1 close :: tabid, tabspec
+function s:F.close(tabid, tabspec)
     unlet t:aurum_tabid
     if tabpagenr('$')>1
         tabclose!
-        if has_key(s:prevtabs, tabid)
-            let tabmark=s:prevtabs[tabid]
+        if has_key(s:prevtabs, a:tabid)
+            let tabmark=s:prevtabs[a:tabid]
             let tabnr=index(map(range(1, tabpagenr('$')),
                         \       'gettabvar(v:val, "aurum_tabmark")'), tabmark)+1
             if tabnr
         while !empty(wlist)
             for wnr in wlist
                 call remove(wlist, 0)
-                if index(tabspec.ids, getwinvar(wnr, 'aurum_winid'))
+                if index(a:tabspec.ids, getwinvar(wnr, 'aurum_winid'))
                     execute wnr.'wincmd w'
                     if winnr('$')==1
                         unlet w:aurum_winid
             endfor
         endwhile
     endif
-    if has_key(s:prevtabs, tabid)
-        unlet s:prevtabs[tabid]
+    if has_key(s:prevtabs, a:tabid)
+        unlet s:prevtabs[a:tabid]
     endif
     return 1
 endfunction
+"▶1 f.cons.setautowrite :: {f}
+function s:f.cons.setautowrite(plugdict, fdict)
+    let [tabid, tabspec]=s:F.gettabspec(a:fdict)
+    if s:_f.getoption(tabspec.oprefix . 'autowrite')
+        augroup AuRecordAutowrite
+            autocmd! BufLeave <buffer> nested write
+        augroup END
+    endif
+endfunction
+"▶1 f.cons.restore :: {f}, bvar
+function s:f.cons.restore(plugdict, fdict, bvar)
+    let [tabid, tabspec]=s:F.gettabspec(a:fdict)
+    let sbuf=get(a:bvar, 'sbuf', -1)
+    "▶2 Check sbuf existence
+    if !bufexists(sbuf)
+        if has_key(a:bvar, 'sbvar')
+            return call(tabspec.unload, [a:bvar.sbvar], {})
+        elseif has_key(s:_r.bufvars, sbuf)
+            return call(tabspec.unload, [s:_r.bufvars[sbuf]], {})
+        else
+            call s:_f.throw('nsbvar')
+        endif
+    endif
+    "▲2
+    let sbvar=a:bvar.sbvar
+    execute 'silent botright sbuffer' sbuf
+    execute 'resize' s:F.getswheight(tabspec)
+    call winrestview(a:bvar.winview)
+    redraw!
+    let w:aurum_winid=tabspec.layout.bottom
+    setlocal bufhidden=wipe
+    return 1
+endfunction
+"▶1 commitvimdiffcb
+function s:F.commitvimdiffcb(file, bvar, hex)
+    let bvar=s:_r.bufvars[bufnr('%')]
+    let [tabid, tabspec]=s:F.gettabspec(a:bvar.fdict)
+    let [lwnr, rwnr]=s:F.getlrwnrs(tabspec)
+
+    execute lwnr.'wincmd w'
+    let file=s:_r.os.path.join(a:bvar.repo.path, a:file)
+    let existed=bufexists(file)
+    execute 'silent edit' fnameescape(file)
+    if !existed
+        setlocal bufhidden=wipe
+    endif
+    diffthis
+
+    execute rwnr.'wincmd w'
+    let existed=s:_r.run('silent edit', 'file', a:bvar.repo, a:hex, a:file)
+    if !existed
+        setlocal bufhidden=wipe
+    endif
+    diffthis
+
+    execute lwnr.'wincmd w'
+endfunction
+"▶1 commitfindwindow :: {f}
+function s:F.commitfindwindow()
+    let bvar=s:_r.bufvars[bufnr('%')]
+    let [tabid, tabspec]=s:F.gettabspec(bvar.fdict)
+    let lwnr=s:F.getlwnr(tabspec)
+    execute lwnr.'wincmd w'
+    return 1
+endfunction
+"▶1 f.cons.copen :: {f}, bvar, buf, keys, opts[, status[, files]]
+function s:f.cons.copen(plugdict, fdict, bvar, buf, keys, opts, ...)
+    if a:0
+        let status=a:1
+        if a:0>1
+            let files=a:2
+        else
+            let files=[]
+        endif
+    else
+        let status=a:bvar.repo.functions.status(a:bvar.repo)
+        let files=[]
+    endif
+    return s:_r.commit.commit(
+                \   a:bvar.repo,
+                \   a:bvar.copts,
+                \   files,
+                \   status,
+                \   a:keys,
+                \   'silent edit',
+                \   extend({
+                \       'vimdiffcb'  : s:F.commitvimdiffcb,
+                \       'findwindow' : s:F.commitfindwindow,
+                \       'bwfunc'     : a:plugdict.g._f.tab.restore,
+                \       'sbvar'      : a:bvar,
+                \       'sbuf'       : a:buf,
+                \       'winview'    : winsaveview(),
+                \       'fdict'      : a:fdict,
+                \   }, a:opts),
+                \)
+endfunction
+"▶1 f.cons.unload :: {f}
+function s:f.cons.unload(plugdict, fdict, tabid, bvar)
+    "▶2 Check argument
+    if type(a:tabid)!=type('') || !has_key(a:fdict, a:tabid)
+        call s:_f.throw('tidukn')
+    endif
+    "▲2
+    let [tabid, tabspec]=s:F.gettabspec(a:fdict, 1)
+    if tabid is 0
+        unlet tabspec
+        if s:F.find(a:tabid)
+            let [tabid, tabspec]=s:F.gettabspec(a:fdict, 1)
+        endif
+        if tabid is 0
+            return 1
+        endif
+    endif
+    let swnr=s:F.getswnr(tabspec)
+    if !swnr
+        let sbuf=0
+        let sbvar=get(a:bvar, 'sbvar', a:bvar)
+    else
+        let sbuf=winbufnr(swnr)
+        let sbvar=s:_r.bufvars[sbuf]
+    endif
+    call tabspec.unload(sbvar)
+    if sbuf isnot 0 && bufexists(sbuf)
+        unlet sbvar.bwfunc
+        execute 'bwipeout!' sbuf
+    endif
+    if has_key(sbvar, 'savedopts')
+        for [o, val] in items(sbvar.savedopts)
+            execute 'let &g:'.o.'=val'
+        endfor
+    endif
+    if bufexists(sbvar.bufnr)
+        call setbufvar(sbvar.bufnr, '&modified', 0)
+    endif
+    call s:F.close(tabid, tabspec)
+endfunction
 "▶1 f.unloadpre :: {f}
 function s:f.unloadpre(plugdict, fdict)
     for tabnr in range(1, tabpagenr('$'))
         if type(tabid)==type('') && has_key(a:fdict, tabid)
             execute 'tabnext' tabnr
             let tabspec=a:fdict[tabid]
-            call call(tabspec.unload, [], {})
+            call s:F.tabunload(tabspec)
         endif
     endfor
     call map(keys(a:fdict), 'remove(s:tabs, v:val)')
 "▶1 Post resource
 call s:_f.newfeature('tab', s:f)
 "▶1
-call frawor#Lockvar(s:, 'tabs,prevtabs,last_prevtabmark')
+call frawor#Lockvar(s:, 'tabs,prevtabs,last_prevtabmark,_options,_r')
 " vim: ft=vim ts=4 sts=4 et fmr=▶,▲
     0.2: Officially added |g:aurum_fullundo|, added |g:aurum_recautowrite|.
 @%aurum/undo:
     1.0: Moved |g:aurum_fullundo| definition here.
+@%aurum/tabutils:
+    1.0: Moved some functions and |g:aurum_recautowrite| and 
+         |g:aurum_recheight| definitions here, moved some options to tabdesc 
+         argument.
 
 vim: ft=help:tw=78
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.