Skip to content

Commit c05873b

Browse files
author
troiganto
committed
feat(properties): add property inheritance for API and search
1 parent 41b9cf2 commit c05873b

File tree

4 files changed

+60
-9
lines changed

4 files changed

+60
-9
lines changed

lua/orgmode/api/headline.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ end
6464
---@private
6565
function OrgHeadline._build_from_internal_headline(section, index)
6666
local todo, _, type = section:get_todo()
67-
local properties = section:get_properties()
67+
local properties = section:get_own_properties()
6868
return OrgHeadline:_new({
6969
title = section:get_title(),
7070
line = section:get_headline_line_content(),

lua/orgmode/files/file.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ function OrgFile:apply_search(search, todo_only)
278278
local deadline = item:get_deadline_date()
279279
local scheduled = item:get_scheduled_date()
280280
local closed = item:get_closed_date()
281-
local properties = item:get_properties()
281+
local properties = item:get_own_properties()
282282
local priority = item:get_priority()
283283

284284
return search:check({

lua/orgmode/files/headline.lua

+35-7
Original file line numberDiff line numberDiff line change
@@ -390,9 +390,9 @@ function Headline:get_title_with_priority()
390390
return title
391391
end
392392

393-
memoize('get_properties')
393+
memoize('get_own_properties')
394394
---@return table<string, string>, TSNode | nil
395-
function Headline:get_properties()
395+
function Headline:get_own_properties()
396396
local section = self:node():parent()
397397
local properties_node = section and section:field('property_drawer')[1]
398398

@@ -416,6 +416,33 @@ function Headline:get_properties()
416416
return properties, properties_node
417417
end
418418

419+
memoize('get_properties')
420+
---@return table<string, string>, TSNode | nil
421+
function Headline:get_properties()
422+
local properties, own_properties_node = self:get_own_properties()
423+
424+
if not config.org_use_property_inheritance then
425+
-- TODO: Do we have to filter non-inherited properties here? (see `Headline:get_tags()`)
426+
return properties, own_properties_node
427+
end
428+
429+
local parent_section = self:node():parent():parent()
430+
while parent_section do
431+
local headline_node = parent_section:field('headline')[1]
432+
if headline_node then
433+
local headline = Headline:new(headline_node, self.file)
434+
for name, value in pairs(headline:get_own_properties()) do
435+
if properties[name] == nil and config:use_property_inheritance(name) then
436+
properties[name] = value
437+
end
438+
end
439+
end
440+
parent_section = parent_section:parent()
441+
end
442+
443+
return properties, own_properties_node
444+
end
445+
419446
---@param name string
420447
---@param value? string
421448
---@return OrgHeadline
@@ -427,19 +454,19 @@ function Headline:set_property(name, value)
427454
vim.fn.deletebufline(bufnr, property_node:start() + 1)
428455
end
429456
self:refresh()
430-
local properties, properties_node = self:get_properties()
457+
local properties, properties_node = self:get_own_properties()
431458
if vim.tbl_isempty(properties) then
432459
self:_set_node_lines(properties_node, {})
433460
end
434461
return self:refresh()
435462
end
436463

437-
local _, properties = self:get_properties()
464+
local _, properties = self:get_own_properties()
438465
if not properties then
439466
local append_line = self:get_append_line()
440467
local property_drawer = self:_apply_indent({ ':PROPERTIES:', ':END:' }) --[[ @as string[] ]]
441468
vim.api.nvim_buf_set_lines(bufnr, append_line, append_line, false, property_drawer)
442-
_, properties = self:refresh():get_properties()
469+
_, properties = self:refresh():get_own_properties()
443470
end
444471

445472
local property = (':%s: %s'):format(name, value)
@@ -478,7 +505,7 @@ end
478505
--- `org_use_property_inheritance`
479506
---@return string | nil, TSNode | nil
480507
function Headline:get_property(property_name, search_parents)
481-
local _, properties = self:get_properties()
508+
local _, properties = self:get_own_properties()
482509
if properties then
483510
for _, node in ipairs(ts_utils.get_named_children(properties)) do
484511
local name = node:field('name')[1]
@@ -550,6 +577,7 @@ memoize('get_tags')
550577
function Headline:get_tags()
551578
local tags, own_tags_node = self:get_own_tags()
552579
if not config.org_use_tag_inheritance then
580+
-- TODO: Why exclude the headline's own tags here?
553581
return config:exclude_tags(tags), own_tags_node
554582
end
555583

@@ -636,7 +664,7 @@ end
636664

637665
---@return number
638666
function Headline:get_append_line()
639-
local _, properties = self:get_properties()
667+
local _, properties = self:get_own_properties()
640668
if properties then
641669
local row = properties:end_()
642670
return row

tests/plenary/files/headline_spec.lua

+23
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ describe('Headline', function()
9797
assert.are.same('some/dir/', file:get_headlines()[2]:get_property('dir'))
9898
assert.is.Nil(file:get_headlines()[2]:get_property('dir', false))
9999
end)
100+
it('does not affect get_own_properties', function()
101+
config:extend({ org_use_property_inheritance = true })
102+
file.metadata.mtime = file.metadata.mtime + 1 -- invalidate cache
103+
assert.are.same({}, file:get_headlines()[2]:get_own_properties())
104+
end)
105+
it('affects get_properties', function()
106+
config:extend({ org_use_property_inheritance = true })
107+
file.metadata.mtime = file.metadata.mtime + 1 -- invalidate cache
108+
local expected = { dir = 'some/dir/', thing = '0', columns = '' }
109+
assert.are.same(expected, file:get_headlines()[2]:get_properties())
110+
end)
111+
it('makes get_properties selective if a list', function()
112+
config:extend({ org_use_property_inheritance = { 'dir' } })
113+
file.metadata.mtime = file.metadata.mtime + 1 -- invalidate cache
114+
local expected = { dir = 'some/dir/' }
115+
assert.are.same(expected, file:get_headlines()[2]:get_properties())
116+
end)
117+
it('makes get_properties selective if a regex', function()
118+
config:extend({ org_use_property_inheritance = '^th...$' })
119+
file.metadata.mtime = file.metadata.mtime + 1 -- invalidate cache
120+
local expected = { thing = '0' }
121+
assert.are.same(expected, file:get_headlines()[2]:get_properties())
122+
end)
100123
end)
101124

102125
describe('get_all_dates', function()

0 commit comments

Comments
 (0)