Skip to content
12 changes: 12 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
52 changes: 52 additions & 0 deletions tests/plenary/clock/init_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
local OrgFiles = require('orgmode.files')
local OrgFile = require('orgmode.files.file')
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)

orgmode.files = OrgFiles:new({
paths = { file.filename },
}):load_sync(true, 20000)

-- Establish baseline: Test 1 is clocked in
local clock = org.clock:new({ files = orgmode.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