Marty Oehme
3a9e04d3ce
Open actions now make use of a 'link' data structure containing a text and ref string, and the respective start and end positions on the line. Additionally, parsers are now simple objects containing extraction regex for extracting their text and ref link individually.
85 lines
2.7 KiB
Lua
85 lines
2.7 KiB
Lua
local A = {}
|
|
|
|
local o = require 'zettelkasten.options'
|
|
|
|
local BIGNUMBER = 10000000
|
|
|
|
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
|
|
-- TODO follow: go to anchor, fall back to filename
|
|
vim.api.nvim_command(string.format("edit %s", link.ref))
|
|
end
|
|
|
|
-- Gets the input at the current buffer cursor and opens it
|
|
-- in the current buffer.
|
|
-- 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
|
|
end
|
|
|
|
-- 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)
|
|
if not input then return end
|
|
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
|
|
end
|
|
|
|
-- 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
|
|
end
|
|
|
|
-- Returns the next link of the line from the cursor onwards.
|
|
function A.get_next_link_on_line()
|
|
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
|
|
end
|
|
|
|
return {open = A.open, open_selected = A.open_selected}
|