Skip to content

Commit 6146d8f

Browse files
author
troiganto
committed
feat(attach): add OrgAttach:expand_links()
1 parent 43d5a45 commit 6146d8f

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

lua/orgmode/attach/core.lua

+36
Original file line numberDiff line numberDiff line change
@@ -567,4 +567,40 @@ function AttachCore:sync(node, delete_empty_dir)
567567
end)
568568
end
569569

570+
---Call `callback` with every attachment link in the file.
571+
---
572+
---@param file OrgFile
573+
---@param callback fun(attach_dir: string|false, basename: string): string|nil
574+
---@return OrgPromise<nil>
575+
function AttachCore:on_every_attachment_link(file, callback)
576+
-- TODO: In a better world, this would use treesitter for parsing ...
577+
return file:update(function()
578+
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
579+
local prev_node = nil ---@type OrgAttachNode | nil
580+
local attach_dir = nil ---@type string | false | nil
581+
for i, line in ipairs(lines) do
582+
-- Check if node has changed; if yes, invalidate cached attach_dir.
583+
local node = AttachNode.at_cursor(file, { i + 1, 0 })
584+
if node ~= prev_node then
585+
attach_dir = nil
586+
end
587+
---@param basename string
588+
---@param bracket '[' | ']'
589+
---@return string
590+
local replaced = line:gsub('%[%[attachment:([^%]]+)%]([%[%]])', function(basename, bracket)
591+
-- Only compute attach_dir when we know that we need it!
592+
if attach_dir == nil then
593+
attach_dir = self:get_dir_or_nil(node, true) or false
594+
end
595+
local res = callback(attach_dir, basename)
596+
return res and ('[[%s]%s'):format(res, bracket) or ('[[attachment:%s]%s'):format(basename, bracket)
597+
end)
598+
if replaced ~= line then
599+
vim.api.nvim_buf_set_lines(0, i - 1, i, true, { replaced })
600+
end
601+
prev_node = node
602+
end
603+
end)
604+
end
605+
570606
return AttachCore

lua/orgmode/attach/init.lua

+32
Original file line numberDiff line numberDiff line change
@@ -637,4 +637,36 @@ function Attach:sync(node)
637637
return self.core:sync(node, delete_empty_dir):wait(MAX_TIMEOUT)
638638
end
639639

640+
---Expand links in current buffer.
641+
---
642+
---It is meant to be added to `org_export_before_parsing_hook`."
643+
---TODO: Add this hook. Will require refactoring `orgmode.export`.
644+
---
645+
---@param bufnr? integer
646+
---@return nil
647+
function Attach:expand_links(bufnr)
648+
bufnr = bufnr or 0
649+
local file = self.core.files:get(vim.api.nvim_buf_get_name(bufnr))
650+
local total = 0
651+
local miss = 0
652+
self.core
653+
:on_every_attachment_link(file, function(attach_dir, basename)
654+
total = total + 1
655+
if not attach_dir then
656+
miss = miss + 1
657+
return
658+
end
659+
return 'file:' .. vim.fs.joinpath(attach_dir, basename)
660+
end)
661+
:next(function()
662+
if miss > 0 then
663+
utils.echo_warning(('failed to expand %d/%d attachment links'):format(miss, total))
664+
else
665+
utils.echo_info(('expanded %d attachment links'):format(total))
666+
end
667+
return nil
668+
end)
669+
:wait(MAX_TIMEOUT)
670+
end
671+
640672
return Attach

0 commit comments

Comments
 (0)