Skip to content

Commit

Permalink
refactor(closing note)!: Use different title per closing note type
Browse files Browse the repository at this point in the history
  • Loading branch information
kristijanhusak committed Jul 14, 2024
1 parent 95fb795 commit f874118
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 49 deletions.
7 changes: 0 additions & 7 deletions DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1168,13 +1168,6 @@ Save note window content as closing note for a headline. Ignores first comment (
_mapped to_: `<Leader>ok`<br />
Close note window without saving anything

#### **org_note_show_help**

_mapped to_: `g?`<br />
Show help popup with mappings

These mappings live under `mappings.note`, and can be changed like this:

```lua
require('orgmode').setup({
org_agenda_files = {'~/Dropbox/org/*', '~/my-orgs/**/*'},
Expand Down
7 changes: 7 additions & 0 deletions lua/orgmode/agenda/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ function Agenda:clock_in()
})
end

function Agenda:add_note()
return self:_remote_edit({
action = 'org_mappings.add_note',
redo = true,
})
end

function Agenda:refile()
return self:_remote_edit({
action = 'capture.refile_headline_to_destination',
Expand Down
79 changes: 62 additions & 17 deletions lua/orgmode/capture/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,66 @@ function Capture:autocomplete_refile(arg_lead)
end, result)
end

function Capture:build_note_capture(title)
return CaptureWindow:new({
template = Template:new({
template = '# ' .. title .. '\n\n%?',
}),
on_finish = function(content)
local result = {}

-- Remove lines from the beginning that are empty or comments
-- until we find a non-empty line
local trim_obsolete = true

for _, line in ipairs(content) do
local is_non_empty_line = not line:match('^%s*#%s') and vim.trim(line) ~= ''

if trim_obsolete and is_non_empty_line then
trim_obsolete = false
end

if not trim_obsolete then
table.insert(result, line)
end
end

if #result == 0 then
return nil
end

local has_non_empty_line = vim.tbl_filter(function(line)
return vim.trim(line) ~= ''
end, result)

if has_non_empty_line then
return result
end

return nil
end,
on_open = function(capture_window)
local maps = config:get_mappings('note', vim.api.nvim_get_current_buf())
if not maps then
return
end
local finalize_map = maps.org_note_finalize
finalize_map.map_entry
:with_handler(function()
return capture_window:finish()
end)
:attach(finalize_map.default_map, finalize_map.user_map, finalize_map.opts)

local kill_map = maps.org_note_kill
kill_map.map_entry
:with_handler(function()
return capture_window:kill()
end)
:attach(kill_map.default_map, kill_map.user_map, kill_map.opts)
end,
})
end

---@param from_mapping? boolean
function Capture:kill(from_mapping)
if self._window then
Expand Down Expand Up @@ -483,25 +543,10 @@ function Capture:_get_refile_vars()
return opts
end

---@deprecated
---@private
function Capture:_setup_closing_note()
return CaptureWindow:new({
template = Template:new({
template = '# Insert note for closed todo item\n\n%?',
}),
on_finish = function(content)
if content[1] and content[1]:match('#%s+') then
content = { unpack(content, 2) }
end
if content[1] and vim.trim(content[1]) == '' then
content = { unpack(content, 2) }
end
return content
end,
on_open = function()
config:setup_mappings('note', vim.api.nvim_get_current_buf())
end,
})
return self:build_note_capture('Insert note for closed todo item')
end

---@private
Expand Down
6 changes: 3 additions & 3 deletions lua/orgmode/capture/window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ local Promise = require('orgmode.utils.promise')

---@class OrgCaptureWindowOpts
---@field template OrgCaptureTemplate
---@field on_open? fun()
---@field on_finish? fun(lines: string[]): string[]
---@field on_open? fun(self: OrgCaptureWindow)
---@field on_finish? fun(lines: string[]): string[] | nil
---@field on_close? fun()

---@class OrgCaptureWindow :OrgCaptureWindowOpts
Expand Down Expand Up @@ -41,7 +41,7 @@ function CaptureWindow:open()
self._bufnr = vim.api.nvim_get_current_buf()

if self.on_open then
self.on_open()
self.on_open(self)
end

return Promise.new(function(resolve)
Expand Down
3 changes: 2 additions & 1 deletion lua/orgmode/config/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ local DefaultConfig = {
org_agenda_schedule = '<prefix>is',
org_agenda_filter = '/',
org_agenda_refile = '<prefix>r',
org_agenda_add_note = '<prefix>na',
org_agenda_show_help = 'g?',
},
capture = {
Expand All @@ -124,7 +125,6 @@ local DefaultConfig = {
note = {
org_note_finalize = '<C-c>',
org_note_kill = '<prefix>k',
org_note_show_help = 'g?',
},
org = {
org_refile = '<prefix>r',
Expand All @@ -142,6 +142,7 @@ local DefaultConfig = {
org_toggle_heading = '<prefix>*',
org_open_at_point = '<prefix>o',
org_edit_special = [[<prefix>']],
org_add_note = '<prefix>na',
org_cycle = '<TAB>',
org_global_cycle = '<S-TAB>',
org_archive_subtree = '<prefix>$',
Expand Down
12 changes: 8 additions & 4 deletions lua/orgmode/config/mappings/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ return {
help_desc = 'Refile headline to specific destination',
},
}),
org_agenda_add_note = m.action(
'agenda.add_note',
{ opts = { desc = 'org add note', help_desc = 'Add a note to the current headline' } }
),
org_agenda_show_help = m.action(
'org_mappings.show_help',
{ args = { 'agenda' }, opts = { desc = 'org show help', help_desc = 'Show this help' } }
Expand Down Expand Up @@ -152,10 +156,6 @@ return {
'capture.closing_note.kill',
{ opts = { desc = 'org kill note', help_desc = 'Close without saving' } }
),
org_note_show_help = m.action('org_mappings.show_help', {
args = { 'note' },
opts = { desc = 'org show help' },
}),
},
org = {
org_refile = m.action(
Expand Down Expand Up @@ -222,6 +222,10 @@ return {
'org_mappings.edit_special',
{ opts = { desc = 'org edit special', help_desc = 'Edit the source block under the cursor in another buffer' } }
),
org_add_note = m.action(
'org_mappings.add_note',
{ opts = { desc = 'org add note', help_desc = 'Add a note to the current headline' } }
),
org_cycle = m.action('org_mappings.cycle', { opts = { desc = 'org toggle fold', help_desc = 'Toggle folding' } }),
org_global_cycle = m.action(
'org_mappings.global_cycle',
Expand Down
54 changes: 37 additions & 17 deletions lua/orgmode/org/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,26 @@ function OrgMappings:toggle_heading()
vim.fn.setline('.', line)
end

---Prompt for a note
---@private
---@param template string
---@param indent string
---@param title string
---@return OrgPromise<string[]>
function OrgMappings:_get_note(template, indent, title)
return self.capture:build_note_capture(title):open():next(function(closing_note)
if closing_note == nil then
return
end

for i, line in ipairs(closing_note) do
closing_note[i] = indent .. ' ' .. line
end

return vim.list_extend({ template }, closing_note)
end)
end

function OrgMappings:_todo_change_state(direction)
local headline = self.files:get_closest_headline()
local old_state = headline:get_todo()
Expand Down Expand Up @@ -403,20 +423,7 @@ function OrgMappings:_todo_change_state(direction)
local indent = headline:get_indent()

local closing_note_text = ('%s- CLOSING NOTE %s \\\\'):format(indent, Date.now():to_wrapped_string(false))

local get_note = function(template)
return self.capture.closing_note:open():next(function(closing_note)
if closing_note == nil then
return
end

for i, line in ipairs(closing_note) do
closing_note[i] = indent .. ' ' .. line
end

return vim.list_extend({ template }, closing_note)
end)
end
local closed_title = 'Insert note for closed todo item'

local repeater_dates = item:get_repeater_dates()

Expand All @@ -436,7 +443,7 @@ function OrgMappings:_todo_change_state(direction)
return item
end

return get_note(closing_note_text):next(function(closing_note)
return self:_get_note(closing_note_text, indent, closed_title):next(function(closing_note)
return item:add_note(closing_note)
end)
end
Expand All @@ -455,6 +462,7 @@ function OrgMappings:_todo_change_state(direction)
old_state,
Date.now():to_string()
)
local repeat_note_title = ('Insert note for state change from "%s" to "%s"'):format(old_state, new_todo)

if log_repeat_enabled then
item:set_property('LAST_REPEAT', Date.now():to_wrapped_string(false))
Expand All @@ -470,12 +478,12 @@ function OrgMappings:_todo_change_state(direction)

-- Done note has precedence over repeat note
if prompt_done_note then
return get_note(closing_note_text):next(function(closing_note)
return self:_get_note(closing_note_text, indent, closed_title):next(function(closing_note)
return item:add_note(closing_note)
end)
end

return get_note(repeat_note_template .. ' \\\\'):next(function(closing_note)
return self:_get_note(repeat_note_template .. ' \\\\', indent, repeat_note_title):next(function(closing_note)
return item:add_note(closing_note)
end)
end
Expand Down Expand Up @@ -803,6 +811,18 @@ function OrgMappings:_edit_special_callback()
EditSpecial:new():done()
end

function OrgMappings:add_note()
local headline = self.files:get_closest_headline()
local indent = headline:get_indent()
local text = ('%s- Note taken on %s \\\\'):format(indent, Date.now():to_wrapped_string(false))
return self:_get_note(text, indent, 'Insert note for entry.'):next(function(note)
if not note then
return false
end
return headline:add_note(note)
end)
end

function OrgMappings:open_at_point()
local link = Hyperlinks.get_link_under_cursor()
if not link then
Expand Down

0 comments on commit f874118

Please sign in to comment.