Skip to content

Commit 7a93ffe

Browse files
committed
Add support for LOGGING property
1 parent 67f4447 commit 7a93ffe

File tree

1 file changed

+46
-12
lines changed

1 file changed

+46
-12
lines changed

lua/orgmode/org/mappings.lua

+46-12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ local ts_org = require('orgmode.treesitter')
1515
local ts_table = require('orgmode.treesitter.table')
1616
local EventManager = require('orgmode.events')
1717
local Promise = require('orgmode.utils.promise')
18+
local TodoConfig = require('orgmode.parser.todo-config')
1819
local events = EventManager.event
1920
local Link = require('orgmode.objects.link')
2021

@@ -386,6 +387,8 @@ end
386387
function OrgMappings:_todo_change_state(direction)
387388
local headline = ts_org.closest_headline()
388389
local _, old_state, was_done = headline:todo()
390+
--- @cast old_state -nil
391+
--- @cast was_done -nil
389392
local changed = self:_change_todo_state(direction, true)
390393
if not changed then
391394
return
@@ -403,9 +406,37 @@ function OrgMappings:_todo_change_state(direction)
403406
return dispatchEvent()
404407
end
405408

406-
local log_note = config.org_log_done == 'note'
407-
local log_time = config.org_log_done == 'time'
408-
local should_log_time = log_note or log_time
409+
local new_state = item.todo_keyword.value
410+
411+
-- Determine which configuration to use
412+
local global_config = config.org_log_done
413+
414+
--- @type nil | false | 'time' | 'note'
415+
local section_config
416+
local logging_prop = item.properties.items.logging
417+
if logging_prop == 'nil' then
418+
section_config = false
419+
elseif logging_prop ~= nil then
420+
local todoConfig = TodoConfig:parse(logging_prop)
421+
if todoConfig ~= nil then
422+
section_config = todoConfig:get_logging_behavior(old_state, new_state)
423+
else
424+
-- TODO: Report invalid config?
425+
section_config = nil
426+
end
427+
else
428+
section_config = nil
429+
end
430+
431+
-- Use the most locally available log config
432+
--- @type false | 'time' | 'note'
433+
local log_config
434+
if section_config ~= nil then
435+
log_config = section_config
436+
else
437+
log_config = global_config
438+
end
439+
409440
local indent = config:get_indent(headline:level() + 1)
410441

411442
local get_note = function(note)
@@ -423,11 +454,12 @@ function OrgMappings:_todo_change_state(direction)
423454

424455
local repeater_dates = item:get_repeater_dates()
425456
if #repeater_dates == 0 then
426-
if should_log_time and item:is_done() and not was_done then
457+
-- If going from "not done" to "done", set the closed date and add the note/time
458+
if log_config ~= false and item:is_done() and not was_done then
427459
headline:set_closed_date()
428460
item = Files.get_closest_headline()
429461

430-
if log_note then
462+
if log_config == 'note' then
431463
dispatchEvent()
432464
return self.capture.closing_note:open():next(function(note)
433465
local valid_note = get_note(note)
@@ -438,7 +470,9 @@ function OrgMappings:_todo_change_state(direction)
438470
end)
439471
end
440472
end
441-
if should_log_time and not item:is_done() and was_done then
473+
474+
-- If going from "done" to "not done", remove the close date
475+
if log_config ~= false and not item:is_done() and was_done then
442476
headline:remove_closed_date()
443477
end
444478
return dispatchEvent()
@@ -450,19 +484,19 @@ function OrgMappings:_todo_change_state(direction)
450484

451485
self:_change_todo_state('reset')
452486
local state_change = {
453-
string.format('%s- State "%s" from "%s" [%s]', indent, item.todo_keyword.value, old_state, Date.now():to_string()),
487+
string.format('%s- State "%s" from "%s" [%s]', indent, new_state, old_state, Date.now():to_string()),
454488
}
455489

456490
dispatchEvent()
457491
return Promise.resolve()
458492
:next(function()
459-
if not log_note then
493+
if log_config == 'time' then
460494
return state_change
495+
elseif log_config == 'note' then
496+
return self.capture.closing_note:open():next(function(closing_note)
497+
return get_note(closing_note)
498+
end)
461499
end
462-
463-
return self.capture.closing_note:open():next(function(closing_note)
464-
return get_note(closing_note)
465-
end)
466500
end)
467501
:next(function(note)
468502
headline:set_property('LAST_REPEAT', Date.now():to_wrapped_string(false))

0 commit comments

Comments
 (0)