@@ -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' ))
@@ -271,6 +303,10 @@ function Attach:attach(file, opts)
271303 :next (function (attachment_name )
272304 if attachment_name then
273305 utils .echo_info ((' File %s is now an attachment' ):format (attachment_name ))
306+ if visit_dir then
307+ local attach_dir = self .core :get_dir (node )
308+ self .core :reveal_nvim (attach_dir )
309+ end
274310 end
275311 return attachment_name
276312 end )
279315
280316--- @class orgmode.attach.attach_buffer.Options
281317--- @inlinedoc
318+ --- @field visit_dir ? boolean if true , visit the directory subsequently using
319+ --- `org_attach_visit_command`
282320--- @field node ? OrgAttachNode
283321
284322--- Attach buffer's contents to current outline node.
290328--- @return string | nil attachment_name
291329function Attach :attach_buffer (buffer , opts )
292330 local node = opts and opts .node or self .core :get_current_node ()
331+ local visit_dir = opts and opts .visit_dir or false
293332 return Promise
294333 .resolve (buffer and ui .get_bufnr_verbose (buffer ) or ui .select_buffer ())
295334 --- @param bufnr ? integer
318357--- @return string | nil attachment_name
319358function Attach :attach_many (files , opts )
320359 local node = opts and opts .node or self .core :get_current_node ()
360+ local visit_dir = opts and opts .visit_dir or false
321361 local method = opts and opts .method or config .org_attach_method
322362
323363 return self .core
@@ -336,6 +376,10 @@ function Attach:attach_many(files, opts)
336376 and { { (' failed to attach %d file%s' ):format (res .failures , plural (res .failures )), ' ErrorMsg' } }
337377 or nil
338378 utils .echo_info (msg , extra )
379+ if res .successes > 0 and visit_dir then
380+ local attach_dir = self .core :get_dir (node )
381+ self .core :reveal_nvim (attach_dir )
382+ end
339383 end
340384 return nil
341385 end )
@@ -419,4 +463,68 @@ function Attach:attach_lns(node)
419463 return self :attach (nil , { method = ' lns' , node = node })
420464end
421465
466+ --- Open the attachments directory via `vim.ui.open()`.
467+ ---
468+ --- @param attach_dir ? string the directory to open
469+ --- @return nil
470+ function Attach :reveal (attach_dir )
471+ attach_dir = attach_dir or self :get_dir_or_create ()
472+ local res = self .core :reveal (attach_dir ):wait ()
473+ if res .code ~= 0 then
474+ error ((' exit code %d for opening: %s' ):format (res .code , attach_dir ))
475+ end
476+ end
477+
478+ --- Open the attachments directory via `org_attach_visit_command`.
479+ ---
480+ --- @param attach_dir ? string the directory to open
481+ --- @return nil
482+ function Attach :reveal_nvim (attach_dir )
483+ attach_dir = attach_dir or self :get_dir_or_create ()
484+ return self .core :reveal_nvim (attach_dir )
485+ end
486+
487+ --- Open an attached file via `vim.ui.open()`.
488+ ---
489+ --- @param name ? string name of the file to open
490+ --- @param node ? OrgAttachNode
491+ --- @return nil
492+ function Attach :open (name , node )
493+ node = node or self .core :get_current_node ()
494+ local attach_dir = self .core :get_dir (node )
495+ --- @type vim.SystemObj ?
496+ local obj = Promise .resolve (name or ui .select_attachment (' Open' , attach_dir ))
497+ :next (function (chosen_name )
498+ if not chosen_name then
499+ return
500+ end
501+ return self .core :open (chosen_name , node )
502+ end )
503+ :wait (MAX_TIMEOUT )
504+ if obj then
505+ local res = obj :wait ()
506+ if res .code ~= 0 then
507+ error ((' exit code %d for command: %s' ):format (res .code , obj .cmd ))
508+ end
509+ end
510+ end
511+
512+ --- Open an attached file via `:edit`.
513+ ---
514+ --- @param name ? string name of the file to open
515+ --- @param node ? OrgAttachNode
516+ --- @return nil
517+ function Attach :open_in_vim (name , node )
518+ node = node or self .core :get_current_node ()
519+ local attach_dir = self .core :get_dir (node )
520+ return Promise .resolve (name or ui .select_attachment (' Open' , attach_dir ))
521+ :next (function (chosen_name )
522+ if not chosen_name then
523+ return
524+ end
525+ self .core :open_in_vim (chosen_name , node )
526+ end )
527+ :wait (MAX_TIMEOUT )
528+ end
529+
422530return Attach
0 commit comments