mirror of
1
0
Fork 0
ultimate-vim/vim_plugins_src/visualmark.vim

337 lines
9.7 KiB
VimL

" Visual Mark
" 2005-10-27, brian wang
"
" Acknowledgements:
" - Thanks to Hari Krishna Dara's genutils.vim (http://vim.sourceforge.net/scripts/script.php?script_id=197)
" - Thanks to Mr. Charles E. Campbell, Jr. for making this script more plugin-like :-)
" - Thanks to Mr. Charles E. Campbell, Jr. for making this script adapt to
" dark/light backgrounds
" - Thanks to Evgeny Filatov for noticing a nasty bug in Vm_get_line_number :-)
if exists("loaded_VisualMark")
finish
endif
let loaded_VisualMark = 1
if !has("signs")
echoerr "***sorry*** [".expand("%")."] your vim doesn't support signs"
finish
endif
if &bg == "dark"
highlight SignColor ctermfg=white ctermbg=blue guifg=white guibg=RoyalBlue3
else
highlight SignColor ctermbg=white ctermfg=blue guibg=grey guifg=RoyalBlue3
endif
" ---------------------------------------------------------------------
" Public Interface:
if !hasmapto('<Plug>Vm_toggle_sign')
map <unique> <c-F2> <Plug>Vm_toggle_sign
map <silent> <unique> mm <Plug>Vm_toggle_sign
endif
nnoremap <silent> <script> <Plug>Vm_toggle_sign :call Vm_toggle_sign()<cr>
if !hasmapto('<Plug>Vm_goto_next_sign')
map <unique> <F2> <Plug>Vm_goto_next_sign
endif
nnoremap <silent> <script> <Plug>Vm_goto_next_sign :call Vm_goto_next_sign()<cr>
if !hasmapto('<Plug>Vm_goto_prev_sign')
map <unique> <s-F2> <Plug>Vm_goto_prev_sign
endif
nnoremap <silent> <script> <Plug>Vm_goto_prev_sign :call Vm_goto_prev_sign()<cr>
" ---------------------------------------------------------------------
" GetVimCmdOutput:
" Stole from Hari Krishna Dara's genutils.vim (http://vim.sourceforge.net/scripts/script.php?script_id=197)
" to ease the scripts dependency issue
fun! s:GetVimCmdOutput(cmd)
" call Dfunc("GetVimCmdOutput(cmd.".a:cmd.">)")
" Save the original locale setting for the messages
let old_lang = v:lang
" Set the language to English
exec ":lan mes en_US"
let v:errmsg = ''
let output = ''
let _z = @z
try
redir @z
silent exe a:cmd
catch /.*/
let v:errmsg = substitute(v:exception, '^[^:]\+:', '', '')
finally
redir END
if v:errmsg == ''
let output = @z
endif
let @z = _z
endtry
" Restore the original locale
exec ":lan mes " . old_lang
" call Dret("GetVimCmdOutput <".output.">")
return output
endfun
" ---------------------------------------------------------------------
" Vm_place_sign:
fun! s:Vm_place_sign()
" call Dfunc("Vm_place_sign()")
if !exists("b:Vm_sign_number")
let b:Vm_sign_number = 1
endif
let ln = line(".")
exe 'sign define SignSymbol linehl=SignColor texthl=SignColor'
exe 'sign place ' . b:Vm_sign_number . ' line=' . ln . ' name=SignSymbol buffer=' . winbufnr(0)
let vsn = b:Vm_sign_number
let b:Vm_sign_number = b:Vm_sign_number + 1
" call Dret("Vm_place_sign : sign#".vsn." line#".ln." buf#".winbufnr(0))
endfun
" ---------------------------------------------------------------------
" Vm_remove_sign:
fun! s:Vm_remove_sign(sign_id)
" call Dfunc("Vm_remove_sign(sign_id=".a:sign_id.")")
silent! exe 'sign unplace ' . a:sign_id . ' buffer=' . winbufnr(0)
" call Dret("Vm_remove_sign")
endfun
" ---------------------------------------------------------------------
" Vm_remove_all_signs:
fun! s:Vm_remove_all_signs()
" call Dfunc("Vm_remove_all_signs()")
silent! exe 'sign unplace *'
" call Dret("Vm_remove_all_signs")
endfun
" ---------------------------------------------------------------------
" Vm_get_sign_id_from_line:
fun! s:Vm_get_sign_id_from_line(line_number)
" call Dfunc("Vm_get_sign_id_from_line(line_number=".a:line_number.")")
let sign_list = s:GetVimCmdOutput('sign place buffer=' . winbufnr(0))
" call Decho(sign_list)
let line_str_index = match(sign_list, "line=" . a:line_number, 0)
if line_str_index < 0
" call Dret("Vm_get_sign_id_from_line -1")
return -1
endif
let id_str_index = matchend(sign_list, "id=", line_str_index)
" let tmp = strpart(sign_list, id_str_index, 10) "Decho
" call Decho("ID str index: " . tmp)
if id_str_index < 0
" call Dret("Vm_get_sign_id_from_line -1")
return -1
endif
let space_index = match(sign_list, " ", id_str_index)
let id = strpart(sign_list, id_str_index, space_index - id_str_index)
" call Dret("Vm_get_sign_id_from_line ".id)
return id
endfun
" ---------------------------------------------------------------------
" Vm_toggle_sign:
fun! Vm_toggle_sign()
" call Dfunc("Vm_toggle_sign()")
let curr_line_number = line(".")
let sign_id = s:Vm_get_sign_id_from_line(curr_line_number)
if sign_id < 0
let is_on = 0
else
let is_on = 1
endif
if (is_on != 0)
call s:Vm_remove_sign(sign_id)
else
call s:Vm_place_sign()
endif
" call Dret("Vm_toggle_sign")
endfun
" ---------------------------------------------------------------------
" Vm_get_line_number:
fun! s:Vm_get_line_number(string)
" call Dfunc("Vm_get_line_number(string<".a:string.">)")
let line_str_index = match(a:string, "line=", b:Vm_start_from)
if line_str_index <= 0
" call Dret("Vm_get_line_number -1")
return -1
endif
let equal_sign_index = match(a:string, "=", line_str_index)
let space_index = match(a:string, " ", equal_sign_index)
let line_number = strpart(a:string, equal_sign_index + 1, space_index - equal_sign_index - 1)
let b:Vm_start_from = space_index
" call Dret("Vm_get_line_number ".line_number." : =indx:".equal_sign_index." _indx=".space_index)
return line_number + 0
endfun
" ---------------------------------------------------------------------
" Vm_get_next_sign_line:
fun! s:Vm_get_next_sign_line(curr_line_number)
" call Dfunc("Vm_get_next_sign_line(curr_line_number=".a:curr_line_number.">)")
let b:Vm_start_from = 1
let sign_list = s:GetVimCmdOutput('sign place buffer=' . winbufnr(0))
" call Decho("sign_list<".sign_list.">")
let curr_line_number = a:curr_line_number
let line_number = 1
let is_no_sign = 1
let min_line_number = -1
let min_line_number_diff = 0
while 1
let line_number = s:Vm_get_line_number(sign_list)
if line_number < 0
break
endif
" Record the very first line that has a sign
if is_no_sign != 0
let min_line_number = line_number
elseif line_number < min_line_number
let min_line_number = line_number
endif
let is_no_sign = 0
" let tmp_diff = curr_line_number - line_number
let tmp_diff = line_number - curr_line_number
if tmp_diff > 0
" line_number is below curr_line_number
if min_line_number_diff > 0
if tmp_diff < min_line_number_diff
let min_line_number_diff = tmp_diff
endif
else
let min_line_number_diff = tmp_diff
endif
endif
" call Decho("[DBG] Line Diff: #" . min_line_number_diff)
endwhile
let line_number = curr_line_number + min_line_number_diff
" call Decho("[DBG] Line Diff: #" . min_line_number_diff)
" call Decho("[DBG] Line Num: #" . line_number)
if is_no_sign != 0 || min_line_number_diff <= 0
let line_number = min_line_number
endif
" call Dret("Vm_get_next_sign_line ".line_number . " XXX")
return line_number
endfun
" ---------------------------------------------------------------------
" Vm_get_prev_sign_line:
fun! s:Vm_get_prev_sign_line(curr_line_number)
" call Dfunc("Vm_get_prev_sign_line(curr_line_number=".a:curr_line_number.">)")
let b:Vm_start_from = 1
let sign_list = s:GetVimCmdOutput('sign place buffer=' . winbufnr(0))
" call Decho("sign_list<".sign_list.">")
let curr_line_number = a:curr_line_number
let line_number = 1
let is_no_sign = 1
let max_line_number = -1
let max_line_number_diff = 0
while 1
let line_number = s:Vm_get_line_number(sign_list)
if line_number < 0
break
endif
" Record the very first line that has a sign
if is_no_sign != 0
let max_line_number = line_number
elseif line_number > max_line_number
let max_line_number = line_number
endif
let is_no_sign = 0
let tmp_diff = curr_line_number - line_number
if tmp_diff > 0
" line_number is below curr_line_number
if max_line_number_diff > 0
if tmp_diff < max_line_number_diff
let max_line_number_diff = tmp_diff
endif
else
let max_line_number_diff = tmp_diff
endif
endif
" call Decho("[DBG] Line Diff: #" . max_line_number_diff)
" call Decho("[DBG] Tmp Diff: #" . tmp_diff)
endwhile
let line_number = curr_line_number - max_line_number_diff
" call Decho("[DBG] Line Diff: #" . max_line_number_diff)
" call Decho("[DBG] Line Num: #" . line_number)
if is_no_sign != 0 || max_line_number_diff <= 0
let line_number = max_line_number
endif
" call Dret("Vm_get_prev_sign_line ".line_number . " XXX")
return line_number
endfun
" ---------------------------------------------------------------------
" Vm_goto_next_sign:
fun! Vm_goto_next_sign()
" call Dfunc("Vm_goto_next_sign()")
let curr_line_number = line(".")
let next_sign_line_number = s:Vm_get_next_sign_line(curr_line_number)
" call Decho("Next sign line #: " . next_sign_line_number)
if next_sign_line_number >= 0
exe ":" . next_sign_line_number
"call Decho("Going to Line #" . next_sign_line_number)
endif
" call Dret("Vm_goto_next_sign")
endfun
" ---------------------------------------------------------------------
" Vm_goto_prev_sign:
fun! Vm_goto_prev_sign()
" call Dfunc("Vm_goto_prev_sign()")
let curr_line_number = line(".")
let prev_sign_line_number = s:Vm_get_prev_sign_line(curr_line_number)
" call Decho("Previous sign line #: " . prev_sign_line_number)
if prev_sign_line_number >= 0
exe prev_sign_line_number
endif
" call Dret("Vm_goto_prev_sign")
endfun
" ---------------------------------------------------------------------