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')endfunction 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 lineApp.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.widthCursor1 = {line=1, pos=2}Screen_top1 = {line=1, pos=1}Screen_bottom1 = {}App.draw()local y = Margin_topApp.screen.check(y, 'abc ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:1')y = y + Line_heightApp.screen.check(y, 'def ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/baseline/screen:2')y = y + Line_heightApp.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 lineApp.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_topApp.screen.check(y, 'ghi ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:1')y = y + Line_heightApp.screen.check(y, 'jkl m', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:2')y = y + Line_heightApp.screen.check(y, 'no ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:3')
Screen_top1.line = Screen_bottom1.lineScreen_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 thentop2.screen_line = math.max(top2.screen_line-10, 1)endlocal new_top1 = Text.to1(top2)if Text.lt1(Screen_top1, new_top1) thenScreen_top1 = new_top1elseScreen_top1.line = Screen_bottom1.lineScreen_top1.pos = Screen_bottom1.posend