diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 410d85988..73df19655 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -231,6 +231,82 @@ is tomorrow. With two prefixes, select the deadline." ((= arg 4) "tomorrow") (t "later")))))) +;;;###autoload +(defun +mu4e/attach-files (&optional files-to-attach) + "When called in a dired buffer, ask for a message to attach the marked files to. +When called in a mu4e:compose or org-msg buffer, open a dired window to select file attachments in, +and enable `dired-mu4e-attach-ctrl-c-ctrl-c' which adds C-c C-c as a keybinding to attach the files. + +When otherwise called, open a dired buffer." + ;; TODO add ability to attach files (+dirs) as a single (named) archive + (interactive "p") + (mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) + (pcase major-mode + ((or 'mu4e-compose-mode 'org-msg-edit-mode) + (let ((mail-buffer (current-buffer)) + (location (read-file-name "Attach: "))) + (if (not (file-directory-p location)) + (pcase major-mode + ('mu4e-compose-mode (mail-add-attachment location)) + ('org-msg-edit-mode (org-msg-attach-attach location))) + (split-window-sensibly) + (with-current-buffer (dired location) + (setq-local dired-mail-buffer mail-buffer) + (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) + ('dired-mode + (unless (and files-to-attach (/= 1 files-to-attach)) + (setq files-to-attach + (delq nil + (mapcar + ;; don't attach directories + (lambda (f) (if (file-directory-p f) nil f)) + (nreverse (dired-map-over-marks (dired-get-filename) nil)))))) + (if (not files-to-attach) + (progn + (message "No files marked, aborting.") + (kill-buffer-and-window)) + (if-let ((mail-target-buffer (bound-and-true-p dired-mail-buffer))) + (progn (kill-buffer-and-window) + (switch-to-buffer mail-target-buffer)) + (if (and (+mu4e-current-buffers) + (y-or-n-p "Attach files to existing mail composition buffer? ")) + (progn (setf mail-target-buffer + (completing-read "Message: " (+mu4e-current-buffers))) + (kill-buffer-and-window) + (switch-to-buffer mail-target-buffer)) + (kill-buffer-and-window) + (mu4e-compose 'new))) + (mapcar + (pcase major-mode + ('mu4e-compose-mode #'mail-add-attachment) + ('org-msg-edit-mode #'org-msg-attach-attach)) + files-to-attach))) + (_ + (split-window-sensibly) + (with-current-buffer (call-interactively #'find-file) + (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) + +;;;###autoload +(define-minor-mode dired-mu4e-attach-ctrl-c-ctrl-c + "Adds C-c C-c as an keybinding to attach files to a message." + :lighter "attach" + :keymap (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-c") '+mu4e/attach-files) + map)) + +;;;###autoload +(defun +mu4e-current-buffers () + "Return a list of active message buffers." + (let (buffers) + (save-current-buffer + (dolist (buffer (buffer-list t)) + (set-buffer buffer) + (when (or (and (derived-mode-p 'message-mode) + (null message-sent-message-via)) + (eq major-mode 'org-msg-edit-mode)) + (push (buffer-name buffer) buffers)))) + (nreverse buffers))) + ;; ;; Hooks diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 2df71f34e..8f39302a4 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -186,7 +186,7 @@ :desc "send and exit" "s" #'message-send-and-exit :desc "kill buffer" "d" #'message-kill-buffer :desc "save draft" "S" #'message-dont-send - :desc "attach" "a" #'mail-add-attachment) + :desc "attach" "a" #'+mu4e/attach-files) ;; Due to evil, none of the marking commands work when making a visual selection in ;; the headers view of mu4e. Without overriding any evil commands we may actually @@ -243,6 +243,11 @@ Usefull for affecting HTML export config.") (advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled-a) (advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled-a) + (map! :map org-msg-edit-mode-map + :desc "attach" "C-c C-a" #'+mu4e/attach-files + :localleader + :desc "attach" "a" #'+mu4e/attach-files) + (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg "Whether to toggle ") (defun mu4e-compose-org-msg-handle-toggle (toggle-p)