I have no idea what the performance implications of this are..
ILOA5BYFTQKBSHLFMMZUVPQ2JXBFJD62ERQFBTDK2WSRXUN525VQC
WLWNS6FBT6D3HKOFWDPBKLK7KS73LJJLWLHNWX3YJ723OHJBZGDQC
CNCYMM6ABOXCRI2IP5A4T2OGBO5FQ7GWBXBP2OQYL4YET5BLJCGQC
LSYLEVBDBZBGLSCXTRBW46WT4TUMMSPCH7M6HSNYI5SIH2WNPYEAC
FKNXK2OAH4U2V2TXCHWE4C3Z5DROBIIPSXUWFKP7Q3DSNOKFFL5AC
EM276IH3NFWRAVNH4MLH43KOEXPZSX4K35CNVRSI3NGZHHUZQPBQC
HGC5RGJPK34K5HRPG6FB7VIKOT6VTWVEC3CBYS5QVH5LVKAL6WGQC
WZFMGVDTNVWZUX46RMEP5XHRZRBKL5G262VAQUWP5AYY7TRXN5XAC
BW2IUB3KA4AKD35DYLCUCUM4Z32FMKGZNUBQBAEDIQJJYPA547MAC
VJ77YABHVJZWJKLHAGIPC562GYM73AUGRLCP4JLKP5JPWPT2RIHAC
73OCE2MCBJJZZMN2KYPJTBOUCKBZAOQ2QIAMTGCNOOJ2AJAXFT2AC
LF7BWEG4DKQI7NMXMZC4LC2BE5PB42HK5PD6OYBNIDMAZBJASOKQC
LNUHQOGHIOFGJXNGA3DZLYEASLYYDGLN2I3EDZY5ANASQAHCG3YQC
LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC
DSLD74DK3P6J2VAFCYF5BGTHZ637QTW3PDHOUHFACDZU66YNM3IAC
M6TH7VSZQGKDB7SFNN5K52WWAX5VTVNT6GOKNKTXPVZBT6NEYDOQC
GJLOKCYKETWXJXBOS5222HVZIKBDOGLLR5QLUZYCTZG7FBYDTQMQC
UHB4GARJI5AB5UCDCZRFSCJNXGJSLU5DYGUGX5ITYEXI7Q43Z4CAC
MYC7XR5QOT2AXHF6UNGSNFFD5VL6UHGUZQBP7PWWLZ5NNXE7UMTAC
4VKEE43Z7MUPNIAOCK36INVBNHRTSWRRN37TIKRPXPH3DRKGHHAQC
IWYLK45KJSPRXKW55OD4GEPMLTYMMTXNFJJU26JTZN3RE35DWSCQC
3ZSUBI574IYW3BKS6OFPDD6UY2IJBNOQIGA4YFGQSF4VZ3PPATYQC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
H2DPLWMVRFYTO2CQTG54FMT2LF3B6UKLXH32CUA22DNQJVP5XBNQC
CVGE3SIGJRGCLY3A2RBPGFXAEKVZXUUIZQLRHJLM4VPUM4SHEZIAC
OYXDYPGSJK2QICJ6RBA7357WT4FSNAWRUT77YLQHT3F3VYMWGNFQC
5L7K4GBDEAFH44LMLNKVFMHLWDNXXBKRPEI347VE5ZLXVFSMD2FAC
537TQ2QNPKPG322I4OIMN5IY22S45Z42LEBBZ2IN5MVM355BEJTAC
JY4VK7L2JKRWRV45QEMGLWPFAQRUWKFHMAL6DWNYEDCKO5Y4W5FQC
PESSMQBJCOIA5PYNVKUG4D25VTFIG44QVCAOFRD4PKOJNW2AIHKAC
PFT5Y2ZYGQA6XXOZ5HH75WVUGA4B3KTDRHSFOZRAUKTPSFOPMNRAC
NDHQN23GI2IFUYGNYSO4BC467L37CQDDYL4C7NYCLD47QHOG6WFQC
5DOTWNVMOGN75GJMXXB4A56UAJYSNYC5WXPRT7QFMAAV27NWPP3AC
IMEJA43L3OX7S5KIYLZJ4F3ITACLAA5SZBHSCIJMULCPRSW7LXBAC
DGK5BPVI6PAD3WK2ZB2ITMBE6WYSU3ZR7TV7RTCQ2WJQ4RGJE5RQC
SPSW74Y5OJ54Y7VQ3SJFCJR5CYDKTR4A3TOEVZODDZLUSDDU2GZAC
XNFTJHC4QSHNSIWNN7K6QZEZ37GTQYKHS4EPNSVPQCUSWREROGIQC
2RXZ3PGOTTZ6M4R372JXIKPLBQKPVBMAXNPIEO2HZDN4EMYW4GNAC
Z5HLXU4PJWWJJDBCK52NBD6PIRIA3TAN2BKZB5HBYFGIDBX4F5HAC
ZPUQSPQPQFVRUIHGLAWW3IDBYODIWDHO62HAC3WWF5TM3CIJGHNQC
WLJCIXYMSTCNSYCFOEBQNDLBZ5D2Z3WTF4E4WYL5CFGIJ434FKNQC
MXA3RZYKUI4UF2ISY7JEF6VKX6NOPZMZH5SLLCZHRJKFIXXXDPSAC
2TQR4PSY2FBIKEEKC2Y5ZPVPOD2QJ3EATII47PPWNMTAQA7EQ6GAC
ODLKHO7BO2AODYO2OEQ6D4NSNBT5GR3CKLUXWMDLRYXL7DJOI7BAC
QCPXQ2E3USF3Z6R6WJ2JKHTRMPKA6QWXFKKRMLXA3MXABJEL543AC
242L3OQXTU2TCAINRJXQEEDSXQXM7Y7USUPBK37ZNM3A7V5TUDSAC
EMRPLZPWIJOEYBBSHFBRUYG4EFROTZ5VG7N3MTXFZFFPBTZ6ODGQC
CTJ3IZGSPY4DBHC6OYNL4DZE24MXYQBM3KVJZTQHM5DI5TED5ZLQC
52ZZ5TIEK5Z6VVXO7R3EFV5JTIWDA4IDD3YISXHHTHQMOAKVYJJQC
CCYSVZA2ONWXB6XJXWSIEBY4CS2LGBEVV3RB6KZ6I4XYRXQLSTXQC
LAW2O3NWVFTPBSKIMIXPAGYBDOCHYJNKCAVWKNKH62G42DIKZCYQC
HYEAFRZ2UEKDYTAE2GDQLHEJBPQASP2NDLMXB7F6MTVK2BKOXKEAC
K4OBZSHEBIZBAKPH3F7ASDGCPLB7D5W5QLFJQYSM5XOYDPB4BUHAC
U52E2XZNDEMIX5QJC6TREX5BSLNYG23Y4XQVFFKS6OFB2KIBW7BAC
BOFNXP5GZDCUMQG3LQVTSSFEQP7REQ4RIRJLDLETFSAGFTVDVEKAC
KZ5GAYRPWF2BA5VEIW3A4G2TULATBL7YEDGFJU42GBP5DET7BI3AC
3OKKTUT4Q7W44JHILOFV5BVUA7ZOBIHBCEXGZ65CPXV4PRLI2W4QC
2H67P75X7FSSNZMV4TU5I46XLIYAJ5VT7H6MS7GYLUSNTA4IRDFQC
P66MRF3UTEWFZPFPTZLQVXWYZTD33SLOQGMCBP6FKMFCQ7EMN2YQC
UV4EWOLYCQ27TL6IGGLKNQX3UUOF7HJ5EJVCZYW345X6BK4J7YQAC
R53OF3ONKT5VL5BGK63YSN6GXIIAVNYDG4UMHITK72WXFWPJ25MQC
GCEF4N3VW2JFTWVXU2ND5XA63BNTMEGRBQQXYA3HULAKGYOYJP7AC
WOXIYUTL4NU7ACHQYXEXJDSXCRDLQ2X457KO6C7GEXFQZ43F3L7QC
HOSPP2ANSW654DYRTC6CQUQA2GUKV6T2FI7QBKXD2DZS3R32IMGAC
PLKNHYZ4KXWWKC2DHXCI4WVO23I7VMEVYT5H2J6JDE4S3D3CHDJQC
S2MISTTMPEULTO6WRO4Q4NRUO7XC2PTZW3UBR7K7SO6JPZO6HBHAC
OTIBCAUJ3KDQJLVDN3A536DLZGNRYMGJLORZVR3WLCGXGO6UGO6AC
2L5MEZV344TOZLVY3432RHJFIRVXFD6O3GWLL5O4CV66BGAFTURQC
WJBZZQE4A4KLYGS2KA254I6VN2DVXDY4XKCNAE76GTMLLQGYCUOQC
K2X6G75Z6XBC4DVIRWC5HC7XA3A2SKOM3MWSQTCFEYWIJL7LME2QC
function patch_placeholders(line_cache, from, to)
assert(from.start_line == to.start_line)
for i=from.end_line,from.start_line,-1 do
table.remove(line_cache, i)
end
assert(#to.lines == to.end_line-to.start_line+1)
for i=1,#to.lines do
table.insert(line_cache, to.start_line+i-1, {})
end
end
'```lines', '```', -- height 25
'def', -- height 15
'ghi'} -- height 15
'```lines', '```', -- height 25
'def', -- height 15
'ghi'} -- height 15
Text.redraw_all(Editor_state)
if State.lines[State.cursor1.line+1].mode == 'drawing' then
table.remove(State.lines, State.cursor1.line+1)
else
if State.lines[State.cursor1.line+1].mode == 'text' then
new_screen_line_starting_pos = State.lines[State.cursor1.line].screen_line_starting_pos[screen_line_index+1]
new_screen_line_starting_pos = State.text_line_cache[State.cursor1.line].screen_line_starting_pos[screen_line_index+1]
for i=#State.lines[State.cursor1.line].screen_line_starting_pos,1,-1 do
local spos = State.lines[State.cursor1.line].screen_line_starting_pos[i]
for i=#State.text_line_cache[State.cursor1.line].screen_line_starting_pos,1,-1 do
local spos = State.text_line_cache[State.cursor1.line].screen_line_starting_pos[i]
if line.starty == nil then return false end -- outside current page
local line_cache = State.text_line_cache[line_index]
if line_cache.starty == nil then return false end -- outside current page
return y < line.starty + State.line_height*(#line.screen_line_starting_pos - Text.screen_line_index(line.screen_line_starting_pos, line.startpos) + 1)
return y < line_cache.starty + State.line_height*(#line_cache.screen_line_starting_pos - Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos) + 1)
if line.fragments == nil then
local line_cache = State.text_line_cache[line_index]
if line_cache.fragments == nil then
local y = line.starty
local start_screen_line_index = Text.screen_line_index(line.screen_line_starting_pos, line.startpos)
for screen_line_index = start_screen_line_index,#line.screen_line_starting_pos do
local screen_line_starting_pos = line.screen_line_starting_pos[screen_line_index]
local y = line_cache.starty
local start_screen_line_index = Text.screen_line_index(line_cache.screen_line_starting_pos, line_cache.startpos)
for screen_line_index = start_screen_line_index,#line_cache.screen_line_starting_pos do
local screen_line_starting_pos = line_cache.screen_line_starting_pos[screen_line_index]
if screen_line_index < #line.screen_line_starting_pos and mx > Text.screen_line_width(State, line_index, screen_line_index) then
if screen_line_index < #line_cache.screen_line_starting_pos and mx > Text.screen_line_width(State, line_index, screen_line_index) then
for i=#State.lines[pos1.line].screen_line_starting_pos,1,-1 do
local spos = State.lines[pos1.line].screen_line_starting_pos[i]
for i=#State.text_line_cache[pos1.line].screen_line_starting_pos,1,-1 do
local spos = State.text_line_cache[pos1.line].screen_line_starting_pos[i]
return {line=pos2.line-1, screen_line=#State.lines[pos2.line-1].screen_line_starting_pos, screen_pos=1}
return {line=pos2.line-1, screen_line=#State.text_line_cache[pos2.line-1].screen_line_starting_pos, screen_pos=1}
for i=2,#line.screen_line_starting_pos do
local pos = line.screen_line_starting_pos[i]
local line_cache = State.text_line_cache[State.screen_top1.line]
for i=2,#line_cache.screen_line_starting_pos do
local pos = line_cache.screen_line_starting_pos[i]
for line_index,line in ipairs(State.lines) do
line.starty = nil
line.startpos = nil
Text.clear_screen_line_cache(State, line_index)
State.text_line_cache = {}
for i=1,#State.lines do
State.text_line_cache[i] = {}
-- some cached data that's blown away and recomputed when data changes:
-- startpos, the index of data the line starts rendering from (if currently on screen), can only be >1 for topmost line on screen
-- starty, the y coord in pixels
-- fragments: snippets of rendered love.graphics.Text, guaranteed to not wrap
-- screen_line_starting_pos: optional array of grapheme indices if it wraps over more than one screen line
--
-- Therefore, any potential location for the cursor can be described in two ways:
-- rendering wrapped text lines needs some additional short-lived data per line:
-- startpos, the index of data the line starts rendering from, can only be >1 for topmost line on screen
-- starty, the y coord in pixels the line starts rendering from
-- fragments: snippets of rendered love.graphics.Text, guaranteed to not straddle screen lines
-- screen_line_starting_pos: optional array of grapheme indices if it wraps over more than one screen line
text_line_cache = {},
-- Given wrapping, any potential location for the text cursor can be described in two ways: