Skip to content

Commit

Permalink
feat(hyperlinks): Add support to follow id link to a file
Browse files Browse the repository at this point in the history
  • Loading branch information
kristijanhusak committed Mar 16, 2024
1 parent c4eeb3d commit b7c42e6
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
12 changes: 12 additions & 0 deletions lua/orgmode/files/file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ function OrgFile:find_headlines_matching_search_term(search_term, no_escape, ign
end, self:get_headlines_including_archived())
end

---Find headlines where property value is matching the term partially from start
---@param property_name string
---@param term string
---@return OrgHeadline[]
Expand All @@ -282,6 +283,17 @@ function OrgFile:find_headlines_with_property_matching(property_name, term)
end, self:get_headlines())
end

---Find headlines where property value is matching the term exactly
---@param property_name string
---@param term string
---@return OrgHeadline[]
function OrgFile:find_headlines_with_property(property_name, term)
return vim.tbl_filter(function(item)
local property = item:get_property(property_name)
return property and property:lower() == term:lower()
end, self:get_headlines())
end

memoize('get_opened_headlines')
---@return OrgHeadline[]
function OrgFile:get_opened_headlines()
Expand Down
28 changes: 28 additions & 0 deletions lua/orgmode/files/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ end

---@param property_name string
---@param term string
---@return OrgHeadline[]
function OrgFiles:find_headlines_with_property_matching(property_name, term)
local headlines = {}
for _, orgfile in ipairs(self:all()) do
Expand All @@ -218,6 +219,33 @@ function OrgFiles:find_headlines_with_property_matching(property_name, term)
return headlines
end

---@param property_name string
---@param term string
---@return OrgHeadline[]
function OrgFiles:find_headlines_with_property(property_name, term)
local headlines = {}
for _, orgfile in ipairs(self:all()) do
for _, headline in ipairs(orgfile:find_headlines_with_property(property_name, term)) do
table.insert(headlines, headline)
end
end
return headlines
end

---@param property_name string
---@param term string
---@return OrgFile[]
function OrgFiles:find_files_with_property(property_name, term)
local files = {}
for _, orgfile in ipairs(self:all()) do
local property = orgfile:get_property(property_name)
if property and property:lower() == term:lower() then
table.insert(files, orgfile)
end
end
return files
end

---@param term string
---@param no_escape boolean
---@param search_extra_files boolean
Expand Down
11 changes: 10 additions & 1 deletion lua/orgmode/org/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,16 @@ function OrgMappings:open_at_point()

if link.url:is_id() then
local id = link.url:get_id() or ''
local headlines = self.files:find_headlines_with_property_matching('id', id)
local files = self.files:find_files_with_property('id', id)
if #files > 0 then
if #files > 1 then
utils.echo_warning(string.format('Multiple files found with id: %s, jumping to first one found', id))
end
vim.cmd(('edit %s'):format(files[1].filename))
return
end

local headlines = self.files:find_headlines_with_property('id', id)
if #headlines == 0 then
return utils.echo_warning(string.format('No headline found with id: %s', id))
end
Expand Down
21 changes: 20 additions & 1 deletion tests/plenary/ui/mappings/hyperlink_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('Hyperlink mappings', function()
assert.is.same('** headline of target custom_id', vim.api.nvim_get_current_line())
end)

it('should follow link to id', function()
it('should follow link to id in headline', function()
local target_file = helpers.create_agenda_file({
'* Test hyperlink',
' - some',
Expand All @@ -71,6 +71,25 @@ describe('Hyperlink mappings', function()
assert.is.same('** headline of target id', vim.api.nvim_get_current_line())
end)

it('should follow link to id in file', function()
local target_file = helpers.create_agenda_file({
':PROPERTIES:',
':ID: add6b93c-9e0e-4922-a4f5-c00926787197',
':END:',
'* Test hyperlink to file',
' - some',
' - boiler',
' - plate',
})
helpers.create_agenda_file({
'This link should lead to [[id:add6b93c-9e0e-4922-a4f5-c00926787197][target file]]',
})
vim.fn.cursor(1, 30)
vim.cmd([[norm ,oo]])
assert.are.same(target_file.filename, vim.api.nvim_buf_get_name(0))
assert.is.same(':PROPERTIES:', vim.api.nvim_get_current_line())
end)

it('should store link to a headline', function()
local target_file = helpers.create_agenda_file({
'* Test hyperlink',
Expand Down

0 comments on commit b7c42e6

Please sign in to comment.