Skip to content

Commit

Permalink
Issue #4: Add column configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
dstein64 committed Dec 17, 2020
1 parent ded4ca8 commit 23fdffb
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 15 deletions.
93 changes: 88 additions & 5 deletions autoload/scrollview.vim
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
" WARN: Sometimes 1-indexing is used (primarily for mutual Vim/Neovim API
" calls) and sometimes 0-indexing (primarily for Neovim-specific API calls).

" *************************************************
" * Globals
" *************************************************
Expand All @@ -23,6 +26,31 @@ function! s:Contains(list, element) abort
return index(a:list, a:element) !=# -1
endfunction

" Executes a list of commands in the context of the specified window.
" Autocommands will not be triggered (unless the commands change eventignore
" accordingly). If a local result variable is set, it will be returned.
" WARN: This differ's from Vim's win_execute, as that triggers autocommands
" when executing a command.
function! s:WinExecute(winid, commands) abort
let l:eventignore = &eventignore
try
set eventignore=all
let l:current_winid = win_getid(winnr())
call win_gotoid(a:winid)
for l:command in a:commands
execute l:command
endfor
call win_gotoid(l:current_winid)
finally
let &eventignore = l:eventignore
endtry
if exists('l:result')
return l:result
else
return
endif
endfunction

" *************************************************
" * Core
" *************************************************
Expand All @@ -47,6 +75,36 @@ function! s:InCommandLineWindow() abort
return l:buftype ==# 'nofile' && l:bufname ==# '[Command Line]'
endfunction

" Returns the window column where the buffer's text begins. This may be
" negative due to horizontal scrolling. This may be greater than one due to
" the sign column and 'number' column.
function! s:BufferTextBeginsColumn(winid) abort
" The calculation assumes lines don't wrap, so 'nowrap' is temporarily set.
let l:commands = [
\ 'let l:wrap = &l:wrap',
\ 'setlocal nowrap',
\ 'let l:result = wincol() - virtcol(".") + 1',
\ 'let &l:wrap = l:wrap'
\ ]
let l:result = s:WinExecute(a:winid, l:commands)
return l:result
endfunction

" Returns the window column where the view of the buffer begins. This can be
" greater than one due to the sign column and 'number' column.
function! s:BufferViewBeginsColumn(winid) abort
" The calculation assumes lines don't wrap, so 'nowrap' is temporarily set.
let l:commands = [
\ 'let l:wrap = &l:wrap',
\ 'setlocal nowrap',
\ 'let l:result = wincol() - virtcol(".")'
\ . ' + winsaveview().leftcol + 1',
\ 'let &l:wrap = l:wrap'
\ ]
let l:result = s:WinExecute(a:winid, l:commands)
return l:result
endfunction

