" ----------------- " Tim's vimrc " ----------------- " " This Vim configuration file is the result of many years of using Vim on a " number of different platforms for all kinds of editing tasks. Primarily C/C++ " development on Linux and OS X, though. Feel free to re-use any scripts or " tweaks found here. It is compatible with Vim version 7.x on Windows, OS X and " Linux. Some features only work on UNIX platforms, some key mappings differ on " the Mac because of the way it reserves and interprets the ALT/CTRL/Fxx keys, " for textmode Vim the ALT key mappings don't work in certain terminals. It's " tricky to have a single setup that works on all platforms and Vim versions, " so expect some differences. Note that at the end of the file there is a handy " Makefile template for setting up C++ projects on UNIX platforms. This file is " constantly changing, depending on whether I type on a laptop or PC keyboard, " editing HTML or C++ code etc. There just never seems to be one ideal, final " version of it... " " tim@blitzcode.net / www.blitzcode.net " " List of new or changed key mappings " ----------------------------------------------------------------------------- " TAB | Open / close QuickName fast buffer switcher " SHIFT+TAB | Open / close QuickBuf buffer manager " F1 | Open man page in Vim for word under cursor (UNIX only) " F3 | Open tag under cursor in preview window " F4 | Recursive grep search (asks for root / pattern / filespec) " F5 | Run ./out (also works in insert mode) " F7 | Make (writes all buffers first, also works in insert mode) " CTRL+F12 | Generate tags file (prompts for root path) " ALT/CMD+D | Delete buffer, keep window " CTRL+S | Save buffer (also works in insert mode) " CTRL/CMD+LEFT | Go backward in the QuickFix list " CTRL/CMD+RIGHT | Go forward in the QuickFix list " CTRL+J | Re-wrap paragraph " ALT+C | Open 'Custom' menu (Windows / Linux GUI only) " SHIFT+T | Toggle tab size " ,, | Turn off highlighting (:nohl) " - | Mapped to $ (end of the line, handy on a kb without END key) " BACKSPACE | Mapped to CTRL+^ (edit alternate file) " ENTER | Bring up command prompt ':' " SPACE | Mapped to CTRL+W, quick window opening / closing / switching " . | Puts cursor back to its starting position after repeating " HOME / 0 | First does ^, then toggles between ^ and 0 " ,s | Switch between C/C++ source and header files " ,cd | Switch Vim's current directory to that of the current buffer " ` | In insert mode the backtick is mapped to CTRL+P " :Calc | Use Python to evaluate mathematical expressions " {{ | Insert 3 line C/C++ curly brace construct (insert mode only) " ----------------------------------------------------------------------------- " Don't inherit any vi craziness set nocompatible " Version check if v:version < 700 echo "Wrong editor version for vimrc, need 7.x or better!" finish endif " Syntax highlighting syntax on " Don't scatter .swp files everywhere, no constant warnings when opening files " from a crashed session etc. set noswapfile " Tabs set smarttab set tabstop=8 set softtabstop=4 set expandtab " Press SHIFT+T to toggle tab size function! ToggleTabStop() if &tabstop == 4 set tabstop=8 echo "tab size 8" else set tabstop=4 echo "tab size 4" endif endfunc map :call ToggleTabStop() " Indentation set cindent set cinoptions+=(1s " Only one shift for a continuation line after an open ( set cinoptions+=g0 " Place public: etc. on the same indent as the { set shiftwidth=4 " I don't like text files reconfiguring my editor, can also have security " implications set nomodeline " Allow backspace to delete indents, line breaks and past the start of the " current insert. This makes the key work like in every other editor set backspace=indent,eol,start " Automatically break text after 80 characters set textwidth=80 " Re-wrap paragraph to make all lines fit in texwidth characters. Similar " behavior and shortcut as Pine's 'Justify' editor command map {gq} " Map - to $, causing it to jump to the end of the line. This is handy on a " keyboard without an END key and is shorter than SHIFT+4. Also right next to " 0, which goes to the beginning of a line map - $ " Map BS to CTRL+^ (edit alternate file). I like to have a frequently used " function like this on a single key map :e # " Map ENTER to bringing up the command prompt map : " Map the space key to CTRL+W, allowing window operations to be executed " quickly map " Map the backtick key to CTRL+P completion in insert mode. I can't think of a " situation where I'd need a backtick, but I constantly use the awkward CTRL+P " combination imap ` " Treat text lines, wrapped to several screen lines as separate lines when " navigating with the arrow keys map gk map gj imap gk imap gj " This puts the cursor back to its starting position when repeating a change " with the useful dot command nmap . .`[ " Pressing HOME or 0 will now place the cursor at the first non-blank " character (like ^). If it's already there it'll be placed at the first " character (like 0). Taken from http://vim.wikia.com/wiki/Smart_home function! SmartHome() let s:col = col(".") normal! ^ if s:col == col(".") normal! 0 endif endfunc map :call SmartHome() map 0 :call SmartHome() " Switch between source and header files function! SwitchSourceHeader() let s:ext = expand("%:e") let s:base = expand("%:t:r") let s:cmd = "find " . s:base if (s:ext == "cpp" || s:ext == "c" || s:ext == "C" || s:ext == "cxx") if findfile(s:base . ".h" ) != "" | exe s:cmd . ".h" | return | en if findfile(s:base . ".hpp") != "" | exe s:cmd . ".hpp" | return | en if findfile(s:base . ".hxx") != "" | exe s:cmd . ".hxx" | return | en else if findfile(s:base . ".cpp") != "" | exe s:cmd . ".cpp" | return | en if findfile(s:base . ".c" ) != "" | exe s:cmd . ".c" | return | en if findfile(s:base . ".C ") != "" | exe s:cmd . ".C" | return | en if findfile(s:base . ".cxx") != "" | exe s:cmd . ".cxx" | return | en endif endfunc nmap ,s :call SwitchSourceHeader() " Enter ,cd to switch Vim's current directory to where the current buffer is. " Taken from http://vim.wikia.com/wiki/VimTip64 map ,cd :cd %:p:h " Give priority to UNIX newlines even on other systems where the default is " different set fileformats=unix,dos,mac " Script helper function that will return the path of the current buffer. Can't " be script local as we will call this from the status bar to display the " buffer's path func! CurBufPath() return fnamemodify(bufname("%"), ":p:h") endfunc " Script helper function that will prompt the user to enter a path, using the " location of the current buffer as a default. Returns the path or an empty " string if the user aborts or enters an invalid path func! s:QueryPath(prompt) let s:path_sep = (has("win32") || has("win64")) ? "\\" : "/" let s:initial_path = CurBufPath() . s:path_sep let s:directory = input(a:prompt, s:initial_path, "dir") if s:directory == "" return endif if !isdirectory(s:directory) echohl ErrorMsg | echo "Not a directory!" | echohl None return endif return s:directory endfunc " Text search options set incsearch " Incremental search set ignorecase " Ignore case set smartcase " ...unless uppercase letters are used if !&hlsearch " Highlight the searched text " Don't set this again as it'll turn highlighting back on every time the " vimrc is reloaded. This can get quite annoying when testing changes set hlsearch endif " Turn off highlighting after a search map ,, :nohl " Highlight merge conflicts delimiters match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$' " Press F4 to initiate a recursive search using Vim's build-in grep feature. " Prompts will appear asking the user for the root of the search (defaulting to " the buffer's directory), the pattern to search for and the types of files to " search (defaulting to typical C/C++ extensions). The search can be cancelled " with CTRL+C. After the search has completed the QuickFix window will be " displayed showing all the matches " " TODO: Cancelling the search will change the current directory func! GrepSearch() let s:directory = s:QueryPath("Search root dir: ") if (s:directory == "") return endif let s:search_pattern = input("Search pattern: ") if (s:search_pattern == "") return endif let s:search_files = input("Search files: ", "**/*.cpp **/*.[cCh]") if (s:search_files == "") return endif let s:old_cwd = getcwd() execute "cd" s:directory execute "vimgrep /" . s:search_pattern . "/j " . s:search_files execute "cd" s:old_cwd execute "cwindow" endfunc map :call GrepSearch() " Setup search path (search upwards and three directory levels downwards) set path=.,./**3,.; " Always show the status bar. The content is similar to what 'set ruler' would " get you, except it displays the buffer name and path separately. Also adds " one space of padding at the beginning and end, I find this a little more " readable set statusline=%<\ %t\ [%{CurBufPath()}]%h%m%r\ %=%-14.(%l,%c%V%)\ %P\ set laststatus=2 " Tag file search path. The ; at the end of the tags path will search for the " tag file in all directories above the file location. Very useful as this will " always find the right tag file, even when working with multiple projects and " sandboxes set tags=./tags; " Additional master tags file in the home directory. This is a good place to " generate tags for i.e. the system includes ('ctags -R /usr/include' on Linux " or 'ctags --languages=C,C++ -R /usr/include/ /System/Library/Frameworks/ " /Developer/SDKs/' on Mac). Note that Vim expects Exuberant Ctags, not the " older out of date versions installed by default on many systems set tags+=~/tags " Helper for quickly generating a tags file. When editing a file in some " project hierarchy without tags one usually wants to cd to a directory a few " levels above the file, execute a ctags -R and switch back to the old " directory. This script does just that, removing most of the typing work. " Since Vim here is configured to automatically search all parent directories " it'll find the newly generated tag file for sure. Just hit CTRL+F12, specify " the project root and hit enter func! GenerateTags() let s:directory = s:QueryPath("Tags root dir: ") if (s:directory == "") return endif let s:old_cwd = getcwd() execute "cd" s:directory execute "!ctags -R" execute "cd" s:old_cwd endfunc map :call GenerateTags() " Enable filetype plugins (required i.e. for omnicppcomplete) filetype plugin on " Enable loading of indent files filetype indent on " CTRL+S saves (also mapped for insert mode) map :w imap :w " Allow buffers with changes to be hidden set hidden " Delete current buffer with Mac style CMD+D (ALT+D everywhere else). Switches " to another buffer first to prevent the window from being closed. Note that " this fails for other windows were the buffer might also be visible. Also " activates the last buffer instead of just the next one func! DeleteBufferSafe() let s:prev_buf = bufnr("#") execute "bn" " Don't proceed if there's only one buffer left if !bufloaded(bufnr("#")) return endif execute "bd #" " Don't switch to the last / alternate buffer if it's already deleted if bufloaded(s:prev_buf) execute "b " s:prev_buf endif endfunc if has("mac") map :call DeleteBufferSafe() else " We use the ALT key on Linux/Windows as it is in the same position as " the command key on the Mac map :call DeleteBufferSafe() endif " VS-like compile shortcuts. Can't use normal -s option for make as this omits " directory stack information required for Vim to locate the error. Note that " like in VS this actually saves before compiling! map :wa:make -j imap :wa:make -j compiler! gcc " VS-like run shortcut map :!./out imap :!./out " Use CTRL+LEFT/RIGHT to cycle through the QuickFix list. Use CMD on the Mac " because of the conflict with the hotkeys for Spaces. Useful for browsing " through compile errors or grep results if has("mac") map :cp map :cn else map :cp map :cn endif " Don't let the cursor on the window border, always show one more line set scrolloff=1 " Allow free positioning of the cursor in visual block mode set virtualedit=block " Don't change the view when returning to a buffer " http://vim.wikia.com/wiki/Avoid_scrolling_when_switch_buffers au! BufLeave * let b:winview = winsaveview() au! BufEnter * if (exists('b:winview')) | call winrestview(b:winview) | endif " Activate enhanced command line completion set wildmenu " The default of 20 entries for the history table is somewhat low set history=100 " I don't like bells. This doesn't actually disable them in gVim as they are " reseted after vimrc is parsed. Need to have a gvimrc for this to work set vb set vb t_vb= " Manpage integration (no use to have this on non-UNIX platforms) if has("unix") " Use a plugin and open the man page in a Vim window runtime! ftplugin/man.vim map :Man endif " File browser (:Explore settings) let g:netrw_list_hide='^\.' " Hide files that start with a dot let g:netrw_liststyle=1 " Long listing (ll-style) as default " I like this color scheme, looks OK even in an xterm colorscheme desert " Use Vim's Python support to provide a quick way of evaluation mathematical " expressions. Taken from http://vim.wikia.com/wiki/VimTip1235. See " http://docs.python.org/library/math.html for a description of Python's math " library if has("python") command! -nargs=+ Calc :py print py from math import * endif " Insert common C/C++ curly brace construct like this: " " { " " } " " When {{ is typed. Also works in the middle of the line. " " TODO: This is enabled editor-wide, maybe use an autocmd with a buffer local " mapping to only set this for certain extensions or check that the " filetype variable indicates a C-like language inoremap {{ o{}o " Show tag under cursor in preview window. This is an example from the Vim " manual, see :h CursorHold-example func! PreviewWord() if &previewwindow " Don't do this in the preview window return endif let w = expand("") " Get the word under cursor if w =~ '\a' " If the word contains a letter " Delete any existing highlight before showing another tag silent! wincmd P " Jump to preview window if &previewwindow " If we really get there... match none " Delete existing highlight wincmd p " Back to old window endif " Try displaying a matching tag for the word under the cursor try exe "ptag " . w catch return endtry silent! wincmd P " Jump to preview window if &previewwindow " If we really get there... if has("folding") silent! .foldopen " Don't want a closed fold endif call search("$", "b") " To end of previous line let w = substitute(w, '\\', '\\\\', "") call search('\<\V' . w . '\>') " Position cursor on match " Add a match highlight to the word at this position hi previewWord term=bold ctermbg=DarkRed guibg=DarkRed exe 'match previewWord "\%' \ . line(".") . 'l\%' . col(".") . 'c\k*"' wincmd p " Back to old window endif endif endfunc " Press F3 to open the tag under the cursor in the preview window map :call PreviewWord() " Options only for the GUI version of Vim if has("gui_running") " Font if has("gui_gtk2") " Default terminal font on Ubuntu set guifont=Monospace\ 8 elseif has("x11") " Normal xterm font set guifont=-Misc-Fixed-Medium-R-Normal--12-120-75-75-C-70-ISO8859-1 elseif has("gui_win32") " First try 6x13 Linux console font from http://www.ank.com.ar/fonts/, " then Consolas (ships with Vista, free download otherwise), then " settle for the standard Lucida Console font set guifont=6x13-ISO8859-1:h10,Consolas:h9,Lucida_Console:h9 " No extra line spacing, 0 is already the non-Win32 default set linespace=0 elseif has("mac") " Terminal font on OSX set guifont=Monaco:h10 " Line spacing is excessive at the 0 default set linespace=-2 endif " Default white on pink for the pop-up menu looks a bit unpleasant highlight Pmenu guibg=DarkRed " Don't need the toolbar set guioptions-=T " Sets some basic mouse / GUI behavior. Make sure we're in xterm mode, even " on Windows behave xterm " Don't use xterm style selection but move the cursor and pop-up a context " menu for the right mouse button. Useful to correct spelling errors with " the mouse set mousemodel=popup_setpos " Enable spell checking. Terminals don't have squiggly lines, so GUI only set spell " Line numbers. Don't need them when quickly opening a file in a terminal. " Also interferes with the system clipboard as the xterm doesn't know that " the numbers are not part of the buffer hi LineNr guifg=#6f6f6f set numberwidth=4 set number " Make sure :mksession saves the size and position of the gVim root window " itself set sessionoptions+=resize set sessionoptions+=winpos " Reasonable default window size if !exists("g:set_win_size") " Only do this once, don't want to resize the window when testing " changes set lines=60 set columns=90 endif let g:set_win_size=1 " Add a new menu called 'Custom'. This is a place for useful commands that " are hard to type or remember, but not used frequently enough to justify a " key binding silent! aunmenu Custom amenu &Custom.Sort\ Paragraph \ !}sort amenu &Custom.Remove\ Trailing\ Blanks \ :%s= *$== amenu &Custom.Remove\ Blank\ Lines \ :g/^\s*$/d amenu &Custom.List\ All\ Lines\ Containing\ Word\ Under\ Cursor \ :g//# amenu &Custom.Copy\ Buffer\ to\ Clipboard \ gg"*yG amenu &Custom.Highlight\ Long\ Lines.On \ :exec 'match Todo /\%>' . &textwidth . 'v.\+/' amenu &Custom.Highlight\ Long\ Lines.Off \ :exec 'match none /\%>' . &textwidth . 'v.\+/' " MacVim automatically maps some of the Mac specific key combinations like " CMD/OPT+ARROW which we want to map ourselves. Fortunately we can disable " this as follows. Note that for this to work the variable has to be set in " the vimrc, gvimrc is already to late if has("gui_macvim") let macvim_skip_cmd_opt_movement=1 endif endif " ----------------------------------------------------------------------------- " QuickName (http://www.vim.org/scripts/script.php?script_id=2317) " " Fast buffer switching script " " I put this here as I like to keep my configuration limited to a single file, " makes syncing and deployment so much easier. A few modification from the " original: " " - Change ls! to plain ls (no unlisted buffers) " - Default hotkey is now TAB " - Disabled check for 'already loaded?', makes debugging easier " - Added a 'echo' to clear the last cmap from the screen " - Broke up lines longer than 79 characters " ----------------------------------------------------------------------------- if !exists("g:qname_hotkey") || g:qname_hotkey == "" let g:qname_hotkey = "" endif exe "nmap" g:qname_hotkey ":cal QNameInit(1):~:echo" let s:qname_hotkey = eval('"\'.g:qname_hotkey.'"') if exists("g:qname_loaded") && g:qname_loaded " (Check disabled - reloading useful for debugging) " finish endif let g:qname_loaded = 1 function! QNameRun() cal s:colPrinter.print() echo "\rMatch" len(s:n)."/".len(s:ls) "names:" s:inp call inputsave() let _key = getchar() if !type(_key) let _key = nr2char(_key) endif if _key == "\" let s:inp = s:inp[:-2] elseif strlen(_key) == 1 && char2nr(_key) > 31 let s:inp = s:inp._key endif if _key == "\" || _key == "\" let _sel = s:colPrinter.sel if _key == "\" && _sel < len(s:n) && _sel >= 0 call s:swb(matchstr(s:s[_sel], '<\zs\d\+\ze>'),"") endif cal QNameInit(0) elseif _key == "\" cal s:colPrinter.vert(-1) elseif _key == "\" cal s:colPrinter.vert(1) elseif _key == "\" cal s:colPrinter.horz(-1) elseif _key == "\" cal s:colPrinter.horz(1) elseif _key == s:qname_hotkey cal QNameInit(0) else cal s:build() endif redraws call inputrestore() endfunc function! QNameInit(start) if a:start cmap ~ cal QNameRun():~ let s:pro = "Prompt: " let s:cmdh = &cmdheight if a:start != -1 let s:inp = "" endif call s:baselist() call s:build() exe "set cmdheight=".(s:colPrinter.trow+1) else cmap ~ exe "cunmap \x7E" exe "set cmdheight=".s:cmdh endif endfunc function! s:build() let s:s = [] let s:n = [] let s:blen = 0 let _cmp = tolower(tr(s:inp, '\', '/')) for _line in s:ls let _name = matchstr(_line, '^.\{-}\ze \+<') if s:fmatch(tolower(_name), _cmp) cal add(s:s, _line) cal add(s:n, _name) endif endfor if len(s:n) > s:colPrinter.trow cal s:colPrinter.put(s:n) else cal s:colPrinter.put(s:s) endif endfunc function! s:swb(bno,mod) if bufwinnr(a:bno) == -1 exe "hid b".a:mod a:bno else exe bufwinnr(a:bno) . "winc w" endif endfunc function! s:fmatch(src,pat) let _si = strlen(a:src)-1 let _pi = strlen(a:pat)-1 while _si>=0 && _pi>=0 if a:src[_si] == a:pat[_pi] let _pi -= 1 endif let _si -= 1 endwhile return _pi < 0 endfunc function! s:baselist() let s:ls = [] redir @y | silent ls | redir END for _line in split(@y,"\n") if _line[3]!='u' || _line[6]!='-' let _bno = matchstr(_line, '^ *\zs\d*')+0 let _fname = substitute(expand("#"._bno.":p"), '\', '/', 'g') if _fname == "" let _fname = "\xA0".matchstr(_line, '"\zs[^"]*') endif let _name = fnamemodify(_fname,":t") cal add(s:ls, _name." <"._bno."> ".fnamemodify(_fname,":h")) endif endfor let _align = max(map(copy(s:ls),'stridx(v:val,">")')) call map(s:ls, 'substitute(v:val, " <", \ repeat(" ",_align-stridx(v:val,">"))." <", "")') cal sort(s:ls, 1) endfunc let s:colPrinter = {"trow": 4} function! s:colPrinter.put(its) dict let _cols = [] let _trow = self.trow let _its = copy(a:its) let _len = len(_its) let _i = 0 while _i < _len if _i+_trow <= _len cal add(_cols, remove(_its,0,_trow-1)) else cal add(_cols, _its) endif let _i += _trow endwhile let _cpos = [0] let _cw = [] let _t = 0 for _li in _cols let _w = max(map(copy(_li),'strlen(v:val)'))+4 let _t += _w cal add(_cpos,_t) cal add(_cw,_w) endfor let _rows = [] for _i in range(_trow) let _row = [] for _j in range(len(_cols)) if _j*_trow+_i < _len cal add(_row,_cols[_j][_i]) endif endfor cal add(_rows, _row) endfor let self.cols = _cols let self.cw = _cw let self.rows = _rows let self.cpos = _cpos let self.len = _len let self.lcol = 0 let self.sel = 0 endfunc function! s:colPrinter.horz(mv) dict let _t = self.sel + a:mv*self.trow if _t >= 0 && _t < self.len let self.sel = _t endif endfunc function! s:colPrinter.vert(mv) dict let _t = self.sel + a:mv let _len = self.len if _t < 0 && _len > 0 let self.sel = _len-1 elseif _t >= _len let self.sel = 0 else let self.sel = _t endif endfunc function! s:colPrinter.print() dict let _len = self.len let _trow = self.trow if !_len echo " No Match" repeat("\n",_trow) return endif let _sel = self.sel let _t = _sel/_trow let _cpos = self.cpos let _lcol = self.lcol let _tcol = &columns if _cpos[_lcol]+_tcol < _cpos[_t+1] let _rcol = _t let _pos = _cpos[_t+1]-_tcol-2 while _cpos[_lcol] < _pos let _lcol += 1 endwhile let _lcol -= _lcol > _t else if _t < _lcol let _lcol = _t endif let _rcol = len(_cpos)-1 let _pos = _cpos[_lcol]+_tcol+2 while _cpos[_rcol] > _pos let _rcol -= 1 endwhile let _rcol -= _rcol > _lcol endif let _cw = self.cw let _pos = _cpos[_lcol]+_tcol let self.lcol = _lcol for _i in range(_trow) let _row = self.rows[_i] for _j in range(_lcol,_rcol) if _j*_trow+_i < _len let _txt = " " . _row[_j] let _txt .= repeat(" ", _cw[_j] - strlen(_txt)) let _txt = _txt[:_pos-_cpos[_j]-2] if _j*_trow + _i == _sel echoh Search|echon _txt|echoh None else echon _txt endif endif endfor echon "\n" endfor endfunc " ----------------------------------------------------------------------------- " QuickBuf (http://www.vim.org/scripts/script.php?script_id=1910) " " Buffer management script " " - Use k/j or / keys to select the buffer " - Press a key to give a command to the currently selected buffer " - d : Delete buffer " - w : Wipe out buffer " - s : Open buffer in a new horizontally split window " - u : Open buffer " - : Open buffer and leave QuickBuf; if the buffer is already " opened in a window, switch to that window " + d, w, and operations may fail (ex: delete a modified buffer), " QuickBuf will inform you so that you can force them by preceding the " above characters with an exclamation mark ('!'). Ex: !d, !w, ! + " Instead of moving the selection bar around to select a buffer, you can " use a number to specify a buffer. For example: '2d' will delete the " second buffer in the list. Try '3', '1w', '1!w' + Use 'l' key to " toggle between LISTED and UNLISTED mode. Which mode QuickBuf enters first " depends on the active buffer. While in UNLISTED mode, 'unlisted' buffers " (the buffers you have deleted) are showed. Also: " - 'd' command makes the selected buffer 'listed' again " " I put this here as I like to keep my configuration limited to a single file, " makes syncing and deployment so much easier. A few modification from the " original: " " - Default hotkey is now SHIFT+TAB " - Broke up lines longer than 79 characters " - Disabled check for 'already loaded?', makes debugging easier " - Added echo to clear status message after exit (TODO) " ----------------------------------------------------------------------------- if !exists("g:qb_hotkey") || g:qb_hotkey == "" let g:qb_hotkey = "" endif exe "nnoremap" g:qb_hotkey " :cal init(1):cal SBRun()" exe "cnoremap" g:qb_hotkey "" if exists("g:qb_loaded") && g:qb_loaded " (Check disabled - reloading useful for debugging) " finish endif let g:qb_loaded = 1 let s:action2cmd = { \"z": 'call switchbuf(#,"")', "!z": 'call switchbuf(#,"!")', \"u": "hid b #|let s:cursel = (s:cursel+1) % s:blen", \"s": "sb #", \"d": 'call qbufdcmd(#,"")', "!d": 'call qbufdcmd(#,"!")', \"w": "bw #", "!w": "bw! #", \"l": "let s:unlisted = 1 - s:unlisted" } function! s:rebuild() redir @y | silent ls! | redir END let s:buflist = [] let s:blen = 0 for l:theline in split(@y,"\n") if s:unlisted && l:theline[3] == "u" && (l:theline[6] != "-" || \ l:theline[5] != " ") || !s:unlisted && l:theline[3] != "u" if s:unlisted let l:moreinfo = substitute(l:theline[5], "[ah]", " [+]", "") else let l:moreinfo = substitute(l:theline[7], "+", " [+]", "") endif let s:blen += 1 let l:fname = matchstr(l:theline, '"\zs[^"]*') let l:bufnum = matchstr(l:theline, '^ *\zs\d*') if l:bufnum == bufnr('') let l:active = '* ' elseif bufwinnr(str2nr(l:bufnum)) > 0 let l:active = '= ' else let l:active = ' ' endif call add(s:buflist, s:blen . l:active \.fnamemodify(l:fname,":t") . l:moreinfo \." <" . l:bufnum . "> " \.fnamemodify(l:fname,":h")) endif endfor let l:alignsize = max(map(copy(s:buflist),'stridx(v:val,">")')) call map(s:buflist, 'substitute(v:val, " <", \ repeat(" ",l:alignsize-stridx(v:val,">"))." <", "")') call map(s:buflist, 'strpart(v:val, 0, &columns-3)') endfunc function! SBRun() if !exists("s:cursel") || (s:cursel >= s:blen) || (s:cursel < 0) let s:cursel = s:blen-1 endif if s:blen < 1 echoh WarningMsg | echo "No" s:unlisted ? "unlisted" : \ "listed" "buffer!" | echoh None call s:init(0) return endif for l:idx in range(s:blen) if l:idx != s:cursel echo " " . s:buflist[l:idx] else echoh DiffText | echo "> " . s:buflist[l:idx] | echoh None endif endfor if s:unlisted echoh WarningMsg endif let l:pkey = input(s:unlisted ? "UNLISTED ([+] loaded):" : \ "LISTED ([+] modified):" , " ") if s:unlisted echoh None endif if l:pkey =~ "j$" let s:cursel = (s:cursel+1) % s:blen elseif l:pkey =~ "k$" if s:cursel == 0 let s:cursel = s:blen - 1 else let s:cursel -= 1 endif elseif s:update_buf(l:pkey) call s:init(0) return endif call s:setcmdh(s:blen+1) endfunc function! s:init(onStart) if a:onStart set nolazyredraw let s:unlisted = 1 - getbufvar("%", "&buflisted") let s:cursorbg = synIDattr(hlID("Cursor"),"bg") let s:cursorfg = synIDattr(hlID("Cursor"),"fg") let s:cmdh = &cmdheight hi Cursor guibg=NONE guifg=NONE let s:klist = ["j", "k", "u", "d", "w", "l", "s"] for l:key in s:klist exe "cnoremap ".l:key." ".l:key.":cal SBRun()" endfor cmap k cmap j call s:rebuild() let s:cursel = match(s:buflist, '^\d*\*') call s:setcmdh(s:blen+1) else call s:setcmdh(s:cmdh) for l:key in s:klist exe "cunmap ".l:key endfor cunmap cunmap exe "hi Cursor guibg=" . s:cursorbg . " \ guifg=".((s:cursorfg == "") ? "NONE" : s:cursorfg) echo "\r" echo redraw endif endfunc function! s:update_buf(cmd) if a:cmd != "" && a:cmd =~ '^ *\d*!\?\a\?$' let l:bufidx = str2nr(a:cmd) - 1 if l:bufidx == -1 let l:bufidx = s:cursel endif let l:action = matchstr(a:cmd, '!\?\a\?$') if l:action == "" || l:action == "!" let l:action .= "z" endif if l:bufidx >= 0 && l:bufidx < s:blen && has_key(s:action2cmd,l:action) try exe substitute(s:action2cmd[l:action], "#", \ matchstr(s:buflist[l:bufidx], '<\zs\d\+\ze>'), "g") if l:action[-1:] != "z" call s:rebuild() endif catch echoh ErrorMsg | echo "\rVIM" \ matchstr(v:exception, '^Vim(\a*):\zs.*') | echoh None if l:action[-1:] != "z" call inputsave() | call getchar() | call inputrestore() endif endtry endif endif return index(s:klist, a:cmd[-1:]) == -1 endfunc function! s:setcmdh(height) if a:height > &lines - winnr('$') * (&winminheight+1) - 1 call s:init(0) echo "\r"|echoerr "QBuf E1: No room to display buffer list" else exe "set cmdheight=".a:height endif endfunc function! s:switchbuf(bno, mod) if bufwinnr(a:bno) == -1 exe "b".a:mod a:bno else exe bufwinnr(a:bno) . "winc w" endif endfunc function! s:qbufdcmd(bno, mod) if s:unlisted call setbufvar(a:bno, "&buflisted", 1) else exe "bd" . a:mod a:bno endif endfunc " ----------------------------------------------------------------------------- " Appended here is my Makefile template for C++ projects on UNIX platforms. I " store this here as Vim is my editor / IDE of choice for C++ development on " these platforms and having this always around ensures I can setup a new " project very quickly. Tested on OS X and Linux " ----------------------------------------------------------------------------- finish " Tell Vim to stop parsing from here on, Makefile starts below # Main makefile for a C++ project using GLFW (http://www.glfw.org/) # # Targets: # # all Compile project (default) # libs Build libraries # clean Clean project build # clean-libs Clean libraries # Default target depending on main output .PHONY : all all : out # Compiler and linker flags CXXFLAGS = -g -O3 -Wall -Wextra -Wno-unused-parameter \ -I ./glfw/include/ # -fno-inline # -DNDEBUG LDFLAGS = ./glfw/lib/cocoa/libglfw.a \ -framework Cocoa \ -framework OpenGL # Sources and objects. We assume all .cpp files in the directory are meant to # be compiled SRC = $(wildcard *.cpp) OBJ = $(SRC:.cpp=.o) # Rule for producing the main output LD_OBJ = $(OBJ) $(patsubst %, %/out, $(LIBSUBDIRS)) out : $(LD_OBJ) $(CXX) -o $@ $(CXXFLAGS) $(LDFLAGS) $(LD_OBJ) # Only include this if we actually build the main output, don't want to # generate dependencies for the clean targets etc. ifeq ($(MAKECMDGOALS), ) # Automatically generate dependencies with the compiler for each source file %.d: %.cpp @set -e; rm -f $@; \ $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ $(RM) $@.$$$$ # Include the generated dependencies for object and dependency files. Be silent # during the first compile where the .d files have not been generated yet and # everything is recompiled -include $(SRC:.cpp=.d) endif # Compile GLFW library .PHONY : glfw glfw: cd ./glfw/lib/cocoa/ && $(MAKE) -f Makefile.cocoa # Compile libraries .PHONY: libs libs: glfw # Clean libraries .PHONY : clean-libs clean-libs: cd ./glfw && $(MAKE) cocoa-clean # Clean by deleting final output, dependency and object files .PHONY : clean clean: $(RM) out $(OBJ) $(OBJ:.o=.d) " ----------------------------------------------------------------------------- " Last but not least, a minimal .bash_login followed by an equivalent .tcshrc " ----------------------------------------------------------------------------- export PS1="\[$(tput rev)\][\w]\[$(tput sgr0)\] " alias ll='ls -FAlG' alias ll ls -FAlG set prompt="%{\033[7m[%}%/]%{\033[0m%} "