Show various marks in the left margin.
authorIain Patterson <me@iain.cx>
Fri, 26 Jun 2009 13:32:48 +0000 (14:32 +0100)
committerIain Patterson <me@iain.cx>
Fri, 26 Jun 2009 13:48:07 +0000 (14:48 +0100)
Use signs to highlight the location of the following marks (see help on
'x for information on mark x): a-f A-F .  ' " ^ < > [ ]
Toggle marks with \m.
Update marks when entering/leaving insert mode and when CursorHold is
triggered.  Trigger CursorHold after 500ms to reduce lag.
Show marks and numbers by default.  Set terminal mouse mode to allow
copying text from Vim to work as expected with the left margin showing
stuff.
Make sure the window isn't resized every time .vimrc is sourced.
Split autocommands into groups to help keep track of all this stuff..

.vim/colors/iain.vim
.vimrc

index d1031b5..0fb251c 100644 (file)
@@ -307,6 +307,12 @@ if has("gui_running") || &t_Co == 88 || &t_Co == 256
     hi link shShellVariables Identifier
 
     " Fix up Perl stuff.
+
+    " Signs to highlight marks.
+    call <SID>X("MarkLine", "", "#2e2e2e", "")
+    call <SID>X("MarkDot", "red", "#2e2e2e", "")
+    call <SID>X("MarkSign", "lightblue", "#2e2e2e", "")
+    hi! link SignColumn LineNr
 endif
 
 " vim: set fdl=0 fdm=marker:
diff --git a/.vimrc b/.vimrc
index 98c3c52..15a6414 100644 (file)
--- a/.vimrc
+++ b/.vimrc
@@ -75,6 +75,13 @@ if ! has("gui_running")
   se bg=dark
 endif
 
+" Allow mouse use in a terminal.
+se mouse=nvir
+
+" Update more quickly.  For use with sign highlighting as polling for
+" CursorMove makes redrawing slow.
+se updatetime=500
+
 " Enable tab-completion prompting for commands.
 se wildmenu
 " Don't list object files when globbing files to load.
@@ -87,10 +94,20 @@ se suffixes-=*.o,*.obj
 se ssop+=unix,slash
 
 " Nuke any pre-existing autocommands.
+augroup Display
+autocmd!
+augroup Mode
 autocmd!
+augroup Signs
+autocmd!
+augroup StatusLine
+autocmd!
+augroup END
 
 " Save the current window width so we can restore it when we quit.
-let oldcols=&columns
+if ! exists("oldcols")
+  let oldcols=&columns
+endif
 
 " More GUI options.  Add icon, tearoffs and toolbar.
 se go+=itT
@@ -136,6 +153,12 @@ fun! Iain_Vars()
   if ! exists("g:iainextracolumns")
     let g:iainextracolumns = 0
   endif
+  if ! exists("g:marksigns")
+    let g:marksigns = 0
+  endif
+  if ! exists("g:firstsign")
+    let g:firstsign = 100
+  endif
 endfun
 
 " Helper for status line.
@@ -213,15 +236,19 @@ fun! Invert_Case()
 endfun
 
 " 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
+fun! Resize_Columns(op, ...)
+  if a:0 == 0
+    " Vim 5 hardcodes the size of numbers column to 8.
+    if version >= "700"
+      let l:columns = &numberwidth
+    else
+      let l:columns = 8
+    endif
   else
-    let l:numberwidth = 8
+    let l:columns = a:1
   endif
 
-  let l:resize = "se columns" . a:op . "=" . l:numberwidth
+  let l:resize = "se columns" . a:op . "=" . l:columns
 
   " 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
@@ -263,11 +290,11 @@ fun! Number()
 endfun
 
 " Restore window size.
-au VimLeave * if exists("oldcols") | let &columns=oldcols | endif
+au Display VimLeave * if exists("oldcols") | let &columns=oldcols | endif
 
 " Map Makefile mode.
-au BufEnter * if &ft == "make" | call MakeMode_map() | endif
-au BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
+au Mode BufEnter * if &ft == "make" | call MakeMode_map() | endif
+au Mode BufLeave * if &ft == "make" | call MakeMode_unmap() | endif
 
 " Entering Make mode.
 fun! MakeMode_map()
@@ -329,6 +356,8 @@ map Q <NOP>
 " 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\") . \">\"<CR>")
 
