Skip to content

Commit 1425b36

Browse files
fix(agenda): Reload agenda if headline range was changed
When completing a todo with a repeater date, date is added to the logbook. This increases the content of the headline and shifts all headlines below the updated headline. This movement can cause those shifted headlines to have outdated position in the agenda. To solve this, we reload the agenda anyway and do update in place if we are able to find the headline.
1 parent 5bd38a6 commit 1425b36

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

lua/orgmode/agenda/init.lua

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ function Agenda:reset()
181181
end
182182

183183
function Agenda:redo(preserve_cursor_pos)
184-
self.files:load(true):next(vim.schedule_wrap(function()
184+
return self.files:load(true):next(vim.schedule_wrap(function()
185185
local cursor_view = nil
186186
if preserve_cursor_pos then
187187
cursor_view = vim.fn.winsaveview() or {}
@@ -435,14 +435,33 @@ function Agenda:_remote_edit(opts)
435435
if not opts.update_in_place or not headline then
436436
return
437437
end
438-
if item.agenda_item then
439-
item.agenda_item:set_headline(headline)
440-
self.content[line] =
441-
AgendaView.build_agenda_item_content(item.agenda_item, item.longest_category, item.longest_date, item.line)
442-
else
443-
self.content[line] = AgendaTodosView.generate_todo_item(headline, item.longest_category, item.line)
438+
local line_range_same = headline:get_range():is_same_line_range(item.headline:get_range())
439+
440+
local update_item_inline = function()
441+
if item.agenda_item then
442+
item.agenda_item:set_headline(headline)
443+
self.content[line] =
444+
AgendaView.build_agenda_item_content(item.agenda_item, item.longest_category, item.longest_date, item.line)
445+
else
446+
self.content[line] = AgendaTodosView.generate_todo_item(headline, item.longest_category, item.line)
447+
end
448+
return self:_render(true)
449+
end
450+
451+
if line_range_same then
452+
return update_item_inline()
444453
end
445-
return self:_render(true)
454+
455+
-- If line range was changed, some other agenda items might have outdated position
456+
-- In that case, we need to reload the agenda and try to find the same headline to update it in place
457+
return self:redo(true):next(function()
458+
for content_line, content_item in pairs(self.content) do
459+
if content_item.headline and content_item.headline:is_same(headline) then
460+
item = self.content[content_line]
461+
return update_item_inline()
462+
end
463+
end
464+
end)
446465
end)
447466
end
448467

lua/orgmode/files/elements/range.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ function Range:is_in_line_range(line)
6363
return line >= self.start_line and line <= self.end_line
6464
end
6565

66+
function Range:is_same_line_range(range)
67+
return self.start_line == range.start_line and self.end_line == range.end_line
68+
end
69+
70+
function Range:is_same(range)
71+
return self.start_line == range.start_line
72+
and self.end_line == range.end_line
73+
and self.start_col == range.start_col
74+
and self.end_col == range.end_col
75+
end
76+
6677
function Range:clone()
6778
return Range:new({
6879
start_line = self.start_line,

lua/orgmode/files/headline.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ end
841841

842842
function Headline:is_same(other_headline)
843843
return self.file.filename == other_headline.filename
844+
and self:get_range():is_same(other_headline:get_range())
844845
and self:get_headline_line_content() == other_headline:get_headline_line_content()
845846
end
846847

0 commit comments

Comments
 (0)