Skip to content

Commit 39c14a4

Browse files
committed
feat(attach): add event to delete attachments of archived headlines
This corresponds to the Emacs function `org-attach-archive-delete-maybe`.
1 parent bbdf63c commit 39c14a4

File tree

9 files changed

+60
-0
lines changed

9 files changed

+60
-0
lines changed

docs/configuration.org

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,16 @@ If not =false=, store a link with [[#org_store_link][org_store_link]] when attac
12891289
- =file= - store a =[[file:attach_dir/name]]= link
12901290
- =original= - store a =[[file:original/location]]= link
12911291

1292+
*** org_attach_archive_delete
1293+
:PROPERTIES:
1294+
:CUSTOM_ID: org_attach_archive_delete
1295+
:END:
1296+
- Type: ='always' | 'ask' | 'never'=
1297+
- Default: ='never'=
1298+
1299+
Determines whether attachments are deleted automatically whenever a subtree
1300+
is moved to an archive file. The value ='ask'= means to ask the user.
1301+
12921302
*** org_attach_id_to_path_function_list
12931303
:PROPERTIES:
12941304
:CUSTOM_ID: org_attach_id_to_path_function_list

lua/orgmode/attach/init.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,23 @@ function Attach:delete_all(force, node)
605605
:wait(MAX_TIMEOUT)
606606
end
607607

608+
---Maybe delete subtree attachments when archiving.
609+
---
610+
---This function is called via the `OrgHeadlineArchivedEvent`. The option
611+
---`org_attach_archive_delete' controls its behavior."
612+
---
613+
---@param headline OrgHeadline
614+
---@return nil
615+
function Attach:maybe_delete_archived(headline)
616+
local delete = config.org_attach_archive_delete
617+
if delete == 'always' then
618+
self:delete_all(true, AttachNode.from_headline(headline))
619+
end
620+
if delete == 'ask' then
621+
self:delete_all(false, AttachNode.from_headline(headline))
622+
end
623+
end
624+
608625
---Synchronize the current outline node with its attachments.
609626
---
610627
---Useful after files have been added/removed externally. The Option

lua/orgmode/capture/init.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ local fs = require('orgmode.utils.fs')
33
local config = require('orgmode.config')
44
local Templates = require('orgmode.capture.templates')
55
local Template = require('orgmode.capture.template')
6+
local EventManager = require('orgmode.events')
67
local Menu = require('orgmode.ui.menu')
78
local Range = require('orgmode.files.elements.range')
89
local CaptureWindow = require('orgmode.capture.window')
@@ -304,6 +305,7 @@ function Capture:refile_file_headline_to_archive(headline)
304305
local headline_category = headline:get_category()
305306
local outline_path = headline:get_outline_path()
306307

308+
EventManager.dispatch(EventManager.event.HeadlineArchived:new(headline, destination_file))
307309
return self
308310
:_refile_from_org_file({
309311
source_headline = headline,

lua/orgmode/config/_meta.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
---@field org_attach_visit_command string | fun(dir: string) Command or Lua function used to open a directory. Default: 'edit'
259259
---@field org_attach_use_inheritance 'always' | 'selective' | 'never' Determines whether headlines inherit the attachments directory of their parents. Default: 'selective'
260260
---@field org_attach_store_link_p 'original' | 'file' | 'attached' | false If true, attaching a file stores a link to it. Default: 'attached'
261+
---@field org_attach_archive_delete 'always' | 'ask' | 'never' Determines whether to delete a headline's attachments when it is archived. Default: 'never'
261262
---@field org_attach_id_to_path_function_list (string | fun(id: string): (string|nil))[] List of functions used to derive the attachments directory from an ID property.
262263
---@field org_attach_sync_delete_empty_dir 'always' | 'ask' | 'never' Determines whether to delete empty directories when using `org.attach.sync()`. Default: 'ask'
263264
---@field win_split_mode? 'horizontal' | 'vertical' | 'auto' | 'float' | string[] How to open agenda and capture windows. Default: 'horizontal'

lua/orgmode/config/defaults.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ local DefaultConfig = {
8888
org_attach_visit_command = 'edit',
8989
org_attach_use_inheritance = 'selective',
9090
org_attach_store_link_p = 'attached',
91+
org_attach_archive_delete = 'never',
9192
org_attach_id_to_path_function_list = {
9293
'uuid_folder_format',
9394
'ts_folder_format',
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---@param event OrgHeadlineArchivedEvent
2+
return function(event)
3+
require('orgmode').attach:maybe_delete_archived(event.headline)
4+
end

lua/orgmode/events/listeners/init.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local Events = require('orgmode.events.types')
22
local AlignTags = require('orgmode.events.listeners.align_tags')
33
local ClockOut = require('orgmode.events.listeners.clock_out')
4+
local AttachMaybeDeleteArchived = require('orgmode.events.listeners.attach_maybe_delete_archived')
45

56
return {
67
[Events.TodoChanged] = {
@@ -13,4 +14,7 @@ return {
1314
[Events.HeadlinePromoted] = {
1415
AlignTags,
1516
},
17+
[Events.HeadlineArchived] = {
18+
AttachMaybeDeleteArchived,
19+
},
1620
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---@class OrgHeadlineArchivedEvent: OrgEvent
2+
---@field type string
3+
---@field headline OrgHeadline
4+
---@field destination_file OrgFile
5+
local HeadlineArchivedEvent = {
6+
type = 'orgmode.headline_archived',
7+
}
8+
9+
---@param headline OrgHeadline
10+
---@param destination_file OrgFile
11+
---@return OrgHeadlineArchivedEvent
12+
function HeadlineArchivedEvent:new(headline, destination_file)
13+
local obj = setmetatable({}, self)
14+
self.__index = self
15+
obj.headline = headline
16+
obj.destination_file = destination_file
17+
return obj
18+
end
19+
20+
return HeadlineArchivedEvent

lua/orgmode/events/types/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ return {
88
HeadingToggled = require('orgmode.events.types.heading_toggled'),
99
AttachChanged = require('orgmode.events.types.attach_changed_event'),
1010
AttachOpened = require('orgmode.events.types.attach_opened_event'),
11+
HeadlineArchived = require('orgmode.events.types.headline_archived_event'),
1112
}

0 commit comments

Comments
 (0)