Skip to content

Commit 62fff18

Browse files
committed
Add a scrollview_visibility option
This replaces scrollview_always_show. The possible values are: * always: Always show scrollbars and signs. * overflow: Show scrollbars and signs only when content overflows the window (when there are lines that are not visible). * info: Show scrollbars and signs when content overflows the window. Otherwise, show when there are signs to display (excluding those from sign groups included in scrollview_excluded_info_signs).
1 parent 9814582 commit 62fff18

File tree

5 files changed

+90
-19
lines changed

5 files changed

+90
-19
lines changed

autoload/scrollview.vim

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ endfunction
1717

1818
" === General ===
1919

20-
let g:scrollview_always_show = get(g:, 'scrollview_always_show', v:false)
2120
let g:scrollview_auto_mouse = get(g:, 'scrollview_auto_mouse', v:true)
2221
let g:scrollview_base = get(g:, 'scrollview_base', 'right')
2322
" The plugin enters a restricted state when the number of buffer bytes exceeds
@@ -30,6 +29,9 @@ let g:scrollview_consider_border =
3029
let g:scrollview_current_only = get(g:, 'scrollview_current_only', v:false)
3130
let g:scrollview_excluded_filetypes =
3231
\ get(g:, 'scrollview_excluded_filetypes', [])
32+
let g:scrollview_excluded_info_signs =
33+
\ get(g:, 'scrollview_excluded_info_signs',
34+
\ ['changelist', 'cursor', 'latestchange'])
3335
let g:scrollview_floating_windows =
3436
\ get(g:, 'scrollview_floating_windows', v:false)
3537
let g:scrollview_signs_hidden_for_insert =
@@ -68,6 +70,12 @@ let g:scrollview_mouse_primary = get(g:, 'scrollview_mouse_primary', 'left')
6870
let g:scrollview_mouse_secondary =
6971
\ get(g:, 'scrollview_mouse_secondary', 'right')
7072
let g:scrollview_on_startup = get(g:, 'scrollview_on_startup', v:true)
73+
" Use the old option, scrollview_always_show, if it's set.
74+
if has_key(g:, 'scrollview_always_show')
75+
\ && !has_key(g:, 'scrollview_visibility')
76+
let g:scrollview_visibility = g:scrollview_always_show ? 'always' : 'overflow'
77+
endif
78+
let g:scrollview_visibility = get(g:, 'scrollview_visibility', 'overflow')
7179
let g:scrollview_winblend = get(g:, 'scrollview_winblend', 50)
7280
let g:scrollview_winblend_gui = get(g:, 'scrollview_winblend_gui', 0)
7381
" The default zindex for floating windows is 50. A smaller value is used here

doc/scrollview.txt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,6 @@ can be set to control when restricted mode is entered.
197197
4. Configuration *scrollview-configuration*
198198

199199
Configuration Variables ~
200-
*scrollview_always_show*
201-
scrollview_always_show |Boolean| specifying whether scrollbars and signs are
202-
shown when all lines are visible. Defaults to |v:false|.
203-
204200
*scrollview_base*
205201
scrollview_base |String| specifying where the scrollbar is anchored.
206202
Possible values are `'left'` or `'right'` for corresponding
@@ -244,6 +240,12 @@ scrollview_excluded_filetypes *scrollview_excluded_filetypes*
244240
which scrollbars should not be displayed. Defaults to
245241
`[]`.
246242

243+
scrollview_excluded_info_signs *scrollview_excluded_info_signs*
244+
|List| of |String|s specifying sign groups to exclude from
245+
visibility consideration when |scrollview_visibility| is
246+
set to `'info'` and there is no overflow. Defaults to
247+
`['changelist', 'cursor', 'latestchange']`.
248+
247249
scrollview_floating_windows *scrollview_floating_windows*
248250
(experimental) |Boolean| specifying whether scrollbars and signs are
249251
shown in floating windows. Defaults to |v:false|.
@@ -324,6 +326,19 @@ scrollview_on_startup |Boolean| specifying whether scrollbars are enabled on
324326
startup. Defaults to |v:true|. Considered only when the
325327
plugin is loaded.
326328

