Skip to content

Commit 21b1722

Browse files
authored
Add org-log-into-drawer (#531)
1 parent 8d9f667 commit 21b1722

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

DOCS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@ Possible values:
241241
* `note` - adds `CLOSED` date as above, and prompts for closing note via capture window. Confirm note with `org_note_finalize` (Default `<C-c>`), or ignore providing note via `org_note_kill` (Default `<Leader>ok`)
242242
* `nil|false` - Disable any logging
243243

244+
#### **org_log_into_drawer**
245+
*type*: `string|nil`<br />
246+
*default value*: `nil`<br />
247+
Possible values:
248+
Log TODO state changes into a drawer with the given name. The recommended value is `LOGBOOK`.
249+
If `nil`, log into the section body.
250+
244251
#### **org_highlight_latex_and_related**
245252
*type*: `string|nil`<br />
246253
*default value*: `nil`<br />

lua/orgmode/config/defaults.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ local DefaultConfig = {
3030
org_hide_emphasis_markers = false,
3131
org_ellipsis = '...',
3232
org_log_done = 'time',
33+
org_log_into_drawer = nil,
3334
org_highlight_latex_and_related = nil,
3435
org_custom_exports = {},
3536
org_indent_mode = 'indent',

lua/orgmode/org/mappings.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,13 @@ function OrgMappings:_todo_change_state(direction)
460460
if not note then
461461
return
462462
end
463-
local append_line = headline:get_append_line()
463+
local drawer = config.org_log_into_drawer
464+
local append_line
465+
if drawer ~= nil then
466+
append_line = headline:get_drawer_append_line(drawer)
467+
else
468+
append_line = headline:get_append_line()
469+
end
464470
vim.api.nvim_buf_set_lines(0, append_line, append_line, false, note)
465471
end)
466472
end

lua/orgmode/treesitter/headline.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,41 @@ function Headline:parse(pattern)
475475
return matching_nodes[1], match
476476
end
477477

478+
function Headline:get_drawer(name)
479+
local section = self.headline:parent()
480+
local body = section:field('body')
481+
if not body then
482+
return nil
483+
end
484+
485+
for node, node_name in body[1]:iter_children() do
486+
if node:type() == 'drawer' then
487+
local drawer_name = node:field('name')
488+
if #drawer_name and string.lower(query.get_node_text(drawer_name[1], 0)) == string.lower(name) then
489+
return node
490+
end
491+
end
492+
end
493+
end
494+
495+
---Return the line number where content can be appended within
496+
---the drawer with the given name, matched case-insensitively
497+
---@param name string
498+
---
499+
---@return number
500+
function Headline:get_drawer_append_line(name)
501+
local drawer = self:get_drawer(name)
502+
503+
if not drawer then
504+
local append_line = self:get_append_line()
505+
local new_drawer = self:_apply_indent({ ':' .. name .. ':', ':END:' })
506+
vim.api.nvim_buf_set_lines(0, append_line, append_line, false, new_drawer)
507+
drawer = self:refresh():get_drawer(name)
508+
end
509+
local name_row = drawer:field('name')[1]:end_()
510+
return name_row + 1
511+
end
512+
478513
---@param type string | "DEADLINE" | "SCHEDULED" | "CLOSED"
479514
---@return Date|nil
480515
function Headline:_get_date(type)

tests/plenary/ui/mappings/todo_spec.lua

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local helpers = require('tests.plenary.ui.helpers')
22
local Date = require('orgmode.objects.date')
3+
local config = require('orgmode.config')
34

45
describe('Todo mappings', function()
56
after_each(function()
@@ -71,6 +72,59 @@ describe('Todo mappings', function()
7172
'* TODO Another task',
7273
}, vim.api.nvim_buf_get_lines(0, 2, 10, false))
7374
end)
75+
it('should add last repeat property and state change to drawer (org_log_into_drawer)', function()
76+
config:extend({
77+
org_log_into_drawer = 'LOGBOOK',
78+
})
79+
80+
helpers.load_file_content({
81+
'#TITLE: Test',
82+
'',
83+
'* TODO Test orgmode',
84+
' DEADLINE: <2021-09-07 Tue 12:00 +1w>',
85+
'',
86+
'* TODO Another task',
87+
})
88+
89+
assert.are.same({
90+
'* TODO Test orgmode',
91+
' DEADLINE: <2021-09-07 Tue 12:00 +1w>',
92+
'',
93+
'* TODO Another task',
94+
}, vim.api.nvim_buf_get_lines(0, 2, 6, false))
95+
vim.fn.cursor(3, 1)
96+
vim.cmd([[norm cit]])
97+
vim.wait(50)
98+
assert.are.same({
99+
'* TODO Test orgmode',
100+
' DEADLINE: <2021-09-14 Tue 12:00 +1w>',
101+
' :PROPERTIES:',
102+
' :LAST_REPEAT: [' .. Date.now():to_string() .. ']',
103+
' :END:',
104+
' :LOGBOOK:',
105+
' - State "DONE" from "TODO" [' .. Date.now():to_string() .. ']',
106+
' :END:',
107+
'',
108+
'* TODO Another task',
109+
}, vim.api.nvim_buf_get_lines(0, 2, 12, false))
110+
111+
vim.fn.cursor(3, 1)
112+
vim.cmd([[norm cit]])
113+
vim.wait(200)
114+
assert.are.same({
115+
'* TODO Test orgmode',
116+
' DEADLINE: <2021-09-21 Tue 12:00 +1w>',
117+
' :PROPERTIES:',
118+
' :LAST_REPEAT: [' .. Date.now():to_string() .. ']',
119+
' :END:',
120+
' :LOGBOOK:',
121+
' - State "DONE" from "TODO" [' .. Date.now():to_string() .. ']',
122+
' - State "DONE" from "TODO" [' .. Date.now():to_string() .. ']',
123+
' :END:',
124+
'',
125+
'* TODO Another task',
126+
}, vim.api.nvim_buf_get_lines(0, 2, 13, false))
127+
end)
74128
it('should change todo state of a headline backward (org_todo_prev)', function()
75129
helpers.load_file_content({
76130
'#TITLE: Test',

0 commit comments

Comments
 (0)