about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-07-20 09:11:29 -0700
committerKartik K. Agaram <vc@akkartik.com>2022-07-20 09:11:29 -0700
commite2734cd572a8578ee07637f9c5471c0ccce119cc (patch)
tree71d09bdea7815b3f9c334351f65d322a01420ddc
parent192e16b42f1312dde5a23a3907de2af5a46de9a7 (diff)
downloadtext.love-e2734cd572a8578ee07637f9c5471c0ccce119cc.tar.gz
bugfix: where cursor is drawn
The published version of lines.love was broken for almost an hour. The
cursor would render one position to the right of where it really is. To
fix it, this commit rolls back 26ba6e4e5a71. There doesn't seem a good
way to test it.
-rw-r--r--Manual_tests.md4
-rw-r--r--text.lua15
-rw-r--r--text_tests.lua20
3 files changed, 25 insertions, 14 deletions
diff --git a/Manual_tests.md b/Manual_tests.md
index 767d0fc..8d121d9 100644
--- a/Manual_tests.md
+++ b/Manual_tests.md
@@ -9,6 +9,10 @@ record those here.
         - Filename as relative path
     - from defaults
 
+* How the screen looks. Our tests use a level of indirection to check text and
+  graphics printed to screen, but not the precise pixels they translate to.
+    - where exactly the cursor is drawn to highlight a given character
+
 ### Other compromises
 
 Lua is dynamically typed. Tests can't patch over lack of type-checking.
diff --git a/text.lua b/text.lua
index 5a9896f..db0c3b7 100644
--- a/text.lua
+++ b/text.lua
@@ -803,15 +803,15 @@ end
 function Text.nearest_pos_less_than(line, x)
 --?   print('', '-- nearest_pos_less_than', line, x)
   local len = utf8.len(line)
-  local max_x = Text.x(line, len)
+  local max_x = Text.x_after(line, len)
   if x > max_x then
     return len+1
   end
   local left, right = 0, len+1
   while true do
     local curr = math.floor((left+right)/2)
-    local currxmin = Text.x(line, curr+1)
-    local currxmax = Text.x(line, curr+2)
+    local currxmin = Text.x_after(line, curr+1)
+    local currxmax = Text.x_after(line, curr+2)
 --?     print('', x, left, right, curr, currxmin, currxmax)
     if currxmin <= x and x < currxmax then
       return curr
@@ -828,7 +828,7 @@ function Text.nearest_pos_less_than(line, x)
   assert(false)
 end
 
-function Text.x(s, pos)
+function Text.x_after(s, pos)
   local offset = Text.offset(s, math.min(pos+1, #s+1))
   local s_before = s:sub(1, offset-1)
 --?   print('^'..s_before..'$')
@@ -836,6 +836,13 @@ function Text.x(s, pos)
   return App.width(text_before)
 end
 
+function Text.x(s, pos)
+  local offset = Text.offset(s, pos)
+  local s_before = s:sub(1, offset-1)
+  local text_before = App.newText(love.graphics.getFont(), s_before)
+  return App.width(text_before)
+end
+
 function Text.to2(State, pos1)
   if State.lines[pos1.line].mode == 'drawing' then
     return {line=pos1.line, screen_line=1, screen_pos=1}
diff --git a/text_tests.lua b/text_tests.lua
index 4de3759..4e3cd2c 100644
--- a/text_tests.lua
+++ b/text_tests.lua
@@ -285,7 +285,7 @@ function test_click_with_mouse_takes_margins_into_account()
   edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- cursor moves
   check_eq(Editor_state.cursor1.line, 1, 'F - test_click_with_mouse_takes_margins_into_account/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 1, 'F - test_click_with_mouse_takes_margins_into_account/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_with_mouse_takes_margins_into_account/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_click_with_mouse_takes_margins_into_account/selection is empty to avoid perturbing future edits')
 end
 
@@ -375,7 +375,7 @@ function test_click_with_mouse_on_wrapping_line()
   edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- cursor moves
   check_eq(Editor_state.cursor1.line, 1, 'F - test_click_with_mouse_on_wrapping_line/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 1, 'F - test_click_with_mouse_on_wrapping_line/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_with_mouse_on_wrapping_line/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_click_with_mouse_on_wrapping_line/selection is empty to avoid perturbing future edits')
 end
 
@@ -395,7 +395,7 @@ function test_click_with_mouse_on_wrapping_line_takes_margins_into_account()
   edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   -- cursor moves
   check_eq(Editor_state.cursor1.line, 1, 'F - test_click_with_mouse_on_wrapping_line_takes_margins_into_account/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 1, 'F - test_click_with_mouse_on_wrapping_line_takes_margins_into_account/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 2, 'F - test_click_with_mouse_on_wrapping_line_takes_margins_into_account/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_click_with_mouse_on_wrapping_line_takes_margins_into_account/selection is empty to avoid perturbing future edits')
 end
 
@@ -834,7 +834,7 @@ function test_move_cursor_using_mouse()
   edit.draw(Editor_state)  -- populate line.y for each line in Editor_state.lines
   edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1)
   check_eq(Editor_state.cursor1.line, 1, 'F - test_move_cursor_using_mouse/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 1, 'F - test_move_cursor_using_mouse/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 2, 'F - test_move_cursor_using_mouse/cursor:pos')
   check_nil(Editor_state.selection1.line, 'F - test_move_cursor_using_mouse/selection:line')
   check_nil(Editor_state.selection1.pos, 'F - test_move_cursor_using_mouse/selection:pos')
 end
@@ -855,7 +855,7 @@ function test_select_text_using_mouse()
   -- drag and release somewhere else
   edit.run_after_mouse_release(Editor_state, Editor_state.left+20,Editor_state.top+Editor_state.line_height+5, 1)
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse/selection:line')
-  check_eq(Editor_state.selection1.pos, 1, 'F - test_select_text_using_mouse/selection:pos')
+  check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse/selection:pos')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_using_mouse/cursor:line')
   check_eq(Editor_state.cursor1.pos, 4, 'F - test_select_text_using_mouse/cursor:pos')
 end
@@ -880,7 +880,7 @@ function test_select_text_using_mouse_and_shift()
   edit.run_after_mouse_release(Editor_state, Editor_state.left+20,Editor_state.top+Editor_state.line_height+5, 1)
   App.fake_key_release('lshift')
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_using_mouse_and_shift/selection:line')
-  check_eq(Editor_state.selection1.pos, 1, 'F - test_select_text_using_mouse_and_shift/selection:pos')
+  check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_using_mouse_and_shift/selection:pos')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_using_mouse_and_shift/cursor:line')
   check_eq(Editor_state.cursor1.pos, 4, 'F - test_select_text_using_mouse_and_shift/cursor:pos')
 end
@@ -911,9 +911,9 @@ function test_select_text_repeatedly_using_mouse_and_shift()
   App.fake_key_release('lshift')
   -- selection is between first and third location. forget the second location, not the first.
   check_eq(Editor_state.selection1.line, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:line')
-  check_eq(Editor_state.selection1.pos, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:pos')
+  check_eq(Editor_state.selection1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/selection:pos')
   check_eq(Editor_state.cursor1.line, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 1, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 2, 'F - test_select_text_repeatedly_using_mouse_and_shift/cursor:pos')
 end
 
 function test_cut_without_selection()
@@ -1129,7 +1129,7 @@ function test_down_arrow_scrolls_down_by_one_screen_line()
   edit.run_after_keychord(Editor_state, 'down')
   check_eq(Editor_state.screen_top1.line, 2, 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen_top')
   check_eq(Editor_state.cursor1.line, 3, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 6, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 5, 'F - test_down_arrow_scrolls_down_by_one_screen_line/cursor:pos')
   y = Editor_state.top
   App.screen.check(y, 'def', 'F - test_down_arrow_scrolls_down_by_one_screen_line/screen:1')
   y = y + Editor_state.line_height
@@ -1693,7 +1693,7 @@ function test_position_cursor_on_recently_edited_wrapping_line()
   edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+Editor_state.line_height*2+5, 1)
   -- cursor should move
   check_eq(Editor_state.cursor1.line, 1, 'F - test_position_cursor_on_recently_edited_wrapping_line/cursor:line')
-  check_eq(Editor_state.cursor1.pos, 25, 'F - test_position_cursor_on_recently_edited_wrapping_line/cursor:pos')
+  check_eq(Editor_state.cursor1.pos, 26, 'F - test_position_cursor_on_recently_edited_wrapping_line/cursor:pos')
 end
 
 function test_backspace_can_scroll_up()