Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix stale clocked header references when making edits to headers #759

Merged
merged 10 commits into from
Nov 5, 2024
13 changes: 13 additions & 0 deletions lua/orgmode/clock/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,20 @@ function Clock:init()
end
end

function Clock:update_clocked_headline()
local last_clocked_headline = self.files:get_clocked_headline()
if last_clocked_headline and last_clocked_headline:is_clocked_in() then
self.clocked_headline = last_clocked_headline
end
end

function Clock:has_clocked_headline()
self:update_clocked_headline()
return self.clocked_headline ~= nil
end

function Clock:org_clock_in()
self:update_clocked_headline()
local item = self.files:get_closest_headline()
if item:is_clocked_in() then
return utils.echo_info(string.format('Clock continues in "%s"', item:get_title()))
Expand All @@ -53,6 +62,7 @@ function Clock:org_clock_in()
end

function Clock:org_clock_out()
self:update_clocked_headline()
if not self.clocked_headline or not self.clocked_headline:is_clocked_in() then
return
end
Expand All @@ -62,6 +72,7 @@ function Clock:org_clock_out()
end

function Clock:org_clock_cancel()
self:update_clocked_headline()
if not self.clocked_headline or not self.clocked_headline:is_clocked_in() then
return utils.echo_info('No active clock')
end
Expand All @@ -72,6 +83,7 @@ function Clock:org_clock_cancel()
end

function Clock:org_clock_goto()
self:update_clocked_headline()
if not self.clocked_headline then
return utils.echo_info('No active or recent clock task')
end
Expand Down Expand Up @@ -99,6 +111,7 @@ function Clock:org_set_effort()
end

function Clock:get_statusline()
self:update_clocked_headline()
if not self.clocked_headline or not self.clocked_headline:is_clocked_in() then
return ''
end
Expand Down
55 changes: 55 additions & 0 deletions tests/plenary/clock/init_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
local OrgFiles = require('orgmode.files')
local OrgFile = require('orgmode.files.file')
local Files = require('orgmode.parser.files')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file no longer exists, it was refactored to a different structure. You can check other tests how to set up your tests.

local org = require('orgmode')

describe('Clock', function()
---@return OrgFile
local load_file_sync = function(content, filename)
content = content or {}
filename = filename or vim.fn.tempname() .. '.org'
vim.fn.writefile(content, filename)
return OrgFile.load(filename):wait()
end

it('should properly close out an existing clock when clocking in a new headline', function()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test is not needed. We already have a similar one. If you want to test some scenario that is not tested you can add a test to that linked file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kristijanhusak could you please point me to the existing test that is similar? I am not familiar with all the test files so some guidance would be appreciated. This test fails without the patch proposed here, so it does seem to be testing something the other tests are not covering-- keeping the currently clocked header up-to-date as the buffer changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, it's not the same. I didn't notice that you are editing file before clocking in/out.
Please move this test into https://github.com/nvim-orgmode/orgmode/blob/master/tests/plenary/ui/clock_spec.lua and adapt the setup around it. For example, you shouldn't do OrgFiles:new directly.

local file = load_file_sync({
'* TODO Test 1',
' :LOGBOOK:',
' CLOCK: [2024-05-22 Wed 05:15]',
' :END:',
'* TODO Test 2',
})

vim.cmd('edit ' .. file.filename)

Files.file_loader = OrgFiles:new({
paths = { file.filename },
})
local files = Files.loader()
files:add_to_paths(file.filename):wait()

-- Establish baseline: Test 1 is clocked in
local clock = org.clock:new({ files = files })
assert.are.same('Test 1', clock.clocked_headline:get_title())
assert.is_true(clock.clocked_headline:is_clocked_in())

-- Move the test 2 header above test 1 and then clock test 2 in
vim.fn.cursor({ 5, 1 })
vim.cmd('normal! dd')
vim.fn.cursor({ 1, 1 })
vim.cmd('normal! P')
vim.fn.cursor({ 1, 1 })
clock:org_clock_in():wait()
file:reload():wait()

-- Test 2 is properly clocked in
assert.are.same('Test 2', clock.clocked_headline:get_title())
assert.are.same('Test 2', file:get_headlines()[1]:get_title())
assert.is_true(file:get_headlines()[1]:is_clocked_in())

-- Test 1 is properly clocked out
assert.are.same('Test 1', file:get_headlines()[2]:get_title())
assert.is_false(file:get_headlines()[2]:is_clocked_in())
end)
end)
Loading