-rw-r--r-- start/self/plugin/noscrollbar.vim
1 "------------------------------------------------------------------" 2 " noscrollbar plugin from github.com/gcavallanti/vim-noscrollbar 3 "------------------------------------------------------------------" 4 if &cp || exists('g:noscrollbar_loaded') 5 finish 6 endif 7 8 let g:noscrollbar_loaded = 1 9 10 function! noscrollbar#statusline(...) 11 let top_line = line("w0") 12 let bottom_line = line("w$") 13 let current_line = line('.') 14 let lines_count = line('$') 15 16 " Default values 17 let length = 20 18 let tracksymbol = '-' 19 let grippersymbol = '#' 20 let gripperleftsymbols = [] 21 let gripperrightsymbols = [] 22 let part = 'a' 23 24 if a:0 >= 3 25 let length = a:1 26 let tracksymbol = a:2 27 let grippersymbol = a:3 28 endif 29 30 if a:0 >= 5 && type(a:4) == 3 && type(a:5) == 3 31 \ && len(a:4) == len(a:5) 32 let gripperleftsymbols = a:4 33 let gripperrightsymbols = a:5 34 endif 35 36 if a:0 >= 6 37 let part = a:6 38 endif 39 40 let scaling = len(gripperleftsymbols) + 1 41 42 " Compute gripper position and size as if we have scaling times a:1 43 " characters available. Will shrink everything back just before returning 44 let scrollbar_length = str2nr(length) * scaling 45 46 " Gripper positions are 0 based (0..scrollbar_length-1) 47 let gripper_position = float2nr((top_line - 1.0) / lines_count 48 \ * scrollbar_length) 49 let gripper_length = float2nr(ceil((bottom_line - top_line + 1.0) 50 \ / lines_count * scrollbar_length)) 51 52 " Users expect to see the scrollbar in the leftmost position only if we 53 " are at the very top of the buffer 54 if (top_line > 1) && (gripper_position == 0) 55 " Since the top line is not visible shift the gripper by one position 56 let gripper_position = 1 57 if (gripper_position + gripper_length > scrollbar_length) 58 " Shrink the gripper if we end up after the end of the scrollbar 59 let gripper_length = gripper_length - 1 60 endif 61 endif 62 63 if (bottom_line < lines_count) 64 \ && (gripper_position + gripper_length == scrollbar_length) 65 " As before, if the last line is not on the screen but the scrollbar 66 " seems to indicate so then either move the scrollbar position leftwise 67 " by one position or decrease its length 68 if gripper_position > 0 69 let gripper_position = gripper_position - 1 70 else 71 let gripper_length = gripper_length - 1 72 endif 73 endif 74 75 " Shrink everything back to the range [0, a:1) 76 let gripper_position = 1.0 * gripper_position / scaling 77 let gripper_length = 1.0 * gripper_length / scaling 78 let scrollbar_length = 1.0 * scrollbar_length / scaling 79 80 " The left of the gripper is broken in 3 parts. The left and right are 81 " fractionals in the range [0, len(a:4)). 82 let gripper_length_left = ceil(gripper_position) - gripper_position 83 " Hackish rounding errors workaround. If `gripper_length 84 " - gripper_lenght_left` is 0.9999.. we force it to 1 before rounding it 85 let gripper_length_middle = floor(round((gripper_length 86 \ - gripper_length_left)*100.0)/100.0) 87 let gripper_length_right = gripper_length - gripper_length_left 88 \ - gripper_length_middle 89 90 " Time to assemble the actual scrollbar 91 let scrollbar = '' 92 if part != 'm' && part != 'r' 93 let scrollbar .= repeat(tracksymbol, float2nr(floor(gripper_position))) 94 95 let grippersymbol_index = float2nr(round(gripper_length_left * scaling)) 96 if grippersymbol_index != 0 97 let scrollbar .= gripperleftsymbols[grippersymbol_index - 1] 98 endif 99 endif 100 101 if part != 'l' && part != 'r' 102 let scrollbar .= repeat(grippersymbol, float2nr(gripper_length_middle)) 103 endif 104 105 if part != 'l' && part != 'm' 106 let grippersymbol_index = float2nr(round(gripper_length_right * scaling)) 107 if grippersymbol_index != 0 108 let scrollbar .= gripperrightsymbols[grippersymbol_index - 1] 109 endif 110 let scrollbar .= repeat(tracksymbol, float2nr(scrollbar_length 111 \ - ceil(gripper_position + gripper_length))) 112 endif 113 114 return scrollbar 115 endfunction 116