diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2022-06-04 14:55:52 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2022-06-04 14:55:52 -0700 |
commit | fa267e25e600a875696b6ab972b72515fa71e20a (patch) | |
tree | e08e70387ef93f6b7b10a8e3f911a96ff3e1c690 | |
parent | 1326914d7bda65a5791c2121dae6d3987a907994 (diff) | |
download | text.love-fa267e25e600a875696b6ab972b72515fa71e20a.tar.gz |
experiment: slightly adaptive scrolling
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.
-rw-r--r-- | text.lua | 16 | ||||
-rw-r--r-- | text_tests.lua | 56 |
2 files changed, 56 insertions, 16 deletions
diff --git a/text.lua b/text.lua index d3cc29d..cbccc85 100644 --- a/text.lua +++ b/text.lua @@ -395,8 +395,20 @@ function Text.pageup() end function Text.pagedown() - 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 --? print('setting top to', Screen_top1.line, Screen_top1.pos) Cursor1.line = Screen_top1.line Cursor1.pos = Screen_top1.pos diff --git a/text_tests.lua b/text_tests.lua index 8272faf..f3a2a6a 100644 --- a/text_tests.lua +++ b/text_tests.lua @@ -246,9 +246,9 @@ function test_pagedown_skips_drawings() App.screen.check(y, 'def', 'F - test_pagedown_skips_drawings/screen:1') end -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.init{width=50, height=60} Lines = load_array{'abc', 'def ghi jkl', 'mno'} Line_width = App.screen.width @@ -257,23 +257,51 @@ function test_pagedown_shows_one_screen_line_in_common() Screen_bottom1 = {} App.draw() local y = Margin_top - App.screen.check(y, 'abc', 'F - test_pagedown_shows_one_screen_line_in_common/baseline/screen:1') + App.screen.check(y, 'abc', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:1') + y = y + Line_height + App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/baseline/screen:2') + y = y + Line_height + 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) + App.run_after_keychord('pagedown') + 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') + y = Margin_top + App.screen.check(y, 'def ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:1') + y = y + Line_height + App.screen.check(y, 'ghi ', 'F - test_pagedown_often_shows_start_of_wrapping_line/screen:2') + y = y + Line_height + 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_shows_one_screen_line_in_common/baseline/screen:2') + 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_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_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, 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, 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_shows_one_screen_line_in_common/screen:1') + 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', 'F - test_pagedown_shows_one_screen_line_in_common/screen:2') + 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, 'mn', 'F - test_pagedown_shows_one_screen_line_in_common/screen:3') + App.screen.check(y, 'no ', 'F - test_pagedown_can_start_from_middle_of_long_wrapping_line/screen:3') end function test_down_arrow_moves_cursor() |