X-Git-Url: http://git.iain.cx/?p=profile.git;a=blobdiff_plain;f=.vimrc;h=98c3c52c9faf8aae6d78a9be880090b2138ffe27;hp=5b9308d11f757fc330f4632368550fc545a8e01d;hb=732626fa6ddea589ef0e67d3627ebb42f81734d4;hpb=b06e3bd3f984e445593d218b659d9597bdaddcaa diff --git a/.vimrc b/.vimrc old mode 100755 new mode 100644 index 5b9308d..98c3c52 --- a/.vimrc +++ b/.vimrc @@ -1,6 +1,4 @@ """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -" $Id$ -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Multi-version vimrc compatible with version 4 and above. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -39,6 +37,7 @@ se laststatus=2 " Use C indent style. se cindent se cinkeys=0{,0},0),:,!^F,o,O,e +se cinoptions=b1,c2 " GUI options. se go=aglmr @@ -57,9 +56,13 @@ se smartcase " Look for ctags in home directory first. se tags=~/.tags,./tags,tags -" Use - and = to create underlines. -map - yyp:s/./-/g:let @/='': -map = yyp:s/./=/g:let @/='': +" Don't timeout waiting to interpet, eg, OA as an escape code. +se ttimeoutlen=100 + +" Use ^B to search backward when completing. +inoremap +" Use ^L to show matching completions but don't select one. +inoremap """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Handle options only available in Vim 5 and above. @@ -67,6 +70,22 @@ map = yyp:s/./=/g:let @/='': if version >= "500" version 5.0 +" Tell Vim we use dark backgrounds in our terminals. +if ! has("gui_running") + se bg=dark +endif + +" Enable tab-completion prompting for commands. +se wildmenu +" Don't list object files when globbing files to load. +se wildignore+=*.o,*.obj +" So there's no need to assign them low priority. +se suffixes-=*.o,*.obj + +" Save sessions in UNIX format with / as file separator. This is +" cross-platform. +se ssop+=unix,slash + " Nuke any pre-existing autocommands. autocmd! @@ -74,7 +93,7 @@ autocmd! let oldcols=&columns " More GUI options. Add icon, tearoffs and toolbar. -se go=agilmrtT +se go+=itT " Allow dynamic window resize even if we aren't in an xterm. se t_WS=[8;%p1%d;%p2%dt @@ -82,8 +101,17 @@ se t_WS=[8;%p1%d;%p2%dt " Highlight search results. se hlsearch -" Syntax highlighting. -syn on +" Set graphical window title. +se titlestring=%{Show_TitleString()} + +" Syntax highlighting. New versions will use syn enable instead. +if version < "600" + syn on +endif + +" Use a discernably different colour to highlight the cursor which shows +" matching brackets. Our regular cursor is green so use blue instead of cyan. +hi MatchParen ctermbg=blue " Catch typos. command! W :w @@ -98,6 +126,16 @@ fun! Iain_Vars() if ! exists("b:iainhex") let b:iainhex = 0 endif + if ! exists("b:iainverbose") + let b:iainverbose = 0 + endif + if ! exists("b:iainstatus") + " Window Flags: (F)ocused, (I)nsert mode, Cursor (H)old. + let b:iainstatus = "Fih" + endif + if ! exists("g:iainextracolumns") + let g:iainextracolumns = 0 + endif endfun " Helper for status line. @@ -142,75 +180,155 @@ fun! Show_Paste() endif endfun +" Show the window title. +fun! Show_TitleString() + if bufname("") == "" + let l:ts1='Vim' + else + let l:ts1=printf("%2d: %s", bufnr(""), expand('%t')) + endif + return printf("%s (%s) %s", l:ts1, getcwd(), v:servername) +endfun + " Show the status line. fun! Show_StatusLine() call Iain_Vars() - let sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %=' - let sl2='\ \|\ P:%4.6o\ L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P' - let hexformat='%b' + let l:sl1='%2n\:\ %<%f\ [%{Show_List()}%{Show_Case()}%{Show_Tabstop()}%{Show_Paste()}%Y%M%R]\ %=' + let l:sl3='L:%4.6l/%-4.6L\ C:%3.6c\ \|\ %P' + let l:hexformat='%b' if b:iainhex - let hexformat='0\x%02B' + let l:hexformat='0\x%02B' + endif + if b:iainverbose + let l:sl2=l:hexformat . '\ \|\ P:%4.6o\ ' + else + let l:sl2='' endif - exec "set statusline=" . sl1 . hexformat . sl2 + exec "set statusline=" . l:sl1 . l:sl2 . l:sl3 endfun -" Restore window size. -au VimLeave * if exists("oldcols") | let &columns=oldcols | endif - -" Map C mode. -au BufEnter * if &ft == "c" || &ft == "cpp" | call CMode_map() | endif -au BufLeave * if &ft == "c" || &ft == "cpp" | call CMode_unmap() | endif +" Toggle case-sensitivity. +fun! Invert_Case() + let &ic = ! &ic +endfun -" Map Perl mode. -au BufEnter * if &ft == "perl" | call PerlMode_map() | endif -au BufLeave * if &ft == "perl" | call PerlMode_unmap() | endif +" Grow or shrink the window size. +fun! Resize_Columns(op) + " Vim 5 hardcodes the size of numbers column to 8. + if version >= "700" + let l:numberwidth = &numberwidth + else + let l:numberwidth = 8 + endif -" Map Makefile mode. -au BufEnter * if &ft == "make" | call MakeMode_map() | endif -au BufLeave * if &ft == "make" | call MakeMode_unmap() | endif + let l:resize = "se columns" . a:op . "=" . l:numberwidth + + " HACK: Inside screen there is an extra line for the status bar. Vim + " manages the resize by sending an escape sequence to set the number of + " lines and number of columns in one action. To do this it will first query + " the number of lines and then set by . Because of the extra line for the status bar this results in + " the real terminal being shrunk by a line. We ask for the terminal to grow + " by a line so it ends up actually being the same. + if &term =~ '^screen' + let l:resize .= " lines+=1" + endif -" Entering C mode. -fun! CMode_map() - let oldcinkeys=&cinkeys - let oldcinwords=&cinwords - set cinkeys=0{,0},:,0#,!^F,o,O,e - set cinwords=if,else,while,do,for,switch + exec l:resize endfun -" Leaving C mode. -fun! CMode_unmap() - set cinkeys=oldcinkeys - set cinwords=oldcinwords +" Toggle number display. +fun! Number() + call Iain_Vars() + let &number = ! &number + + if version >= "700" + let l:i = 0 + let l:num_numbers = 0 + while l:i <= winnr("$") + if getwinvar(l:i, "&number") == 1 + let l:num_numbers = l:num_numbers + 1 + endif + let l:i = l:i + 1 + endwhile + + if l:num_numbers == 0 + let g:iainextracolumns = 0 + call Resize_Columns("-") + elseif g:iainextracolumns == 0 + let g:iainextracolumns = 1 + call Resize_Columns("+") + endif + endif endfun -" Entering Perl mode. -fun! PerlMode_map() - let oldcinkeys=&cinkeys - let oldcinwords=&cinwords - set cinkeys=0{,0},:,!^F,o,O,e - set cinwords=if,else,while,do,for,eval -endfun +" Restore window size. +au VimLeave * if exists("oldcols") | let &columns=oldcols | endif -" Leaving Perl mode. -fun! PerlMode_unmap() - set cinkeys=oldcinkeys - set cinwords=oldcinwords -endfun +" Map Makefile mode. +au BufEnter * if &ft == "make" | call MakeMode_map() | endif +au BufLeave * if &ft == "make" | call MakeMode_unmap() | endif " Entering Make mode. fun! MakeMode_map() - set list + call Iain_Vars() + let b:iainlist=1 + call Cycle_List() + set ts=8 set noexpandtab endfun " Leaving Make mode. fun! MakeMode_unmap() - set nolist + call Cycle_List() + set ts=2 set expandtab endfun " Show the status line for the first time. call Show_StatusLine() + +" Function to create mappings with either a hardcoded \ or . +fun! Mapping(keysequence,mapping) + if version < "600" + exec "map \\" . a:keysequence . " " . a:mapping + else + exec "map " . a:keysequence . " " . a:mapping + endif +endfun + +" Use - and = to create underlines. +call Mapping("-", "yyp:s/./-/g:let @/='':") +call Mapping("=", "yyp:s/./=/g:let @/='':") + +" Change to ts=2 with \2. +call Mapping("2", ":se ts=2:") +" Change to ts=4 with \4. +call Mapping("4", ":se ts=4:") +" Change to ts=8 with \8. +call Mapping("8", ":se ts=8:") +" Change to ts=16 with \6. +call Mapping("6", ":se ts=16:") +" Change to ts=32 with \3. +call Mapping("3", ":se ts=32:") +" Toggle paste mode with \p. +call Mapping("p", ":se paste!:") +" Swap case-sensitivity with \c. +call Mapping("c", ":call Invert_Case():") +" Change number mode with \n. +call Mapping("n", ":call Number():") +" Expand or shrink window size with \> and \<. +call Mapping(">", ":call Resize_Columns('+'):") +call Mapping("<", ":call Resize_Columns('-'):") +" Clear search pattern with \/. +call Mapping("/", ":let @/=\"\":") + +" Forget the Ex mode mapping. +map Q + +" Vim tip 99: What's the highlighting group under the cursor? +call Mapping("h", ":echo \"hi<\" . synIDattr(synID(line(\".\"),col(\".\"),1),\"name\") . '> trans<' . synIDattr(synID(line(\".\"),col(\".\"),0),\"name\") . \"> lo<\" . synIDattr(synIDtrans(synID(line(\".\"),col(\".\"),1)),\"name\") . \">\"") + endif """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -219,32 +337,46 @@ endif if version >= "600" version 6.0 -" Track changing number mode. -let g:numbercols=&columns -let g:numberchanges=0 +" Remember quickfix state. +let g:quickfixing=0 + +" Set indenting by filetype. +filetype indent on " Less intrusive syntax highlighting. syn enable " Nice GUI colour. if has("gui_running") - se guifont=Bitstream\ Vera\ Sans\ Mono\ 12 + se guifont=DejaVu\ Sans\ Mono\ 10 colo darkblue + hi LineNr guibg=#303030 +elseif &t_Co > 16 + try + colo iain + catch + endtry endif if has("win32") - se guifont=Bitstream_Vera_Sans_Mono:h10:cANSI + se guifont=DejaVu_Sans_Mono:h10:cANSI endif +hi! link TabLineSel StatusLine +hi! link TabLine StatusLineNC + +" Ignore whitespace when diffing. +se diffopt=filler,iwhite " Expand window when doing a vertical diff. if &diff let &columns = 164 endif -" Status bar matches the colour. -highlight StatusLine guifg=white guibg=blue ctermbg=white ctermfg=blue +" Remember that we are opening the quickfix window. +au BufWinEnter quickfix let g:quickfixing=1 +au BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif -" Numbers in blue. -highlight LineNr term=underline cterm=bold guifg=blue ctermfg=blue +" Allow in-place editing of crontabs. +au FileType crontab set backupcopy=yes " Make * and # work the way you expect in visual mode. vnoremap * y/\V=substitute(escape(@@,"/\\"),"\n","\\\\n","ge") @@ -276,87 +408,114 @@ fun! Cycle_HexStatusLine() call Show_StatusLine() endfun -" Cycle between number mode. -" FIXME: Toggling in a split window doesn't work properly. We need to track -" the number of windows and number modes. Something for later... -" Perhaps have a redraw callback that checks width and original column number. -fun! Cycle_Number() - if &number - " Restore width. - if &t_WS =~ '^.' - " Track changes. - let g:numberchanges=g:numberchanges-1 - if g:numberchanges<0 - g:numberchanges=0 - endif +" Cycle verbose display of toolbar stuff. +fun! Cycle_VerboseStatusLine() + call Iain_Vars() + let b:iainverbose = ! b:iainverbose + call Show_StatusLine() +endfun - " Change size back if this was the last window. - if g:numberchanges == 0 - let &columns=g:numbercols - endif +" Toggle quickfix window. +fun! Cycle_Quickfix() + if g:quickfixing == 1 + cclose + let g:quickfixing=0 + else + copen + endif +endfun + +" Swap hex/decimal statusline with \x. +call Mapping("x", ":call Cycle_HexStatusLine():") +" Change statusline verbosity with \v. +call Mapping("v", ":call Cycle_VerboseStatusLine():") +" Cycle list styles with \l. +call Mapping("l", ":call Cycle_List():") +" Toggle tags with \t. +call Mapping("t", ":Tlist") +" Change foldmethod with \f. +call Mapping("f", ":se foldenable!:") +" Toggle quickfix window with \q. +call Mapping("q", ":call Cycle_Quickfix():") +" Rerun filetype detection with \s. The s is for syntax, as this will be +" updated as a side-effect. +call Mapping("s", ":filetype detect:") + +fun! Iain_Colour(colour) + if &t_Co == 88 + if a:colour == "darkblue" + return 17 + elseif a:colour == "darkmagenta" + return 33 + elseif a:colour == "darkred" + return 32 + elseif a:colour == "red" + return 64 + endif + elseif &t_Co == 256 + if a:colour == "darkblue" + return 17 + elseif a:colour == "darkmagenta" + return 90 + elseif a:colour == "darkred" + return 88 + elseif a:colour == "red" + return 196 endif - set nonumber else - " Save width between number toggling. - if &t_WS =~ '^' - " Expand if this was the first change. - if g:numberchanges == 0 - let g:numbercols=&columns - if version >= 700 - " Expand column by our preferred width. - let &columns=&columns+&numberwidth - else - " Vim 6 hardcodes width to 8. - let &columns=&columns+8 - endif + return a:colour + endif +endfun + +" Change status bar colour when various things happen. +" Flags: H/h: Cursor held/moved. +" F/f: Focus gained/lost. +" I/i: Insert mode entered/left. +fun! Highlight_StatusLine(flag) + " Get current status. + call Iain_Vars() + + " Change the status based on the flag. XXX: Does Vim let us to do flags? + let re = "[" . tolower(a:flag) . toupper(a:flag) . "]" + let b:iainstatus = substitute(b:iainstatus, re, a:flag, "") + + let l:normalcolour = "darkblue" + let l:editingcolour = "darkmagenta" + let l:warningcolour = "darkred" + let l:readonlycolour = "red" + + " Default colour. + let l:colour = l:normalcolour + " Maybe override depending on status. + if b:iainstatus =~# "H" + if b:iainstatus =~# "I" + " Held in insert mode. Add extra highlight if we don't have focus. + if b:iainstatus =~# "f" + let l:colour = l:warningcolour + else + let l:colour = l:editingcolour endif + endif + else + if b:iainstatus =~# "I" + " Regular insert mode. + let l:colour = l:editingcolour + endif + endif - " Track changes. - let g:numberchanges=g:numberchanges+1 + " Override again if readonly. + if l:colour != l:normalcolour + if getbufvar("", "&ro") + let l:colour = l:readonlycolour endif - set number endif -endfun -" Toggle case-sensitivity. -fun! Invert_Case() - let &ic = ! &ic -endfun + let l:termcolour = Iain_Colour(l:colour) -" We'll use Q for various commands. Unmap it. -map Q - -" Change to ts=2 with Q2. -map Q2 :se ts=2: -" Change to ts=4 with Q4. -map Q4 :se ts=4: -" Change to ts=8 with Q8. -map Q8 :se ts=8: -" Change to ts=16 with Q6. -map Q6 :se ts=16: -" Change to ts=32 with Q3. -map Q3 :se ts=32: -" Change foldmethod with Qf. -map Qf :se foldenable!: -" Toggle paste mode with Qp. -map Qp :se paste!: -" Swap hex/decimal statusline with Qx -map Qx :call Cycle_HexStatusLine(): -" Swap case-sensitivity with Qc. -map Qc :call Invert_Case(): -" Cycle list styles with Ql. -map Ql :call Cycle_List(): -" Change number mode with Qn. -map Qn :call Cycle_Number(): -" Toggle tags with Qt. -map Qt :Tlist - -" Leaving Perl mode. -fun! PerlMode_unmap() - set cinkeys=oldcinkeys - set cinwords=oldcinwords - set foldmethod=manual + exec "highlight StatusLine guifg=white guibg=" . l:colour . " ctermbg=white ctermfg=" . l:termcolour endfun + +call Highlight_StatusLine("") endif """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -365,9 +524,105 @@ endif if version >= "700" version 7.0 +" Helper to show tab name. +fun! TabName(label, gui) + let l:label = a:label + if l:label == "" + let l:label = "No Name" + if a:gui + let l:label = "[" . l:label . "]" + endif + else + let l:label = fnamemodify(l:label, ":t") + if strlen(l:label) >= 18 + let l:label = l:label[0:17] . ".." + endif + endif + return l:label +endfun + +" Find out if any buffer was modified. +fun! TabModified(buflist) + let l:i = 0 + while i < len(a:buflist) + if getbufvar(a:buflist[l:i], "&modified") == 1 + return "+" + endif + let l:i = l:i + 1 + endwhile + return "" +endfun + +" Tab line. +fun! Show_TabLine() + let l:s = "%#TabLineFill#Tabs:" + + let l:i = 0 + while l:i < tabpagenr("$") + let l:i = l:i + 1 + " Get the label. + let l:buflist = tabpagebuflist(l:i) + let l:winnr = tabpagewinnr(l:i) + let l:n = tabpagewinnr(l:i, "$") + let l:label = TabName(bufname(l:buflist[l:winnr - 1]), 0) + let l:modified = TabModified(l:buflist) + + " Choose highlighting. + if l:i == tabpagenr() + let l:s .= "%#TabLineSel#[" . l:n . l:modified . " " . l:label . "]" + else + let l:s .= "%#TabLine# " . l:n . l:modified . " " . l:label . " " + endif + endwhile + + " Padding. + let l:s .= "%#TabLine#%T" + return l:s +endfun + +" Per tab label for the GUI. +fun! Show_GUITabLine() + let l:buflist = tabpagebuflist(v:lnum) + let l:winnr = tabpagewinnr(v:lnum) + let l:s = tabpagewinnr(v:lnum, "$") + let l:label = TabName(bufname(l:buflist[l:winnr - 1]), 1) + let l:modified = TabModified(l:buflist) + + let l:s .= l:modified . " " . l:label + return l:s +endfun + +se tabline=%!Show_TabLine() +se guitablabel=%!Show_GUITabLine() + +au CursorHoldI * call Highlight_StatusLine("H") +au CursorMovedI * call Highlight_StatusLine("h") +au FocusGained * call Highlight_StatusLine("F") +au FocusLost * call Highlight_StatusLine("f") +au InsertEnter * call Highlight_StatusLine("I") +au InsertLeave * call Highlight_StatusLine("i") + +" Limit the size of the popup menu when completing. +se pumheight=20 + +" Make diffs vertical by default. +se diffopt+=vertical + " Set size of numbers column. se numberwidth=5 " Add "previous tab" mapping as gb. -map gb :tabPrev +map gb :tabprevious: + +" Transparency. +if has("gui_macvim") + se transparency=15 +endif + +" Yet more GUI options. Add tabs. +se go+=e + +" Perforce. +let g:p4EnableMenu=1 +let g:p4Presets='P4CONFIG' endif