@@ -12,11 +12,8 @@ local utils = require('orgmode.utils')
12
12
local fs = require (' orgmode.utils.fs' )
13
13
local Table = require (' orgmode.files.elements.table' )
14
14
local EventManager = require (' orgmode.events' )
15
- local Promise = require (' orgmode.utils.promise' )
16
15
local events = EventManager .event
17
- local Link = require (' orgmode.org.hyperlinks.link' )
18
16
local Babel = require (' orgmode.babel' )
19
- local OrgApi = require (' orgmode.api' )
20
17
21
18
--- @class OrgMappings
22
19
--- @field capture OrgCapture
@@ -384,96 +381,103 @@ function OrgMappings:_todo_change_state(direction)
384
381
local old_state = headline :get_todo ()
385
382
local was_done = headline :is_done ()
386
383
local changed = self :_change_todo_state (direction , true )
384
+
387
385
if not changed then
388
386
return
389
387
end
388
+
390
389
local item = self .files :get_closest_headline ()
390
+ EventManager .dispatch (events .TodoChanged :new (item , old_state , was_done ))
391
391
392
- local dispatchEvent = function ()
393
- EventManager .dispatch (events .TodoChanged :new (item , old_state , was_done ))
394
- return item
395
- end
392
+ local is_done = item :is_done () and not was_done
393
+ local is_undone = not item :is_done () and was_done
396
394
397
- if not item :is_done () and not was_done then
398
- return dispatchEvent ()
395
+ -- State was changed in the same group (TODO NEXT | DONE)
396
+ -- For example: Changed from TODO to NEXT
397
+ if not is_done and not is_undone then
398
+ return item
399
399
end
400
400
401
- local log_note = config .org_log_done == ' note'
402
- local log_time = config .org_log_done == ' time'
403
- local should_log_time = log_note or log_time
401
+ local prompt_done_note = config .org_log_done == ' note'
402
+ local log_closed_time = config .org_log_done == ' time'
404
403
local indent = headline :get_indent ()
405
404
406
- local get_note = function (note )
407
- if note == nil then
408
- return
409
- end
405
+ local closing_note_text = (' %s- CLOSING NOTE %s \\\\ ' ):format (indent , Date .now ():to_wrapped_string (false ))
410
406
411
- for i , line in ipairs (note ) do
412
- note [i ] = indent .. ' ' .. line
413
- end
407
+ local get_note = function (template )
408
+ return self .capture .closing_note :open ():next (function (closing_note )
409
+ if closing_note == nil then
410
+ return
411
+ end
414
412
415
- table.insert (note , 1 , (' %s- CLOSING NOTE %s \\\\ ' ):format (indent , Date .now ():to_wrapped_string (false )))
416
- return note
413
+ for i , line in ipairs (closing_note ) do
414
+ closing_note [i ] = indent .. ' ' .. line
415
+ end
416
+
417
+ return vim .list_extend ({ template }, closing_note )
418
+ end )
417
419
end
418
420
419
421
local repeater_dates = item :get_repeater_dates ()
420
- if # repeater_dates == 0 then
421
- if should_log_time and item :is_done () and not was_done then
422
- headline :set_closed_date ()
423
- item = self .files :get_closest_headline ()
424
422
425
- if log_note then
426
- dispatchEvent ()
427
- return self .capture .closing_note :open ():next (function (note )
428
- local valid_note = get_note (note )
429
- if valid_note then
430
- local append_line = headline :get_append_line ()
431
- vim .api .nvim_buf_set_lines (0 , append_line , append_line , false , valid_note )
432
- end
433
- end )
423
+ -- No dates with a repeater. Add closed date and note if enabled.
424
+ if # repeater_dates == 0 then
425
+ local set_closed_date = prompt_done_note or log_closed_time
426
+ if set_closed_date then
427
+ if is_done then
428
+ headline :set_closed_date ()
429
+ elseif is_undone then
430
+ headline :remove_closed_date ()
434
431
end
432
+ item = self .files :get_closest_headline ()
435
433
end
436
- if should_log_time and not item :is_done () and was_done then
437
- headline :remove_closed_date ()
434
+
435
+ if is_undone or not prompt_done_note then
436
+ return item
438
437
end
439
- return dispatchEvent ()
438
+
439
+ return get_note (closing_note_text ):next (function (closing_note )
440
+ return item :add_note (closing_note )
441
+ end )
440
442
end
441
443
442
444
for _ , date in ipairs (repeater_dates ) do
443
445
self :_replace_date (date :apply_repeater ())
444
446
end
445
-
446
447
local new_todo = item :get_todo ()
447
448
self :_change_todo_state (' reset' )
448
- local state_change = {
449
- string.format (' %s- State "%s" from "%s" [%s]' , indent , new_todo , old_state , Date .now ():to_string ()),
450
- }
451
449
452
- dispatchEvent ()
453
- return Promise .resolve ()
454
- :next (function ()
455
- if not log_note then
456
- return state_change
457
- end
450
+ local prompt_repeat_note = config .org_log_repeat == ' note'
451
+ local log_repeat_enabled = config .org_log_repeat ~= false
452
+ local repeat_note_template = (' %s- State "%s" from "%s" [%s]' ):format (
453
+ indent ,
454
+ new_todo ,
455
+ old_state ,
456
+ Date .now ():to_string ()
457
+ )
458
458
459
- return self .capture .closing_note :open ():next (function (closing_note )
460
- return get_note (closing_note )
461
- end )
462
- end )
463
- :next (function (note )
464
- headline :set_property (' LAST_REPEAT' , Date .now ():to_wrapped_string (false ))
465
- if not note then
466
- return
467
- end
468
- local drawer = config .org_log_into_drawer
469
- local append_line
470
- if drawer ~= nil then
471
- append_line = headline :get_drawer_append_line (drawer )
472
- else
473
- append_line = headline :get_append_line ()
474
- end
475
- vim .api .nvim_buf_set_lines (0 , append_line , append_line , false , note )
459
+ if log_repeat_enabled then
460
+ headline :set_property (' LAST_REPEAT' , Date .now ():to_wrapped_string (false ))
461
+ end
462
+
463
+ if not prompt_repeat_note and not prompt_done_note then
464
+ -- If user is not prompted for a note, use a default repeat note
465
+ if log_repeat_enabled then
466
+ return item :add_note ({ repeat_note_template })
467
+ end
468
+ return item
469
+ end
470
+
471
+ -- Done note has precedence over repeat note
472
+ if prompt_done_note then
473
+ return get_note (closing_note_text ):next (function (closing_note )
474
+ return item :add_note (closing_note )
476
475
end )
476
+ end
477
+
478
+ return get_note (repeat_note_template .. ' \\\\ ' ):next (function (closing_note )
479
+ return item :add_note (closing_note )
480
+ end )
477
481
end
478
482
479
483
function OrgMappings :do_promote (whole_subtree )
0 commit comments