about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2024-02-08 02:23:56 -0800
committerKartik K. Agaram <vc@akkartik.com>2024-02-08 02:37:12 -0800
commit4e9298dda1fb67527d5fdd3172217b803b27e652 (patch)
treef14402956377fd275e2b9033bb88ad314d8c3013
parent1dbd734abb757c924d2f72b5eaa6663712962035 (diff)
downloadview.love-4e9298dda1fb67527d5fdd3172217b803b27e652.tar.gz
bugfix in cursor positioning
scenario:
- create a long wrapping line
- tap past end of first screen line

Before this commit the cursor would be positioned not quite at the end
of the screen line but one character before. In effect there was no way
to position cursor at end of a wrapping line.

I'm not sure how this bug has lasted so long. It was introduced in
commit 8d3adfa36 back in June 2022, which was itself billed as a bugfix
for "clicking past end of screen line". But when I go back to it this
bug exists even back then. How did I miss it?! I wrote a test back then
-- and the test was wrong, has always been wrong.
-rw-r--r--source_text.lua2
-rw-r--r--source_text_tests.lua12
-rw-r--r--text.lua2
-rw-r--r--text_tests.lua12
4 files changed, 14 insertions, 14 deletions
diff --git a/source_text.lua b/source_text.lua
index b22d358..7c1838c 100644
--- a/source_text.lua
+++ b/source_text.lua
@@ -798,7 +798,7 @@ function Text.to_pos_on_line(State, line_index, mx, my)
       -- (The final screen line positions past end of screen line as always.)
       if screen_line_index < #line_cache.screen_line_starting_pos and mx > State.left + Text.screen_line_width(State, line_index, screen_line_index) then
 --?         print('past end of non-final line; return')
-        return line_cache.screen_line_starting_pos[screen_line_index+1]-1
+        return line_cache.screen_line_starting_pos[screen_line_index+1]
       end
       local s = string.sub(line.data, screen_line_starting_byte_offset)
 --?       print('return', mx, Text.nearest_cursor_pos(State.font, s, mx, State.left), '=>', screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, mx, State.left) - 1)
diff --git a/source_text_tests.lua b/source_text_tests.lua
index c0edeab..6376ec8 100644
--- a/source_text_tests.lua
+++ b/source_text_tests.lua
@@ -485,9 +485,9 @@ function test_click_past_end_of_screen_line()
   y = y + Editor_state.line_height
   -- click past end of second screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
+  -- cursor moves to end of screen line (one more than final character shown)
   check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
-  check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
 end
 
 function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()
@@ -506,9 +506,9 @@ function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()
   y = y + Editor_state.line_height
   -- click past end of second screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
+  -- cursor moves to end of screen line (one more than final character shown)
   check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
-  check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
 end
 
 function test_click_past_end_of_wrapping_line()
@@ -576,8 +576,8 @@ function test_click_past_end_of_word_wrapping_line()
   y = y + Editor_state.line_height
   -- click past the end of the screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
-  check_eq(Editor_state.cursor1.pos, 20, 'cursor')
+  -- cursor moves to end of screen line (one more than final character shown)
+  check_eq(Editor_state.cursor1.pos, 21, 'cursor')
 end
 
 function test_select_text()
diff --git a/text.lua b/text.lua
index 3b67710..9c27bde 100644
--- a/text.lua
+++ b/text.lua
@@ -736,7 +736,7 @@ function Text.to_pos_on_line(State, line_index, mx, my)
       -- (The final screen line positions past end of screen line as always.)
       if screen_line_index < #line_cache.screen_line_starting_pos and mx > State.left + Text.screen_line_width(State, line_index, screen_line_index) then
 --?         print('past end of non-final line; return')
-        return line_cache.screen_line_starting_pos[screen_line_index+1]-1
+        return line_cache.screen_line_starting_pos[screen_line_index+1]
       end
       local s = string.sub(line.data, screen_line_starting_byte_offset)
 --?       print('return', mx, Text.nearest_cursor_pos(State.font, s, mx, State.left), '=>', screen_line_starting_pos + Text.nearest_cursor_pos(State.font, s, mx, State.left) - 1)
diff --git a/text_tests.lua b/text_tests.lua
index ae3d94d..b8f89db 100644
--- a/text_tests.lua
+++ b/text_tests.lua
@@ -485,9 +485,9 @@ function test_click_past_end_of_screen_line()
   y = y + Editor_state.line_height
   -- click past end of second screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
+  -- cursor moves to end of screen line (one more than final character shown)
   check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
-  check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
 end
 
 function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()
@@ -506,9 +506,9 @@ function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen()
   y = y + Editor_state.line_height
   -- click past end of second screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
+  -- cursor moves to end of screen line (one more than final character shown)
   check_eq(Editor_state.cursor1.line, 1, 'cursor:line')
-  check_eq(Editor_state.cursor1.pos, 12, 'cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 13, 'cursor:pos')
 end
 
 function test_click_past_end_of_wrapping_line()
@@ -576,8 +576,8 @@ function test_click_past_end_of_word_wrapping_line()
   y = y + Editor_state.line_height
   -- click past the end of the screen line
   edit.run_after_mouse_click(Editor_state, App.screen.width-2,y-2, 1)
-  -- cursor moves to end of screen line
-  check_eq(Editor_state.cursor1.pos, 20, 'cursor')
+  -- cursor moves to end of screen line (one more than final character shown)
+  check_eq(Editor_state.cursor1.pos, 21, 'cursor')
 end
 
 function test_select_text()