+" Show numbers by default.
+au Display VimEnter * call Number()
 endif
 
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -349,8 +378,14 @@ syn enable
 " Nice GUI colour.
 if has("gui_running")
   se guifont=DejaVu\ Sans\ Mono\ 10
+  " XXX: Sort this out.
   colo darkblue
+  hi Cursor guibg=green
   hi LineNr guibg=#303030
+  hi MarkLine guibg=#2e2e2e
+  hi MarkDot guifg=red guibg=#2e2e2e
+  hi MarkSign guifg=lightblue guibg=#2e2e2e
+  hi! link SignColumn LineNr
 elseif &t_Co > 16
   try
     colo iain
@@ -372,16 +407,203 @@ if &diff
 endif
 
 " 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
+au Mode BufWinEnter quickfix let g:quickfixing=1
+au Mode BufUnload * if &ft == "qf" | let g:quickfixing=0 | endif
 
 " Allow in-place editing of crontabs.
-au FileType crontab set backupcopy=yes
+au Mode FileType crontab set backupcopy=yes
 
 " Make * and # work the way you expect in visual mode.
 vnoremap * y/\V<C-R>=substitute(escape(@@,"/\\"),"\n","\\\\n","ge")<CR><CR>
 vnoremap # y?\V<C-R>=substitute(escape(@@,"?\\"),"\n","\\\\n","ge")<CR><CR>
 
