diff --git a/.config/emacs/config.org b/.config/emacs/config.org index fbcca1b..750c6d0 100644 --- a/.config/emacs/config.org +++ b/.config/emacs/config.org @@ -48,6 +48,7 @@ - [[#kotlin][Kotlin]] - [[#rss][RSS]] - [[#git][Git]] + - [[#mail][Mail]] - [[#prettify][Prettify]] - [[#general][General]] - [[#buffers][Buffers]] @@ -365,6 +366,7 @@ Places buffers as tabs in a bar at the top. ((eshell-mode help-mode helpful-mode + mu4e-view-mode neotree-mode org-roam-backlinks-mode shell-mode) @@ -824,6 +826,117 @@ Debug Adapter Protocol. (put 'magit-log-select-quit :advertised-binding [?\M-k])) #+END_SRC +*** Mail + +#+BEGIN_SRC emacs-lisp +(use-package mu4e + :ensure nil + :load-path "/usr/share/emacs/site-lisp/mu4e" + :defer 5 + :config + (setq auth-sources `(,(concat dot-etc-dir "/authinfo.gpg"))) + (setq user-full-name (dot/mail-auth-get-field "fullname" :user)) + (setq user-mail-address (dot/mail-auth-get-field "info" :user)) + (setq mail-user-agent 'mu4e-user-agent) + + ;; Headers + (setq mu4e-headers-date-format "%d-%m-%Y") + (setq mu4e-headers-time-format "%I:%M %p") + (setq mu4e-headers-long-date-format "%d-%m-%Y %I:%M:%S %p") + + ;; Syncing + (setq mu4e-get-mail-command (concat "mbsync -a -c " (getenv "XDG_CONFIG_HOME") "/isync/mbsyncrc")) + (setq mu4e-update-interval (* 15 60)) ; 15 minutes + (setq mu4e-maildir "~/mail") + (setq mu4e-attachment-dir "~/downloads") + + ;; Avoid mail syncing issues when using mbsync + (setq mu4e-change-filenames-when-moving t) + + ;; Misc + (setq mu4e-completing-read-function 'completing-read) + (setq mu4e-confirm-quit nil) + (setq mu4e-display-update-status-in-modeline t) + (setq mu4e-hide-index-messages t) + (setq mu4e-sent-messages-behavior 'sent) + (setq mu4e-view-show-addresses t) + (setq mu4e-view-show-images nil) + + ;; Compose + (setq mu4e-compose-context-policy 'ask) + (setq mu4e-compose-dont-reply-to-self t) + (setq mu4e-compose-signature (concat (dot/mail-auth-get-field "fullname" :user) "\nriyyi.com\n")) + (setq mu4e-compose-signature-auto-include t) + + ;; Contexts + (setq mu4e-context-policy 'pick-first) + (setq mu4e-contexts + `(,(make-mu4e-context + :name "info" + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/info"))) + :vars `((user-mail-address . ,(dot/mail-auth-get-field "info" :user)) + (mu4e-drafts-folder . "/info/Drafts") + (mu4e-refile-folder . "/info/Archive") + (mu4e-sent-folder . "/info/Sent") + (mu4e-trash-folder . "/info/Trash"))) + ,(make-mu4e-context + :name "private" + :match-func (lambda (msg) + (when msg + (string= (mu4e-message-field msg :maildir) "/private"))) + :vars `((user-mail-address . ,(dot/mail-auth-get-field "private" :user)) + (mu4e-drafts-folder . "/private/Drafts") + (mu4e-refile-folder . "/private/Archive") + (mu4e-sent-folder . "/private/Sent") + (mu4e-trash-folder . "/private/Trash"))) + )) + + ;; Do not mark messages as IMAP-deleted, just move them to the Trash directory! + ;; https://github.com/djcb/mu/issues/1136#issuecomment-486177435 + (setf (alist-get 'trash mu4e-marks) + (list :char '("d" . "▼") + :prompt "dtrash" + :dyn-target (lambda (target msg) + (mu4e-get-trash-folder msg)) + :action (lambda (docid msg target) + (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))) + + ;; Start mu4e in the background for mail syncing + (mu4e t)) + +(use-package mu4e-alert + :after mu4e + :config + (mu4e-alert-set-default-style 'libnotify) + (mu4e-alert-enable-notifications)) + +(use-package smtpmail ; built-in + :init (setq smtpmail-default-smtp-server "mail.riyyi.com") + :config + (setq smtpmail-smtp-server "mail.riyyi.com") + (setq smtpmail-local-domain "riyyi.com") + (setq smtpmail-smtp-service 587) + (setq smtpmail-stream-type 'starttls) + (setq smtpmail-queue-mail nil)) + +(use-package sendmail ; built-in + :config (setq send-mail-function 'smtpmail-send-it)) + +(use-package message ; built-in + :config + (setq message-kill-buffer-on-exit t) + (setq message-send-mail-function 'smtpmail-send-it)) +#+END_SRC + +Sources: +- https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/ +- https://wiki.archlinux.org/title/Isync +- https://gitlab.com/protesilaos/dotfiles/-/blob/master/mbsync/.mbsyncrc +- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mail.el +- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mu4e-deprecated-conf.el + *** Prettify #+BEGIN_SRC emacs-lisp @@ -1240,6 +1353,13 @@ Functions that only use built-in Emacs functionality. (save-excursion (insert (make-string diff ?\ ))) (user-error "Column should be higher than point"))))) +(defun dot/mail-auth-get-field (host prop) + "Find PROP in `auth-sources' for HOST entry." + (when-let ((source (auth-source-search :max 1 :host host))) + (if (eq prop :secret) + (funcall (plist-get (car source) prop)) + (plist-get (flatten-list source) prop)))) + (defun dot/reload-theme () "Reload custom theme." (interactive) @@ -1921,6 +2041,13 @@ Set keybinds to functionality of installed packages. "" #'selectrum-next-candidate ) + ;; Mu4e + (general-def 'normal mu4e-compose-mode-map + "q" #'mu4e-message-kill-buffer + "M-c" #'message-send-and-exit + "M-k" #'mu4e-message-kill-buffer + ) + ;; Neotree (general-def 'normal neotree-mode-map "RET" 'neotree-enter diff --git a/.config/isync/mbsyncrc b/.config/isync/mbsyncrc index 341fc7c..752227f 100644 --- a/.config/isync/mbsyncrc +++ b/.config/isync/mbsyncrc @@ -84,6 +84,8 @@ CopyArrivalDate yes # Example config: +# machine fullname login "" + # machine info port 993 login password # machine private port 993 login password diff --git a/packages b/packages index 4e4d5fc..4794bb0 100644 --- a/packages +++ b/packages @@ -99,6 +99,7 @@ minted mkvtoolnix-cli moka-icon-theme-git mpv +mu mysql-workbench namcap ncdu