Skip to content

Commit

Permalink
fix(dates): Fix parsing dates from headlines
Browse files Browse the repository at this point in the history
Fixes #796 #797
  • Loading branch information
kristijanhusak committed Aug 19, 2024
1 parent adf277c commit d0baf31
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
7 changes: 4 additions & 3 deletions lua/orgmode/files/headline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,10 @@ end
memoize('get_non_plan_dates')
---@return OrgDate[]
function Headline:get_non_plan_dates()
local section = self:node():parent()
local headline_node = self:node()
local section = headline_node:parent()
local body = section and section:field('body')[1]
local headline_text = self.file:get_node_text(self:_get_child_node('item')) or ''
local headline_text = self.file:get_node_text(headline_node) or ''
local dates = Date.parse_all_from_line(headline_text, self:node():start() + 1)
local properties_node = section and section:field('property_drawer')[1]

Expand All @@ -684,7 +685,7 @@ function Headline:get_non_plan_dates()
end

local start_line = body:range()
local lines = self.file:get_node_text_list(body)
local lines = self.file:get_node_text_list(body, ts_utils.range_with_zero_start_col(body))
for i, line in ipairs(lines) do
local line_dates = Date.parse_all_from_line(line, start_line + i)
local is_clock_line = line:match('^%s*:?CLOCK:') ~= nil
Expand Down
11 changes: 11 additions & 0 deletions lua/orgmode/utils/treesitter/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ function M.node_to_lsp_range(node)
return rtn
end

---Return the range of the given node, but override the start column to be 0.
---This is needed when we want to parse the lines manually to ensure that
---we parse from the start of the line
---@param node TSNode
---@return number[]
function M.range_with_zero_start_col(node)
local range = { node:range() }
range[2] = 0
return range
end

-- Memoizes a function based on the buffer tick of the provided bufnr.
-- The cache entry is cleared when the buffer is detached to avoid memory leaks.
-- The options argument is a table with one optional value:
Expand Down
31 changes: 31 additions & 0 deletions tests/plenary/files/headline_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,35 @@ describe('Headline', function()
assert.are.same('headline_2_category', file:get_headlines()[2]:get_category())
end)
end)

describe('get_all_dates', function()
it('should properly parse dates from the headline and body', function()
local file = helpers.create_file({
'* TODO testing <2024-08-17 Sat>',
'DEADLINE: <2024-08-19 Mon>',
'* stuff <2024-01-17 Wed>',
' <2024-02-17 Sat>',
' <2024-03-18 Sun>',
})

local assert_range = function(date, expected_range)
assert.are.same(expected_range[1], date.range.start_line, 'Start line is not matching')
assert.are.same(expected_range[2], date.range.start_col, 'Start col is not matching')
assert.are.same(expected_range[3], date.range.end_line, 'End line is not matching')
assert.are.same(expected_range[4], date.range.end_col, 'End col is not matching')
end

local first_headline_dates = file:get_headlines()[1]:get_all_dates()
assert.are.same(2, #first_headline_dates)
assert_range(first_headline_dates[1], { 2, 11, 2, 26 })
assert_range(first_headline_dates[2], { 1, 16, 1, 31 })

local second_headline_dates = file:get_headlines()[2]:get_all_dates()
assert.are.same(3, #second_headline_dates)
-- First date in the list is is always a plan date
assert_range(second_headline_dates[1], { 4, 3, 4, 18 })
assert_range(second_headline_dates[2], { 3, 9, 3, 24 })
assert_range(second_headline_dates[3], { 5, 3, 5, 18 })
end)
end)
end)

0 comments on commit d0baf31

Please sign in to comment.