Skip to content

Instantly share code, notes, and snippets.

@anyakichi
Created May 7, 2011 04:03
Show Gist options
  • Save anyakichi/960188 to your computer and use it in GitHub Desktop.
Save anyakichi/960188 to your computer and use it in GitHub Desktop.
Tab management utility.
" Tab management utility.
let s:save_cpo = &cpo
set cpo&vim
function! s:any(list, item)
for i in a:list
if type(i) == type(a:item) && i == a:item
return 1
endif
endfor
return 0
endfunction
function! s:split(mod)
if bufnr('#') == -1
return
endif
let bufnr = bufnr('%')
buffer #
execute a:mod 'sbuffer ' . bufnr
endfunction
" Move current buffer to a new tab (like CTRL-W_T).
" If a tab has only one window, move the buffer to a new tab and go back to
" buffer # in original window.
function! tabutil#split()
if winnr('$') > 1
wincmd T
else
call s:split('tab')
endif
endfunction
" Move current buffer to new window.
function! tabutil#wsplit()
call s:split('')
endfunction
" Like tabutil#wsplit but vertical.
function! tabutil#vsplit()
call s:split('vertical')
endfunction
" Save window layout.
function! tabutil#savewinlayout()
let session = {}
let session['file'] = tempname()
let session['restcmd'] = winrestcmd()
let session['winnr'] = winnr()
let session['buflist'] = []
1wincmd w
for bufnr in tabpagebuflist()
let buf = {'bufnr': bufnr, 'view': winsaveview()}
call add(session['buflist'], buf)
wincmd w
endfor
let ssop_save = &sessionoptions
set sessionoptions=blank,help
execute 'mksession! ' . session['file']
let &sessionoptions = ssop_save
return session
endfunction
" Restore window layout.
function! tabutil#restwinlayout(session)
let split_save = [&splitbelow, &splitright]
" Restore window layout from session file
let lines = readfile(a:session['file'])
for i in range(0, len(lines) - 1)
if lines[i] =~ '^set splitbelow'
break
endif
endfor
for i in range(i - 1, len(lines) - 1)
if lines[i] =~ '^set winheight'
break
endif
execute lines[i]
endfor
" Resize windows
execute a:session['restcmd']
" Open buffers
1wincmd w
for buf in a:session['buflist']
execute 'buffer ' . buf['bufnr']
call winrestview(buf['view'])
wincmd w
endfor
" Change current buffer
execute a:session['winnr'] . 'wincmd w'
" Clean up
call delete(a:session['file'])
let [&splitbelow, &splitright] = split_save
endfunction
" Close a tab and push the tab state to tab stack.
" Closing tab can be restored later by tabutil#undo().
function! tabutil#close()
if tabpagenr('$') == 1
echo 'Already only one tab'
return
endif
let tab_state = {'tabnr': tabpagenr(), 'session': tabutil#savewinlayout()}
call add(s:tab_stack, tab_state)
tabclose
endfunction
" Close all other tabs and the states of closing tabs are pushed to tab stack.
function! tabutil#only()
for tabnr in range(tabpagenr('$'), tabpagenr() + 1, -1)
execute 'tabnext ' . tabnr
call tabutil#close()
endfor
for tabnr in range(tabpagenr() - 1, 1, -1)
execute 'tabnext ' . tabnr
call tabutil#close()
endfor
endfunction
" Restore the last closed tab.
function! tabutil#undo()
try
let tab_state = remove(s:tab_stack, -1)
catch
echo 'No closed tab'
return
endtry
tab split
call tabutil#restwinlayout(tab_state['session'])
execute 'silent! tabmove ' . (tab_state['tabnr'] - 1)
endfunction
" Restore all closed tabs.
function! tabutil#undoall()
while len(s:tab_stack) > 0
call tabutil#undo()
endwhile
endfunction
" Close duplicate tabs and open hidden buffers in new tabs.
function! tabutil#reorganize()
let tablists = []
let bufs = {}
let tabnr = 1
while type(tabpagebuflist(tabnr)) == type([])
let tablist = tabpagebuflist(tabnr)
if s:any(tablists, tablist)
execute 'tabclose ' . tabnr
continue
endif
call add(tablists, tablist)
for i in tablist
let bufs[i] = 1
endfor
let tabnr += 1
endwhile
tablast
for bufnr in range(1, bufnr('$'))
if get(bufs, bufnr, 0) == 0 && buflisted(bufnr)
execute 'tab sbuffer ' . bufnr
endif
endfor
tabfirst
endfunction
" Like tabutil#reorganize but one buffer per one tab.
function! tabutil#reorganize1()
let bufnrs = []
for tabnr in range(1, tabpagenr('$'))
call extend(bufnrs, tabpagebuflist(tabnr))
endfor
tabfirst
tabonly
let bufs = {}
for bufnr in bufnrs
if !has_key(bufs, bufnr)
execute 'tab sbuffer ' . bufnr
let bufs[bufnr] = 1
endif
endfor
for bufnr in range(1, bufnr('$'))
if get(bufs, bufnr, 0) == 0 && buflisted(bufnr)
execute 'tab sbuffer ' . bufnr
endif
endfor
tabfirst
tabclose
endfunction
if !exists('s:tab_stack')
let s:tab_stack = []
endif
let &cpo = s:save_cpo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment