@@ -12,11 +12,8 @@ local utils = require('orgmode.utils')
1212local fs = require (' orgmode.utils.fs' )
1313local Table = require (' orgmode.files.elements.table' )
1414local EventManager = require (' orgmode.events' )
15- local Promise = require (' orgmode.utils.promise' )
1615local events = EventManager .event
17- local Link = require (' orgmode.org.hyperlinks.link' )
1816local Babel = require (' orgmode.babel' )
19- local OrgApi = require (' orgmode.api' )
2017
2118--- @class OrgMappings
2219--- @field capture OrgCapture
@@ -384,96 +381,103 @@ function OrgMappings:_todo_change_state(direction)
384381 local old_state = headline :get_todo ()
385382 local was_done = headline :is_done ()
386383 local changed = self :_change_todo_state (direction , true )
384+
387385 if not changed then
388386 return
389387 end
388+
390389 local item = self .files :get_closest_headline ()
390+ EventManager .dispatch (events .TodoChanged :new (item , old_state , was_done ))
391391
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
396394
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
399399 end
400400
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'
404403 local indent = headline :get_indent ()
405404
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 ))
410406
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
414412
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 )
417419 end
418420
419421 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 ()
424422
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 ()
434431 end
432+ item = self .files :get_closest_headline ()
435433 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
438437 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 )
440442 end
441443
442444 for _ , date in ipairs (repeater_dates ) do
443445 self :_replace_date (date :apply_repeater ())
444446 end
445-
446447 local new_todo = item :get_todo ()
447448 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- }
451449
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+ )
458458
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 )
476475 end )
476+ end
477+
478+ return get_note (repeat_note_template .. ' \\\\ ' ):next (function (closing_note )
479+ return item :add_note (closing_note )
480+ end )
477481end
478482
479483function OrgMappings :do_promote (whole_subtree )
0 commit comments