To fix this I have to first stop incrementally updating screen_bottom1 in the middle of a frame. Now it always has a good value from the end of a frame.
I'm also running into some limitations in the test I'd ideally like to write (that are documented in a comment), but I still get some sort of automated test for this bugfix.
6XCJX4DZB6UEAXEXXUGVVPBCF5SNDYOJGU3Q6BPB4ZMI5DZH4MYQC
KYNGDE2CKNOKUC2XMAS5MEU6YT2C3IW5SIZLOJE64G3ERT7BSWFAC
YFW4MNNPY452RIUIGW6NO7WAUWPBXXOKOJJBNZGU727PUBZFATSAC
WAR3HXHTN7JZVV6TFMU2F3QYAG6NDH7DN7KKPTM2ICEHRNQYP6PAC
LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC
SVJZZDC3K6AKAXHGRNAZKRE2ZXEKJANNLG7LSSUZJARFBL5F7C4AC
GNQC72UXBU6KYXW6MXLNRGTLXV2VPQXMVCLYMJT6POTFXSF5ASJAC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
HYEAFRZ2UEKDYTAE2GDQLHEJBPQASP2NDLMXB7F6MTVK2BKOXKEAC
MXA3RZYKUI4UF2ISY7JEF6VKX6NOPZMZH5SLLCZHRJKFIXXXDPSAC
MRA2Y3EEDV73ZFMWL3EBUXAWZYQSDK4E5FWISWHHJZ2YXTYYYTBAC
S2MISTTMPEULTO6WRO4Q4NRUO7XC2PTZW3UBR7K7SO6JPZO6HBHAC
GNKUD23IHHTLV6COIR4LBK36GPN2FPBGSXHOSJHRW5KKEA2ENWUAC
LF7BWEG4DKQI7NMXMZC4LC2BE5PB42HK5PD6OYBNIDMAZBJASOKQC
6RYLD5ONDIQFWU5CNL4NGHJQ2LNAZZFGTPXQJDNJGLNYAUOTUI7QC
OP643FFG5WQWHLPLYZ2VTDJYXK6VQ3NODRDPJNVDN26CF3ESM5RAC
UHB4GARJI5AB5UCDCZRFSCJNXGJSLU5DYGUGX5ITYEXI7Q43Z4CAC
2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC
LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC
OI4FPFINEROK6GNDEMOBTGSPYIULCLRGGT5W3H7VLM7VFH22GMWQC
WJBZZQE4A4KLYGS2KA254I6VN2DVXDY4XKCNAE76GTMLLQGYCUOQC
BW2IUB3KA4AKD35DYLCUCUM4Z32FMKGZNUBQBAEDIQJJYPA547MAC
7FPELAZBPC6545IA75OOVI5CJUKCV5OLBHVMWM3KMSKTZO6SOWNAC
K6DTOGOQG4YXWTFKHGZ3DIC23G5ZV3WQZQPRRDYIWEGLNQW6QDGQC
QJISOCHJGOGK4PTD4IGOBKBU2KMEXJZJCTBL6Y2ZNDVQ2WNR7N4AC
DLQAEAC76KLM3KZXQ2C5DASP4IBS64GR6L7QYEP67CNXJ6LRL7LQC
3OTESDW65UJ2W5RIXA6FNKRSD7TBCZTCCCEAYOQMEVGYZ6RCU34QC
52ZZ5TIEK5Z6VVXO7R3EFV5JTIWDA4IDD3YISXHHTHQMOAKVYJJQC
GFXWHTE6POBIOBUMRAWD5QS22JEO52EF4VTLMB4CDK4RLSCK7HCAC
function test_select_text_using_mouse_starting_below_text()
-- I'd like to test what happens when a mouse click is below some page of
-- text, potentially even in the middle of a line.
-- However, it's brittle to set up a text line boundary just right.
-- So I'm going to just check things below the bottom of the final line of
-- text when it's in the middle of the screen.
-- final screen line ends in the middle of screen
App.screen.init{width=50, height=60}
Editor_state = edit.initialize_test_state()
Editor_state.lines = load_array{'abcde'}
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')
y = y + Editor_state.line_height
App.screen.check(y, 'cde', 'baseline:screen:2')
-- press mouse above first line of text
edit.run_after_mouse_press(Editor_state, 5,App.screen.height-5, 1)
-- selection is past bottom-most text in screen
check(Editor_state.selection1.line ~= nil, 'selection:line-not-nil')
check_eq(Editor_state.selection1.line, 1, 'selection:line')
check_eq(Editor_state.selection1.pos, 6, 'selection:pos')
end
function Text.pos_at_end_of_screen_line(State, loc1)
Text.populate_screen_line_starting_pos(State, loc1.line)
local line_cache = State.line_cache[loc1.line]
local most_recent_final_pos = utf8.len(State.lines[loc1.line].data)+1
for i=#line_cache.screen_line_starting_pos,1,-1 do
local spos = line_cache.screen_line_starting_pos[i]
if spos <= loc1.pos then
return most_recent_final_pos
end
most_recent_final_pos = spos-1
end
assert(false)
end
local line,pos = Text.to_pos(State, App.mouse_x(), App.mouse_y())
return line, pos
end
function Text.to_pos(State, x,y)
local x,y = App.mouse_x(), App.mouse_y()
-- still here? click is below all screen lines
State.old_cursor1 = State.cursor1
State.old_selection1 = State.selection1
State.mousepress_shift = App.shift_down()
State.selection1 = {
line=State.screen_bottom1.line,
pos=Text.pos_at_end_of_screen_line(State, State.screen_bottom1),
}
print_and_log(('edit.mouse_release: finally selection %s,%s cursor %d,%d'):format(tostring(State.selection1.line), tostring(State.selection1.pos), State.cursor1.line, State.cursor1.pos))
--? print_and_log(('edit.mouse_release: finally selection %s,%s cursor %d,%d'):format(tostring(State.selection1.line), tostring(State.selection1.pos), State.cursor1.line, State.cursor1.pos))