Created
May 7, 2011 04:03
-
-
Save anyakichi/960188 to your computer and use it in GitHub Desktop.
Tab management utility.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 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