@@ -61,6 +61,7 @@ module UI.Actions (
61
61
, delete
62
62
, applySearch
63
63
, openWithCommand
64
+ , openAttachment
64
65
, pipeToCommand
65
66
) where
66
67
@@ -92,11 +93,11 @@ import qualified Data.Vector as Vector
92
93
import Prelude hiding (readFile , unlines )
93
94
import Data.Functor (($>) )
94
95
import Control.Lens
95
- (_Just , to , at , ix , _1 , _2 , toListOf , traversed , has , snoc ,
96
+ (_Just , to , at , ix , _1 , _2 , toListOf , traverse , traversed , has , snoc ,
96
97
filtered , set , over , preview , view , views , (&) , nullOf , firstOf ,
97
- traversed , traverse , Getting , Lens' )
98
+ Getting , Lens' )
98
99
import Control.Concurrent (forkIO )
99
- import Control.Monad ((>=>) )
100
+ import Control.Monad ((>=>) , join )
100
101
import Control.Monad.Except (runExceptT )
101
102
import Control.Exception (catch , IOException )
102
103
import Control.Monad.IO.Class (liftIO , MonadIO )
@@ -109,10 +110,10 @@ import Data.MIME
109
110
(createMultipartMixedMessage , contentTypeApplicationOctetStream ,
110
111
createTextPlainMessage , createAttachmentFromFile , renderMessage ,
111
112
contentDisposition , dispositionType , headers , filename ,
112
- parseContentType , attachments , isAttachment , entities ,
113
- matchContentType , contentType , mailboxList , renderMailboxes ,
114
- addressList , renderAddresses , renderRFC5422Date , MIMEMessage ,
115
- WireEntity , DispositionType ( .. ), ContentType (.. ), Mailbox (.. ))
113
+ parseContentType , attachments , isAttachment , entities , matchContentType ,
114
+ contentType , mailboxList , renderMailboxes , addressList , renderAddresses ,
115
+ renderRFC5422Date , MIMEMessage , WireEntity , DispositionType ( .. ) ,
116
+ ContentType (.. ), Mailbox (.. ))
116
117
import qualified Storage.Notmuch as Notmuch
117
118
import Storage.ParsedMail
118
119
(parseMail , getTo , getFrom , getSubject , toQuotedMail , entityToBytes )
@@ -559,10 +560,31 @@ invokeEditor = Action ["invoke external editor"] (Brick.suspendAndResume . liftI
559
560
edit :: Action 'ComposeView 'ComposeListOfAttachments (T. Next AppState )
560
561
edit = Action [" edit file" ] (Brick. suspendAndResume . liftIO . editAttachment)
561
562
563
+ openAttachment :: Action 'ViewMail ctx (T. Next AppState )
564
+ openAttachment =
565
+ Action
566
+ { _aDescription = [" open attachment with external command" ]
567
+ , _aAction = \ s ->
568
+ let
569
+ match ct = firstOf (asConfig . confMailView . mvMailcap . traversed
570
+ . filtered (flip (uncurry matchContentType) ct . fst )
571
+ . _2) s
572
+ maybeCommand =
573
+ join
574
+ $ match
575
+ <$> preview (asMailView . mvAttachments . to L. listSelectedElement . _Just . _2 . headers . contentType) s
576
+ in case maybeCommand of
577
+ (Just cmd) -> Brick. suspendAndResume $ liftIO $ openCommand' s cmd
578
+ Nothing ->
579
+ Brick. continue
580
+ $ s & set (asViews . vsViews . at ViewMail . _Just . vFocus) MailAttachmentOpenWithEditor
581
+ . set (asViews . vsViews . at ViewMail . _Just . vWidgets . ix MailAttachmentOpenWithEditor . veState) Visible
582
+ }
583
+
562
584
openWithCommand :: Action 'ViewMail 'MailAttachmentOpenWithEditor (T. Next AppState )
563
585
openWithCommand =
564
586
Action
565
- { _aDescription = [" pass to external command " ]
587
+ { _aDescription = [" ask for command to open attachment " ]
566
588
, _aAction = \ s ->
567
589
let cmd = view (asMailView . mvOpenCommand . E. editContentsL . to (T. unpack . currentLine)) s
568
590
in Brick. suspendAndResume $ liftIO $ openCommand' s cmd
0 commit comments