2020-10-31 13:17:26 +00:00
|
|
|
local A = {}
|
|
|
|
|
2020-11-02 20:51:14 +00:00
|
|
|
local o = require 'zettelkasten.options'
|
|
|
|
|
2020-11-04 20:29:23 +00:00
|
|
|
local BIGNUMBER = 10000000
|
2020-11-02 20:51:14 +00:00
|
|
|
|
2020-11-04 20:29:23 +00:00
|
|
|
local parsers = {
|
|
|
|
markdown = {ref = "%[.-%]%((.-)%)", text = "%[(.-)%]%(.-%)"},
|
|
|
|
wiki = {ref = "%[%[(.-)|?.-%]%]", text = "%[%[.-|?(.-)%]%]"}
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Opens the link passed in in the editor's current buffer.
|
|
|
|
-- Requires a link object passed in.
|
|
|
|
function A.open(link)
|
|
|
|
if not link or not link.ref then return end
|
2020-10-31 13:17:26 +00:00
|
|
|
-- TODO follow: go to anchor, fall back to filename
|
2020-11-04 20:29:23 +00:00
|
|
|
vim.api.nvim_command(string.format("edit %s", link.ref))
|
2020-10-31 13:17:26 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Gets the input at the current buffer cursor and opens it
|
|
|
|
-- in the current buffer.
|
2020-11-02 20:51:14 +00:00
|
|
|
-- Takes an optional style of link following to use,
|
|
|
|
-- superseding the one set in options.
|
|
|
|
function A.open_selected(style)
|
|
|
|
local style = style or o.zettel().link_following
|
|
|
|
if style == 'line' then
|
|
|
|
A.open(A.get_next_link_on_line())
|
|
|
|
elseif style == 'cursor' then
|
|
|
|
A.open(A.get_link_under_cursor())
|
|
|
|
end
|
2020-10-31 13:17:26 +00:00
|
|
|
end
|
|
|
|
|
2020-11-04 20:29:23 +00:00
|
|
|
-- Return all links contained in the input given in an array.
|
|
|
|
-- Returned link tables have the following structure:
|
|
|
|
-- link = { text=, ref=, startpos=27, endpos=65 }
|
|
|
|
function A.extract_all_links(input)
|
2020-11-01 21:18:40 +00:00
|
|
|
if not input then return end
|
2020-11-04 20:29:23 +00:00
|
|
|
local links = {}
|
|
|
|
local curpos = 1
|
|
|
|
for _, parser in pairs(parsers) do
|
|
|
|
while input:find(parser.ref, curpos) do
|
|
|
|
local ref = input:match(parser.ref, curpos)
|
|
|
|
local text = input:match(parser.text, curpos)
|
|
|
|
local startpos, endpos = input:find(parser.ref, curpos)
|
|
|
|
table.insert(links, {
|
|
|
|
ref = ref,
|
|
|
|
text = text,
|
|
|
|
startpos = startpos,
|
|
|
|
endpos = endpos
|
|
|
|
})
|
|
|
|
curpos = endpos
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return links
|
2020-11-01 21:18:40 +00:00
|
|
|
end
|
|
|
|
|
2020-11-04 20:29:23 +00:00
|
|
|
-- Returns the link currently under cursor, roughly the vim equivalent of yiW.
|
|
|
|
-- Works for links containing spaces in their text or reference link.
|
|
|
|
function A.get_link_under_cursor()
|
|
|
|
local curpos = vim.api.nvim_win_get_cursor(0)[2]
|
|
|
|
local links = A.extract_all_links(vim.api.nvim_get_current_line())
|
|
|
|
for _, link in pairs(links) do
|
|
|
|
if link.startpos <= curpos + 1 and link.endpos > curpos then
|
|
|
|
return link
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return nil
|
2020-10-31 13:17:26 +00:00
|
|
|
end
|
2020-11-01 21:18:40 +00:00
|
|
|
|
2020-11-04 20:29:23 +00:00
|
|
|
-- Returns the next link of the line from the cursor onwards.
|
2020-11-02 20:51:14 +00:00
|
|
|
function A.get_next_link_on_line()
|
2020-11-04 20:29:23 +00:00
|
|
|
local curpos = vim.api.nvim_win_get_cursor(0)[2]
|
|
|
|
local links = A.extract_all_links(vim.api.nvim_get_current_line())
|
|
|
|
local nearestpos = BIGNUMBER
|
|
|
|
local nearestlink
|
|
|
|
for k, link in pairs(links) do
|
|
|
|
if link.endpos > curpos and link.endpos < nearestpos then
|
|
|
|
nearestpos = link.endpos
|
|
|
|
nearestlink = link
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return nearestlink
|
2020-11-02 20:51:14 +00:00
|
|
|
end
|
2020-10-31 13:17:26 +00:00
|
|
|
|
|
|
|
return {open = A.open, open_selected = A.open_selected}
|