" ----------------------------------------------------------------------------- " Tim's vimrc tested with GTK2 gvim / Win32 gvim / text mode vim 7.x " ----------------------------------------------------------------------------- " 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 " No stupid mswin quirks behave xterm " Don't scatter .swp files everywhere, no constant warnings when opening files " from a crashed session etc. set noswapfile " Setup indentation and tabs set cindent set cinoptions+=(1s " Only one shift for a continuation line after an open ( set smarttab set tabstop=8 set shiftwidth=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() " Show line numbers etc. in the bar at the bottom of the window set laststatus=2 set ruler " Allows deleting of previously entered characters in insert mode using " backspace set backspace=2 " Automatically break text after 79 characters set textwidth=79 " Highlight lines in source code files which are longer than 79 characters " au BufNewFile,BufRead *.[Cch],*.cpp,*.hpp exec 'match Todo /\%>79v.\+/' " Give priority to UNIX newlines even on other systems where the default " is different set fileformats=unix,dos " Text search options set incsearch " Incremental search set hlsearch " Highlight the searched text set ignorecase " Ignore case set smartcase " ...unless uppercase letters are used " Turn of highlighting after a search map ,, :nohl " Setup search path " set path+= TODO: add project root / include directories " 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) 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:path_sep = (has("win32") || has("win64")) ? "\\" : "/" let s:initial_path = fnamemodify(bufname("%"), ":p:h") . s:path_sep let s:directory = input("Tags root dir: ", s:initial_path) if s:directory == "" return endif if !isdirectory(s:directory) echohl ErrorMsg | echo "Not a directory!" | echohl None return endif let s:old_cwd = getcwd() execute "cd " s:directory execute "!ctags -R" execute "cd " s:old_cwd endfunc map :call GenerateTags() " Enable plugins, required for omnicppcomplete filetype plugin on " Disable automatic activation of omnicppcomplete let OmniCpp_MayCompleteDot=0 let OmniCpp_MayCompleteArrow=0 let OmniCpp_MayCompleteScope=0 " CTRL+S saves (also map to make it work in insert mode) map :w imap :w " Allow buffers with changes to be hidden set hidden " Display buffer list and switch prompt with F2 map :ls:b " Delete current buffer with Windows style CTRL+F4. 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" execute "bd #" execute "b " s:prev_buf endfunc map :call DeleteBufferSafe() " 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. The ! " prevents the cursor from automatically being moved to the first error map :make! map :make! -s clean:make! compiler! gcc " Use CTRL+LEFT/RIGHT to cycle through the :clist. Useful for browsing through " compile errors or grep results map :cp map :cn " Don't always show the tab header set showtabline=1 " Don't let the cursor on the window border, always show one more line set scrolloff=1 " Map CTRL+UP/DOWN to their meaning in VS map map " Activate enhanced command line completion set wildmenu " 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 need 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 " Cut, copy & paste functionality that uses a named register instead of the " unnamed one. This way normal editing operations don't always overwrite " what was supposed to be kept in the clipboard. Activated by pressing ALT " with the usual y/p/P/d commands. This doesn't work in many terminals because " of the way they handle the ALT key map "ay map "ap map "aP map "ad " 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 " Options only for the GUI version of vim if has("gui_running") " Font if has("gui_gtk2") " Normal xterm font set guifont=MiscFixed\ 12 elseif has("x11") " Also for GTK1 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 endif " Color scheme, doesn't look good in an xterm colorscheme desert " 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 " 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 endif " Show tag under cursor in preview window " (this is from the Vim manual) func! PreviewWord() if &previewwindow " don't do this in the preview window return endif let w = expand("") " get the word under cursor if w != "" " if there is one ":ptag" to it " 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 let v:errmsg = "" exe "silent! ptag " . w if v:errmsg =~ "tag not found" return endif 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=green guibg=green exe 'match previewWord "\%' . line(".") . 'l\%' . col(".") . 'c\k*"' wincmd p " back to old window endif endif endfun " (Automatically open preview window when the cursor rests) " set updatetime=150 " au! CursorHold *.[cCh],*.cpp nested call PreviewWord() " " Press F3 to open the tag under the cursor in the preview window map :call PreviewWord() " 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 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