When long wrapping lines go past the current page, I find myself scrolling before I get to the bottom. So let's scroll less, usually from the start of the bottom-most line, even if it wraps multiple screen lines.
The challenge with this is to ensure that a long line that fills the whole page by itself doesn't get you stuck. I take some care to make sure <pagedown> always makes forward progress.
CVSRHMJ2BM4LPVG67ULIVQMP2NW3YY2JC2ZQBEA6EB5KVM4O2L5AC
function test_pagedown_shows_one_screen_line_in_common()
io.write('\ntest_pagedown_shows_one_screen_line_in_common')
-- some lines of text with a drawing intermixed
function test_pagedown_often_shows_start_of_wrapping_line()
io.write('\ntest_pagedown_often_shows_start_of_wrapping_line')
-- draw a few lines ending in part of a wrapping line
App.screen.check(y, 'ghi ', 'F - test_pagedown_shows_one_screen_line_in_common/baseline/screen:3')
-- after pagedown the bottom screen line becomes the top
App.screen.check(y, 'ghi ', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:3')
-- after pagedown we start drawing from the bottom _line_ (multiple screen lines)
check_eq(Screen_top1.line, 2, 'F - test_pagedown_shows_one_screen_line_in_common/screen_top:line')
check_eq(Screen_top1.pos, 5, 'F - test_pagedown_shows_one_screen_line_in_common/screen_top:pos')
check_eq(Cursor1.line, 2, 'F - test_pagedown_shows_one_screen_line_in_common/cursor:line')
check_eq(Cursor1.pos, 5, 'F - test_pagedown_shows_one_screen_line_in_common/cursor:pos')
check_eq(Screen_top1.line, 2, 'F - test_pagedown_often_shows_start_of_wrapping_line/screen_top:line')
check_eq(Screen_top1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/screen_top:pos')
check_eq(Cursor1.line, 2, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:line')
check_eq(Cursor1.pos, 1, 'F - test_pagedown_often_shows_start_of_wrapping_line/cursor:pos')
App.screen.check(y, 'mn', 'F - test_pagedown_shows_one_screen_line_in_common/screen:3')
App.screen.check(y, 'jkl', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:3')
end
function test_pagedown_can_start_from_middle_of_long_wrapping_line()
io.write('\ntest_pagedown_can_start_from_middle_of_long_wrapping_line')
-- draw a few lines starting from a very long wrapping line
App.screen.init{width=25+30, height=60}
Lines = load_array{'abc def ghi jkl mno pqr stu vwx yza bcd efg hij', 'XYZ'}
Line_width = App.screen.width
Cursor1 = {line=1, pos=2}
Screen_top1 = {line=1, pos=1}
Screen_bottom1 = {}
App.draw()
local y = Margin_top
App.screen.check(y, 'abc ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:1')
y = y + Line_height
App.screen.check(y, 'def ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:2')
y = y + Line_height
App.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:3')
-- after pagedown we scroll down the very long wrapping line
App.run_after_keychord('pagedown')
check_eq(Screen_top1.line, 1, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:line')
check_eq(Screen_top1.pos, 9, 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen_top:pos')
y = Margin_top
App.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:1')
y = y + Line_height
App.screen.check(y, 'jkl m', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:2')
y = y + Line_height
App.screen.check(y, 'no ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:3')
Screen_top1.line = Screen_bottom1.line
Screen_top1.pos = Screen_bottom1.pos
-- If a line/paragraph gets to a page boundary, I often want to scroll
-- before I get to the bottom.
-- However, only do this if it makes forward progress.
local top2 = Text.to2(Screen_bottom1)
if top2.screen_line > 1 then
top2.screen_line = math.max(top2.screen_line-10, 1)
end
local new_top1 = Text.to1(top2)
if Text.lt1(Screen_top1, new_top1) then
Screen_top1 = new_top1
else
Screen_top1.line = Screen_bottom1.line
Screen_top1.pos = Screen_bottom1.pos
end