329+
*scrollview_visibility*
330+
scrollview_visibility |String| specifying the visibility level of scrollbars
331+
and signs. Possible values are `'always'`, `'overflow'`,
332+
and `'info'`. Defaults to `'overflow'`.
333+
* `always` Always show scrollbars and signs.
334+
* `overflow` Show scrollbars and signs only when content
335+
overflows the window (when there are lines that are
336+
not visible).
337+
* `info` Show scrollbars and signs when content overflows
338+
the window. Otherwise, show when there are signs to
339+
display (excluding those from sign groups included in
340+
|scrollview_excluded_info_signs|).
341+
327342
*scrollview_winblend*
328343
scrollview_winblend |Number| specifying the level of transparency for
329344
scrollbars when a GUI is not running and 'termguicolors'
@@ -972,8 +987,8 @@ register_sign_spec({spec}) *scrollview.register_sign_spec()*
972987
`false`.
973988
+ extend (boolean): Show each sign on all corresponding rows
974989
of the scrollview column, instead of just a single row. This
975-
is relevant when |scrollview_always_show| is on and all lines
976-
and at least one filler line are visible.
990+
is relevant when the window is not scrollable (see
991+
|scrollview_visibility|).
977992
+ group (string): Defaults to `'other'`.
978993
+ highlight (string): Defaults to `'Pmenu'`.
979994
+ priority (integer): Defaults to `50`.

doc/tags

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ scrollview.set_sign_group_callback() scrollview.txt /*scrollview.set_sign_group_
4444
scrollview.set_sign_group_state() scrollview.txt /*scrollview.set_sign_group_state()*
4545
scrollview.setup() scrollview.txt /*scrollview.setup()*
4646
scrollview.txt scrollview.txt /*scrollview.txt*
47-
scrollview_always_show scrollview.txt /*scrollview_always_show*
4847
scrollview_base scrollview.txt /*scrollview_base*
4948
scrollview_byte_limit scrollview.txt /*scrollview_byte_limit*
5049
scrollview_changelist_current_priority scrollview.txt /*scrollview_changelist_current_priority*
@@ -76,6 +75,7 @@ scrollview_diagnostics_warn_priority scrollview.txt /*scrollview_diagnostics_war
7675
scrollview_diagnostics_warn_symbol scrollview.txt /*scrollview_diagnostics_warn_symbol*
7776
scrollview_enabled scrollview.txt /*scrollview_enabled*
7877
scrollview_excluded_filetypes scrollview.txt /*scrollview_excluded_filetypes*
78+
scrollview_excluded_info_signs scrollview.txt /*scrollview_excluded_info_signs*
7979
scrollview_floating_windows scrollview.txt /*scrollview_floating_windows*
8080
scrollview_folds_priority scrollview.txt /*scrollview_folds_priority*
8181
scrollview_folds_symbol scrollview.txt /*scrollview_folds_symbol*
@@ -130,6 +130,7 @@ scrollview_textwidth_priority scrollview.txt /*scrollview_textwidth_priority*
130130
scrollview_textwidth_symbol scrollview.txt /*scrollview_textwidth_symbol*
131131
scrollview_trail_priority scrollview.txt /*scrollview_trail_priority*
132132
scrollview_trail_symbol scrollview.txt /*scrollview_trail_symbol*
133+
scrollview_visibility scrollview.txt /*scrollview_visibility*
133134
scrollview_winblend scrollview.txt /*scrollview_winblend*
134135
scrollview_winblend_gui scrollview.txt /*scrollview_winblend_gui*
135136
scrollview_zindex scrollview.txt /*scrollview_zindex*

lua/scrollview.lua

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ local binary_search = utils.binary_search
88
local concat = utils.concat
99
local copy = utils.copy
1010
local echo = utils.echo
11+
local extend = utils.extend
12+
local mapify = utils.mapify
1113
local preceding = utils.preceding
1214
local remove_duplicates = utils.remove_duplicates
1315
local round = utils.round
@@ -1172,6 +1174,14 @@ local is_scrollview_window = function(winid)
11721174
return bufnr == bar_bufnr or bufnr == sign_bufnr
11731175
end
11741176

1177+
-- Indicates whether content overflows the window.
1178+
local has_overflow = function(winid)
1179+
local bufnr = api.nvim_win_get_buf(winid)
1180+
local topline, botline = line_range(winid)
1181+
local line_count = api.nvim_buf_line_count(bufnr)
1182+
return botline - topline + 1 ~= line_count
1183+
end
1184+
11751185
-- Whether scrollbar and signs should be shown. This is the first check; it
11761186
-- only checks for conditions that apply to both the position bar and signs.
11771187
local should_show = function(winid)
@@ -1215,14 +1225,8 @@ local should_show = function(winid)
12151225
if winheight == 0 or winwidth == 0 then
12161226
return false
12171227
end
1218-
local always_show = to_bool(vim.g.scrollview_always_show)
1219-
if not always_show then
1220-
-- Don't show when all lines are on screen.
1221-
local topline, botline = line_range(winid)
1222-
local line_count = api.nvim_buf_line_count(bufnr)
1223-
if botline - topline + 1 == line_count then
1224-
return false
1225-
end
1228+
if vim.g.scrollview_visibility == 'overflow' and not has_overflow(winid) then
1229+
return false
12261230
end
12271231
return true
12281232
end
@@ -1679,9 +1683,10 @@ end
16791683
-- removed from the list. The bar_winid is necessary so that signs can be
16801684
-- properly highlighted when intersecting a scrollbar.
16811685
local show_signs = function(winid, sign_winids, bar_winid)
1686+
local shown = {} -- a list winids for the signs created
16821687
-- Neovim 0.8 has an issue with matchaddpos highlighting (similar type of
16831688
-- issue reported in Neovim #22906).
1684-
if not to_bool(fn.has('nvim-0.9')) then return end
1689+
if not to_bool(fn.has('nvim-0.9')) then return shown end
16851690
local bar_props
16861691
if bar_winid ~= -1 then
16871692
bar_props = api.nvim_win_get_var(bar_winid, PROPS_VAR)
@@ -1690,7 +1695,7 @@ local show_signs = function(winid, sign_winids, bar_winid)
16901695
local wininfo = fn.getwininfo(winid)[1]
16911696
local config = api.nvim_win_get_config(winid)
16921697
local is_float = tbl_get(config, 'relative', '') ~= ''
1693-
if is_restricted(winid) then return end
1698+
if is_restricted(winid) then return shown end
16941699
local bufnr = api.nvim_win_get_buf(winid)
16951700
local line_count = api.nvim_buf_line_count(bufnr)
16961701
local topline_lookup = nil -- only set when needed
@@ -1939,6 +1944,7 @@ local show_signs = function(winid, sign_winids, bar_winid)
19391944
sign_winid = table.remove(sign_winids)
19401945
api.nvim_win_set_config(sign_winid, sign_config)
19411946
end
1947+
table.insert(shown, sign_winid)
19421948
local over_scrollbar = bar_props ~= nil
19431949
and bar_props.col >= col
19441950
and bar_props.col <= col + sign_width - 1
@@ -2046,6 +2052,7 @@ local show_signs = function(winid, sign_winids, bar_winid)
20462052
end
20472053
end
20482054
end
2055+
return shown
20492056
end
20502057

20512058
-- Given a scrollbar properties dictionary and a target window row, the
@@ -2464,6 +2471,7 @@ local refresh_bars = function()
24642471
sign_bufnr, 0, api.nvim_buf_line_count(sign_bufnr), true, {})
24652472
api.nvim_buf_set_option(sign_bufnr, 'modifiable', false)
24662473
end
2474+
local excluded_info_signs = mapify(vim.g.scrollview_excluded_info_signs)
24672475
for _, winid in ipairs(target_wins) do
24682476
if should_show(winid) then
24692477
local existing_winid = -1
@@ -2484,7 +2492,25 @@ local refresh_bars = function()
24842492
table.remove(existing_barids)
24852493
end
24862494
-- Repeat a similar process for signs.
2487-
show_signs(winid, existing_signids, bar_winid)
2495+
local sign_winids = show_signs(winid, existing_signids, bar_winid)
2496+
-- If scrollview_visibility is info, there's no overflow, and there are
2497+
-- no info signs, make the bar_winid and the sign_winids available for
2498+
-- potential re-use.
2499+
if vim.g.scrollview_visibility == 'info' and not has_overflow(winid) then
2500+
local has_info_signs = false
2501+
for _, sign_winid in ipairs(sign_winids) do
2502+
local sign_props = api.nvim_win_get_var(sign_winid, PROPS_VAR)
2503+
local group = sign_specs[sign_props.sign_spec_id].group
2504+
if excluded_info_signs[group] == nil then
2505+
has_info_signs = true
2506+
break
2507+
end
2508+
end
2509+
if not has_info_signs then
2510+
table.insert(existing_barids, bar_winid)
2511+
extend(existing_signids, sign_winids)
2512+
end
2513+
end
24882514
end
24892515
end
24902516
local existing_wins = concat(existing_barids, existing_signids)

lua/scrollview/utils.lua

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ function M.echo(echo_list)
5656
vim.cmd('echohl None')
5757
end
5858

59+
-- Given array-like tables a and b, add all elements from b to a.
60+
function M.extend(a, b)
61+
for _, item in ipairs(b) do
62+
table.insert(a, item)
63+
end
64+
end
65+
66+
-- Convert a list-like table to a map-like table. The output's keys are the
67+
-- elements of the input, and the corresponding values are the indices where
68+
-- the element is in the list.
69+
function M.mapify(l)
70+
local result = {}
71+
for idx, item in ipairs(l) do
72+
if result[item] == nil then
73+
result[item] = {}
74+
end
75+
table.insert(result[item], idx)
76+
end
77+
return result
78+
end
79+
5980
-- For sorted list l with no duplicates, return the previous item before the
6081
-- specified item (wraps around).
6182
function M.preceding(l, item, count, wrapscan)

0 commit comments

Comments
 (0)