+" Set mark and update highlighting.
+if has("signs")
+ au Signs BufReadPost * call <SID>Highlight_Signs()
+ au Signs CursorHold * call <SID>Highlight_Signs()
+endif
+
+" Helper to set buffer variable for a given sign.
+fun! <SID>Prep_Sign(sign) "{{{2
+ if ! exists("b:sign" . a:sign) || ! g:marksigns
+ exe "let b:sign" . a:sign . "=0"
+ endif
+endfun "}}}2
+
+fun! <SID>Place_Sign(number, line, old, name) "{{{2
+ 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 "}}}2
+
+fun! <SID>Highlight_Signs(...) "{{{2
+ if ! has("signs") || ! g:marksigns || Uncluttered_Buffer()
+ return
+ endif
+
+ let l:signs = g:iainsigns
+ let l:sign = ""
+ let l:i = 0
+ while strlen(l:signs)
+ let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
+
+ let l:name = substitute(l:sign, '[:.=>-].*', "", "")
+ let l:var = tolower(l:name)
+ let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
+ let l:ascii = matchstr(l:sign, '^:.')
+ let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
+ if strlen(l:ascii)
+ let l:ascii = substitute(l:ascii, '^:', "", "")
+ else
+ let l:ascii = l:mark
+ endif
+ let l:ascii = substitute(l:ascii, '"', '\\"', "")
+
+ if l:ascii == "o"
+ let l:line = "."
+ else
+ let l:line = "'" . l:ascii
+ endif
+
+ call <SID>Prep_Sign(l:var)
+ exe "let " . l:var . " = <SID>Place_Sign(" . l:i . ", line(\"" . l:line . "\"), b:sign" . l:var . ", \"Mark" . l:name . "\")"
+ let l:i = l:i + 1
+
+ let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
+ endwhile
+endfun "}}}2
+
+" Toggle signs.
+fun! <SID>Cycle_Signs(resize) "{{{2
+ if ! has("signs")
+ return
+ endif
+ call Iain_Vars()
+ let g:marksigns = ! g:marksigns
+
+ " Retrofit arrays on to Vim 6.
+ if ! exists("g:iainsigns")
+ " Signs are defined in g:iainsigns. The syntax is as follows:
+ "
+ " Sign ::= Name (':' Mark)* Type Symbol
+ " Type ::= '=' | '-' | '.'
+ "
+ " Signs with Type '=' will be highlighted with the MarkSign group.
+ " Signs with Type '-' will be highlighted with the MarkLine group.
+ " Signs with Type '.' will be highlighted with the MarkDot group.
+ " Signs with Type '>' will be highlighted with the MarkArrow group.
+ " Define the Mark where Symbol is not also the mark name, eg "']".
+ let g:iainsigns = "Less=< Greater=> Left=( Right=) SquareLeft=[ SquareRight=] BraceLeft={ BraceRight=} a-a b-b c-c d-d e-e f-f A-A B-B C-C D-D E-E F-F"
+ if Has_Unicode()
+ let g:iainsigns = g:iainsigns . " Quote:\"=” Dash:'=’ Caret:^.ʌ Dot:..•"
+ if version < "704"
+ let g:iainsigns = g:iainsigns ." Cursor:o>▶"
+ endif
+ else
+ let g:iainsigns = g:iainsigns . " Quote=\" Dash=' Caret.^ Dot:..*"
+ if version < "704"
+ let g:iainsigns = g:iainsigns ." Cursor>o"
+ endif
+ endif
+ endif
+
+ if g:marksigns
+ " Signs to highlight marks.
+ " Syntax won't work properly in Vim 6.
+ let l:signs = g:iainsigns
+ let l:sign = ""
+ while strlen(l:signs)
+ let l:sign = matchstr(l:signs, '^[A-Za-z]\+\(:.\)*[.=>-][^ ]\+')
+
+ let l:name = substitute(l:sign, '[:.=>-].*', "", "")
+ let l:sign = substitute(l:sign, '^[A-Za-z]\+', "", "")
+ let l:ascii = matchstr(l:sign, '^:.')
+ let l:mark = substitute(l:sign, '^\(:.\)*[.=>-]', "", "")
+ if strlen(l:ascii)
+ let l:ascii = substitute(l:ascii, '^:', "", "")
+ let l:ascii = matchstr(l:ascii, '^.')
+ else
+ let l:ascii = l:mark
+ endif
+ let l:ascii = substitute(l:ascii, '"', '\\"', "")
+ let l:type = substitute(l:sign, '^:.', "", "")
+ let l:type = matchstr(l:type, '^.')
+
+ let l:hl = ""
+ if l:type == "="
+ let l:hl = "texthl=MarkSign text="
+ elseif l:type == "."
+ let l:hl = "texthl=MarkDot text="
+ elseif l:type == "-"
+ let l:hl = "texthl=MarkLine text="
+ elseif l:type == ">"
+ let l:hl = "texthl=MarkArrow text="
+ endif
+
+ exe "sign define Mark" . l:name . " " . l:hl . l:mark
+
+ let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
+ endwhile
+
+ if a:resize
+ call Resize_Columns("+", 2)
+ endif
+ call <SID>Highlight_Signs()
+ else
+ let l:i = 0
+ while l:i < 25
+ exe "sign unplace " . (g:firstsign + l:i)
+ let l:i = l:i + 1
+ endwhile
+
+ let l:signs = g:iainsigns
+ let l:sign = ""
+ while strlen(l:signs)
+ let l:sign = matchstr(l:signs, '^[A-Za-z]\+')
+
+ exe "sign undefine Mark" . l:sign
+ call <SID>Prep_Sign(tolower(l:sign))
+ let l:signs = substitute(l:signs, '^[^ ]\+ *', "", "")
+ endwhile
+
+ if a:resize
+ call Resize_Columns("-", 2)
+ endif
+ endif
+endfun "}}}2
+