+" Set mark and update highlighting.
+au Signs BufEnter * call <SID>Highlight_Signs()
+au Signs CursorHold * call <SID>Highlight_Signs()
+
+fun! <SID>Prep_Signs()
+  if ! exists("b:signdot") || ! g:marksigns
+    let b:signdot=0
+  endif
+  if ! exists("b:signdash") || ! g:marksigns
+    let b:signdash=0
+  endif
+  if ! exists("b:signquote") || ! g:marksigns
+    let b:signquote=0
+  endif
+  if ! exists("b:signcaret") || ! g:marksigns
+    let b:signcaret=0
+  endif
+  if ! exists("b:signless") || ! g:marksigns
+    let b:signless=0
+  endif
+  if ! exists("b:signgreater") || ! g:marksigns
+    let b:signgreater=0
+  endif
+  if ! exists("b:signleft") || ! g:marksigns
+    let b:signleft=0
+  endif
+  if ! exists("b:signright") || ! g:marksigns
+    let b:signright=0
+  endif
+  if ! exists("b:signa") || ! g:marksigns
+    let b:signa=0
+  endif
+  if ! exists("b:signb") || ! g:marksigns
+    let b:signb=0
+  endif
+  if ! exists("b:signc") || ! g:marksigns
+    let b:signc=0
+  endif
+  if ! exists("b:signd") || ! g:marksigns
+    let b:signd=0
+  endif
+  if ! exists("b:signe") || ! g:marksigns
+    let b:signe=0
+  endif
+  if ! exists("b:signf") || ! g:marksigns
+    let b:signf=0
+  endif
+  if ! exists("b:signA") || ! g:marksigns
+    let b:signA=0
+  endif
+  if ! exists("b:signB") || ! g:marksigns
+    let b:signB=0
+  endif
+  if ! exists("b:signC") || ! g:marksigns
+    let b:signC=0
+  endif
+  if ! exists("b:signD") || ! g:marksigns
+    let b:signD=0
+  endif
+  if ! exists("b:signE") || ! g:marksigns
+    let b:signE=0
+  endif
+  if ! exists("b:signF") || ! g:marksigns
+    let b:signF=0
+  endif
+endfun!
+
+fun! <SID>Place_Sign(number, line, old, name)
+  if a:line == a:old
+    return a:old
+  endif
+
+  exe "sign unplace " . (g:firstsign + a:number) . " buffer=" . bufnr("")
+  " Don't place the sign if it would conflict with the last change sign.
+  exe "sign place " . (g:firstsign + a:number) . " line=" . a:line . " name=" . a:name . " buffer=" . bufnr("")
+  return a:line
+endfun
+
+fun! <SID>Highlight_Signs(...)
+  if ! g:marksigns
+    return
+  endif
+
+  call <SID>Prep_Signs()
+
+  let b:signdot = <SID>Place_Sign(0, line("'."), b:signdot, "MarkDot")
+  let b:signdash = <SID>Place_Sign(1, line("''"), b:signdash, "MarkDash")
+  let b:signquote = <SID>Place_Sign(2, line("'\""), b:signquote, "MarkQuote")
+  let b:signcaret = <SID>Place_Sign(3, line("'^"), b:signcaret, "MarkCaret")
+  let b:signless = <SID>Place_Sign(4, line("'<"), b:signcaret, "MarkLess")
+  let b:signgreater = <SID>Place_Sign(5, line("'>"), b:signcaret, "MarkGreater")
+  let b:signleft = <SID>Place_Sign(6, line("'["), b:signcaret, "MarkLeft")
+  let b:signright = <SID>Place_Sign(7, line("']"), b:signcaret, "MarkRight")
+
+  let b:signa = <SID>Place_Sign(8, line("'a"), b:signa, "Marka")
+  let b:signb = <SID>Place_Sign(9, line("'b"), b:signb, "Markb")
+  let b:signc = <SID>Place_Sign(10, line("'c"), b:signc, "Markc")
+  let b:signd = <SID>Place_Sign(11, line("'d"), b:signd, "Markd")
+  let b:signe = <SID>Place_Sign(12, line("'e"), b:signe, "Marke")
+  let b:signf = <SID>Place_Sign(13, line("'f"), b:signf, "Markf")
+  let b:signA = <SID>Place_Sign(14, line("'A"), b:signA, "MarkA")
+  let b:signB = <SID>Place_Sign(15, line("'B"), b:signB, "MarkB")
+  let b:signC = <SID>Place_Sign(16, line("'C"), b:signC, "MarkC")
+  let b:signD = <SID>Place_Sign(17, line("'D"), b:signD, "MarkD")
+  let b:signE = <SID>Place_Sign(18, line("'E"), b:signE, "MarkE")
+  let b:signF = <SID>Place_Sign(19, line("'F"), b:signF, "MarkF")
+endfun
+
+" Toggle signs.
+fun! <SID>Cycle_Signs()
+  call Iain_Vars()
+  let g:marksigns = ! g:marksigns
+
+  if g:marksigns
+    " Signs to highlight marks.
+    " Syntax won't work properly in Vim 6.
+    sign define MarkDash text=' texthl=MarkSign
+    sign define MarkDot text=* texthl=MarkDot
+    sign define MarkQuote text=" texthl=MarkSign
+    sign define MarkCaret text=^ texthl=MarkSign
+    sign define MarkLess text=< texthl=MarkSign
+    sign define MarkGreater text=> texthl=MarkSign
+    sign define MarkLeft text=[ texthl=MarkSign
+    sign define MarkRight text=] texthl=MarkSign
+    sign define Marka text=a texthl=MarkSign linehl=MarkLine
+    sign define Markb text=b texthl=MarkSign linehl=MarkLine
+    sign define Markc text=c texthl=MarkSign linehl=MarkLine
+    sign define Markd text=d texthl=MarkSign linehl=MarkLine
+    sign define Marke text=e texthl=MarkSign linehl=MarkLine
+    sign define Markf text=f texthl=MarkSign linehl=MarkLine
+    sign define MarkA text=A texthl=MarkSign linehl=MarkLine
+    sign define MarkB text=B texthl=MarkSign linehl=MarkLine
+    sign define MarkC text=C texthl=MarkSign linehl=MarkLine
+    sign define MarkD text=D texthl=MarkSign linehl=MarkLine
+    sign define MarkE text=E texthl=MarkSign linehl=MarkLine
+    sign define MarkF text=F texthl=MarkSign linehl=MarkLine
+
+    call Resize_Columns("+", 2)
+    call <SID>Highlight_Signs()
+  else
+    exe "sign unplace " . (g:firstsign + 0)
+    exe "sign unplace " . (g:firstsign + 1)
+    exe "sign unplace " . (g:firstsign + 2)
+    exe "sign unplace " . (g:firstsign + 3)
+    exe "sign unplace " . (g:firstsign + 4)
+    exe "sign unplace " . (g:firstsign + 5)
+    exe "sign unplace " . (g:firstsign + 6)
+    exe "sign unplace " . (g:firstsign + 7)
+    exe "sign unplace " . (g:firstsign + 8)
+    exe "sign unplace " . (g:firstsign + 9)
+    exe "sign unplace " . (g:firstsign + 10)
+    exe "sign unplace " . (g:firstsign + 11)
+    exe "sign unplace " . (g:firstsign + 12)
+    exe "sign unplace " . (g:firstsign + 13)
+    exe "sign unplace " . (g:firstsign + 14)
+    exe "sign unplace " . (g:firstsign + 15)
+    exe "sign unplace " . (g:firstsign + 16)
+    exe "sign unplace " . (g:firstsign + 17)
+    exe "sign unplace " . (g:firstsign + 18)
+    exe "sign unplace " . (g:firstsign + 19)
+
+    sign undefine MarkDash
+    sign undefine MarkDot
+    sign undefine MarkQuote
+    sign undefine MarkCaret
+    sign undefine MarkLess
+    sign undefine MarkGreater
+    sign undefine MarkLeft
+    sign undefine MarkRight
+    sign undefine Marka
+    sign undefine Markb
+    sign undefine Markc
+    sign undefine Markd
+    sign undefine Marke
+    sign undefine Markf
+    sign undefine MarkA
+    sign undefine MarkB
+    sign undefine MarkC
+    sign undefine MarkD
+    sign undefine MarkE
+    sign undefine MarkF
+
+    call <SID>Prep_Signs()
+    call Resize_Columns("-", 2)
+  endif
+endfun
+
 " Change list mode.
 fun! Cycle_List()
   let basic='tab:\\_,trail:_,extends:<,precedes:>'
