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.
This commit is contained in:
parent
19615eade0
commit
f2299cb422
5
app.lua
5
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
|
||||
|
|
8
edit.lua
8
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
131
source_text.lua
131
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')
|
||||
-- duplicate some logic from love.draw
|
||||
local top2 = Text.to2(State, State.screen_top1)
|
||||
--? print(App.screen.height)
|
||||
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
|
||||
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)
|
||||
end
|
||||
top2 = Text.previous_screen_line(State, top2)
|
||||
end
|
||||
State.screen_top1 = Text.to1(State, top2)
|
||||
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)
|
||||
--? print(State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos)
|
||||
--? print('pageup end')
|
||||
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
|
||||
-- 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
|
||||
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[loc2.line].mode == 'drawing' then
|
||||
y = y - Drawing_padding_height - Drawing.pixels(State.lines[loc2.line].h, State.width)
|
||||
end
|
||||
loc2 = Text.previous_screen_line(State, loc2)
|
||||
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)
|
||||
|
|
|
@ -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')
|
||||
|
|
146
text.lua
146
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')
|
||||
-- duplicate some logic from love.draw
|
||||
local top2 = Text.to2(State, State.screen_top1)
|
||||
--? print(App.screen.height)
|
||||
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
|
||||
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)
|
||||
end
|
||||
top2 = Text.previous_screen_line(State, top2)
|
||||
end
|
||||
State.screen_top1 = Text.to1(State, top2)
|
||||
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)
|
||||
--? print(State.cursor1.line, State.cursor1.pos, State.screen_top1.line, State.screen_top1.pos)
|
||||
--? print('pageup end')
|
||||
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
|
||||
-- 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
|
||||
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[loc2.line].mode == 'drawing' then
|
||||
y = y - Drawing_padding_height - Drawing.pixels(State.lines[loc2.line].h, State.width)
|
||||
end
|
||||
loc2 = Text.previous_screen_line(State, loc2)
|
||||
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)
|
||||
|
|
106
text_tests.lua
106
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')
|
||||
|
|
Loading…
Reference in New Issue