This was complicated. I had to:
LEP7X3CT5H7NRQOBIAKQU32QLQQWLBURBNTR2YZUYL53C5BRAM6QC
JW7O3UZDMKOZSC4RPAOXLQ4J2IDSQT2FUSPY5U6YBAAPIFW4LHOQC
UK6NZJVBRXW6NVHAQO464UKOVNZ44X2Y7E227UVT2OFMW67PXUAAC
I3B3KLAB3GFQVOZBD7DBJTVIZ34G2TGFNEOADS6JKPA54DB5R5LAC
6K5PFF6XBFTM6CXUVVFIH4CQMCMPHTND3ICDMRMNOME5BUBF27NQC
NNCEQQFVHBFCVDOPHGPQSJA7IT26PY5FXXU3E6N7MJJXK3LSI4GAC
E4H624JKZ7QELJT3GDVMN4ALXOQ4N3HSNSQSTVUDIJALDUSHLHMQC
AHOO2ILEJWTPCYHJH26WAF7A4YYVMHFX4UWHSAAAMHI73TSQZ6CAC
I64IPGJXWRTGHHVAYJUBUIWFR4BY6NM5P7TLTV4JOD7K4BVYDECQC
R5QXEHUIZLELJGGCZAE7ATNS3CLRJ7JFRENMGH4XXH24C5WABZDQC
KKMFQDR43ZWVCDRHQLWWX3FCWCFA3ZSXYOBRJNPHUQZR2XPKWULAC
MDGHRTIFMMWBQZPIUCPE6ZM65Z4UOEQOHYDGH6J3M7MNQ6DCMR4AC
R3KXFRZNL4CAT5OSKIIGWR3CHL2YJ5S4TKQDIPEHIJ2HW2WS46BQC
D3FLL7SL45CAFMGVOVABX75JBG4LGL4O35R5AIF3INW7N4VUP4DAC
NYRESFK6T6NNVQRPVQEJP37Z4XUOUDBQWWU7DMQ23Y3GX7U2A4XQC
QFTLLRGLZ2LV4CWD23WKPM4NU4HU7NX4P73BN2EFHVVQEJUXH74AC
RQUVBX627HPVMS77HCERQGTGFNP6JXSBBAZNR2PTNT6B7LRRGQIAC
FFAPDHHHSWGBUDN3ES3H2KFWYHBN5KMFVHOKU2QUQOZFIK75G27QC
HTWAM4NZFOY463TNSKYIM2EWB7QNBGDRRTTGHF5N3Z4TGC7Q3SFAC
LXTTOB33N2HCUZFIUDRQGGBVHK2HODRG4NBLH6RXRQZDCHF27BSAC
NZKYPBSKYJ7NQU7ABRHLYZ2P2P5V2UF76OLRURGTGRUB54R4SPBQC
BW2IUB3KA4AKD35DYLCUCUM4Z32FMKGZNUBQBAEDIQJJYPA547MAC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
H5JVZ42KOC3QKTARTCJQUZP6473FCWTW72RKPORLARCRVBERBLKQC
3ZSUBI574IYW3BKS6OFPDD6UY2IJBNOQIGA4YFGQSF4VZ3PPATYQC
DHI6IJCNSTHGED67T6H5X6Y636C7PIDGIJD32HBEKLT5WIMRS5MAC
KURLAXXIKHKBL7UDFVIR26BI5FDO3ZFLIQASKVGJRDD3RETTOWNQC
42XEN6VO4O37LR3WF5YEZPNRKDQOSPJJ7LB2RM6LJEET2ABUVNZQC
H4R5BHVYKFKF2JOFITQ45VEVW32BOWIMHWFOQ35KAUS6QUI7G5QQC
V5SYDHPQ7IKNLZZ3NJ24FDW3IG4O23AASLP2DTKOBPWUUZ5KUPOAC
HALS7E5UGKCP3DFY456F7Z3Y6WNGIABOCV2SHT34D5ZAGNCPV5PQC
S2QMLRXLULVA6M73YVC5VQJ2SYUBHG2DTGXEMOBKEPR4OU7ZKG3AC
6WDBV52ZFEYAUK6L66LDOKJ5JGHP63VY5R4NDOROZDY6HZJF45KAC
ISOFHXB2DX6IRN4HVBYWLADZM7QXQKRNAAS577G542KS4L6G5H3QC
4PWZSWW46E3PVL2LIO7PZLAJVIOJ4CY5HZ5VHUWLBZPEKTGZHN4AC
X3F7ECSLGXCH6NBSDIH7LY47I4EG2RR5VFPEMM6ZVDYQIGFID4HQC
HOSPP2ANSW654DYRTC6CQUQA2GUKV6T2FI7QBKXD2DZS3R32IMGAC
X4IMZTJHZDYTKABS2SHGQWP6PN7ESECHYQQKLLGZKBDE7Y4TYX4QC
OYVFFWBK5IL7IPAF5HGFONJ2NEBRR3GTISPFROG7HJDEZYJAM7VQC
PFT5Y2ZYGQA6XXOZ5HH75WVUGA4B3KTDRHSFOZRAUKTPSFOPMNRAC
2CK5QI7WA7M4IVSACFGOJYAIDKRUTZVMMPSFWEJTUNMWTN7AX4NAC
W5D22DQ5HRM3SGVEDY3E57Q6UPXGYLPQUJEVYMP2SU5KKG4J5K2AC
IWYLK45KJSPRXKW55OD4GEPMLTYMMTXNFJJU26JTZN3RE35DWSCQC
WOXIYUTL4NU7ACHQYXEXJDSXCRDLQ2X457KO6C7GEXFQZ43F3L7QC
R53OF3ONKT5VL5BGK63YSN6GXIIAVNYDG4UMHITK72WXFWPJ25MQC
TGHAJBESCIEGWUE2D3FGLNOIAYT4D2IRGZKRXRMTUFW7QZETC7OAC
JMUE7GSN6QDQZ6NDRB55MRJMKJN6LBD6MVQPKROYPDOIXM7I3XNQC
YU7LZFIFZ7U2XC5U37AK3I5SULKCTRLZ4P357WWM6IWETGHTXS7QC
AW766XSWHNS2BNXH7NFCMNITYXZCWYJHGDXTOJE4CDCTYUO6HFTQC
Z575DEB7ULZXYH2BJCFXQMKPVXCSG72P46EHVBDD5PAOQTUDNZHQC
JC64ZBDKHZ54FRG2HZ76PFVQYK4EIFLNU36KDQ762KMT2DG7M4HQC
YKRUNSPXQMYUZM2HC2BWRL3OLVF5X3Y3XASG7JCT4TW4VUHZD6ZAC
GQBUV2XOMEPMTXMPCBQWGGIUXGQDX77VTGPFIG6YT7G64ASOYHXQC
CMZFG5EKA2MGFNYA66TJLYQ7VUIXRPCHDBQLZB2QTZMEUMNEGJUAC
PXCTDLE5XS3QSYBVK65TEPA7ZWVZN7GPHKX3ZUEVEO3F6LH3OKSAC
ZPIIIN2B4EENXZAANI23O2IBKAMFNPLGZYFFMJIZ6ENYVPH5ECDQC
D7D6T2F3FRMONF627F2NV227T5KTZ4FOHZKROEIIA236U7FVASTQC
OOUCNHXBSUYBBBMBWWJZX3CRPXI2KNQWO24UJOO3IYORXK2MLAJQC
LA63KIU2TQ4ISN3VG3OJKKB6NEKU33RF7MC6XJRJMXEGCBBM4E2QC
UHCBQAEPO46E4DOYJV7YDGJVZ62SH2OHZI4FVBNSGXXMX5JZAFFQC
RQ37HOBMOPOATWRTCEYIRSSGO6P63SQTGFUQM32QFJXKQI5NYDMQC
AVTNUQYRBW7IX2YQ3KDLVQ23RGW3BAKTAE7P73ASBYNKOHMQMH5AC
EGS44RTAG7JVLLEA4KH63MBZAD4O5HNRSJQIOC6SRKHUG3G56R6QC
3QNOKBFMKBGXBVJIRHR2444JRRMBTABHE4674NR3DT67RRM2X6GAC
local width = App.width(filename)
if x + width > App.screen.width - 5 then
y = y + Editor_state.line_height
x = 5
local width = App.width(filename)
if x + width > App.screen.width - 5 then
y = y + Editor_state.line_height
x = 5
end
if i == index then
return y, x, width
end
x = x + width + 30
end
end
function file_index(fy, fx, fwidth)
log_start('file index')
log(2, ('for %d %d %d'):format(fy, fx, fwidth))
local y,x = Menu_status_bar_height, 5
local best_guess, best_guess_x, best_guess_width
for i,filename in ipairs(File_navigation.candidates) do
App.screen.print(filename, x + x3-menu_xmin, y3)
end
x3 = x3 + width + 30
end
--
return h+20
width = App.width(filename)
if x3 + width > App.screen.width - 5 then
y3 = y3 + Editor_state.line_height
x3 = 0
end
if i == o.index then
App.color(Menu_highlight_color)
love.graphics.rectangle('fill', x + x3-menu_xmin - 5, y3-2, width+5*2, Editor_state.line_height+2*2)
end
if x3 >= menu_xmin and x3 + width < menu_xmax then
App.color(Menu_command_color)
width = App.width(filename)
if x2 + width > App.screen.width - 5 then
y2 = y2 + Editor_state.line_height
x2 = 0
end
if i == o.index then
break
end
x2 = x2 + width + 30
App.screen.print(s, x,y)
x = x + width + 30
return x,y
local width = App.width(s)
if x + width > App.screen.width - 5 then
y = y + Editor_state.line_height
x = 5
end
local width = App.width(filename)
if x + width > App.screen.width - 5 then
result = result+1
x = 5 + width
else
x = x + width + 30
end
App.screen.print(File_navigation.filter, 5, 5)
draw_cursor(5 + App.width(File_navigation.filter), 5)
if File_navigation.num_lines == nil then
App.screen.print(s, Menu_cursor,5)
Menu_cursor = Menu_cursor + width + 30
end
function source.draw_file_navigator()
local width = App.width(s)
if Menu_cursor > App.screen.width - 30 then
else
final_screen_line_starting_pos = pos
local f = Text.screen_line(line, line_cache, i)
--? print('text.draw:', f, 'at', line_index,pos, 'after', x,y)
local frag_len = utf8.len(f)
-- render fragment
local frag_width = App.width(frag_text)
if x + frag_width > State.right then
assert(x > State.left) -- no overfull lines
end
-- Make [[WikiWords]] (single word, all in one screen line) clickable.
local trimmed_word = rtrim(frag) -- compute_fragments puts whitespace at the end
if starts_with(trimmed_word, '[[') and ends_with(trimmed_word, ']]') then
local filename = trimmed_word:gsub('^..(.*)..$', '%1')
if link_exists(State, filename) then
local filename_text = App.newText(love.graphics.getFont(), filename)
button(State, 'link', {x=x+App.width(to_text('[[')), y=y, w=App.width(filename_text), h=State.line_height, color={1,1,1},
-- render any link decorations
for _,link_offsets in ipairs(line_cache.link_offsets) do
local s,e,filename = unpack(link_offsets)
local lo, hi = Text.clip_wikiword_with_screen_line(line, line_cache, i, s, e)
if lo then
button(State, 'link', {x=State.left+lo, y=y, w=hi-lo, h=State.line_height, color={1,1,1},
function Text.populate_link_offsets(State, line_index)
local line = State.lines[line_index]
if line.mode ~= 'text' then return end
local line_cache = State.line_cache[line_index]
if line_cache.link_offsets then
return
end
line_cache.link_offsets = {}
local pos = 1
-- try to wrap at word boundaries
local s, e = 1, 0
while s <= #line.data do
s, e = line.data:find('%[%[%S+%]%]', s)
if s == nil then break end
local word = line.data:sub(s+2, e-2) -- strip out surrounding '[[..]]'
--? print('wikiword:', s, e, word)
table.insert(line_cache.link_offsets, {s, e, word})
s = e + 1
end
end
-- Intersect the filename between byte offsets s,e with the bounds of screen line i.
-- Return the left/right pixel coordinates of of the intersection,
-- or nil if it doesn't intersect with screen line i.
function Text.clip_wikiword_with_screen_line(line, line_cache, i, s, e)
local spos = line_cache.screen_line_starting_pos[i]
local soff = Text.offset(line.data, spos)
if e < soff then
return
end
local eoff
if i < #line_cache.screen_line_starting_pos then
local epos = line_cache.screen_line_starting_pos[i+1]
eoff = Text.offset(line.data, epos)
if s > eoff then
return
end
end
local loff = math.max(s, soff)
local hoff
if eoff then
hoff = math.min(e, eoff)
else
hoff = e
end
--? print(s, e, soff, eoff, loff, hoff)
return App.width(line.data:sub(1, loff-1)), App.width(line.data:sub(1, hoff))
end
local vertically_ok = cursor_sx > Display_settings.x and cursor_sx < Display_settings.x + App.screen.width - App.width(Em)
local vertically_ok = cursor_sx > Display_settings.x and cursor_sx < Display_settings.x + App.screen.width - App.width('m')
local left = math.max(0, 1/2*(App.screen.width-App.width(Current_error_text)-10))
local width = math.min(App.screen.width, App.width(Current_error_text)+20)
local left = math.max(0, 1/2*(App.screen.width-App.width(Current_error)-10))
local width = math.min(App.screen.width, App.width(Current_error)+20)
if Text_cache[s] == nil then
Text_cache[s] = App.newText(love.graphics.getFont(), s)
end
local width = App.width(Text_cache[s])
local width = App.width(s)