@@ -122,7 +122,7 @@ local VIRTUAL_LINE_COUNT_KEY_PREFIX = 0
122122local PROPER_LINE_COUNT_KEY_PREFIX = 1
123123local TOPLINE_LOOKUP_KEY_PREFIX = 2
124124local GET_WINDOW_EDGES_KEY_PREFIX = 3
125- local ROW_LENGTH_KEY_PREFIX = 4
125+ local ROW_LENGTH_LOOKUP_KEY_PREFIX = 4
126126
127127-- Maps window ID and highlight group to a temporary highlight group with the
128128-- corresponding definition. This is reset on each refresh cycle.
@@ -1403,34 +1403,41 @@ end
14031403-- Returns a table that maps window rows to the length of text on that row.
14041404-- WARN: When a multi-cell character is the last character on a row, the length
14051405-- returned by this function represents the first cell of that character.
1406- local get_row_length = function (winid , row )
1406+ local get_row_length_lookup = function (winid )
14071407 local memoize_key =
1408- table.concat ({ROW_LENGTH_KEY_PREFIX , winid , row }, ' :' )
1408+ table.concat ({ROW_LENGTH_LOOKUP_KEY_PREFIX , winid }, ' :' )
14091409 if memoize and cache [memoize_key ] then return cache [memoize_key ] end
1410- local result = nil
1410+ local result = {}
14111411 with_win_workspace (winid , function ()
14121412 local scrolloff = api .nvim_win_get_option (0 , ' scrolloff' )
14131413 local virtualedit = api .nvim_win_get_option (0 , ' virtualedit' )
14141414 set_window_option (0 , ' scrolloff' , 0 )
14151415 set_window_option (0 , ' virtualedit' , ' none' )
14161416 fn .winrestview (api .nvim_win_call (winid , fn .winsaveview ))
1417- local init_topline = fn .line (' w0' )
1418- vim .cmd (' keepjumps normal! g0' )
1419- if row >= 1 and row <= get_window_height (0 ) then
1420- local diff = row - fn .winline ()
1421- if diff < 0 then
1422- vim .cmd (' keepjumps normal! ' .. - diff .. ' gk' )
1423- elseif diff > 0 then
1424- vim .cmd (' keepjumps normal! ' .. diff .. ' gj' )
1425- end
1417+ vim .cmd (' keepjumps normal! Hg0' )
1418+ local prior
1419+ -- Limit the number of steps as a precaution. The doubling of window height
1420+ -- is to be safe.
1421+ local max_steps = fn .winheight (0 ) * 2
1422+ local steps = 0
1423+ while fn .winline () > 1
1424+ and prior ~= fn .winline ()
1425+ and steps < max_steps do
1426+ steps = steps + 1
1427+ prior = fn .winline ()
1428+ vim .cmd (' keepjumps normal! g0gk' )
1429+ end
1430+ prior = nil
1431+ steps = 0
1432+ local winheight = get_window_height (0 )
1433+ while fn .winline () <= winheight
1434+ and prior ~= fn .winline ()
1435+ and steps < max_steps do
1436+ steps = steps + 1
1437+ prior = fn .winline ()
14261438 vim .cmd (' keepjumps normal! g$' )
1427- -- It may not be possible to get to the desired row (e.g., virtual lines).
1428- local success = fn .winline () == row
1429- -- Make sure the view didn't change, as a precaution.
1430- success = success and init_topline == fn .line (' w0' )
1431- if success then
1432- result = fn .wincol ()
1433- end
1439+ result [fn .winline ()] = fn .wincol ()
1440+ vim .cmd (' keepjumps normal! g0gj' )
14341441 end
14351442 set_window_option (0 , ' scrolloff' , scrolloff )
14361443 set_window_option (0 , ' virtualedit' , virtualedit )
@@ -1505,9 +1512,10 @@ local show_scrollbar = function(winid, bar_winid)
15051512 end
15061513 end
15071514 if to_bool (vim .g .scrollview_hide_on_text_intersect ) then
1515+ local row_length_lookup = get_row_length_lookup (winid )
15081516 for row = bar_position .row , bar_position .row + bar_position .height - 1 do
1509- local row_length = get_row_length ( winid , row )
1510- if row_length ~= nil and row_length >= bar_position .col then
1517+ if row_length_lookup [ row ] ~= nil
1518+ and row_length_lookup [ row ] >= bar_position .col then
15111519 return - 1
15121520 end
15131521 end
@@ -1869,9 +1877,13 @@ local show_signs = function(winid, sign_winids, bar_winid)
18691877 end
18701878 end
18711879 if to_bool (vim .g .scrollview_hide_on_text_intersect ) then
1872- local row_length = get_row_length (winid , row )
1873- if row_length ~= nil and row_length >= col then
1874- show = false
1880+ local row_length_lookup = get_row_length_lookup (winid )
1881+ for c = col , col + sign_width - 1 do
1882+ if row_length_lookup [row ] ~= nil
1883+ and row_length_lookup [row ] >= c then
1884+ show = false
1885+ break
1886+ end
18751887 end
18761888 end
18771889 if show then
0 commit comments