diff --git a/commands.lua b/commands.lua index 9a69e50..897ebf9 100644 --- a/commands.lua +++ b/commands.lua @@ -163,7 +163,7 @@ function draw_menu_bar() if pane.cursor_x == nil then add_panning_hotkeys_to_menu() else - assert(pane.cursor_y) + assert(pane.cursor_y, 'cursor fell off viewport') add_hotkey_to_menu('ctrl+e: stop editing') add_hotkey_to_menu('ctrl+h on drawing: help') add_hotkey_to_menu('ctrl+f: find') @@ -671,7 +671,7 @@ function command.edit_note() add_error('no current note') return end - assert(not pane.editable) + assert(not pane.editable, 'pane already editable') stop_editing_all() pane.recent_updated = false pane.editable = true @@ -681,10 +681,10 @@ function command.edit_note() end function command.exit_editing() - assert(Cursor_pane.col >= 1) + assert(Cursor_pane.col >= 1, 'no current pane') local pane = Surface[Cursor_pane.col][Cursor_pane.row] - assert(pane) - assert(pane.editable) + assert(pane, 'no current pane') + assert(pane.editable, 'current pane not editable') stop_editing(pane) end @@ -853,7 +853,7 @@ end function finalize_search_all_pane() if Display_settings.search_all_query:sub(1,1) == '"' then -- support only a single quoted phrase by itself - assert(Display_settings.search_all_query:sub(#Display_settings.search_all_query) == '"') + assert(Display_settings.search_all_query:sub(#Display_settings.search_all_query) == '"', 'you can search for strings in quotes, but only one of them by itself') Display_settings.search_all_terms = {Display_settings.search_all_query:sub(2, #Display_settings.search_all_query-1)} else Display_settings.search_all_terms = split(Display_settings.search_all_query) @@ -1168,17 +1168,17 @@ function remove_link(src, rel, target) if array.find(Non_unique_links, rel) then --? print(('%s is non-unique'):format(rel)) local arr = Links[src][rel] - assert(arr) - assert(type(arr) == 'table') + assert(arr, 'found no link') + assert(type(arr) == 'table', 'links not arranged in a table') local pos = array.find(arr, target) --? print(('contains %s at index %s'):format(target, pos)) - assert(pos) + assert(pos, "couldn't find link to remove in links table") table.remove(arr, pos) if #arr == 0 then Links[src][rel] = nil end else - assert(Links[src][rel] == target) + assert(Links[src][rel] == target, 'link at this rel is not the target; giving up') Links[src][rel] = nil end end @@ -1345,7 +1345,7 @@ function command.unroll(rel) return end if #Surface[Cursor_pane.col] == 1 then - assert(Cursor_pane.row == 1) + assert(Cursor_pane.row == 1, "couldn't set current pane after unrolling") stop_editing(pane) -- save any edits before we blow it away Surface[Cursor_pane.col] = column else @@ -1471,7 +1471,7 @@ function command.neighbors() local column = {name=('neighbors of %s'):format(pane.id)} populate_neighbors_column(column, pane.id) if #Surface[Cursor_pane.col] == 1 then - assert(Cursor_pane.row == 1) + assert(Cursor_pane.row == 1, "couldn't repurpose column for neighbors") Surface[Cursor_pane.col] = column else table.insert(Surface, Cursor_pane.col+1, column) @@ -1561,7 +1561,7 @@ function command.delete_note() Cursor_pane.row = 1 end else - assert(not delete_cursor_column) + assert(not delete_cursor_column, "failed to delete note's column") end -- while Cursor_pane.row > #Surface[Cursor_pane.col] do @@ -1605,7 +1605,7 @@ function new_pane() local id = os.date('%Y/%m/%d/%H-%M-%S', t) print_and_log('new_pane: creating directory '..Directory..dirname(id)) local status = App.mkdir(Directory..dirname(id)) - assert(status) + assert(status, "failed to create directory for note") Links[id] = {} local pane = load_pane(id) if not file_exists(pane.filename) then diff --git a/drawing.lua b/drawing.lua index 65e4aa6..d7fdcad 100644 --- a/drawing.lua +++ b/drawing.lua @@ -34,7 +34,6 @@ function Drawing.draw(State, line_index, y) --? print(State.left, State.right) for _,shape in ipairs(line.shapes) do - assert(shape) if State.editable and geom.on_shape(mx,my, line, shape) then App.color(Focus_stroke_color) else @@ -114,8 +113,7 @@ function Drawing.draw_shape(drawing, shape, top, left,right) elseif shape.mode == 'deleted' then -- ignore else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end @@ -208,8 +206,7 @@ function Drawing.draw_pending_shape(drawing, top, left,right) elseif shape.mode == 'name' then -- nothing pending; changes are immediately committed else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end @@ -240,8 +237,7 @@ function Drawing.mouse_press(State, drawing_index, x,y, mouse_button) elseif State.current_drawing_mode == 'name' then -- nothing else - print(State.current_drawing_mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(State.current_drawing_mode)) end end @@ -256,7 +252,7 @@ function Drawing.update(State) -- just skip this frame return end - assert(drawing.mode == 'drawing') + assert(drawing.mode == 'drawing', 'Drawing.update: line is not a drawing') local pmx, pmy = App.mouse_x(), App.mouse_y() local mx = Drawing.coord(pmx-State.left, State.width) local my = Drawing.coord(pmy-line_cache.starty, State.width) @@ -343,7 +339,7 @@ function Drawing.mouse_release(State, x,y, mouse_button) table.insert(drawing.shapes, drawing.pending) end elseif drawing.pending.mode == 'rectangle' then - assert(#drawing.pending.vertices <= 2) + assert(#drawing.pending.vertices <= 2, 'Drawing.mouse_release: rectangle has too many pending vertices') if #drawing.pending.vertices == 2 then local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width) if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then @@ -358,7 +354,7 @@ function Drawing.mouse_release(State, x,y, mouse_button) -- too few points; draw nothing end elseif drawing.pending.mode == 'square' then - assert(#drawing.pending.vertices <= 2) + assert(#drawing.pending.vertices <= 2, 'Drawing.mouse_release: square has too many pending vertices') if #drawing.pending.vertices == 2 then local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width) if mx >= 0 and mx < 256 and my >= 0 and my < drawing.h then @@ -387,8 +383,7 @@ function Drawing.mouse_release(State, x,y, mouse_button) elseif drawing.pending.mode == 'name' then -- drop it else - print(drawing.pending.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(drawing.pending.mode)) end State.lines.current_drawing.pending = {} State.lines.current_drawing = nil @@ -546,7 +541,7 @@ function Drawing.keychord_press(State, chord) if Drawing.contains_point(shape, i) then if shape.mode == 'polygon' then local idx = table.find(shape.vertices, i) - assert(idx) + assert(idx, 'point to delete is not in vertices') table.remove(shape.vertices, idx) if #shape.vertices < 3 then shape.mode = 'deleted' @@ -642,7 +637,6 @@ function Drawing.select_shape_at_mouse(State) if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width) for i,shape in ipairs(drawing.shapes) do - assert(shape) if geom.on_shape(mx,my, drawing, shape) then return drawing,line_cache,i,shape end @@ -660,7 +654,6 @@ function Drawing.select_point_at_mouse(State) if Drawing.in_drawing(drawing, line_cache, x,y, State.left,State.right) then local mx,my = Drawing.coord(x-State.left, State.width), Drawing.coord(y-line_cache.starty, State.width) for i,point in ipairs(drawing.points) do - assert(point) if Drawing.near(point, mx,my, State.width) then return drawing_index,drawing,line_cache,i,point end @@ -697,13 +690,12 @@ function Drawing.contains_point(shape, p) elseif shape.mode == 'deleted' then -- already done else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end function Drawing.smoothen(shape) - assert(shape.mode == 'freehand') + assert(shape.mode == 'freehand', 'can only smoothen freehand shapes') for _=1,7 do for i=2,#shape.points-1 do local a = shape.points[i-1] diff --git a/edit.lua b/edit.lua index 858b81e..05363c1 100644 --- a/edit.lua +++ b/edit.lua @@ -82,7 +82,7 @@ function edit.initialize_state(top, left, right, font_height, line_height) -- c cursor_x = nil, cursor_y = nil, - current_drawing_mode = 'line', + current_drawing_mode = 'line', -- one of the available shape modes previous_drawing_mode = nil, -- extra state for some ephemeral modes like moving/deleting/naming points font_height = font_height, @@ -169,10 +169,7 @@ function edit.draw(State) --? print_and_log(('edit.draw %s %d %d,%d'):format(State.id, State.top, State.left,State.right)) State.button_handlers = {} App.color(Text_color) - if #State.lines ~= #State.line_cache then - log(2, os.date('%Y/%m/%d/%H-%M-%S')..(' line_cache is out of date; %d when it should be %d'):format(#State.line_cache, #State.lines)) - assert(false) - end + assert(#State.lines == #State.line_cache, ('line_cache is out of date; %d elements when it should be %d'):format(#State.line_cache, #State.lines)) State.cursor_x = nil State.cursor_y = nil local y = State.top @@ -215,8 +212,7 @@ function edit.draw(State) Drawing.draw(State, line_index, y) y = y + Drawing.pixels(line.h, State.width) + Drawing_padding_bottom else - print(line.mode) - assert(false) + assert(false, ('unknown line mode %s'):format(line.mode)) end end State.bottom = y diff --git a/file.lua b/file.lua index ebc00a7..cb289ba 100644 --- a/file.lua +++ b/file.lua @@ -66,7 +66,7 @@ function save_to_disk(State) if not f then error(err) end - assert(not err) + assert(not err, 'failed to save recent') f:write(State.id, '\n') f:close() end @@ -79,7 +79,7 @@ function load_drawing(infile_next_line) local drawing = {mode='drawing', h=256/2, points={}, shapes={}, pending={}} while true do local line = infile_next_line() - assert(line) + assert(line, 'drawing in file is incomplete') if line == '```' then break end local shape = json.decode(line) if shape.mode == 'freehand' then @@ -104,8 +104,7 @@ function load_drawing(infile_next_line) elseif shape.mode == 'deleted' then -- ignore else - print_and_log('load_drawing: '..shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end table.insert(drawing.shapes, shape) end @@ -139,8 +138,7 @@ function store_drawing(outfile, drawing) elseif shape.mode == 'deleted' then -- ignore else - print_and_log('store_drawing: '..shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end outfile:write('```\n') @@ -158,7 +156,7 @@ end function save_links(id) local links_filename = Directory..id..'.json' local status = App.mkdir(dirname(links_filename)) - assert(status) + assert(status, 'failed to create directory for links') log(2, 'save_links: '..id) if empty(Links[id]) then print_and_log('save_links: no links; getting rid of .json if it exists') @@ -206,7 +204,7 @@ function load_drawing_from_array(iter, a, i) local line while true do i, line = iter(a, i) - assert(i) + assert(i, 'drawing in array is incomplete') --? print(i) if line == '```' then break end local shape = json.decode(line) @@ -232,8 +230,7 @@ function load_drawing_from_array(iter, a, i) elseif shape.mode == 'deleted' then -- ignore else - print_and_log('load_drawing_from_array: '..shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end table.insert(drawing.shapes, shape) end diff --git a/geom.lua b/geom.lua index 891e98d..ea007b7 100644 --- a/geom.lua +++ b/geom.lua @@ -38,8 +38,7 @@ function geom.on_shape(x,y, drawing, shape) return geom.angle_between(center.x,center.y, x,y, shape.start_angle,shape.end_angle) elseif shape.mode == 'deleted' then else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end diff --git a/log_browser.lua b/log_browser.lua index 6b71da6..b6195b9 100644 --- a/log_browser.lua +++ b/log_browser.lua @@ -75,7 +75,7 @@ function table.shallowcopy(x) end function log_browser.draw(State, hide_cursor) - assert(#State.lines == #State.line_cache) + assert(#State.lines == #State.line_cache, ('line_cache is out of date; %d elements when it should be %d'):format(#State.line_cache, #State.lines)) local mouse_line_index = log_browser.line_index(State, App.mouse_x(), App.mouse_y()) local y = State.top for line_index = State.screen_top1.line,#State.lines do @@ -95,7 +95,7 @@ function log_browser.draw(State, hide_cursor) love.graphics.line(xleft,sectiony, xleft+50-2,sectiony) love.graphics.print(line.section_name, xleft+50,y) love.graphics.line(xleft+50+App.width(line.section_name)+2,sectiony, xright,sectiony) - else assert(line.section_end) + else assert(line.section_end, "log line has a section name, but it's neither the start nor end of a section") local sectiony = y+State.line_height-Section_border_padding_vertical love.graphics.line(xleft,y, xleft,sectiony) love.graphics.line(xright,y, xright,sectiony) diff --git a/run.lua b/run.lua index 188188c..52f1326 100644 --- a/run.lua +++ b/run.lua @@ -176,7 +176,7 @@ function run.initialize(arg) return end - assert(Directory) + assert(Directory, 'no directory to browse notes in') print('Directory initialized to '..Directory) Error_log.filename = Directory..'errors' @@ -332,8 +332,7 @@ function refresh_pane_height(pane) -- nothing y = y + Drawing.pixels(line.h, Display_settings.column_width) + Drawing_padding_height else - print_and_log('refresh_pane_height: '..line.mode) - assert(false) + assert(false, ('unknown line mode %s'):format(line.mode)) end end if Links[pane.id] and not empty(Links[pane.id]) then @@ -436,8 +435,7 @@ function run.draw() end end else - print_and_log('run.draw: '..Display_settings.mode) - assert(false) + assert(false, ('pensieve is in an unknown mode %s'):format(Display_settings.mode)) end if Grab_pane then local old_top, old_left, old_right = Grab_pane.top, Grab_pane.left, Grab_pane.right @@ -467,11 +465,11 @@ function run.draw() end function draw_normal_mode() - assert(Cursor_pane.col) - assert(Cursor_pane.row) + assert(Cursor_pane.col, 'no current column') + assert(Cursor_pane.row, 'no current row') --? print('draw', Display_settings.x, Display_settings.y) for _,pane in ipairs(Panes_to_draw) do - assert(pane.top) + assert(pane.top, "pane has no top coordinate; there's likely a problem in plan_draw") --? if pane.column_index == 1 and pane.pane_index == 1 then --? print('draw', pane.id, 'from y', pane.top, 'down to screen height', App.screen.height) --? print('screen top', pane.screen_top1.line, pane.screen_top1.pos) @@ -517,7 +515,7 @@ function should_show_pane(pane, sy) end function draw_title(pane) - assert(pane.title) + assert(pane.title, 'pane has no title') App.color(Pane_title_color) App.screen.print(pane.title, pane.left, pane.top-Margin_above -5-Line_height) App.color(Pane_title_background_color) @@ -675,7 +673,9 @@ function run.quit() end function run.settings() - assert(Directory_error == nil) -- this will go into an infinite loop if handle_error ever tries to save settings + -- avoid an infinite loop if handle_error ever tries to save settings + assert(Directory_error == nil, + "tried to save settings when we couldn't determine the directory to browse notes in") -- side effect: save notes-related settings inside Directory local column_names = {} for _,column in ipairs(Surface) do @@ -690,7 +690,7 @@ function run.settings() surface_x=Display_settings.x, surface_y=Display_settings.y, })) - assert(status) + assert(status, 'failed to write settings') if Settings == nil then Settings = {} end Settings.x, Settings.y, Settings.displayindex = App.screen.position() @@ -717,8 +717,7 @@ function run.mouse_press(x,y, mouse_button) end end else - print_and_log('run.mouse_press: '..Display_settings.mode) - assert(false) + assert(false, ('pensieve is in an unknown mode %s'):format(Display_settings.mode)) end end @@ -874,8 +873,7 @@ function run.text_input(t) end end else - print_and_log('run.text_input: '..Display_settings.mode) - assert(false) + assert(false, ('pensieve is in an unknown mode %s'):format(Display_settings.mode)) end end @@ -911,7 +909,7 @@ function run.keychord_press(chord, key) command.exit_editing() elseif pane.cursor_x == nil then -- ignore if cursor is not visible on screen - assert(pane.cursor_y == nil) + assert(pane.cursor_y == nil, 'cursor x is not set but y is set') panning_keychord_press(chord, key) plan_draw() else @@ -949,8 +947,7 @@ function run.keychord_press(chord, key) keychord_press_in_maximize_mode(chord, key) end else - print_and_log('run.keychord_press: '..Display_settings.mode) - assert(false) + assert(false, ('pensieve is in an unknown mode %s'):format(Display_settings.mode)) end end @@ -1203,8 +1200,7 @@ function bring_cursor_of_cursor_pane_in_view(dir) if not horizontally_ok then Display_settings.y = cursor_sy - 3*Line_height end - else - assert(dir == 'down') + elseif dir == 'down' then if not vertically_ok then Display_settings.x = left_edge_sx + Display_settings.column_width + Margin_right + Padding_horizontal - App.screen.width end @@ -1213,7 +1209,9 @@ function bring_cursor_of_cursor_pane_in_view(dir) Display_settings.y = cursor_sy + Text.search_bar_height(pane) - (App.screen.height - Header_height) -- Bah, temporarily giving up on debugging. Display_settings.y = Display_settings.y + Line_height - assert(App.screen.height - (cursor_sy-Display_settings.y) > 1.5*Line_height) + assert(App.screen.height - (cursor_sy-Display_settings.y) > 1.5*Line_height, 'ugh, ancient bug is back: panning the viewport when cursor falls off') + else + assert(false, ('unknown dir %s'):format(dir)) end end Display_settings.x = math.max(Display_settings.x, 0) @@ -1414,7 +1412,7 @@ end -- - let loc, y_offset = schema1_of_y(pane, y) -- y - y_offset == y_of_schema1(pane, loc) function schema1_of_y(pane, y) - assert(y >= 0) + assert(y >= 0, 'something is at negative y on the surface') local y_offset = y for i=1,#pane.lines do --? print('--', y_offset) @@ -1427,7 +1425,7 @@ function schema1_of_y(pane, y) else local nlines = math.floor(y_offset/pane.line_height) --? print(y_offset, pane.line_height, nlines) - assert(nlines >= 0 and nlines < #pane.line_cache[i].screen_line_starting_pos) + assert(nlines >= 0 and nlines < #pane.line_cache[i].screen_line_starting_pos, 'error in mapping y coordinate to schema-1') local pos = pane.line_cache[i].screen_line_starting_pos[nlines+1] -- switch to 1-indexing y_offset = y_offset - nlines*pane.line_height return {line=i, pos=pos}, y_offset @@ -1459,7 +1457,7 @@ function stop_editing_all() end end end - assert(edit_count <= 1) + assert(edit_count <= 1, 'multiple panes were editable') end function stop_editing(pane) diff --git a/search.lua b/search.lua index b870c96..a16c3f1 100644 --- a/search.lua +++ b/search.lua @@ -151,7 +151,7 @@ function rfind(s, pat, i, plain) local rendpos = rs:find(rpat, ri, plain) if rendpos == nil then return nil end local endpos = #s - rendpos + 1 - assert (endpos >= #pat) + assert (endpos >= #pat, ('rfind: endpos %d should be >= #pat %d at this point'):format(endpos, #pat)) return endpos-#pat+1 end diff --git a/select.lua b/select.lua index 9b2a278..9ede1da 100644 --- a/select.lua +++ b/select.lua @@ -33,13 +33,13 @@ function Text.clip_selection(State, line_index, apos, bpos) -- fully contained return apos,bpos elseif a_ge then - assert(maxl == line_index) + assert(maxl == line_index, ('maxl %d not equal to line_index %d'):format(maxl, line_index)) return apos,maxp elseif b_lt then - assert(minl == line_index) + assert(minl == line_index, ('minl %d not equal to line_index %d'):format(minl, line_index)) return minp,bpos else - assert(minl == maxl and minl == line_index) + assert(minl == maxl and minl == line_index, ('minl %d, maxl %d and line_index %d are not all equal'):format(minl, maxl, line_index)) return minp,maxp end end @@ -127,7 +127,7 @@ function Text.delete_selection_without_undo(State) State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..State.lines[minl].data:sub(max_offset) return end - assert(minl < maxl) + assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl)) local rhs = State.lines[maxl].data:sub(max_offset) for i=maxl,minl+1,-1 do table.remove(State.lines, i) @@ -154,7 +154,7 @@ function Text.selection(State) if minl == maxl then return State.lines[minl].data:sub(min_offset, max_offset-1) end - assert(minl < maxl) + assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl)) local result = {State.lines[minl].data:sub(min_offset)} for i=minl+1,maxl-1 do if State.lines[i].mode == 'text' then diff --git a/source_commands.lua b/source_commands.lua index 62e7733..c911044 100644 --- a/source_commands.lua +++ b/source_commands.lua @@ -136,7 +136,7 @@ end function move_candidate_to_front(s) local index = array.find(File_navigation.all_candidates, s) - assert(index) + assert(index, 'file missing from manifest') table.remove(File_navigation.all_candidates, index) table.insert(File_navigation.all_candidates, 1, s) end diff --git a/source_edit.lua b/source_edit.lua index 12c2bae..6259ebe 100644 --- a/source_edit.lua +++ b/source_edit.lua @@ -158,14 +158,8 @@ end function edit.draw(State, hide_cursor, show_line_numbers) State.button_handlers = {} App.color(Text_color) - if #State.lines ~= #State.line_cache then - print(('line_cache is out of date; %d when it should be %d'):format(#State.line_cache, #State.lines)) - assert(false) - end - if not Text.le1(State.screen_top1, State.cursor1) then - print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) - assert(false) - end + assert(#State.lines == #State.line_cache, ('line_cache is out of date; %d elements when it should be %d'):format(#State.line_cache, #State.lines)) + 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)) State.cursor_x = nil State.cursor_y = nil local y = State.top @@ -209,8 +203,7 @@ function edit.draw(State, hide_cursor, show_line_numbers) Drawing.draw(State, line_index, y) y = y + Drawing.pixels(line.h, State.width) + Drawing_padding_bottom else - print(line.mode) - assert(false) + assert(false, ('unknown line mode %s'):format(line.mode)) end end State.screen_bottom1 = screen_bottom1 diff --git a/source_file.lua b/source_file.lua index dbb6f95..6d04f6b 100644 --- a/source_file.lua +++ b/source_file.lua @@ -63,7 +63,7 @@ function load_drawing(infile_next_line) local drawing = {mode='drawing', h=256/2, points={}, shapes={}, pending={}} while true do local line = infile_next_line() - assert(line) + assert(line, 'drawing in file is incomplete') if line == '```' then break end local shape = json.decode(line) if shape.mode == 'freehand' then @@ -88,8 +88,7 @@ function load_drawing(infile_next_line) elseif shape.mode == 'deleted' then -- ignore else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end table.insert(drawing.shapes, shape) end @@ -123,8 +122,7 @@ function store_drawing(outfile, drawing) elseif shape.mode == 'deleted' then -- ignore else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end end outfile:write('```\n') @@ -162,7 +160,7 @@ function load_drawing_from_array(iter, a, i) local line while true do i, line = iter(a, i) - assert(i) + assert(i, 'drawing in array is incomplete') --? print(i) if line == '```' then break end local shape = json.decode(line) @@ -188,8 +186,7 @@ function load_drawing_from_array(iter, a, i) elseif shape.mode == 'deleted' then -- ignore else - print(shape.mode) - assert(false) + assert(false, ('unknown drawing mode %s'):format(shape.mode)) end table.insert(drawing.shapes, shape) end diff --git a/source_select.lua b/source_select.lua index 9b2a278..9ede1da 100644 --- a/source_select.lua +++ b/source_select.lua @@ -33,13 +33,13 @@ function Text.clip_selection(State, line_index, apos, bpos) -- fully contained return apos,bpos elseif a_ge then - assert(maxl == line_index) + assert(maxl == line_index, ('maxl %d not equal to line_index %d'):format(maxl, line_index)) return apos,maxp elseif b_lt then - assert(minl == line_index) + assert(minl == line_index, ('minl %d not equal to line_index %d'):format(minl, line_index)) return minp,bpos else - assert(minl == maxl and minl == line_index) + assert(minl == maxl and minl == line_index, ('minl %d, maxl %d and line_index %d are not all equal'):format(minl, maxl, line_index)) return minp,maxp end end @@ -127,7 +127,7 @@ function Text.delete_selection_without_undo(State) State.lines[minl].data = State.lines[minl].data:sub(1, min_offset-1)..State.lines[minl].data:sub(max_offset) return end - assert(minl < maxl) + assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl)) local rhs = State.lines[maxl].data:sub(max_offset) for i=maxl,minl+1,-1 do table.remove(State.lines, i) @@ -154,7 +154,7 @@ function Text.selection(State) if minl == maxl then return State.lines[minl].data:sub(min_offset, max_offset-1) end - assert(minl < maxl) + assert(minl < maxl, ('minl %d not < maxl %d'):format(minl, maxl)) local result = {State.lines[minl].data:sub(min_offset)} for i=minl+1,maxl-1 do if State.lines[i].mode == 'text' then diff --git a/source_text.lua b/source_text.lua index fb5123a..8b34d52 100644 --- a/source_text.lua +++ b/source_text.lua @@ -17,7 +17,7 @@ function Text.draw(State, line_index, y, startpos, hide_cursor, show_line_number love.graphics.print(line_index, State.left-Line_number_width*App.width('m')+10,y) end initialize_color() - 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 @@ -209,7 +209,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) @@ -286,7 +286,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 @@ -452,7 +452,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 @@ -478,7 +478,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) @@ -495,9 +495,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') @@ -571,7 +571,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 @@ -605,15 +605,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 @@ -646,7 +645,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 @@ -671,7 +670,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) @@ -685,7 +684,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) @@ -710,7 +709,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 @@ -742,8 +741,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) @@ -775,7 +774,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) @@ -798,7 +797,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) @@ -864,7 +863,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 @@ -895,7 +894,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) @@ -926,7 +925,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 @@ -968,7 +967,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 diff --git a/source_undo.lua b/source_undo.lua index d3d5f0f..e5dea93 100644 --- a/source_undo.lua +++ b/source_undo.lua @@ -36,11 +36,11 @@ end -- Make copies of objects; the rest of the app may mutate them in place, but undo requires immutable histories. function snapshot(State, s,e) -- Snapshot everything by default, but subset if requested. - assert(s) + assert(s, 'failed to snapshot operation for undo history') if e == nil then e = s end - assert(#State.lines > 0) + assert(#State.lines > 0, 'failed to snapshot operation for undo history') if s < 1 then s = 1 end if s > #State.lines then s = #State.lines end if e < 1 then e = 1 end @@ -65,8 +65,7 @@ function snapshot(State, s,e) elseif line.mode == 'drawing' then table.insert(event.lines, {mode='drawing', h=line.h, points=deepcopy(line.points), shapes=deepcopy(line.shapes), pending={}}) else - print(line.mode) - assert(false) + assert(false, ('unknown line mode %s'):format(line.mode)) end end return event @@ -80,22 +79,22 @@ function patch(lines, from, to) --? lines[from.start_line] = to.lines[1] --? return --? end - assert(from.start_line == to.start_line) + assert(from.start_line == to.start_line, 'failed to patch undo operation') for i=from.end_line,from.start_line,-1 do table.remove(lines, i) end - assert(#to.lines == to.end_line-to.start_line+1) + assert(#to.lines == to.end_line-to.start_line+1, 'failed to patch undo operation') for i=1,#to.lines do table.insert(lines, to.start_line+i-1, to.lines[i]) end end function patch_placeholders(line_cache, from, to) - assert(from.start_line == to.start_line) + assert(from.start_line == to.start_line, 'failed to patch undo operation') for i=from.end_line,from.start_line,-1 do table.remove(line_cache, i) end - assert(#to.lines == to.end_line-to.start_line+1) + assert(#to.lines == to.end_line-to.start_line+1, 'failed to patch undo operation') for i=1,#to.lines do table.insert(line_cache, to.start_line+i-1, {}) end diff --git a/text.lua b/text.lua index 4e0735d..2f80d91 100644 --- a/text.lua +++ b/text.lua @@ -13,7 +13,7 @@ function Text.draw(State, line_index, y, startpos) local final_screen_line_starting_pos = startpos -- track value to return Text.populate_screen_line_starting_pos(State, line_index) Text.populate_link_offsets(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 @@ -205,7 +205,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) @@ -282,7 +282,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 @@ -459,7 +459,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 @@ -485,7 +485,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) @@ -502,9 +502,9 @@ function Text.up(State) end function Text.down(State) - assert(State.lines[State.cursor1.line].mode == 'text') ---? print('down', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) - assert(State.cursor1.pos) + 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, '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') @@ -579,7 +579,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 @@ -613,15 +613,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 @@ -654,7 +653,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 @@ -679,7 +678,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) @@ -693,7 +692,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) @@ -718,7 +717,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 @@ -759,8 +758,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) @@ -793,7 +792,7 @@ function Text.to_pos_on_line(State, line_index, mx, my) --? print('Text.to_pos_on_line', State.left, State.right, App.screen.width, mx) 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) @@ -816,7 +815,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) @@ -894,7 +893,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 @@ -925,7 +924,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) @@ -956,7 +955,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 @@ -1004,7 +1003,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 diff --git a/undo.lua b/undo.lua index d3d5f0f..1ed3ce7 100644 --- a/undo.lua +++ b/undo.lua @@ -36,11 +36,11 @@ end -- Make copies of objects; the rest of the app may mutate them in place, but undo requires immutable histories. function snapshot(State, s,e) -- Snapshot everything by default, but subset if requested. - assert(s) + assert(s, 'failed to snapshot operation for undo history') if e == nil then e = s end - assert(#State.lines > 0) + assert(#State.lines > 0, 'failed to snapshot operation for undo history') if s < 1 then s = 1 end if s > #State.lines then s = #State.lines end if e < 1 then e = 1 end @@ -66,7 +66,7 @@ function snapshot(State, s,e) table.insert(event.lines, {mode='drawing', h=line.h, points=deepcopy(line.points), shapes=deepcopy(line.shapes), pending={}}) else print(line.mode) - assert(false) + assert(false, ('unknown line mode %s'):format(line.mode)) end end return event @@ -80,22 +80,22 @@ function patch(lines, from, to) --? lines[from.start_line] = to.lines[1] --? return --? end - assert(from.start_line == to.start_line) + assert(from.start_line == to.start_line, 'failed to patch undo operation') for i=from.end_line,from.start_line,-1 do table.remove(lines, i) end - assert(#to.lines == to.end_line-to.start_line+1) + assert(#to.lines == to.end_line-to.start_line+1, 'failed to patch undo operation') for i=1,#to.lines do table.insert(lines, to.start_line+i-1, to.lines[i]) end end function patch_placeholders(line_cache, from, to) - assert(from.start_line == to.start_line) + assert(from.start_line == to.start_line, 'failed to patch undo operation') for i=from.end_line,from.start_line,-1 do table.remove(line_cache, i) end - assert(#to.lines == to.end_line-to.start_line+1) + assert(#to.lines == to.end_line-to.start_line+1, 'failed to patch undo operation') for i=1,#to.lines do table.insert(line_cache, to.start_line+i-1, {}) end