Copy over the implementation of links from the lines-and-links fork.
HGDWZ7WCY7SZWF77WYA6IALE74IZTFUSSE42VI4XIOOCXSXJX7JQC
6K5PFF6XBFTM6CXUVVFIH4CQMCMPHTND3ICDMRMNOME5BUBF27NQC
FKAYZHU7UX4X2LNRNQEWNX6TZCMQ6R26XOCH3PAM53XIXD2GJ2WQC
I64IPGJXWRTGHHVAYJUBUIWFR4BY6NM5P7TLTV4JOD7K4BVYDECQC
V5SYDHPQ7IKNLZZ3NJ24FDW3IG4O23AASLP2DTKOBPWUUZ5KUPOAC
BULPIBEGL7TMK6CVIE7IS7WGAHGOSUJBGJSFQK542MOWGHP2ADQQC
6WDBV52ZFEYAUK6L66LDOKJ5JGHP63VY5R4NDOROZDY6HZJF45KAC
HALS7E5UGKCP3DFY456F7Z3Y6WNGIABOCV2SHT34D5ZAGNCPV5PQC
7MMFX7LON7VH7PPZWAALQMRFVBAQD44Q5RBIJEI4GNEVWN47NO2AC
X3F7ECSLGXCH6NBSDIH7LY47I4EG2RR5VFPEMM6ZVDYQIGFID4HQC
PFT5Y2ZYGQA6XXOZ5HH75WVUGA4B3KTDRHSFOZRAUKTPSFOPMNRAC
2CK5QI7WA7M4IVSACFGOJYAIDKRUTZVMMPSFWEJTUNMWTN7AX4NAC
TGHAJBESCIEGWUE2D3FGLNOIAYT4D2IRGZKRXRMTUFW7QZETC7OAC
-- 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_filename_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},
icon = icon.hyperlink_decoration,
onpress1 = function()
run.switch_to_file(filename)
end,
})
end
-- If fragment is a filename relative to the current directory, register
-- a button for clicks on it.
local filename = rtrim(frag) -- compute_fragments puts whitespace at the end
if file_exists(filename) then
local filename_text = App.newText(love.graphics.getFont(), filename)
button(State, 'link', {x=x,y=y, w=App.width(filename_text), h=State.line_height, color={1,1,1},
icon = icon.hyperlink_decoration,
onpress1 = function()
run.switch_to_file(filename)
end,
})
-- render fragment
function Text.populate_link_offsets(State, line_index)
local line = State.lines[line_index]
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('%w+', s)
if s == nil then break end
local word = line.data:sub(s, e)
if file_exists(word) then
--? print('filename:', s, e, word)
table.insert(line_cache.link_offsets, {s, e, word})
end
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_filename_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