You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
8.3 KiB
VimL

" RltvNmbr.vim
" Author: Charles E. Campbell, Jr.
" Date: Nov 21, 2008
" Version: 3
" GetLatestVimScripts: 2351 1 :AutoInstall: RltvNmbr.vim
" Phillippians 1:27 : Only let your manner of life be worthy of the gospel of
" Christ, that, whether I come and see you or am absent, I may hear of
" your state, that you stand firm in one spirit, with one soul striving
" for the faith of the gospel
" ---------------------------------------------------------------------
" Load Once: {{{1
if &cp || exists("g:loaded_RltvNmbr")
finish
endif
let g:loaded_RltvNmbr = "v3"
if v:version < 700
echohl WarningMsg
echo "***warning*** this version of RltvNmbr needs vim 7.0"
echohl Normal
finish
endif
if !has("signs")
echoerr 'Sorry, your vim is missing +signs; use "configure --with-features=huge" , recompile, and install'
finish
endif
if !has("syntax")
echoerr 'Sorry, your vim is missing +syntax; use "configure --with-features=huge" , recompile, and install'
finish
endif
let s:keepcpo= &cpo
set cpo&vim
"DechoTabOn
" ---------------------------------------------------------------------
" Parameters: {{{1
let s:RLTVNMBR= 2683
if !exists("g:DrChipTopLvlMenu")
let g:DrChipTopLvlMenu= "DrChip."
endif
" =====================================================================
" Functions: {{{1
" ---------------------------------------------------------------------
" RltvNmbr: {{{2
fun! s:RltvNmbr(mode,...)
" call Dfunc("s:RltvNmbr(mode=".a:mode.((a:0 > 0)? " ".a:1.")" : ")"))
if a:mode == 1
" initial placement of signs
" call Decho("mode ".a:mode.": initial sign placement")
let wt = line("w0")
let wc = line(".")
let wb = line("w$")
" call Decho("initial placement of signs: wt=".wt." wc=".wc." wb=".wb)
let w = wt
let s:rltvnmbr_topline_{bufnr("%")} = wt
let s:rltvnmbr_curline_{bufnr("%")} = wc
let s:rltvnmbr_botline_{bufnr("%")} = wb
while w <= wb
if w == wc
let w= w + 1
continue
endif
let wmwc = w - wc
if foldclosed(w) != -1
" call Decho("skipping w=".w." wmwc=".wmwc." foldclosed=".foldclosed(w))
let w= foldclosedend(w)+1
continue
endif
if wmwc <= -100
let w= wc - 99
continue
endif
if wmwc >= 100
break
endif
if wmwc < 0
let name = "RLTVN_M".(-wmwc)
exe "sign place ".(s:RLTVNMBR + wmwc)." line=".w." name=".name." buffer=".bufnr("%")
else
let name = "RLTVN_P".wmwc
exe "sign place ".(s:RLTVNMBR + wmwc)." line=".w." name=".name." buffer=".bufnr("%")
endif
let w= w + 1
endwhile
elseif a:mode == 2
" call Decho("mode ".a:mode.": consider removing and placing signs")
if exists("s:rltvnmbr_curline_{bufnr('%')}")
" remove and place signs
if line(".") != s:rltvnmbr_curline_{bufnr("%")} || line("w0") != s:rltvnmbr_topline_{bufnr("%")} || line("w$") != s:rltvnmbr_botline_{bufnr("%")}
" call Decho("do remove&place signs : (".line(".").",".line("w0").") =?= (".s:rltvnmbr_curline_{bufnr("%")}.",".s:rltvnmbr_topline_{bufnr("%")}.")")
exe "sign place ".s:RLTVNMBR." line=".s:rltvnmbr_curline_{bufnr("%")}." name=RLTVCURID buffer=".bufnr("%")
let lzkeep= &lz
set lz
call s:RltvNmbr(3) " remove signs
call s:RltvNmbr(1) " place signs
exe "sign unplace ".s:RLTVNMBR." buffer=".bufnr("%")
let &lz= lzkeep
endif
endif
elseif a:mode == 3
" removal of signs
" call Decho("mode ".a:mode.": removal of signs")
let wt = s:rltvnmbr_topline_{bufnr("%")}
let wc = s:rltvnmbr_curline_{bufnr("%")}
let wb = s:rltvnmbr_botline_{bufnr("%")}
" call Decho("using s:wt=".wt." s:wc=".wc." s:wb=".wb)
let w = wt
while w <= wb
if w == wc
let w= w + 1
continue
endif
let wmwc = w - wc
if foldclosed(w) != -1
" call Decho("skipping w=".w." wmwc=".wmwc." foldclosed=".foldclosed(w))
let w= foldclosedend(w)+1
continue
endif
if wmwc <= -100
let w= wc - 99
continue
endif
if wmwc >= 100
break
endif
if wmwc < 0
let name= "RLTVN_M".(-wmwc)
else
let name= "RLTVN_P".wmwc
endif
exe "sign unplace ".(s:RLTVNMBR + wmwc)." buffer=".bufnr("%")
let w= w + 1
endwhile
else
echoerr "mode=".a:mode." unsupported"
endif
" call Dret("s:RltvNmbr")
endfun
" ---------------------------------------------------------------------
" RltvNmbr#RltvNmbrCtrl: {{{2
fun! RltvNmbr#RltvNmbrCtrl(start)
" call Dfunc("RltvNmbr#RltvNmbrCtrl(start=".a:start.")")
if a:start && !exists("s:rltvnmbr_{bufnr('%')}")
let s:rltvnmbr_{bufnr("%")}= 1
let b:rltvnmbrmode = 1
if !exists("s:rltvnmbr_signs")
let s:rltvnmbr_signs= 1
hi default HL_RltvNmbr_Minus gui=none,italic ctermfg=red ctermbg=black guifg=red guibg=black
hi default HL_RltvNmbr_Positive gui=none,italic ctermfg=green ctermbg=black guifg=green guibg=black
silent call s:AvoidOtherSigns()
let L= 1
while L <= 99
exe "sign define RLTVN_M".L.' text='.string(L).' texthl=HL_RltvNmbr_Minus'
exe "sign define RLTVN_P".L.' text='.string(L).' texthl=HL_RltvNmbr_Positive'
let L= L+1
endwhile
endif
sign define RLTVCURID text=-- texthl=Ignore
exe "menu ".g:DrChipTopLvlMenu."RltvNmbr.Stop<tab>:RltvNmbr! :RltvNmbr!<cr>"
exe 'silent! unmenu '.g:DrChipTopLvlMenu.'RltvNmbr.Start'
call s:RltvNmbr(1)
augroup RltvNmbrAutoCmd
au!
au CursorHold * call <SID>RltvNmbr(2,"cursorhold")
au CursorMoved * call <SID>RltvNmbr(2,"cursormoved")
au FileChangedShellPost * call <SID>RltvNmbr(2,"filechangedshellpost")
au FocusGained * call <SID>RltvNmbr(2,"focusgained")
au FocusLost * call <SID>RltvNmbr(2,"focuslost")
au ShellCmdPost * call <SID>RltvNmbr(2,"shellcmdpost")
au ShellFilterPost * call <SID>RltvNmbr(2,"shellfilterpost")
au TabEnter * call <SID>RltvNmbr(2,"tabenter")
au VimResized * call <SID>RltvNmbr(2,"vimresized")
au WinEnter * call <SID>RltvNmbr(2,"winenter")
au ColorScheme * call <SID>ColorschemeLoaded()
augroup END
elseif !a:start && exists("s:rltvnmbr_{bufnr('%')}")
let b:rltvnmbrmode = 0
unlet s:rltvnmbr_{bufnr("%")}
augroup RltvNmbrAutoCmd
au!
augroup END
augroup! RltvNmbrAutoCmd
call s:RltvNmbr(3)
exe "sign unplace ".s:RLTVNMBR." buffer=".bufnr("%")
exe "menu ".g:DrChipTopLvlMenu."RltvNmbr.Start<tab>:RltvNmbr :RltvNmbr<cr>"
exe 'silent! unmenu '.g:DrChipTopLvlMenu.'RltvNmbr.Stop'
else
echo "RltvNmbr is already ".((a:start)? "enabled" : "off")
endif
" call Dret("RltvNmbr#RltvNmbrCtrl")
endfun
" ---------------------------------------------------------------------
" RltvNmbr#RltvNmbrToggle: supports the :RN command for quick relative-number-mode toggling {{{2
" If the :RN command is already available, then it will not be overridden.
fun! RltvNmbr#RltvNmbrToggle()
" call Dfunc("RltvNmbr#RltvNmbrToggle()")
if !exists("b:rltvnmbrmode")
let b:rltvnmbrmode= 0
endif
if b:rltvnmbrmode == 0
RltvNmbr
else
RltvNmbr!
endif
" call Dret("RltvNmbr#RltvNmbrToggle")
endfun
" ---------------------------------------------------------------------
" s:ColorschemeLoaded: {{{2
fun! s:ColorschemeLoaded()
" call Dfunc("s:ColorschemeLoaded()")
hi HL_RltvNmbr_Minus ctermfg=red ctermbg=black guifg=red guibg=black
hi HL_RltvNmbr_Positive ctermfg=green ctermbg=black guifg=green guibg=black
" call Dret("s:ColorschemeLoaded")
endfun
" ---------------------------------------------------------------------
" s:AvoidOtherSigns: {{{2
fun! s:AvoidOtherSigns()
" call Dfunc("s:AvoidOtherSigns()")
if !exists("s:othersigns")
" only do this one time
redir => s:othersigns
sign place
redir END
" determine the max id being used and use one more than that as the beginning of RltvNmbr ids
let signlist= split(s:othersigns,'\n')
let idlist = map(signlist,"substitute(v:val,'^.\\{-}\\<id=\\(\\d\\+\\)\\s.*$','\\1','')")
if len(idlist) > 2
let idlist = remove(idlist,2,-1)
let idlist = map(idlist,"str2nr(v:val)")
let idmax = max(idlist)
if idmax > s:RLTVNMBR
let s:RLTVNMBR = idmax + 1
" call Decho("s:RLTVNMBR=".s:RLTVNMBR)
endif
endif
unlet s:othersigns
let s:othersigns= 1
endif
" call Dret("s:AvoidOtherSigns : s:RLTVNMBR=".s:RLTVNMBR)
endfun
" ---------------------------------------------------------------------
" Restore: {{{1
let &cpo= s:keepcpo
unlet s:keepcpo
" vim: ts=4 fdm=marker