" Calculates the bar position for the specified window. Returns a dictionary
" with a height, row, and col.
function! s:CalculatePosition(winnr) abort
Expand All @@ -63,6 +121,7 @@ function! s:CalculatePosition(winnr) abort
let l:line_count = nvim_buf_line_count(l:bufnr)
let [l:row, l:col] = win_screenpos(l:winnr)
let l:winheight = winheight(l:winnr)
let l:winwidth = winwidth(l:winnr)
" l:top is relative to the window, and 0-indexed.
let l:top = 0
if l:line_count ># 1
Expand All @@ -82,12 +141,23 @@ function! s:CalculatePosition(winnr) abort
if l:top + l:height ># l:winheight
let l:top = l:winheight - l:height
endif
let l:col += winwidth(l:winnr) - 1
" At this point, l:col corresponds the window's leftmost column.
if g:scrollview_base ==# 'left'
let l:col += g:scrollview_column - 1
elseif g:scrollview_base ==# 'right'
let l:col += l:winwidth - g:scrollview_column
elseif g:scrollview_base ==# 'buffer'
let l:col += g:scrollview_column - 1
\ + s:BufferTextBeginsColumn(l:winid) - 1
else
" For an unknown base, use the default position (right edge of window).
let l:col += l:winwidth - 1
endif
let l:line = l:row + l:top
let l:result = {
\ 'height': l:height,
\ 'row': l:line - 1,
\ 'col': l:col - 1
\ 'row': l:line,
\ 'col': l:col
\ }
return l:result
endfunction
Expand Down Expand Up @@ -116,6 +186,19 @@ function! s:ShowScrollbar(winnr) abort
if l:winheight ==# l:bar_position.height
return
endif
" Don't show scrollbar when its column is beyond what's valid.
let l:min_valid_col = 1
let l:max_valid_col = l:winwidth
if g:scrollview_base ==# 'buffer'
let l:min_valid_col = s:BufferViewBeginsColumn(l:winid)
endif
let l:col = l:bar_position.col - win_screenpos(l:winnr)[1] + 1
if l:col <# l:min_valid_col
return
endif
if l:col ># l:winwidth
return
endif
if s:bar_bufnr ==# -1
let s:bar_bufnr = nvim_create_buf(0, 1)
call setbufvar(s:bar_bufnr, '&modifiable', 0)
Expand All @@ -128,8 +211,8 @@ function! s:ShowScrollbar(winnr) abort
\ 'style': 'minimal',
\ 'height': l:bar_position.height,
\ 'width': 1,
\ 'row': l:bar_position.row,
\ 'col': l:bar_position.col
\ 'row': l:bar_position.row - 1,
\ 'col': l:bar_position.col - 1
\ }
let l:bar_winid = nvim_open_win(s:bar_bufnr, 0, l:options)
call add(s:bar_winids, l:bar_winid)
Expand Down
30 changes: 20 additions & 10 deletions doc/scrollview.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*scrollview.txt* Plugin that displays (non-interactive) scrollbars
*scrollview.txt* Plugin that displays (non-interactive) scrollbars
*nvim-scrollview*

Author: Daniel Steinberg - https://www.dannyadam.com
Expand Down Expand Up @@ -41,30 +41,40 @@ Use |packages| or one of the various package managers.
The following variables can be used to customize the behavior of
|nvim-scrollview|.

`Variable` `Default`
Description Info
------------- -------
`Variable` `Default`
Description Info
------------- -------

*g:scrollview_on_startup* `1`
*g:scrollview_on_startup* `1`
Specifies whether scrollbars are
enabled on startup
*g:scrollview_excluded_filetypes* `[]`
*g:scrollview_excluded_filetypes* `[]`
Optional file types for which
scrollbars should not be displayed
*g:scrollview_current_only* `0`
*g:scrollview_current_only* `0`
Specifies whether scrollbars should
only be displayed in the current
window
*g:scrollview_winblend* `50`
Specifies the level of transparency An integer between 0 (opaque)
for scrollbars and 100 (transparent)
*g:scrollview_winblend* `50`
Specifies the level of transparency An integer between 0 (opaque) and
for scrollbars 100 (transparent)
*g:scrollview_base* `right`
Specifies where the scrollbar is `left` or `right` for corresponding
anchored window edges, or `buffer` for buffer
*g:scrollview_column* `1`
Specifies the scrollbar column An integer greater than or equal
(relative to |g:scrollview_base|) to 1


The variables can be customized in your |init.vim|, as shown in the following
example.
>
let g:scrollview_excluded_filetypes = ['nerdtree']
let g:scrollview_current_only = 1
let g:scrollview_winblend = 75
" Position the scrollbar at the 80th character of the buffer
let g:scrollview_base = 'buffer'
let g:scrollview_column = 80
Color Customization ~
*scrollview-color-customization*
Expand Down
2 changes: 2 additions & 0 deletions plugin/scrollview.vim
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ let g:scrollview_current_only = get(g:, 'scrollview_current_only', 0)
highlight default link ScrollView Visual
" Using a winblend of 100 results in the bar becoming invisible on nvim-qt.
let g:scrollview_winblend = get(g:, 'scrollview_winblend', 50)
let g:scrollview_column = get(g:, 'scrollview_column', 1)
let g:scrollview_base = get(g:, 'scrollview_base', 'right')

" *************************************************
" * Commands
Expand Down

0 comments on commit 23fdffb

Please sign in to comment.