Created
August 4, 2010 13:45
-
-
Save robince/508150 to your computer and use it in GitHub Desktop.
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
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" buftabs (C) 2006 Ico Doornekamp | |
" | |
" This program is free software; you can redistribute it and/or modify it | |
" under the terms of the GNU General Public License as published by the Free | |
" Software Foundation; either version 2 of the License, or (at your option) | |
" any later version. | |
" | |
" This program is distributed in the hope that it will be useful, but WITHOUT | |
" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
" more details. | |
" | |
" Introduction | |
" ------------ | |
" | |
" This is a simple script that shows a tabs-like list of buffers in the bottom | |
" of the window. The biggest advantage of this script over various others is | |
" that it does not take any lines away from your terminal, leaving more space | |
" for the document you're editing. The tabs are only visible when you need | |
" them - when you are switchin between buffers. | |
" | |
" Usage | |
" ----- | |
" | |
" This script draws buffer tabs on vim startup, when a new buffer is created | |
" and when switching between buffers. | |
" | |
" It might be handy to create a few maps for easy switching of buffers in your | |
" .vimrc file. For example, using F1 and F2 keys: | |
" | |
" noremap <f1> :bprev<CR> | |
" noremap <f2> :bnext<CR> | |
" | |
" or using control-left and control-right keys: | |
" | |
" :noremap <C-left> :bprev<CR> | |
" :noremap <C-right> :bnext<CR> | |
" | |
" | |
" The following extra configuration variables are availabe: | |
" | |
" * g:buftabs_only_basename | |
" | |
" Define this variable to make buftabs only print the filename of each buffer, | |
" omitting the preceding directory name. Add to your .vimrc: | |
" | |
" :let g:buftabs_only_basename=1 | |
" | |
" | |
" * g:buftabs_in_statusline | |
" | |
" Define this variable to make the plugin show the buftabs in the statusline | |
" instead of the command line. It is a good idea to configure vim to show | |
" the statusline as well when only one window is open. Add to your .vimrc: | |
" | |
" set laststatus=2 | |
" :let g:buftabs_in_statusline=1 | |
" | |
" | |
" * g:buftabs_active_highlight_group | |
" * g:buftabs_inactive_highlight_group | |
" | |
" The name of a highlight group (:help highligh-groups) which is used to | |
" show the name of the current active buffer and of all other inactive | |
" buffers. If these variables are not defined, no highlighting is used. | |
" (Highlighting is only functional when g:buftabs_in_statusline is enabled) | |
" | |
" :let g:buftabs_active_highlight_group="Visual" | |
" | |
" | |
" * g:buftabs_marker_start [ | |
" * g:buftabs_marker_end ] | |
" * g:buftabs_separator - | |
" | |
" These strings are drawn around each tab as separators. | |
" | |
" :let g:buftabs_separator = "." | |
" :let g:buftabs_marker_start = "(" | |
" :let g:buftabs_marker_end = ")" | |
" | |
" | |
" Changelog | |
" --------- | |
" | |
" 0.1 2006-09-22 Initial version | |
" | |
" 0.2 2006-09-22 Better handling when the list of buffers is longer then the | |
" window width. | |
" | |
" 0.3 2006-09-27 Some cleanups, set 'hidden' mode by default | |
" | |
" 0.4 2007-02-26 Don't draw buftabs until VimEnter event to avoid clutter at | |
" startup in some circumstances | |
" | |
" 0.5 2007-02-26 Added option for showing only filenames without directories | |
" in tabs | |
" | |
" 0.6 2007-03-04 'only_basename' changed to a global variable. Removed | |
" functions and add event handlers instead. 'hidden' mode | |
" broke some things, so is disabled now. Fixed documentation | |
" | |
" 0.7 2007-03-07 Added configuration option to show tabs in statusline | |
" instead of cmdline | |
" | |
" 0.8 2007-04-02 Update buftabs when leaving insertmode | |
" | |
" 0.9 2007-08-22 Now compatible with older Vim versions < 7.0 | |
" | |
" 0.10 2008-01-26 Added GPL license | |
" | |
" 0.11 2008-02-29 Added optional syntax highlighting to active buffer name | |
" | |
" 0.12 2009-03-18 Fixed support for split windows | |
" | |
" 0.13 2009-05-07 Store and reuse right-aligned part of original statusline | |
" | |
" 0.14 2010-01-28 Fixed bug that caused buftabs in command line being | |
" overwritten when 'hidden' mode is enabled. | |
" | |
" 0.15 2010-02-16 Fixed window width handling bug which caused strange | |
" behaviour in combination with the bufferlist plugin. | |
" Fixed wrong buffer display when deleting last window. | |
" Added extra options for tabs style and highlighting. | |
" | |
" 0.16 2010-02-28 Fixed bug causing errors when using buftabs in vim | |
" diff mode. | |
" | |
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
let g:buftabs_enabled = 0 | |
let g:original_statusline = matchstr(&statusline, "%=.*") | |
" | |
" Don't bother when in diff mode | |
" | |
if &diff | |
finish | |
endif | |
" | |
" Called on VimEnter event | |
" | |
function! Buftabs_enable() | |
let g:buftabs_enabled = 1 | |
endfunction | |
" | |
" Persistent echo to avoid overwriting of status line when 'hidden' is enabled | |
" | |
function! Pecho(msg) | |
let s:hold_ut=&ut|let &ut=1 | |
let s:Pecho=a:msg | |
aug Pecho | |
au CursorHold * ec s:Pecho | |
\|let &ut=s:hold_ut | |
\|aug Pecho|exe 'au!'|aug END|aug! Pecho | |
aug END | |
endf | |
" | |
" Draw the buftabs | |
" | |
function! Buftabs_show(deleted_buf) | |
let l:i = 1 | |
let l:list = '' | |
let l:start = 0 | |
let l:end = 0 | |
let l:count = 1 | |
if ! exists("w:from") | |
let w:from = 0 | |
endif | |
if ! exists("g:buftabs_enabled") | |
return | |
endif | |
" Walk the list of buffers | |
while(l:i <= bufnr('$')) | |
" Only show buffers in the list, and omit help screens | |
if buflisted(l:i) && getbufvar(l:i, "&modifiable") && a:deleted_buf != l:i | |
" Get the name of the current buffer, and escape characters that might | |
" mess up the statusline | |
if exists("g:buftabs_only_basename") | |
let l:name = fnamemodify(bufname(l:i), ":t") | |
else | |
let l:name = bufname(l:i) | |
endif | |
let l:name = substitute(l:name, "%", "%%", "g") | |
" Append the current buffer number and name to the list. If the buffer | |
" is the active buffer, enclose it in some magick characters which will | |
" be replaced by markers later. If it is modified, it is appended with | |
" an exclaimation mark | |
if winbufnr(winnr()) == l:i | |
let l:start = strlen(l:list) | |
let l:list = l:list . "\x01" | |
else | |
let l:list = l:list . ' ' | |
endif | |
let l:buftabs_separator = "-" | |
if exists("g:buftabs_separator") | |
let l:buftabs_separator = g:buftabs_separator | |
endif | |
"let l:list = l:list . l:i . l:buftabs_separator | |
let l:list = l:list . l:count . l:buftabs_separator | |
let l:list = l:list . l:name | |
let l:count = l:count + 1 | |
if getbufvar(l:i, "&modified") == 1 | |
let l:list = l:list . "+" | |
endif | |
if winbufnr(winnr()) == l:i | |
let l:list = l:list . "\x02" | |
let l:end = strlen(l:list) | |
else | |
let l:list = l:list . ' ' | |
endif | |
end | |
let l:i = l:i + 1 | |
endwhile | |
" If the resulting list is too long to fit on the screen, chop | |
" out the appropriate part | |
let l:width = winwidth(0) - 12 | |
if(l:start < w:from) | |
let w:from = l:start - 1 | |
endif | |
if l:end > w:from + l:width | |
let w:from = l:end - l:width | |
endif | |
let l:list = strpart(l:list, w:from, l:width) | |
" Replace the magic characters by visible markers for highlighting the | |
" current buffer. The markers can be simple characters like square brackets, | |
" but can also be special codes with highlight groups | |
let l:buftabs_marker_start = "[" | |
if exists("g:buftabs_marker_start") | |
let l:buftabs_marker_start = g:buftabs_marker_start | |
endif | |
let l:buftabs_marker_end = "]" | |
if exists("g:buftabs_marker_end") | |
let l:buftabs_marker_end = g:buftabs_marker_end | |
endif | |
if exists("g:buftabs_active_highlight_group") | |
if exists("g:buftabs_in_statusline") | |
let l:buftabs_marker_start = "%#" . g:buftabs_active_highlight_group . "#" . l:buftabs_marker_start | |
let l:buftabs_marker_end = l:buftabs_marker_end . "%##" | |
end | |
end | |
if exists("g:buftabs_inactive_highlight_group") | |
if exists("g:buftabs_in_statusline") | |
let l:list = '%#' . g:buftabs_inactive_highlight_group . '#' . l:list | |
let l:list .= '%##' | |
let l:buftabs_marker_end = l:buftabs_marker_end . '%#' . g:buftabs_inactive_highlight_group . '#' | |
end | |
end | |
let l:list = substitute(l:list, "\x01", l:buftabs_marker_start, 'g') | |
let l:list = substitute(l:list, "\x02", l:buftabs_marker_end, 'g') | |
" Show the list. The buftabs_in_statusline variable determines of the list | |
" is displayed in the command line (volatile) or in the statusline | |
" (persistent) | |
if exists("g:buftabs_in_statusline") | |
let &l:statusline = l:list . g:original_statusline | |
else | |
redraw | |
call Pecho(l:list) | |
end | |
endfunction | |
" Hook to events to show buftabs at startup, when creating and when switching | |
" buffers | |
autocmd VimEnter * call Buftabs_enable() | |
autocmd VimEnter,BufNew,BufEnter,BufWritePost * call Buftabs_show(-1) | |
autocmd BufDelete * call Buftabs_show(expand('<abuf>')) | |
if version >= 700 | |
autocmd InsertLeave,VimResized * call Buftabs_show(-1) | |
end | |
" vi: ts=2 sw=2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment