about summary refs log tree commit diff stats
path: root/text.lua
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2023-11-18 11:30:57 -0800
committerKartik K. Agaram <vc@akkartik.com>2023-11-18 11:32:01 -0800
commit007b965b11b681550ee2e2244a2f53e64e88697d (patch)
treee3bff0e0d71e896ea1d954ae7715f672b247bf0e /text.lua
parent5cce5115507800eeca7ba9c271e07c23473228f4 (diff)
downloadview.love-007b965b11b681550ee2e2244a2f53e64e88697d.tar.gz
audit all asserts
Each one should provide a message that will show up within LÖVE. Stop
relying on nearby prints to the terminal.

I also found some unnecessary ones.

There is some potential here for performance regressions: the format()
calls will trigger whether or not the assertion fails, and cause
allocations. So far Lua's GC seems good enough to manage the load even
with Moby Dick, even in some situations that caused issues in the past
like undo.
Diffstat (limited to 'text.lua')
-rw-r--r--text.lua45
1 files changed, 22 insertions, 23 deletions
diff --git a/text.lua b/text.lua
index 3323af6..cd80464 100644
--- a/text.lua
+++ b/text.lua
@@ -12,7 +12,7 @@ function Text.draw(State, line_index, y, startpos)
   -- wrap long lines
   local final_screen_line_starting_pos = startpos  -- track value to return
   Text.populate_screen_line_starting_pos(State, line_index)
-  assert(#line_cache.screen_line_starting_pos >= 1)
+  assert(#line_cache.screen_line_starting_pos >= 1, 'line cache missing screen line info')
   for i=1,#line_cache.screen_line_starting_pos do
     local pos = line_cache.screen_line_starting_pos[i]
     if pos < startpos then
@@ -135,7 +135,7 @@ function Text.text_input(State, t)
 end
 
 function Text.insert_at_cursor(State, t)
-  assert(State.lines[State.cursor1.line].mode == 'text')
+  assert(State.lines[State.cursor1.line].mode == 'text', 'line is not text')
   local byte_offset = Text.offset(State.lines[State.cursor1.line].data, State.cursor1.pos)
   State.lines[State.cursor1.line].data = string.sub(State.lines[State.cursor1.line].data, 1, byte_offset-1)..t..string.sub(State.lines[State.cursor1.line].data, byte_offset)
   Text.clear_screen_line_cache(State, State.cursor1.line)
@@ -212,7 +212,7 @@ function Text.keychord_press(State, chord)
       Text.redraw_all(State)  -- if we're scrolling, reclaim all fragments to avoid memory leaks
     end
     Text.clear_screen_line_cache(State, State.cursor1.line)
-    assert(Text.le1(State.screen_top1, State.cursor1))
+    assert(Text.le1(State.screen_top1, State.cursor1), ('screen_top (line=%d,pos=%d) is below cursor (line=%d,pos=%d)'):format(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos))
     schedule_save(State)
     record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)})
   elseif chord == 'delete' then
@@ -390,7 +390,7 @@ function Text.pagedown(State)
 end
 
 function Text.up(State)
-  assert(State.lines[State.cursor1.line].mode == 'text')
+  assert(State.lines[State.cursor1.line].mode == 'text', 'line is not text')
 --?   print('up', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos)
   local screen_line_starting_pos, screen_line_index = Text.pos_at_start_of_screen_line(State, State.cursor1)
   if screen_line_starting_pos == 1 then
@@ -416,7 +416,7 @@ function Text.up(State)
     end
   else
     -- move up one screen line in current line
-    assert(screen_line_index > 1)
+    assert(screen_line_index > 1, 'bumped up against top screen line in line')
     local new_screen_line_starting_pos = State.line_cache[State.cursor1.line].screen_line_starting_pos[screen_line_index-1]
     local new_screen_line_starting_byte_offset = Text.offset(State.lines[State.cursor1.line].data, new_screen_line_starting_pos)
     local s = string.sub(State.lines[State.cursor1.line].data, new_screen_line_starting_byte_offset)
@@ -433,9 +433,9 @@ function Text.up(State)
 end
 
 function Text.down(State)
-  assert(State.lines[State.cursor1.line].mode == 'text')
+  assert(State.lines[State.cursor1.line].mode == 'text', 'line is not text')
 --?   print('down', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos, State.screen_bottom1.line, State.screen_bottom1.pos)
-  assert(State.cursor1.pos)
+  assert(State.cursor1.pos, 'cursor has no pos')
   if Text.cursor_at_final_screen_line(State) then
     -- line is done, skip to next text line
 --?     print('cursor at final screen line of its line')
@@ -509,7 +509,7 @@ function Text.word_left(State)
     if State.cursor1.pos == 1 then
       break
     end
-    assert(State.cursor1.pos > 1)
+    assert(State.cursor1.pos > 1, 'bumped up against start of line')
     if Text.match(State.lines[State.cursor1.line].data, State.cursor1.pos-1, '%s') then
       break
     end
@@ -543,15 +543,14 @@ end
 
 function Text.match(s, pos, pat)
   local start_offset = Text.offset(s, pos)
-  assert(start_offset)
   local end_offset = Text.offset(s, pos+1)
-  assert(end_offset > start_offset)
+  assert(end_offset > start_offset, ('end_offset %d not > start_offset %d'):format(end_offset, start_offset))
   local curr = s:sub(start_offset, end_offset-1)
   return curr:match(pat)
 end
 
 function Text.left(State)
-  assert(State.lines[State.cursor1.line].mode == 'text')
+  assert(State.lines[State.cursor1.line].mode == 'text', 'line is not text')
   if State.cursor1.pos > 1 then
     State.cursor1.pos = State.cursor1.pos-1
   else
@@ -584,7 +583,7 @@ function Text.right(State)
 end
 
 function Text.right_without_scroll(State)
-  assert(State.lines[State.cursor1.line].mode == 'text')
+  assert(State.lines[State.cursor1.line].mode == 'text', 'line is not text')
   if State.cursor1.pos <= utf8.len(State.lines[State.cursor1.line].data) then
     State.cursor1.pos = State.cursor1.pos+1
   else
@@ -609,7 +608,7 @@ function Text.pos_at_start_of_screen_line(State, loc1)
       return spos,i
     end
   end
-  assert(false)
+  assert(false, ('invalid pos %d'):format(loc1.pos))
 end
 
 function Text.pos_at_end_of_screen_line(State, loc1)
@@ -623,7 +622,7 @@ function Text.pos_at_end_of_screen_line(State, loc1)
     end
     most_recent_final_pos = spos-1
   end
-  assert(false)
+  assert(false, ('invalid pos %d'):format(loc1.pos))
 end
 
 function Text.cursor_at_final_screen_line(State)
@@ -648,7 +647,7 @@ function Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necess
   end
   -- hack: insert a text line at bottom of file if necessary
   if State.cursor1.line > #State.lines then
-    assert(State.cursor1.line == #State.lines+1)
+    assert(State.cursor1.line == #State.lines+1, 'tried to ensure bottom line of file is text, but failed')
     table.insert(State.lines, {mode='text', data=''})
     table.insert(State.line_cache, {})
   end
@@ -680,8 +679,8 @@ function Text.snap_cursor_to_bottom_of_screen(State)
       end
       y = y - h
     else
-      assert(top2.line > 1)
-      assert(State.lines[top2.line-1].mode == 'drawing')
+      assert(top2.line > 1, 'tried to snap cursor to buttom of screen but failed')
+      assert(State.lines[top2.line-1].mode == 'drawing', "expected a drawing but it's not")
       -- We currently can't draw partial drawings, so either skip it entirely
       -- or not at all.
       local h = Drawing_padding_height + Drawing.pixels(State.lines[top2.line-1].h, State.width)
@@ -713,7 +712,7 @@ end
 function Text.to_pos_on_line(State, line_index, mx, my)
   local line = State.lines[line_index]
   local line_cache = State.line_cache[line_index]
-  assert(my >= line_cache.starty)
+  assert(my >= line_cache.starty, 'failed to map y pixel to line')
   -- duplicate some logic from Text.draw
   local y = line_cache.starty
   local start_screen_line_index = Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos)
@@ -736,7 +735,7 @@ function Text.to_pos_on_line(State, line_index, mx, my)
     end
     y = nexty
   end
-  assert(false)
+  assert(false, 'failed to map y pixel to line')
 end
 
 function Text.screen_line_width(State, line_index, i)
@@ -802,7 +801,7 @@ function Text.nearest_cursor_pos(line, x, left)
       leftpos = curr
     end
   end
-  assert(false)
+  assert(false, 'failed to map x pixel to pos')
 end
 
 -- return the nearest index of line (in utf8 code points) which lies entirely
@@ -833,7 +832,7 @@ function Text.nearest_pos_less_than(line, x)
       left = curr
     end
   end
-  assert(false)
+  assert(false, 'failed to map x pixel to pos')
 end
 
 function Text.x_after(s, pos)
@@ -864,7 +863,7 @@ function Text.to2(State, loc1)
       break
     end
   end
-  assert(result.screen_pos)
+  assert(result.screen_pos, 'failed to convert schema-1 coordinate to schema-2')
   return result
 end
 
@@ -906,7 +905,7 @@ function Text.offset(s, pos1)
   if result == nil then
     print(pos1, #s, s)
   end
-  assert(result)
+  assert(result, "Text.offset returned nil; this is likely a failure to handle utf8")
   return result
 end