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 dotable.remove(line_cache, i)endassert(#to.lines == to.end_line-to.start_line+1)for i=1,#to.lines dotable.insert(line_cache, to.start_line+i-1, {})endend
'```lines', '```', -- height 25'def', -- height 15'ghi'} -- height 15
'```lines', '```', -- height 25'def', -- height 15'ghi'} -- height 15Text.redraw_all(Editor_state)
if State.lines[State.cursor1.line+1].mode == 'drawing' thentable.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 dolocal 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 dolocal 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.startylocal 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 dolocal screen_line_starting_pos = line.screen_line_starting_pos[screen_line_index]
local y = line_cache.startylocal 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 dolocal 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 dolocal spos = State.lines[pos1.line].screen_line_starting_pos[i]
for i=#State.text_line_cache[pos1.line].screen_line_starting_pos,1,-1 dolocal 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 dolocal 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 dolocal pos = line_cache.screen_line_starting_pos[i]
for line_index,line in ipairs(State.lines) doline.starty = nilline.startpos = nilText.clear_screen_line_cache(State, line_index)
State.text_line_cache = {}for i=1,#State.lines doState.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 linetext_line_cache = {},-- Given wrapping, any potential location for the text cursor can be described in two ways: