diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2024-06-11 06:58:07 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2024-06-11 07:02:46 -0700 |
commit | f2299cb422d0fc07a1b01f0c31f88e9ae5ab168f (patch) | |
tree | 1216103a49bdba04dbcad0f35f14ee3128e51a9c | |
parent | 19615eade0106ad5a3a988b3f1f257367aceb7ec (diff) | |
download | lines.love-f2299cb422d0fc07a1b01f0c31f88e9ae5ab168f.tar.gz |
stop caching screen_bottom1
I'm not sure this is very useful. I had an initial idea to stop using screen_bottom1 in final_text_loc_on_screen, by starting from screen_top1 rather than screen_bottom1. But that changes the direction in which we scan for the text line in situations where there is somehow no text on screen (something that should never happen but I have zero confidence in that). Still, it doesn't seem like a bad thing to drastically reduce the lifetime of some derived state. Really what I need to do is throw this whole UX out and allow the cursor to be on a drawing as a whole. So up arrow or left arrow below a drawing would focus the whole drawing in a red border, and another up arrow and left arrow would skip the drawing and continue upward. I think that change to the UX will eliminate a whole class of special cases in the code.
-rw-r--r-- | app.lua | 5 | ||||
-rw-r--r-- | edit.lua | 8 | ||||
-rw-r--r-- | search.lua | 6 | ||||
-rw-r--r-- | select.lua | 3 | ||||
-rw-r--r-- | source_edit.lua | 8 | ||||
-rw-r--r-- | source_select.lua | 3 | ||||
-rw-r--r-- | source_text.lua | 123 | ||||
-rw-r--r-- | source_text_tests.lua | 76 | ||||
-rw-r--r-- | text.lua | 138 | ||||
-rw-r--r-- | text_tests.lua | 106 |
10 files changed, 173 insertions, 303 deletions
diff --git a/app.lua b/app.lua index 627a438..5e61d47 100644 --- a/app.lua +++ b/app.lua @@ -130,6 +130,8 @@ function App.run_tests() end end table.sort(sorted_names) +--? App.initialize_for_test() -- debug: run a single test at a time like these 2 lines +--? test_pagedown_skips_drawings() for _,name in ipairs(sorted_names) do App.initialize_for_test() --? print('=== '..name) @@ -404,9 +406,10 @@ end -- prepend file/line/test function prepend_debug_info_to_test_failure(test_name, err) local err_without_line_number = err:gsub('^[^:]*:[^:]*: ', '') - local stack_trace = debug.traceback('', --[[stack frame]]5) + local stack_trace = debug.traceback('', --[[stack frame]]5) -- most likely to be useful, but set to 0 for a complete stack trace local file_and_line_number = stack_trace:gsub('stack traceback:\n', ''):gsub(': .*', '') local full_error = file_and_line_number..':'..test_name..' -- '..err_without_line_number + -- uncomment this line for a complete stack trace --? local full_error = file_and_line_number..':'..test_name..' -- '..err_without_line_number..'\t\t'..stack_trace:gsub('\n', '\n\t\t') table.insert(Test_errors, full_error) end diff --git a/edit.lua b/edit.lua index 42309df..5a2ab28 100644 --- a/edit.lua +++ b/edit.lua @@ -70,7 +70,6 @@ function edit.initialize_state(top, left, right, font, font_height, line_height) -- On lines that are drawings, pos will be nil. screen_top1 = {line=1, pos=1}, -- position of start of screen line at top of screen cursor1 = {line=1, pos=1}, -- position of cursor; must be on a text line - screen_bottom1 = {line=1, pos=1}, -- position of start of screen line at bottom of screen selection1 = {}, -- some extra state to compute selection between mouse press and release @@ -166,13 +165,11 @@ function edit.draw(State) State.cursor_x = nil State.cursor_y = nil local y = State.top - local screen_bottom1 = {line=nil, pos=nil} --? print('== draw') for line_index = State.screen_top1.line,#State.lines do local line = State.lines[line_index] --? print('draw:', y, line_index, line) if y + State.line_height > App.screen.height then break end - screen_bottom1.line = line_index if line.mode == 'text' then --? print('text.draw', y, line_index) local startpos = 1 @@ -196,7 +193,7 @@ function edit.draw(State) end, }) end - y, screen_bottom1.pos = Text.draw(State, line_index, y, startpos) + y = Text.draw(State, line_index, y, startpos) --? print('=> y', y) elseif line.mode == 'drawing' then y = y+Drawing_padding_top @@ -206,7 +203,6 @@ function edit.draw(State) assert(false, ('unknown line mode %s'):format(line.mode)) end end - State.screen_bottom1 = screen_bottom1 if State.search_term then Text.draw_search_bar(State) end @@ -361,7 +357,7 @@ function edit.mouse_wheel_move(State, dx,dy) Text.up(State) end elseif dy < 0 then - State.cursor1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos} + State.cursor1 = Text.screen_bottom1(State) edit.put_cursor_on_next_text_line(State) for i=1,math.floor(-dy) do Text.down(State) diff --git a/search.lua b/search.lua index 54bab14..d3a5fea 100644 --- a/search.lua +++ b/search.lua @@ -62,7 +62,8 @@ function Text.search_next(State) State.screen_top1.line = State.search_backup.screen_top.line State.screen_top1.pos = State.search_backup.screen_top.pos end - if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(State.screen_bottom1, State.cursor1) then + local screen_bottom1 = Text.screen_bottom1(State) + if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(screen_bottom1, State.cursor1) then State.screen_top1.line = State.cursor1.line local pos = Text.pos_at_start_of_screen_line(State, State.cursor1) State.screen_top1.pos = pos @@ -115,7 +116,8 @@ function Text.search_previous(State) State.screen_top1.line = State.search_backup.screen_top.line State.screen_top1.pos = State.search_backup.screen_top.pos end - if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(State.screen_bottom1, State.cursor1) then + local screen_bottom1 = Text.screen_bottom1(State) + if Text.lt1(State.cursor1, State.screen_top1) or Text.lt1(screen_bottom1, State.cursor1) then State.screen_top1.line = State.cursor1.line local pos = Text.pos_at_start_of_screen_line(State, State.cursor1) State.screen_top1.pos = pos diff --git a/select.lua b/select.lua index 6e21c7b..78d18db 100644 --- a/select.lua +++ b/select.lua @@ -79,7 +79,8 @@ function Text.mouse_pos(State) end end end - return State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1) + local screen_bottom1 = Text.screen_bottom1(State) + return screen_bottom1.line, Text.pos_at_end_of_screen_line(State, screen_bottom1) end function Text.cut_selection(State) diff --git a/source_edit.lua b/source_edit.lua index 53b50eb..64c8980 100644 --- a/source_edit.lua +++ b/source_edit.lua @@ -72,7 +72,6 @@ function edit.initialize_state(top, left, right, font, font_height, line_height) -- On lines that are drawings, pos will be nil. screen_top1 = {line=1, pos=1}, -- position of start of screen line at top of screen cursor1 = {line=1, pos=1}, -- position of cursor; must be on a text line - screen_bottom1 = {line=1, pos=1}, -- position of start of screen line at bottom of screen selection1 = {}, -- some extra state to compute selection between mouse press and release @@ -167,13 +166,11 @@ function edit.draw(State, hide_cursor, show_line_numbers) State.cursor_x = nil State.cursor_y = nil local y = State.top - local screen_bottom1 = {line=nil, pos=nil} --? print('== draw') for line_index = State.screen_top1.line,#State.lines do local line = State.lines[line_index] --? print('draw:', y, line_index, line) if y + State.line_height > App.screen.height then break end - screen_bottom1.line = line_index if line.mode == 'text' then --? print('text.draw', y, line_index) local startpos = 1 @@ -201,7 +198,7 @@ function edit.draw(State, hide_cursor, show_line_numbers) end, }) end - y, screen_bottom1.pos = Text.draw(State, line_index, y, startpos, hide_cursor, show_line_numbers) + y = Text.draw(State, line_index, y, startpos, hide_cursor, show_line_numbers) --? print('=> y', y) elseif line.mode == 'drawing' then y = y+Drawing_padding_top @@ -211,7 +208,6 @@ function edit.draw(State, hide_cursor, show_line_numbers) assert(false, ('unknown line mode %s'):format(line.mode)) end end - State.screen_bottom1 = screen_bottom1 if State.search_term then Text.draw_search_bar(State) end @@ -365,7 +361,7 @@ function edit.mouse_wheel_move(State, dx,dy) Text.up(State) end elseif dy < 0 then - State.cursor1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos} + State.cursor1 = Text.screen_bottom1(State) edit.put_cursor_on_next_text_line(State) for i=1,math.floor(-dy) do Text.down(State) diff --git a/source_select.lua b/source_select.lua index 6e21c7b..78d18db 100644 --- a/source_select.lua +++ b/source_select.lua @@ -79,7 +79,8 @@ function Text.mouse_pos(State) end end end - return State.screen_bottom1.line, Text.pos_at_end_of_screen_line(State, State.screen_bottom1) + local screen_bottom1 = Text.screen_bottom1(State) + return screen_bottom1.line, Text.pos_at_end_of_screen_line(State, screen_bottom1) end function Text.cut_selection(State) diff --git a/source_text.lua b/source_text.lua index 0fced93..0fb1147 100644 --- a/source_text.lua +++ b/source_text.lua @@ -2,14 +2,13 @@ Text = {} -- draw a line starting from startpos to screen at y between State.left and State.right --- return y for the next line, and position of start of final screen line drawn +-- return y for the next line function Text.draw(State, line_index, y, startpos, hide_cursor, show_line_numbers) local line = State.lines[line_index] local line_cache = State.line_cache[line_index] line_cache.starty = y line_cache.startpos = startpos -- wrap long lines - 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) if show_line_numbers then @@ -24,7 +23,6 @@ function Text.draw(State, line_index, y, startpos, hide_cursor, show_line_number -- render nothing --? print('skipping', screen_line) else - final_screen_line_starting_pos = pos local screen_line = Text.screen_line(line, line_cache, i) --? print('text.draw:', screen_line, 'at', line_index,pos, 'after', x,y) local frag_len = utf8.len(screen_line) @@ -84,7 +82,7 @@ function Text.draw(State, line_index, y, startpos, hide_cursor, show_line_number end end end - return y, final_screen_line_starting_pos + return y end function Text.screen_line(line, line_cache, i) @@ -208,7 +206,7 @@ function Text.text_input(State, t) end end local before = snapshot(State, State.cursor1.line) ---? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.insert_at_cursor(State, t) if State.cursor_y > App.screen.height - State.line_height then Text.populate_screen_line_starting_pos(State, State.cursor1.line) @@ -241,12 +239,12 @@ function Text.keychord_press(State, chord) record_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)}) elseif chord == 'tab' then local before = snapshot(State, State.cursor1.line) ---? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.insert_at_cursor(State, '\t') if State.cursor_y > App.screen.height - State.line_height then Text.populate_screen_line_starting_pos(State, State.cursor1.line) Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right) ---? print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) end schedule_save(State) record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)}) @@ -427,37 +425,54 @@ function Text.insert_return(State) end function Text.pageup(State) ---? print('pageup') + State.screen_top1 = Text.previous_screen_top1(State) + State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} + Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) + Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks +end + +function Text.previous_screen_top1(State) -- duplicate some logic from love.draw - local top2 = Text.to2(State, State.screen_top1) ---? print(App.screen.height) + -- does not modify State (except to populate line_cache) + local loc2 = Text.to2(State, State.screen_top1) local y = App.screen.height - State.line_height while y >= State.top do ---? print(y, top2.line, top2.screen_line, top2.screen_pos) - if State.screen_top1.line == 1 and State.screen_top1.pos == 1 then break end - if State.lines[State.screen_top1.line].mode == 'text' then + if loc2.line == 1 and loc2.screen_line == 1 and loc2.screen_pos == 1 then break end + if State.lines[loc2.line].mode == 'text' then y = y - State.line_height - elseif State.lines[State.screen_top1.line].mode == 'drawing' then - y = y - Drawing_padding_height - Drawing.pixels(State.lines[State.screen_top1.line].h, State.width) + elseif State.lines[loc2.line].mode == 'drawing' then + y = y - Drawing_padding_height - Drawing.pixels(State.lines[loc2.line].h, State.width) end - top2 = Text.previous_screen_line(State, top2) + loc2 = Text.previous_screen_line(State, loc2) end - State.screen_top1 = Text.to1(State, top2) - State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} - Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) ---? print(State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos) ---? print('pageup end') + return Text.to1(State, loc2) end function Text.pagedown(State) ---? print('pagedown') - State.screen_top1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos} ---? print('setting top to', State.screen_top1.line, State.screen_top1.pos) + State.screen_top1 = Text.screen_bottom1(State) State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) ---? print('top now', State.screen_top1.line) Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks ---? print('pagedown end') +end + +-- return the location of the start of the bottom-most line on screen +function Text.screen_bottom1(State) + -- duplicate some logic from love.draw + -- does not modify State (except to populate line_cache) + local loc2 = Text.to2(State, State.screen_top1) + local y = State.top + while true do + if State.lines[loc2.line].mode == 'text' then + y = y + State.line_height + elseif State.lines[loc2.line].mode == 'drawing' then + y = y + Drawing_padding_height + Drawing.pixels(State.lines[loc2.line].h, State.width) + end + if y + State.line_height > App.screen.height then break end + local next_loc2 = Text.next_screen_line(State, loc2) + if Text.eq2(next_loc2, loc2) then break end + loc2 = next_loc2 + end + return Text.to1(State, loc2) end function Text.up(State) @@ -505,7 +520,7 @@ end function Text.down(State) 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) +--? print('down', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.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 @@ -522,7 +537,9 @@ function Text.down(State) break end end - if State.cursor1.line > State.screen_bottom1.line then + local screen_bottom1 = Text.screen_bottom1(State) +--? print('down 2', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos, screen_bottom1.line, screen_bottom1.pos) + if State.cursor1.line > screen_bottom1.line then --? print('screen top before:', State.screen_top1.line, State.screen_top1.pos) --? print('scroll up preserving cursor') Text.snap_cursor_to_bottom_of_screen(State) @@ -530,7 +547,8 @@ function Text.down(State) end else -- move down one screen line in current line - local scroll_down = Text.le1(State.screen_bottom1, State.cursor1) + local screen_bottom1 = Text.screen_bottom1(State) + local scroll_down = Text.le1(screen_bottom1, State.cursor1) --? print('cursor is NOT at final screen line of its line') local screen_line_starting_pos, screen_line_index = Text.pos_at_start_of_screen_line(State, State.cursor1) Text.populate_screen_line_starting_pos(State, State.cursor1.line) @@ -546,7 +564,7 @@ function Text.down(State) --? print('screen top after:', State.screen_top1.line, State.screen_top1.pos) end end ---? print('=>', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('=>', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos) end function Text.start_of_line(State) @@ -698,13 +716,14 @@ function Text.pos_at_end_of_screen_line(State, loc1) end function Text.final_text_loc_on_screen(State) - if State.lines[State.screen_bottom1.line].mode == 'text' then + local screen_bottom1 = Text.screen_bottom1(State) + if State.lines[screen_bottom1.line].mode == 'text' then return { - line=State.screen_bottom1.line, - pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1), + line=screen_bottom1.line, + pos=Text.pos_at_end_of_screen_line(State, screen_bottom1), } end - local loc2 = Text.to2(State, State.screen_bottom1) + local loc2 = Text.to2(State, screen_bottom1) while true do if State.lines[loc2.line].mode == 'text' then break end assert(loc2.line > 1 or loc2.screen_line > 1 and loc2.screen_pos > 1) -- elsewhere we're making sure there's always at least one text line on screen @@ -755,7 +774,7 @@ function Text.snap_cursor_to_bottom_of_screen(State) --? print('to2: =>', top2.line, top2.screen_line, top2.screen_pos) -- slide to start of screen line top2.screen_pos = 1 -- start of screen line ---? print('snap', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('snap', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) --? print('cursor pos '..tostring(State.cursor1.pos)..' is on the #'..tostring(top2.screen_line)..' screen line down') local y = App.screen.height - State.line_height -- duplicate some logic from love.draw @@ -785,7 +804,7 @@ function Text.snap_cursor_to_bottom_of_screen(State) --? print('top2 finally:', top2.line, top2.screen_line, top2.screen_pos) State.screen_top1 = Text.to1(State, top2) --? print('top1 finally:', State.screen_top1.line, State.screen_top1.pos) ---? print('snap =>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('snap =>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks end @@ -990,6 +1009,10 @@ function Text.le1(a, b) return a.pos <= b.pos end +function Text.eq2(a, b) + return a.line == b.line and a.screen_line == b.screen_line and a.screen_pos == b.screen_pos +end + function Text.offset(s, pos1) if pos1 == 1 then return 1 end local result = utf8.offset(s, pos1) @@ -1013,6 +1036,22 @@ function Text.previous_screen_line(State, loc2) end end +function Text.next_screen_line(State, loc2) + if State.lines[loc2.line].mode == 'drawing' then + return {line=loc2.line+1, screen_line=1, screen_pos=1} + end + Text.populate_screen_line_starting_pos(State, loc2.line) + if loc2.screen_line >= #State.line_cache[loc2.line].screen_line_starting_pos then + if loc2.line < #State.lines then + return {line=loc2.line+1, screen_line=1, screen_pos=1} + else + return loc2 + end + else + return {line=loc2.line, screen_line=loc2.screen_line+1, screen_pos=1} + end +end + -- resize helper function Text.tweak_screen_top_and_cursor(State) if State.screen_top1.pos == 1 then return end @@ -1036,15 +1075,16 @@ function Text.tweak_screen_top_and_cursor(State) end end -- make sure cursor is on screen + local screen_bottom1 = Text.screen_bottom1(State) if Text.lt1(State.cursor1, State.screen_top1) then State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} - elseif State.cursor1.line >= State.screen_bottom1.line then + elseif State.cursor1.line >= screen_bottom1.line then --? print('too low') if Text.cursor_out_of_screen(State) then --? print('tweak') State.cursor1 = { - line=State.screen_bottom1.line, - pos=Text.to_pos_on_line(State, State.screen_bottom1.line, State.right-5, App.screen.height-5), + line=screen_bottom1.line, + pos=Text.to_pos_on_line(State, screen_bottom1.line, State.right-5, App.screen.height-5), } end end @@ -1054,11 +1094,6 @@ end function Text.cursor_out_of_screen(State) edit.draw(State) return State.cursor_y == nil - -- this approach is cheaper and almost works, except on the final screen - -- where file ends above bottom of screen ---? local botpos = Text.pos_at_start_of_screen_line(State, State.cursor1) ---? local botline1 = {line=State.cursor1.line, pos=botpos} ---? return Text.lt1(State.screen_bottom1, botline1) end function Text.redraw_all(State) diff --git a/source_text_tests.lua b/source_text_tests.lua index b8f29d1..c17842a 100644 --- a/source_text_tests.lua +++ b/source_text_tests.lua @@ -75,7 +75,6 @@ function test_press_ctrl() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.run_after_keychord(Editor_state, 'C-m', 'm') end @@ -255,7 +254,6 @@ function test_click_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -274,7 +272,6 @@ function test_click_to_left_of_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=3} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click to the left of the line edit.draw(Editor_state) @@ -294,7 +291,6 @@ function test_click_takes_margins_into_account() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click on the other line edit.draw(Editor_state) @@ -313,7 +309,6 @@ function test_click_on_empty_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click on the empty line edit.draw(Editor_state) @@ -332,7 +327,6 @@ function test_click_below_all_lines() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click below first line edit.draw(Editor_state) @@ -350,7 +344,6 @@ function test_draw_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'screen:1') @@ -367,7 +360,6 @@ function test_draw_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'screen:1') @@ -384,7 +376,6 @@ function test_draw_word_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc ', 'screen:1') @@ -402,7 +393,6 @@ function test_click_on_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=20} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- click on the other line edit.draw(Editor_state) edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -421,7 +411,6 @@ function test_click_on_wrapping_line_takes_margins_into_account() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=20} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- click on the other line edit.draw(Editor_state) edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -439,7 +428,6 @@ function test_draw_text_wrapping_within_word() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abcd ', 'screen:1') @@ -457,7 +445,6 @@ function test_draw_wrapping_text_containing_non_ascii() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'mad', 'screen:1') @@ -476,7 +463,6 @@ function test_click_past_end_of_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -499,7 +485,6 @@ function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=8} Editor_state.screen_top1 = {line=1, pos=7} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, "I'm ad", 'baseline/screen:2') @@ -520,7 +505,6 @@ function test_click_past_end_of_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -544,7 +528,6 @@ function test_click_past_end_of_wrapping_line_containing_non_ascii() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -569,7 +552,6 @@ function test_click_past_end_of_word_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'the quick brown fox ', 'baseline/screen:1') @@ -588,7 +570,6 @@ function test_select_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- select a letter App.fake_key_press('lshift') @@ -611,7 +592,6 @@ function test_cursor_movement_without_shift_resets_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press an arrow key without shift edit.run_after_keychord(Editor_state, 'right', 'right') @@ -629,7 +609,6 @@ function test_edit_deletes_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press a key edit.run_after_text_input(Editor_state, 'x') @@ -646,7 +625,6 @@ function test_edit_with_shift_key_deletes_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- mimic precise keypresses for a capital letter App.fake_key_press('lshift') @@ -668,7 +646,6 @@ function test_copy_does_not_reset_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- copy selection edit.run_after_keychord(Editor_state, 'C-c', 'c') @@ -686,7 +663,6 @@ function test_cut() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press a key edit.run_after_keychord(Editor_state, 'C-x', 'x') @@ -704,7 +680,6 @@ function test_paste_replaces_selection() Editor_state.cursor1 = {line=2, pos=1} Editor_state.selection1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- set clipboard App.clipboard = 'xyz' @@ -723,7 +698,6 @@ function test_deleting_selection_may_scroll() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=2} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -747,7 +721,6 @@ function test_edit_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) edit.run_after_text_input(Editor_state, 'g') local y = Editor_state.top @@ -766,7 +739,6 @@ function test_insert_newline() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -795,7 +767,6 @@ function test_insert_newline_at_start_of_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- hitting the enter key splits the line edit.run_after_keychord(Editor_state, 'return', 'return') check_eq(Editor_state.cursor1.line, 2, 'cursor:line') @@ -812,7 +783,6 @@ function test_insert_from_clipboard() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -841,7 +811,6 @@ function test_select_text_using_mouse() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- press and hold on first location @@ -861,7 +830,6 @@ function test_select_text_using_mouse_starting_above_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- press mouse above first line of text @@ -879,7 +847,6 @@ function test_select_text_using_mouse_starting_above_text_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=2, pos=3} - Editor_state.screen_bottom1 = {} -- press mouse above first line of text edit.draw(Editor_state) edit.run_after_mouse_press(Editor_state, Editor_state.left+8,5, 1) @@ -902,7 +869,6 @@ function test_select_text_using_mouse_starting_below_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ab', 'baseline:screen:1') @@ -923,7 +889,6 @@ function test_select_text_using_mouse_and_shift() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- click on first location @@ -948,7 +913,6 @@ function test_select_text_repeatedly_using_mouse_and_shift() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- click on first location @@ -978,7 +942,6 @@ function test_select_all_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- select all App.fake_key_press('lctrl') @@ -1000,7 +963,6 @@ function test_cut_without_selection() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- try to cut without selecting text @@ -1016,7 +978,6 @@ function test_pagedown() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- initially the first two lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1046,7 +1007,6 @@ function test_pagedown_skips_drawings() check_eq(Editor_state.lines[2].mode, 'drawing', 'baseline/lines') Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} local drawing_height = Drawing_padding_height + drawing_width/2 -- default -- initially the screen displays the first line and the drawing -- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80px @@ -1070,7 +1030,6 @@ function test_pagedown_can_start_from_middle_of_long_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc ', 'baseline/screen:1') @@ -1105,7 +1064,6 @@ function test_pagedown_never_moves_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=9} Editor_state.screen_top1 = {line=1, pos=9} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- pagedown makes no change edit.run_after_keychord(Editor_state, 'pagedown', 'pagedown') @@ -1120,7 +1078,6 @@ function test_down_arrow_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- initially the first three lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1153,7 +1110,6 @@ function test_down_arrow_skips_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1175,7 +1131,6 @@ function test_down_arrow_scrolls_down_by_one_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1203,7 +1158,6 @@ function test_down_arrow_scrolls_down_by_one_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1232,7 +1186,6 @@ function test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_ Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1260,7 +1213,6 @@ function test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1294,7 +1246,6 @@ function test_up_arrow_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1326,7 +1277,6 @@ function test_up_arrow_skips_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1348,7 +1298,6 @@ function test_up_arrow_scrolls_up_by_one_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1376,7 +1325,6 @@ function test_up_arrow_scrolls_up_by_one_line_skipping_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=3, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1398,7 +1346,6 @@ function test_up_arrow_scrolls_up_by_one_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=6} Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -1426,7 +1373,6 @@ function test_up_arrow_scrolls_up_to_final_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ghi', 'baseline/screen:1') @@ -1456,7 +1402,6 @@ function test_up_arrow_scrolls_up_to_empty_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1483,7 +1428,6 @@ function test_pageup() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} -- initially the last two lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1508,7 +1452,6 @@ function test_pageup_scrolls_up_by_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ghi', 'baseline/screen:1') @@ -1537,7 +1480,6 @@ function test_pageup_scrolls_up_from_middle_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=2, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:2') @@ -1564,7 +1506,6 @@ function test_enter_on_bottom_line_scrolls_down() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1593,7 +1534,6 @@ function test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=4, pos=2} Editor_state.screen_top1 = {line=4, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -1616,7 +1556,6 @@ function test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bot Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- after hitting the inserting_text key the screen does not scroll down edit.run_after_text_input(Editor_state, 'a') @@ -1635,7 +1574,6 @@ function test_typing_on_bottom_line_scrolls_down() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1665,7 +1603,6 @@ function test_left_arrow_scrolls_up_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} -- cursor is at top of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1694,7 +1631,6 @@ function test_right_arrow_scrolls_down_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- cursor is at bottom right of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1724,7 +1660,6 @@ function test_home_scrolls_up_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} -- cursor is at top of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1753,7 +1688,6 @@ function test_end_scrolls_down_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- cursor is at bottom right of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1784,7 +1718,6 @@ function test_position_cursor_on_recently_edited_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=25} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc def ghi ', 'baseline1/screen:1') @@ -1818,7 +1751,6 @@ function test_backspace_can_scroll_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1846,7 +1778,6 @@ function test_backspace_can_scroll_up_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=5} Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -1981,7 +1912,6 @@ function test_undo_insert_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- insert a character edit.draw(Editor_state) edit.run_after_text_input(Editor_state, 'g') @@ -2016,7 +1946,6 @@ function test_undo_delete_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- delete a character edit.run_after_keychord(Editor_state, 'backspace', 'backspace') check_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line') @@ -2055,7 +1984,6 @@ function test_undo_restores_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- delete selected text edit.run_after_text_input(Editor_state, 'x') @@ -2076,7 +2004,6 @@ function test_search() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2103,7 +2030,6 @@ function test_search_upwards() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2121,7 +2047,6 @@ function test_search_wrap() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2139,7 +2064,6 @@ function test_search_wrap_upwards() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search upwards for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') diff --git a/text.lua b/text.lua index d9e7653..f203950 100644 --- a/text.lua +++ b/text.lua @@ -2,7 +2,7 @@ Text = {} -- draw a line starting from startpos to screen at y between State.left and State.right --- return y for the next line, and position of start of final screen line drawn +-- return y for the next line function Text.draw(State, line_index, y, startpos) --? print('text.draw', line_index, y) local line = State.lines[line_index] @@ -10,7 +10,6 @@ function Text.draw(State, line_index, y, startpos) line_cache.starty = y line_cache.startpos = 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, 'line cache missing screen line info') for i=1,#line_cache.screen_line_starting_pos do @@ -18,7 +17,6 @@ function Text.draw(State, line_index, y, startpos) if pos < startpos then -- render nothing else - final_screen_line_starting_pos = pos local screen_line = Text.screen_line(line, line_cache, i) --? print('text.draw:', screen_line, 'at', line_index,pos, 'after', x,y) local frag_len = utf8.len(screen_line) @@ -59,7 +57,7 @@ function Text.draw(State, line_index, y, startpos) end end end - return y, final_screen_line_starting_pos + return y end function Text.screen_line(line, line_cache, i) @@ -134,7 +132,7 @@ function Text.text_input(State, t) end end local before = snapshot(State, State.cursor1.line) ---? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.insert_at_cursor(State, t) if State.cursor_y > App.screen.height - State.line_height then Text.populate_screen_line_starting_pos(State, State.cursor1.line) @@ -167,12 +165,12 @@ function Text.keychord_press(State, chord) record_undo_event(State, {before=before, after=snapshot(State, before_line, State.cursor1.line)}) elseif chord == 'tab' then local before = snapshot(State, State.cursor1.line) ---? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print(State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.insert_at_cursor(State, '\t') if State.cursor_y > App.screen.height - State.line_height then Text.populate_screen_line_starting_pos(State, State.cursor1.line) Text.snap_cursor_to_bottom_of_screen(State, State.left, State.right) ---? print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('=>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) end schedule_save(State) record_undo_event(State, {before=before, after=snapshot(State, State.cursor1.line)}) @@ -353,49 +351,54 @@ function Text.insert_return(State) end function Text.pageup(State) ---? print('pageup') + State.screen_top1 = Text.previous_screen_top1(State) + State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} + Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) + Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks +end + +function Text.previous_screen_top1(State) -- duplicate some logic from love.draw - local top2 = Text.to2(State, State.screen_top1) ---? print(App.screen.height) + -- does not modify State (except to populate line_cache) + local loc2 = Text.to2(State, State.screen_top1) local y = App.screen.height - State.line_height while y >= State.top do ---? print(y, top2.line, top2.screen_line, top2.screen_pos) - if State.screen_top1.line == 1 and State.screen_top1.pos == 1 then break end - if State.lines[State.screen_top1.line].mode == 'text' then + if loc2.line == 1 and loc2.screen_line == 1 and loc2.screen_pos == 1 then break end + if State.lines[loc2.line].mode == 'text' then y = y - State.line_height - elseif State.lines[State.screen_top1.line].mode == 'drawing' then - y = y - Drawing_padding_height - Drawing.pixels(State.lines[State.screen_top1.line].h, State.width) + elseif State.lines[loc2.line].mode == 'drawing' then + y = y - Drawing_padding_height - Drawing.pixels(State.lines[loc2.line].h, State.width) end - top2 = Text.previous_screen_line(State, top2) + loc2 = Text.previous_screen_line(State, loc2) end - State.screen_top1 = Text.to1(State, top2) - State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} - Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) ---? print(State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos) ---? print('pageup end') + return Text.to1(State, loc2) end function Text.pagedown(State) ---? print('pagedown') - -- 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 bot2 = Text.to2(State, State.screen_bottom1) - if bot2.screen_line > 1 then - bot2.screen_line = math.max(bot2.screen_line-10, 1) - end - local new_top1 = Text.to1(State, bot2) - if Text.lt1(State.screen_top1, new_top1) then - State.screen_top1 = new_top1 - else - State.screen_top1 = {line=State.screen_bottom1.line, pos=State.screen_bottom1.pos} - end ---? print('setting top to', State.screen_top1.line, State.screen_top1.pos) + State.screen_top1 = Text.screen_bottom1(State) State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary(State) ---? print('top now', State.screen_top1.line) Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks ---? print('pagedown end') +end + +-- return the location of the start of the bottom-most line on screen +function Text.screen_bottom1(State) + -- duplicate some logic from love.draw + -- does not modify State (except to populate line_cache) + local loc2 = Text.to2(State, State.screen_top1) + local y = State.top + while true do + if State.lines[loc2.line].mode == 'text' then + y = y + State.line_height + elseif State.lines[loc2.line].mode == 'drawing' then + y = y + Drawing_padding_height + Drawing.pixels(State.lines[loc2.line].h, State.width) + end + if y + State.line_height > App.screen.height then break end + local next_loc2 = Text.next_screen_line(State, loc2) + if Text.eq2(next_loc2, loc2) then break end + loc2 = next_loc2 + end + return Text.to1(State, loc2) end function Text.up(State) @@ -443,7 +446,7 @@ end function Text.down(State) 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) +--? print('down', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.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 @@ -460,7 +463,9 @@ function Text.down(State) break end end - if State.cursor1.line > State.screen_bottom1.line then + local screen_bottom1 = Text.screen_bottom1(State) +--? print('down 2', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos, screen_bottom1.line, screen_bottom1.pos) + if State.cursor1.line > screen_bottom1.line then --? print('screen top before:', State.screen_top1.line, State.screen_top1.pos) --? print('scroll up preserving cursor') Text.snap_cursor_to_bottom_of_screen(State) @@ -468,7 +473,8 @@ function Text.down(State) end else -- move down one screen line in current line - local scroll_down = Text.le1(State.screen_bottom1, State.cursor1) + local screen_bottom1 = Text.screen_bottom1(State) + local scroll_down = Text.le1(screen_bottom1, State.cursor1) --? print('cursor is NOT at final screen line of its line') local screen_line_starting_pos, screen_line_index = Text.pos_at_start_of_screen_line(State, State.cursor1) Text.populate_screen_line_starting_pos(State, State.cursor1.line) @@ -484,7 +490,7 @@ function Text.down(State) --? print('screen top after:', State.screen_top1.line, State.screen_top1.pos) end end ---? print('=>', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('=>', State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos) end function Text.start_of_line(State) @@ -636,13 +642,14 @@ function Text.pos_at_end_of_screen_line(State, loc1) end function Text.final_text_loc_on_screen(State) - if State.lines[State.screen_bottom1.line].mode == 'text' then + local screen_bottom1 = Text.screen_bottom1(State) + if State.lines[screen_bottom1.line].mode == 'text' then return { - line=State.screen_bottom1.line, - pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1), + line=screen_bottom1.line, + pos=Text.pos_at_end_of_screen_line(State, screen_bottom1), } end - local loc2 = Text.to2(State, State.screen_bottom1) + local loc2 = Text.to2(State, screen_bottom1) while true do if State.lines[loc2.line].mode == 'text' then break end assert(loc2.line > 1 or loc2.screen_line > 1 and loc2.screen_pos > 1) -- elsewhere we're making sure there's always at least one text line on screen @@ -693,7 +700,7 @@ function Text.snap_cursor_to_bottom_of_screen(State) --? print('to2: =>', top2.line, top2.screen_line, top2.screen_pos) -- slide to start of screen line top2.screen_pos = 1 -- start of screen line ---? print('snap', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('snap', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) --? print('cursor pos '..tostring(State.cursor1.pos)..' is on the #'..tostring(top2.screen_line)..' screen line down') local y = App.screen.height - State.line_height -- duplicate some logic from love.draw @@ -723,7 +730,7 @@ function Text.snap_cursor_to_bottom_of_screen(State) --? print('top2 finally:', top2.line, top2.screen_line, top2.screen_pos) State.screen_top1 = Text.to1(State, top2) --? print('top1 finally:', State.screen_top1.line, State.screen_top1.pos) ---? print('snap =>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos, State.screen_bottom1.line, State.screen_bottom1.pos) +--? print('snap =>', State.screen_top1.line, State.screen_top1.pos, State.cursor1.line, State.cursor1.pos) Text.redraw_all(State) -- if we're scrolling, reclaim all fragments to avoid memory leaks end @@ -928,6 +935,10 @@ function Text.le1(a, b) return a.pos <= b.pos end +function Text.eq2(a, b) + return a.line == b.line and a.screen_line == b.screen_line and a.screen_pos == b.screen_pos +end + function Text.offset(s, pos1) if pos1 == 1 then return 1 end local result = utf8.offset(s, pos1) @@ -951,6 +962,22 @@ function Text.previous_screen_line(State, loc2) end end +function Text.next_screen_line(State, loc2) + if State.lines[loc2.line].mode == 'drawing' then + return {line=loc2.line+1, screen_line=1, screen_pos=1} + end + Text.populate_screen_line_starting_pos(State, loc2.line) + if loc2.screen_line >= #State.line_cache[loc2.line].screen_line_starting_pos then + if loc2.line < #State.lines then + return {line=loc2.line+1, screen_line=1, screen_pos=1} + else + return loc2 + end + else + return {line=loc2.line, screen_line=loc2.screen_line+1, screen_pos=1} + end +end + -- resize helper function Text.tweak_screen_top_and_cursor(State) if State.screen_top1.pos == 1 then return end @@ -974,16 +1001,12 @@ function Text.tweak_screen_top_and_cursor(State) end end -- make sure cursor is on screen + local screen_bottom1 = Text.screen_bottom1(State) if Text.lt1(State.cursor1, State.screen_top1) then State.cursor1 = {line=State.screen_top1.line, pos=State.screen_top1.pos} - elseif State.cursor1.line >= State.screen_bottom1.line then ---? print('too low') + elseif State.cursor1.line >= screen_bottom1.line then if Text.cursor_out_of_screen(State) then ---? print('tweak') - State.cursor1 = { - line=State.screen_bottom1.line, - pos=Text.to_pos_on_line(State, State.screen_bottom1.line, State.right-5, App.screen.height-5), - } + State.cursor1 = Text.final_text_loc_on_screen(State) end end end @@ -992,11 +1015,6 @@ end function Text.cursor_out_of_screen(State) edit.draw(State) return State.cursor_y == nil - -- this approach is cheaper and almost works, except on the final screen - -- where file ends above bottom of screen ---? local botpos = Text.pos_at_start_of_screen_line(State, State.cursor1) ---? local botline1 = {line=State.cursor1.line, pos=botpos} ---? return Text.lt1(State.screen_bottom1, botline1) end function Text.redraw_all(State) diff --git a/text_tests.lua b/text_tests.lua index 44cdafc..40320b1 100644 --- a/text_tests.lua +++ b/text_tests.lua @@ -75,7 +75,6 @@ function test_press_ctrl() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.run_after_keychord(Editor_state, 'C-m', 'm') end @@ -255,7 +254,6 @@ function test_click_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache edit.run_after_mouse_release(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -274,7 +272,6 @@ function test_click_to_left_of_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=3} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click to the left of the line edit.draw(Editor_state) @@ -294,7 +291,6 @@ function test_click_takes_margins_into_account() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click on the other line edit.draw(Editor_state) @@ -313,7 +309,6 @@ function test_click_on_empty_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click on the empty line edit.draw(Editor_state) @@ -332,7 +327,6 @@ function test_click_below_all_lines() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} -- click below first line edit.draw(Editor_state) @@ -350,7 +344,6 @@ function test_draw_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'screen:1') @@ -367,7 +360,6 @@ function test_draw_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'screen:1') @@ -384,7 +376,6 @@ function test_draw_word_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc ', 'screen:1') @@ -402,7 +393,6 @@ function test_click_on_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=20} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- click on the other line edit.draw(Editor_state) edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -421,7 +411,6 @@ function test_click_on_wrapping_line_takes_margins_into_account() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=20} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- click on the other line edit.draw(Editor_state) edit.run_after_mouse_click(Editor_state, Editor_state.left+8,Editor_state.top+5, 1) @@ -439,7 +428,6 @@ function test_draw_text_wrapping_within_word() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abcd ', 'screen:1') @@ -457,7 +445,6 @@ function test_draw_wrapping_text_containing_non_ascii() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'mad', 'screen:1') @@ -476,7 +463,6 @@ function test_click_past_end_of_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -499,7 +485,6 @@ function test_click_on_wrapping_line_rendered_from_partway_at_top_of_screen() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=8} Editor_state.screen_top1 = {line=1, pos=7} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, "I'm ad", 'baseline/screen:2') @@ -520,7 +505,6 @@ function test_click_past_end_of_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -544,7 +528,6 @@ function test_click_past_end_of_wrapping_line_containing_non_ascii() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'madam ', 'baseline/screen:1') @@ -569,7 +552,6 @@ function test_click_past_end_of_word_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'the quick brown fox ', 'baseline/screen:1') @@ -588,7 +570,6 @@ function test_select_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- select a letter App.fake_key_press('lshift') @@ -611,7 +592,6 @@ function test_cursor_movement_without_shift_resets_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press an arrow key without shift edit.run_after_keychord(Editor_state, 'right', 'right') @@ -629,7 +609,6 @@ function test_edit_deletes_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press a key edit.run_after_text_input(Editor_state, 'x') @@ -646,7 +625,6 @@ function test_edit_with_shift_key_deletes_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- mimic precise keypresses for a capital letter App.fake_key_press('lshift') @@ -668,7 +646,6 @@ function test_copy_does_not_reset_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- copy selection edit.run_after_keychord(Editor_state, 'C-c', 'c') @@ -686,7 +663,6 @@ function test_cut() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- press a key edit.run_after_keychord(Editor_state, 'C-x', 'x') @@ -704,7 +680,6 @@ function test_paste_replaces_selection() Editor_state.cursor1 = {line=2, pos=1} Editor_state.selection1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- set clipboard App.clipboard = 'xyz' @@ -723,7 +698,6 @@ function test_deleting_selection_may_scroll() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=2} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -747,7 +721,6 @@ function test_edit_wrapping_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) edit.run_after_text_input(Editor_state, 'g') local y = Editor_state.top @@ -766,7 +739,6 @@ function test_insert_newline() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -795,7 +767,6 @@ function test_insert_newline_at_start_of_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- hitting the enter key splits the line edit.run_after_keychord(Editor_state, 'return', 'return') check_eq(Editor_state.cursor1.line, 2, 'cursor:line') @@ -812,7 +783,6 @@ function test_insert_from_clipboard() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -841,7 +811,6 @@ function test_select_text_using_mouse() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- press and hold on first location @@ -861,7 +830,6 @@ function test_select_text_using_mouse_starting_above_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- press mouse above first line of text @@ -879,7 +847,6 @@ function test_select_text_using_mouse_starting_above_text_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=2, pos=3} - Editor_state.screen_bottom1 = {} -- press mouse above first line of text edit.draw(Editor_state) edit.run_after_mouse_press(Editor_state, Editor_state.left+8,5, 1) @@ -902,7 +869,6 @@ function test_select_text_using_mouse_starting_below_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ab', 'baseline:screen:1') @@ -923,7 +889,6 @@ function test_select_text_using_mouse_and_shift() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- click on first location @@ -948,7 +913,6 @@ function test_select_text_repeatedly_using_mouse_and_shift() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- populate line_cache.starty for each line Editor_state.line_cache -- click on first location @@ -978,7 +942,6 @@ function test_select_all_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- select all App.fake_key_press('lctrl') @@ -1000,7 +963,6 @@ function test_cut_without_selection() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} Editor_state.selection1 = {} edit.draw(Editor_state) -- try to cut without selecting text @@ -1016,7 +978,6 @@ function test_pagedown() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- initially the first two lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1046,7 +1007,6 @@ function test_pagedown_skips_drawings() check_eq(Editor_state.lines[2].mode, 'drawing', 'baseline/lines') Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} local drawing_height = Drawing_padding_height + drawing_width/2 -- default -- initially the screen displays the first line and the drawing -- 15px margin + 15px line1 + 10px margin + 25px drawing + 10px margin = 75px < screen height 80px @@ -1062,36 +1022,6 @@ function test_pagedown_skips_drawings() App.screen.check(y, 'def', 'screen:1') end -function test_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} - Editor_state = edit.initialize_test_state() - Editor_state.lines = load_array{'abc', 'def ghi jkl', 'mno'} - Text.redraw_all(Editor_state) - Editor_state.cursor1 = {line=1, pos=1} - Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} - edit.draw(Editor_state) - local y = Editor_state.top - App.screen.check(y, 'abc', 'baseline/screen:1') - y = y + Editor_state.line_height - App.screen.check(y, 'def ', 'baseline/screen:2') - y = y + Editor_state.line_height - App.screen.check(y, 'ghi ', 'baseline/screen:3') - -- after pagedown we start drawing from the bottom _line_ (multiple screen lines) - edit.run_after_keychord(Editor_state, 'pagedown', 'pagedown') - check_eq(Editor_state.screen_top1.line, 2, 'screen_top:line') - check_eq(Editor_state.screen_top1.pos, 1, 'screen_top:pos') - check_eq(Editor_state.cursor1.line, 2, 'cursor:line') - check_eq(Editor_state.cursor1.pos, 1, 'cursor:pos') - y = Editor_state.top - App.screen.check(y, 'def ', 'screen:1') - y = y + Editor_state.line_height - App.screen.check(y, 'ghi ', 'screen:2') - y = y + Editor_state.line_height - App.screen.check(y, 'jkl', 'screen:3') -end - function test_pagedown_can_start_from_middle_of_long_wrapping_line() -- draw a few lines starting from a very long wrapping line App.screen.init{width=Editor_state.left+30, height=60} @@ -1100,7 +1030,6 @@ function test_pagedown_can_start_from_middle_of_long_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc ', 'baseline/screen:1') @@ -1135,7 +1064,6 @@ function test_pagedown_never_moves_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=9} Editor_state.screen_top1 = {line=1, pos=9} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- pagedown makes no change edit.run_after_keychord(Editor_state, 'pagedown', 'pagedown') @@ -1150,7 +1078,6 @@ function test_down_arrow_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- initially the first three lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1183,7 +1110,6 @@ function test_down_arrow_skips_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1205,7 +1131,6 @@ function test_down_arrow_scrolls_down_by_one_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1233,7 +1158,6 @@ function test_down_arrow_scrolls_down_by_one_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1262,7 +1186,6 @@ function test_down_arrow_scrolls_down_by_one_screen_line_after_splitting_within_ Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1290,7 +1213,6 @@ function test_pagedown_followed_by_down_arrow_does_not_scroll_screen_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1324,7 +1246,6 @@ function test_up_arrow_moves_cursor() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1356,7 +1277,6 @@ function test_up_arrow_skips_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1378,7 +1298,6 @@ function test_up_arrow_scrolls_up_by_one_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1406,7 +1325,6 @@ function test_up_arrow_scrolls_up_by_one_line_skipping_drawing() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=1} Editor_state.screen_top1 = {line=3, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1428,7 +1346,6 @@ function test_up_arrow_scrolls_up_by_one_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=6} Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -1456,7 +1373,6 @@ function test_up_arrow_scrolls_up_to_final_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ghi', 'baseline/screen:1') @@ -1486,7 +1402,6 @@ function test_up_arrow_scrolls_up_to_empty_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1513,7 +1428,6 @@ function test_pageup() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} -- initially the last two lines are displayed edit.draw(Editor_state) local y = Editor_state.top @@ -1538,7 +1452,6 @@ function test_pageup_scrolls_up_by_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'ghi', 'baseline/screen:1') @@ -1567,7 +1480,6 @@ function test_pageup_scrolls_up_from_middle_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=2, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:2') @@ -1594,7 +1506,6 @@ function test_enter_on_bottom_line_scrolls_down() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1623,7 +1534,6 @@ function test_enter_on_final_line_avoids_scrolling_down_when_not_at_bottom() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=4, pos=2} Editor_state.screen_top1 = {line=4, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -1646,7 +1556,6 @@ function test_inserting_text_on_final_line_avoids_scrolling_down_when_not_at_bot Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- after hitting the inserting_text key the screen does not scroll down edit.run_after_text_input(Editor_state, 'a') @@ -1665,7 +1574,6 @@ function test_typing_on_bottom_line_scrolls_down() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc', 'baseline/screen:1') @@ -1695,7 +1603,6 @@ function test_left_arrow_scrolls_up_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} -- cursor is at top of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1724,7 +1631,6 @@ function test_right_arrow_scrolls_down_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- cursor is at bottom right of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1754,7 +1660,6 @@ function test_home_scrolls_up_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} -- cursor is at top of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1783,7 +1688,6 @@ function test_end_scrolls_down_in_wrapped_line() Editor_state.lines = load_array{'abc', 'def', 'ghi jkl', 'mno'} Text.redraw_all(Editor_state) Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- cursor is at bottom right of screen Editor_state.cursor1 = {line=3, pos=5} edit.draw(Editor_state) @@ -1814,7 +1718,6 @@ function test_position_cursor_on_recently_edited_wrapping_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=25} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'abc def ghi ', 'baseline1/screen:1') @@ -1848,7 +1751,6 @@ function test_backspace_can_scroll_up() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=2, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'def', 'baseline/screen:1') @@ -1876,7 +1778,6 @@ function test_backspace_can_scroll_up_screen_line() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=3, pos=5} Editor_state.screen_top1 = {line=3, pos=5} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) local y = Editor_state.top App.screen.check(y, 'jkl', 'baseline/screen:1') @@ -2011,7 +1912,6 @@ function test_undo_insert_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=4} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- insert a character edit.draw(Editor_state) edit.run_after_text_input(Editor_state, 'g') @@ -2046,7 +1946,6 @@ function test_undo_delete_text() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=5} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} -- delete a character edit.run_after_keychord(Editor_state, 'backspace', 'backspace') check_eq(Editor_state.cursor1.line, 2, 'baseline/cursor:line') @@ -2085,7 +1984,6 @@ function test_undo_restores_selection() Editor_state.cursor1 = {line=1, pos=1} Editor_state.selection1 = {line=1, pos=2} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- delete selected text edit.run_after_text_input(Editor_state, 'x') @@ -2106,7 +2004,6 @@ function test_search() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2133,7 +2030,6 @@ function test_search_upwards() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2151,7 +2047,6 @@ function test_search_wrap() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=2, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') @@ -2169,7 +2064,6 @@ function test_search_wrap_upwards() Text.redraw_all(Editor_state) Editor_state.cursor1 = {line=1, pos=1} Editor_state.screen_top1 = {line=1, pos=1} - Editor_state.screen_bottom1 = {} edit.draw(Editor_state) -- search upwards for a string edit.run_after_keychord(Editor_state, 'C-f', 'f') |