Skip to content

Commit 9deee54

Browse files
feat: ClockedIn and ClockedOut events (#1111)
* feat: ClockedIn and ClockedOut events * test: clock events
1 parent 929337a commit 9deee54

5 files changed

Lines changed: 126 additions & 0 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---@class OrgClockedInEvent: OrgEvent
2+
---@field headline? OrgHeadline
3+
local ClockedInEvent = {
4+
type = 'orgmode.clocked_in',
5+
}
6+
ClockedInEvent.__index = ClockedInEvent
7+
8+
---@param headline OrgHeadline
9+
function ClockedInEvent:new(headline)
10+
return setmetatable({
11+
headline = headline,
12+
}, self)
13+
end
14+
15+
return ClockedInEvent
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---@class OrgClockedOutEvent: OrgEvent
2+
---@field headline? OrgHeadline
3+
local ClockedOutEvent = {
4+
type = 'orgmode.clocked_out',
5+
}
6+
ClockedOutEvent.__index = ClockedOutEvent
7+
8+
---@param headline OrgHeadline
9+
function ClockedOutEvent:new(headline)
10+
return setmetatable({
11+
headline = headline,
12+
}, self)
13+
end
14+
15+
return ClockedOutEvent

lua/orgmode/events/types/init.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ return {
77
HeadlineDemoted = require('orgmode.events.types.headline_demoted_event'),
88
HeadingToggled = require('orgmode.events.types.heading_toggled'),
99
NoteAdded = require('orgmode.events.types.note_added_event'),
10+
ClockedIn = require('orgmode.events.types.clocked_in'),
11+
ClockedOut = require('orgmode.events.types.clocked_out'),
1012
}

lua/orgmode/files/headline.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,15 @@ function Headline:clock_in()
156156
logbook = Logbook.new_from_headline(self)
157157
end
158158
logbook:add_clock_in()
159+
EventManager.dispatch(events.ClockedIn:new(self))
159160
return self:refresh()
160161
end
161162

162163
function Headline:clock_out()
163164
local logbook = self:get_logbook()
164165
if logbook then
165166
logbook:clock_out()
167+
EventManager.dispatch(events.ClockedOut:new(self))
166168
end
167169
return self:refresh()
168170
end

tests/plenary/ui/clock_spec.lua

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
local helpers = require('tests.plenary.helpers')
22
local Date = require('orgmode.objects.date')
33
local orgmode = require('orgmode')
4+
local EventManager = require('orgmode.events')
5+
local events = EventManager.event
46

57
describe('Clock', function()
68
local files = {}
@@ -211,4 +213,94 @@ describe('Clock', function()
211213
'* TODO Test 3',
212214
}, vim.api.nvim_buf_get_lines(0, 0, -1, false))
213215
end)
216+
217+
it('should dispatch ClockedIn event when clocking in', function()
218+
local file = helpers.create_agenda_file({
219+
'* TODO Clock event test',
220+
})
221+
222+
local received_event = nil
223+
local listener = function(event)
224+
received_event = event
225+
end
226+
EventManager.listen(events.ClockedIn, listener)
227+
228+
vim.cmd('edit ' .. file.filename)
229+
vim.fn.cursor({ 1, 1 })
230+
vim.cmd([[norm ,oxi]])
231+
vim.wait(100)
232+
233+
assert.is_not_nil(received_event)
234+
assert.are.same('orgmode.clocked_in', received_event.type)
235+
assert.are.same('Clock event test', received_event.headline:get_title())
236+
237+
-- cleanup listener
238+
local listeners = EventManager._listeners[events.ClockedIn.type]
239+
for i, l in ipairs(listeners) do
240+
if l == listener then
241+
table.remove(listeners, i)
242+
break
243+
end
244+
end
245+
end)
246+
247+
it('should dispatch ClockedOut event when clocking out', function()
248+
local file = helpers.create_agenda_file({
249+
'* TODO Clock out event test',
250+
})
251+
252+
vim.cmd('edit ' .. file.filename)
253+
vim.fn.cursor({ 1, 1 })
254+
vim.cmd([[norm ,oxi]])
255+
vim.wait(100)
256+
257+
local received_event = nil
258+
local listener = function(event)
259+
received_event = event
260+
end
261+
EventManager.listen(events.ClockedOut, listener)
262+
263+
vim.fn.cursor({ 1, 1 })
264+
vim.cmd([[norm ,oxo]])
265+
266+
assert.is_not_nil(received_event)
267+
assert.are.same('orgmode.clocked_out', received_event.type)
268+
assert.are.same('Clock out event test', received_event.headline:get_title())
269+
270+
-- cleanup listener
271+
local listeners = EventManager._listeners[events.ClockedOut.type]
272+
for i, l in ipairs(listeners) do
273+
if l == listener then
274+
table.remove(listeners, i)
275+
break
276+
end
277+
end
278+
end)
279+
280+
it('should not dispatch ClockedOut event when headline has no logbook', function()
281+
local file = helpers.create_agenda_file({
282+
'* TODO No logbook headline',
283+
})
284+
285+
local received_event = nil
286+
local listener = function(event)
287+
received_event = event
288+
end
289+
EventManager.listen(events.ClockedOut, listener)
290+
291+
vim.cmd('edit ' .. file.filename)
292+
local headline = file:get_headlines()[1]
293+
headline:clock_out()
294+
295+
assert.is_nil(received_event)
296+
297+
-- cleanup listener
298+
local listeners = EventManager._listeners[events.ClockedOut.type]
299+
for i, l in ipairs(listeners) do
300+
if l == listener then
301+
table.remove(listeners, i)
302+
break
303+
end
304+
end
305+
end)
214306
end)

0 commit comments

Comments
 (0)