@@ -440,6 +662,8 @@ call Mapping("q", ":call Cycle_Quickfix()<CR>:<CR>")
 " Rerun filetype detection with \s.  The s is for syntax, as this will be
 " updated as a side-effect.
 call Mapping("s", ":filetype detect<CR>:<CR>")
+" Toggle marks with \m.
+call Mapping("m", ":call <SID>Cycle_Signs()<CR>:<CR>")
 
 fun! <SID>Iain_Colour(colour)
   if &t_Co == 88
@@ -515,7 +739,10 @@ fun! Highlight_StatusLine(flag)
   exec "highlight StatusLine guifg=white guibg=" . l:colour . " ctermbg=white ctermfg=" . l:termcolour
 endfun
 
-call Highlight_StatusLine("")
+au Display VimEnter * call Highlight_StatusLine("")
+
+" Show signs by default.
+au Display VimEnter * call <SID>Cycle_Signs()
 endif
 
 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -595,12 +822,15 @@ 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")
+au StatusLine CursorHoldI * call Highlight_StatusLine("H")
+au StatusLine CursorMovedI * call Highlight_StatusLine("h")
+au StatusLine FocusGained * call Highlight_StatusLine("F")
+au StatusLine FocusLost * call Highlight_StatusLine("f")
+au StatusLine InsertEnter * call Highlight_StatusLine("I")
+au StatusLine InsertLeave * call Highlight_StatusLine("i")
+
+au Signs InsertEnter * call <SID>Highlight_Signs()
+au Signs InsertLeave * call <SID>Highlight_Signs()
 
 " Limit the size of the popup menu when completing.
 se pumheight=20