@@ -78,6 +78,35 @@ function Attach:prompt()
7878 return self :attach_new ()
7979 end ,
8080 })
81+ menu :add_separator ({ length = # menu .title })
82+ menu :add_option ({
83+ label = ' Open an attachment externally.' ,
84+ key = ' o' ,
85+ action = function ()
86+ return self :open ()
87+ end ,
88+ })
89+ menu :add_option ({
90+ label = ' Open an attachment in vim.' ,
91+ key = ' O' ,
92+ action = function ()
93+ return self :open_in_vim ()
94+ end ,
95+ })
96+ menu :add_option ({
97+ label = ' Open the attachment directory externally.' ,
98+ key = ' f' ,
99+ action = function ()
100+ return self :reveal ()
101+ end ,
102+ })
103+ menu :add_option ({
104+ label = ' Open the attachment directory in vim.' ,
105+ key = ' F' ,
106+ action = function ()
107+ return self :reveal_nvim ()
108+ end ,
109+ })
81110 menu :add_option ({
82111 label = ' Set specific attachment directory for this task.' ,
83112 key = ' s' ,
243272
244273--- @class orgmode.attach.attach.Options
245274--- @inlinedoc
275+ --- @field visit_dir ? boolean if true , visit the directory subsequently using
276+ --- `org_attach_visit_command`
246277--- @field method ? OrgAttachMethod The method via which to attach ` file` ;
247278--- default is taken from `org_attach_method`
248279--- @field node ? OrgAttachNode
254285--- @return string | nil attachment_name
255286function Attach :attach (file , opts )
256287 local node = opts and opts .node or self .core :get_current_node ()
288+ local visit_dir = opts and opts .visit_dir or false
257289 local method = opts and opts .method or config .org_attach_method
258290 return Promise
259291 .resolve (file or Input .open (' File to keep as an attachment: ' , ' ' , ' file' ))
@@ -274,6 +306,10 @@ function Attach:attach(file, opts)
274306 :next (function (attachment_name )
275307 if attachment_name then
276308 utils .echo_info ((' File %s is now an attachment' ):format (attachment_name ))
309+ if visit_dir then
310+ local attach_dir = self .core :get_dir (node )
311+ self .core :reveal_nvim (attach_dir )
312+ end
277313 end
278314 return attachment_name
279315 end )
282318
283319--- @class orgmode.attach.attach_buffer.Options
284320--- @inlinedoc
321+ --- @field visit_dir ? boolean if true , visit the directory subsequently using
322+ --- `org_attach_visit_command`
285323--- @field node ? OrgAttachNode
286324
287325--- Attach buffer's contents to current outline node.
293331--- @return string | nil attachment_name
294332function Attach :attach_buffer (buffer , opts )
295333 local node = opts and opts .node or self .core :get_current_node ()
334+ local visit_dir = opts and opts .visit_dir or false
296335 return Promise
297336 .resolve (buffer and ui .get_bufnr_verbose (buffer ) or ui .select_buffer ())
298337 --- @param bufnr ? integer
321360--- @return string | nil attachment_name
322361function Attach :attach_many (files , opts )
323362 local node = opts and opts .node or self .core :get_current_node ()
363+ local visit_dir = opts and opts .visit_dir or false
324364 local method = opts and opts .method or config .org_attach_method
325365
326366 return self .core
@@ -339,6 +379,10 @@ function Attach:attach_many(files, opts)
339379 and { { (' failed to attach %d file%s' ):format (res .failures , plural (res .failures )), ' ErrorMsg' } }
340380 or nil
341381 utils .echo_info (msg , extra )
382+ if res .successes > 0 and visit_dir then
383+ local attach_dir = self .core :get_dir (node )
384+ self .core :reveal_nvim (attach_dir )
385+ end
342386 end
343387 return nil
344388 end )
@@ -422,4 +466,68 @@ function Attach:attach_lns(node)
422466 return self :attach (nil , { method = ' lns' , node = node })
423467end
424468
469+ --- Open the attachments directory via `vim.ui.open()`.
470+ ---
471+ --- @param attach_dir ? string the directory to open
472+ --- @return nil
473+ function Attach :reveal (attach_dir )
474+ attach_dir = attach_dir or self :get_dir_or_create ()
475+ local res = self .core :reveal (attach_dir ):wait ()
476+ if res .code ~= 0 then
477+ error ((' exit code %d for opening: %s' ):format (res .code , attach_dir ))
478+ end
479+ end
480+
481+ --- Open the attachments directory via `org_attach_visit_command`.
482+ ---
483+ --- @param attach_dir ? string the directory to open
484+ --- @return nil
485+ function Attach :reveal_nvim (attach_dir )
486+ attach_dir = attach_dir or self :get_dir_or_create ()
487+ return self .core :reveal_nvim (attach_dir )
488+ end
489+
490+ --- Open an attached file via `vim.ui.open()`.
491+ ---
492+ --- @param name ? string name of the file to open
493+ --- @param node ? OrgAttachNode
494+ --- @return nil
495+ function Attach :open (name , node )
496+ node = node or self .core :get_current_node ()
497+ local attach_dir = self .core :get_dir (node )
498+ --- @type vim.SystemObj ?
499+ local obj = Promise .resolve (name or ui .select_attachment (' Open' , attach_dir ))
500+ :next (function (chosen_name )
501+ if not chosen_name then
502+ return
503+ end
504+ return self .core :open (chosen_name , node )
505+ end )
506+ :wait (MAX_TIMEOUT )
507+ if obj then
508+ local res = obj :wait ()
509+ if res .code ~= 0 then
510+ error ((' exit code %d for command: %s' ):format (res .code , obj .cmd ))
511+ end
512+ end
513+ end
514+
515+ --- Open an attached file via `:edit`.
516+ ---
517+ --- @param name ? string name of the file to open
518+ --- @param node ? OrgAttachNode
519+ --- @return nil
520+ function Attach :open_in_vim (name , node )
521+ node = node or self .core :get_current_node ()
522+ local attach_dir = self .core :get_dir (node )
523+ return Promise .resolve (name or ui .select_attachment (' Open' , attach_dir ))
524+ :next (function (chosen_name )
525+ if not chosen_name then
526+ return
527+ end
528+ self .core :open_in_vim (chosen_name , node )
529+ end )
530+ :wait (MAX_TIMEOUT )
531+ end
532+
425533return Attach
0 commit comments