" Vim global plugin to display a curses scrollbar " Version: 0.2.0 " Last Change: 2015 Jul 18 " Initial Author: Loni Nix " Contributors: Samuel Chern-Shinn Liu " www.martin35.de " " License: Distributed under the same terms as Vim itself. See " `:help license` " Skip init if the loaded_scrollbar var is set. if exists('g:loaded_scrollbar') finish endif let g:loaded_scrollbar=1 " Save cpoptions. let s:save_cpoptions=&cpoptions set cpoptions&vim " Set what character gets displayed for normal vs scrollbar highlighted lines. " Default to '#' for scrollbar, '|' for non-scrollbar. " (User can override these!) if !exists('g:scrollbar_thumb') let g:scrollbar_thumb='█' endif " Set highlighting scheme. (User can override these!) highlight Scrollbar_Thumb ctermfg=blue ctermbg=blue guifg=blue guibg=blue cterm=reverse highlight Scrollbar_Marker ctermfg=yellow ctermbg=yellow guifg=yellow guibg=yellow cterm=reverse " Set signs we're goint to use. http://vimdoc.sourceforge.net/htmldoc/sign.html exec "sign define sbthumb text=".g:scrollbar_thumb." texthl=Scrollbar_Thumb" exec "sign define sbmarker text=█ texthl=Scrollbar_Marker" " Set up a default mapping to toggle the scrollbar (but only if user hasn't " already done it). Default is sb. if !hasmapto('ToggleScrollbar') map sb :call ToggleScrollbar() endif " Function to initialize the scrollbar's 'active' vars. function! SetScrollbarActiveIfUninitialized() " Checks to ensure the active vars are set for global / this buffer. if !exists('b:scrollbar_active') if !exists('g:scrollbar_active') let g:scrollbar_active=1 endif let b:scrollbar_active=g:scrollbar_active endif endfunction call SetScrollbarActiveIfUninitialized() " Function to toggle the scrollbar. function! ToggleScrollbar() call SetScrollbarActiveIfUninitialized() if b:scrollbar_active " Toggle to inactive mode. let b:scrollbar_active=0 " Unset all autocmds for scrollbar. augroup Scrollbar_augroup autocmd! augroup END " Remove all signs that have been set. :sign unplace * else " Toggle to active. Setup the scrollbar. let b:scrollbar_active=1 call SetupScrollbar() endif endfunction " Set up autocmds to react to user input. function! SetupScrollbar() augroup Scrollbar_augroup z autocmd BufEnter * :call showScrollbar() autocmd BufWinEnter * :call showScrollbar() autocmd CursorMoved * :call showScrollbar() autocmd CursorMovedI * :call showScrollbar() autocmd FocusGained * :call showScrollbar() autocmd VimResized * :call changeScreenSize()|:call showScrollbar() augroup END call showScrollbar() endfunction " Main function that is called every time a user navigates the current buffer. function! showScrollbar() call SetScrollbarActiveIfUninitialized() " Quit if the initialized active vars are set to false. if g:scrollbar_active==0 || b:scrollbar_active==0 return endif " Buffer number. let buffer_number=bufnr("%") " Total # lines. let total_lines=line('$') " First line visible in the current window (at top of the buffer). let buffer_top=line('w0') " Last line visible in the current window. (at bottom of the buffer). let buffer_bottom=line('w$') " Text height. let text_height=buffer_bottom-buffer_top " If the window height is the same or greater than the total # of lines, we " don't need to show a scrollbar. The whole page is visible in the buffer! if winheight(0) >= total_lines exec ":sign unplace * buffer=" . buffer_number return endif " Performance enhancer: don't redraw unless buffer window is changed. if !exists('b:buffer_top') || !exists('b:buffer_bottom') let b:buffer_top=buffer_top let b:buffer_bottom=buffer_bottom elseif b:buffer_top==buffer_top && b:buffer_bottom==buffer_bottom return else let b:buffer_top=buffer_top let b:buffer_bottom=buffer_bottom endif " How much padding at the top and bottom to give the scrollbar. let padding_top=float2nr(float2nr((buffer_top*1000 / total_lines) * text_height) / 1000) let padding_bottom=float2nr(float2nr(((total_lines - buffer_bottom)*1000 / total_lines) * text_height) / 1000) " place markers for top and bottom of file exec ":sign place 9999998 line=1 name=sbmarker buffer=" . buffer_number exec ":sign place 9999999 line=" . total_lines . " name=sbmarker buffer=" . buffer_number " get all set signs for current buffer redir => idlist silent exec ":sign place buffer=" . buffer_number redir END " unset all signs except top and bottom marker let curr_line = buffer_top let indexline = stridx(idlist, "id=") while indexline > -1 let idstart = indexline + 3 let indexspace = stridx(idlist, " ", idstart) let idlength = indexspace - idstart let idnumber = strpart(idlist, idstart, idlength) if idnumber != "9999999" && idnumber != "9999998" && curr_line > 1 && curr_line < total_lines exec ":sign unplace " . idnumber . " buffer=" . buffer_number endif let indexline = indexspace let indexline = stridx(idlist, "id=", indexline) endwhile " Set the signs based on the delimiters calculated above! while curr_line <= buffer_bottom if curr_line > 1 && curr_line < total_lines if curr_line >= (buffer_top+padding_top) && curr_line <= (buffer_bottom-padding_bottom) exec ":sign place " . curr_line . " line=" . curr_line." name=sbthumb buffer=" . buffer_number endif endif let curr_line=curr_line + 1 endwhile endfunction " Call setup if vars are set for 'active' scrollbar. if g:scrollbar_active != 0 call SetupScrollbar() endif " " Restore cpoptions. let &cpoptions=s:save_cpoptions unlet s:save_cpoptions " " vim: set filetype=vim fileformat=unix expandtab softtabstop=4 shiftwidth=4 tabstop=8: