From bd71e16cf441a8d0ab4ccd6ce28913adccb69140 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 3 Sep 2024 20:25:06 -0400 Subject: [PATCH 01/15] bump: :completion corfu minad/corfu@921dd7c97ec4 -> minad/corfu@0a616caedf10 Ref: minad/corfu@157b373abc79 Fix: #7977 --- modules/completion/corfu/config.el | 7 ++----- modules/completion/corfu/packages.el | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index df9a0a48d..fae0d36d5 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -48,11 +48,7 @@ If any return non-nil, `corfu-auto' will not invoke as-you-type completion.") circe-mode help-mode gud-mode - vterm-mode - ;; Needed for `+corfu-want-minibuffer-completion' to be - ;; respected. See #7977. - minibuffer-mode - minibuffer-inactive-mode) + vterm-mode) t) corfu-cycle t corfu-preselect 'prompt @@ -70,6 +66,7 @@ If any return non-nil, `corfu-auto' will not invoke as-you-type completion.") (add-to-list 'corfu-continue-commands #'+corfu/smart-sep-toggle-escape) (add-hook 'evil-insert-state-exit-hook #'corfu-quit) + ;; Respect `+corfu-want-minibuffer-completion' (defun +corfu-enable-in-minibuffer-p () "Return non-nil if Corfu should be enabled in the minibuffer. See `+corfu-want-minibuffer-completion'." diff --git a/modules/completion/corfu/packages.el b/modules/completion/corfu/packages.el index fe78eb17b..72cc828b6 100644 --- a/modules/completion/corfu/packages.el +++ b/modules/completion/corfu/packages.el @@ -1,7 +1,7 @@ ;; -*- no-byte-compile: t; -*- ;;; completion/corfu/packages.el -(package! corfu :pin "921dd7c97ec41fe8ef81dd5f5a08b0f717586c86") +(package! corfu :pin "0a616caedf10ebba812a87de3adacd24cd46522b") (package! cape :pin "9110956a5155d5e3c460160fa1b4dac59322c229") (when (modulep! +icons) (package! nerd-icons-corfu :pin "7077bb76fefc15aed967476406a19dc5c2500b3c")) From 2d3f00396948ec309ba8e9b6188085c0c42acc79 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 4 Sep 2024 13:46:24 -0400 Subject: [PATCH 02/15] fix(default): removal vestigial drag-stuff config drag-stuff was removed for evil users in 816db4a, but I forgot to stage the removal of its use-package! block when I moved it, leaving defunct keybinds in its wake. Amend: 816db4a62add --- modules/config/default/config.el | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 5873b54a9..eab995ec2 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -71,15 +71,6 @@ (setq woman-manpath manpath)))) -(use-package! drag-stuff - :defer t - :init - (map! "" #'drag-stuff-up - "" #'drag-stuff-down - "" #'drag-stuff-left - "" #'drag-stuff-right)) - - ;;;###package tramp (unless (featurep :system 'windows) (setq tramp-default-method "ssh")) ; faster than the default scp From 52c91cc51cb49886380bd85a3d0d01fc27d16f62 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 3 Sep 2024 06:42:58 -0400 Subject: [PATCH 03/15] fix(tabs): workspace-scoped buffer lists --- modules/ui/tabs/config.el | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/ui/tabs/config.el b/modules/ui/tabs/config.el index b4d2b9124..d46ea273f 100644 --- a/modules/ui/tabs/config.el +++ b/modules/ui/tabs/config.el @@ -23,6 +23,18 @@ (add-hook 'doom-first-file-hook #'centaur-tabs-mode)) :config + (defun +tabs-buffer-list () + (seq-filter (lambda (b) + (cond ((eq (current-buffer) b) b) + ((doom-temp-buffer-p b) nil) + ((doom-unreal-buffer-p b) nil) + ((buffer-file-name b) b) + ((buffer-live-p b) b))) + (if (bound-and-true-p persp-mode) + (persp-buffer-list) + (buffer-list)))) + (setq centaur-tabs-buffer-list-function #'+tabs-buffer-list) + (add-hook! '(+doom-dashboard-mode-hook +popup-buffer-mode-hook) (defun +tabs-disable-centaur-tabs-mode-maybe-h () "Disable `centaur-tabs-mode' in current buffer." From 42df7cb9fd08cc6c34e8b3e4c7619e1e372a79f9 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 4 Sep 2024 14:47:19 -0400 Subject: [PATCH 04/15] docs(cli): doom install: reformat output Also simplifies the first-timer "things you should know" snippet after running 'doom install'. --- lisp/cli/ci.el | 25 ++++++++++++------------- lisp/cli/install.el | 12 ++++++------ templates/QUICKSTART_INTRO | 16 ++++++---------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/lisp/cli/ci.el b/lisp/cli/ci.el index b5757fa68..b0b515662 100644 --- a/lisp/cli/ci.el +++ b/lisp/cli/ci.el @@ -270,19 +270,18 @@ Note: warnings are not considered failures.") hooks-path)) (user-error "Aborted"))) (make-directory hooks-path 'parents) - (print-group! - (dolist (hook '("commit-msg" "pre-push")) - (let* ((hook (doom-path hooks-path hook)) - (overwrite-p (file-exists-p hook))) - (with-temp-file hook - (insert "#!/usr/bin/env sh\n" - (doom-path doom-emacs-dir "bin/doom") - " --no-color ci hook " (file-name-base hook) - " \"$@\"")) - (set-file-modes hook #o700) - (print! (success "%s %s") - (if overwrite-p "Overwrote" "Created") - (path hook))))))) + (dolist (hook '("commit-msg" "pre-push")) + (let* ((hook (doom-path hooks-path hook)) + (overwrite-p (file-exists-p hook))) + (with-temp-file hook + (insert "#!/usr/bin/env sh\n" + (doom-path doom-emacs-dir "bin/doom") + " --no-color ci hook " (file-name-base hook) + " \"$@\"")) + (set-file-modes hook #o700) + (print! (success "%s %s") + (if overwrite-p "Overwrote" "Created") + (path hook)))))) ;; TODO Move to 'doom lint commits' (defcli! (ci lint-commits) (from &optional to) diff --git a/lisp/cli/install.el b/lisp/cli/install.el index 8eaec4abe..3b737c3de 100644 --- a/lisp/cli/install.el +++ b/lisp/cli/install.el @@ -99,15 +99,15 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g. ;; Install Doom packages (if (eq install? :no) (print! (warn "Not installing plugins, as requested")) - (print! "Installing plugins") - (doom-packages-ensure)) + (print! (start "Installing plugins")) + (print-group! (doom-packages-ensure))) - (print! "Regenerating autoloads files") - (doom-profile-generate) + (print! (start "Synchronizing default profile...")) + (print-group! (doom-profile-generate)) (if (eq hooks? :no) (print! (warn "Not deploying commit-msg and pre-push git hooks, as requested")) - (print! "Deploying commit-msg and pre-push git hooks") + (print! (start "Deploying commit-msg and pre-push git hooks")) (print-group! (condition-case e (call! `(ci deploy-hooks ,@(if yes? '("--force")))) @@ -117,7 +117,7 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g. (when (file-exists-p "~/.emacs") (print! (warn "A ~/.emacs file was detected. This conflicts with Doom and should be deleted!"))) - (print! (success "\nFinished! Doom is ready to go!\n")) + (print! (success "Finished! Doom is ready to go!\n")) (with-temp-buffer (insert-file-contents (doom-path doom-emacs-dir "templates/QUICKSTART_INTRO")) (print! "%s" (buffer-string))))) diff --git a/templates/QUICKSTART_INTRO b/templates/QUICKSTART_INTRO index c909aba98..4c656d10e 100644 --- a/templates/QUICKSTART_INTRO +++ b/templates/QUICKSTART_INTRO @@ -1,19 +1,15 @@ But before you doom yourself, here are some things you should know: -1. Don't forget to run 'doom sync', then restart Emacs, after modifying init.el - or packages.el in ~/.config/doom. +1. Don't forget to run 'doom sync' and restart Emacs after modifying init.el or + packages.el in ~/.config/doom. This is never necessary for config.el. - This command ensures needed packages are installed, orphaned packages are - removed, and your autoloads/cache files are up to date. When in doubt, run - 'doom sync'! - -2. If something goes wrong, run `doom doctor`. It diagnoses common issues with - your environment and setup, and may offer clues about what is wrong. +2. If something goes wrong, run `doom doctor` to diagnose common issues with + your environment, setup, and config. 3. Use 'doom upgrade' to update Doom. Doing it any other way will require - additional steps. Run 'doom help upgrade' to understand those extra steps. + additional steps (see 'doom help upgrade'). 4. Access Doom's documentation from within Emacs via 'SPC h d h' or 'C-h d h' - (or 'M-x doom/help') + (or 'M-x doom/help'). Have fun! From 1a5ff08da4a1f011e6ec0697f672373517d224d6 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 4 Sep 2024 14:49:20 -0400 Subject: [PATCH 05/15] fix(cli): doom install: bootstrap other profiles if present Like 'doom sync', have 'doom install' set up the profiles bootloader. --- lisp/cli/install.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lisp/cli/install.el b/lisp/cli/install.el index 3b737c3de..746f79f50 100644 --- a/lisp/cli/install.el +++ b/lisp/cli/install.el @@ -102,6 +102,10 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g. (print! (start "Installing plugins")) (print-group! (doom-packages-ensure))) + (when (doom-profiles-bootloadable-p) + (print! (start "Initializing profile bootstrapper...")) + (call! '(profiles sync "--reload"))) + (print! (start "Synchronizing default profile...")) (print-group! (doom-profile-generate)) From a940ac5614c0bb34358682e42e9d7791f56d135a Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 4 Sep 2024 15:00:37 -0400 Subject: [PATCH 06/15] fix(cli): doom install: load $DOOMDIR/cli.el too In case the user's put some configuration in cli.el that could be relevant to eventual profile generation. --- lisp/cli/install.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/cli/install.el b/lisp/cli/install.el index 746f79f50..0852b7b67 100644 --- a/lisp/cli/install.el +++ b/lisp/cli/install.el @@ -81,8 +81,9 @@ Change `$DOOMDIR' with the `--doomdir' option, e.g. . ,(file-name-with-extension (doom-path template-dir doom-module-packages-file) ".example.el"))))))) - ;; In case no init.el was present the first time it was loaded. + ;; In case no init.el (or cli.el) was present before the config was deployed (doom-load (doom-path doom-user-dir doom-module-init-file) t) + (doom-load (doom-path doom-user-dir "cli.el") t) ;; Ask if user would like an envvar file generated (if (eq envfile? :no) From 0c8dff66de394f94f4f1b2225aa9575319db926e Mon Sep 17 00:00:00 2001 From: Johannes Maier Date: Mon, 16 Oct 2023 09:42:10 +0200 Subject: [PATCH 07/15] docs(mu4e): update NixOS installation instructions Recently, the Emacs package 'mu4e' has been moved into a separate derivation output. Now you need both the 'mu' package (installing the program) as well as its 'mu4e' output, which adds the Emacs package to the system. Ref: https://github.com/NixOS/nixpkgs/commit/ac4f5079f7e668afa312458d621dad7fc0320f9b --- modules/email/mu4e/README.org | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 548bf7080..30a204df8 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -93,12 +93,24 @@ If you use =msmtp=: #+begin_src nix environment.systemPackages = with pkgs; [ mu + # For nixpkgs versions after 23.05: this installs Emacs with mu4e already + # included (you still need mu above; it just doesn't ship with mu4e anymore) + ((emacsPackagesFor emacs).emacsWithPackages (epkgs: [ epkgs.mu4e ])) # And one of the following isync offlineimap ]; #+end_src +If you use ~home-manager~ you should specify ~mu4e~ as an additionally included +package as follows (requires ~nixpkgs~ > 23.05): +#+begin_src nix +programs.emacs = { + enable = true; + extraPackages = epkgs: [ epkgs.mu4e ]; +} +#+end_src + [[https://github.com/Emiller88/dotfiles/blob/5eaabedf1b141c80a8d32e1b496055231476f65e/modules/shell/mail.nix][An example of setting up mbsync and mu with home-manager]] * TODO Usage @@ -356,9 +368,9 @@ mail retrieval/indexing, change the value of ~mu4e-update-interval~: You will get =No such file or directory, mu4e= errors if you don't run ~$ doom sync~ after installing =mu= through your package manager. -Some times the ~mu~ package does not include ~mu4e~ (*cough Ubuntu*). if -that's the case you will need to [[https://github.com/djcb/mu][install]] it and add it to your ~load-path~ you -can do that by: +Sometimes the ~mu~ package does not include ~mu4e~ (*cough Ubuntu*). If that's +the case you will need to [[https://github.com/djcb/mu][install]] it and add it to your ~load-path~. You can +do that by: #+begin_src emacs-lisp (add-to-list 'load-path "your/path/to/mu4e") ;; if you installed it using your package manager From 200c9083152184e26b6a1c9f8a14581729ba5f02 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 4 Sep 2024 23:09:09 -0400 Subject: [PATCH 08/15] bump: :email mu4e jeremy-compostella/org-msg@0b65f0f77a7a -> jeremy-compostella/org-msg@59e2042e5f23 Close: #7770 Ref: jeremy-compostella/org-msg#182 --- modules/email/mu4e/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 1d2642782..bfe302b06 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -2,4 +2,4 @@ ;;; email/mu4e/packages.el (when (modulep! +org) - (package! org-msg :pin "0b65f0f77a7a71881ddfce19a8cdc60465bda057")) + (package! org-msg :pin "59e2042e5f23e25f31c6aef0db1e70c6f54f117d")) From f3ad08c4cd2c6d57cf0a49618324f5d06690a35c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 03:14:51 -0400 Subject: [PATCH 09/15] refactor(mu4e): org-msg config - Simplify advice. - Fix load-order of org-msg and :config (which use-packages' :after convolutes). - Remove dummy functions (and guard where they were formerly relied on; this is a stopgap solution though). --- modules/email/mu4e/autoload/email.el | 3 +- modules/email/mu4e/config.el | 72 ++++++++++++---------------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 15c99096d..e3f001854 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -281,7 +281,8 @@ attach a file, or select a folder to open dired in and select file attachments When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c-ctrl-c'." ;; TODO add ability to attach files (+dirs) as a single (named) archive (interactive "p") - (+mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) + (when (fboundp '+mu4e-compose-org-msg-handle-toggle) + (+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)) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 072309620..40e4cabb5 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -375,19 +375,14 @@ This should already be the case yet it does not always seem to be." (advice-add 'mu4e--start :around #'+mu4e-lock-start) (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) -(unless (modulep! +org) - (after! mu4e - (defun org-msg-mode (&optional _) - "Dummy function." - (message "Enable the +org mu4e flag to use org-msg-mode.")) - (defun +mu4e-compose-org-msg-handle-toggle (&rest _) - "Placeholder to allow for the assumtion that this function is defined. -Ignores all arguments and returns nil." - nil))) (use-package! org-msg - :after mu4e :when (modulep! +org) + :defer t + :init + ;; Avoid using `:after' because it ties the :config below to when `mu4e' + ;; loads, rather than when `org-msg' loads. + (after! mu4e (require 'org-msg)) :config (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" @@ -403,26 +398,25 @@ Ignores all arguments and returns nil." (\\(?:attached\\|enclosed\\))\\|\ \\(?:attached\\|enclosed\\)[ \t\n]\\(?:for\\|is\\)[ \t\n]") - (defvar +org-msg-currently-exporting nil - "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. -Usefull for affecting HTML export config.") - (defadvice! +org-msg--now-exporting-a (&rest _) - :before #'org-msg-org-to-xml - (setq +org-msg-currently-exporting t)) - (defadvice! +org-msg--not-exporting-a (&rest _) - :after #'org-msg-org-to-xml - (setq +org-msg-currently-exporting nil)) - - (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 + "TAB" #'org-msg-tab ; To mirror the binding on :desc "attach" "C-c C-a" #'+mu4e/attach-files :localleader :desc "attach" "a" #'+mu4e/attach-files) - ;; I feel like it's reasonable to expect files to be attached - ;; in the order you attach them, not the reverse. + ;; HACK: ... + (defvar +org-msg-currently-exporting nil + "Non-nil if org-msg is currently exporting the org buffer to HTML.") + (defadvice! +org-msg--now-exporting-a (fn &rest args) + :around #'org-msg-org-to-xml + (let ((+org-msg-currently-exporting t)) + (apply fn args))) + + ;; HACK: ... + (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) + + ;; HACK: Ensure files are attached in the order they were attached. (defadvice! +org-msg-attach-attach-in-order-a (file &rest _args) "Link FILE into the list of attachment." :override #'org-msg-attach-attach @@ -431,31 +425,28 @@ Usefull for affecting HTML export config.") (org-msg-set-prop "attachment" (nconc files (list file))))) (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg - "Whether to toggle ") + "Whether to toggle `org-msg-toggle' on ") (defun +mu4e-compose-org-msg-handle-toggle (toggle-p) (when (xor toggle-p +mu4e-compose-org-msg-toggle-next) (org-msg-mode (if org-msg-mode -1 1)) (setq +mu4e-compose-org-msg-toggle-next (not +mu4e-compose-org-msg-toggle-next)))) - (defadvice! +mu4e-maybe-toggle-org-msg-a (fn &optional toggle-p) - :around #'mu4e-compose-new - :around #'mu4e-compose-reply - :around #'mu4e-compose-forward - :around #'mu4e-compose-resend - (interactive "p") - (+mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) - (funcall fn)) + ;; HACK: ... + (defadvice! +mu4e-maybe-toggle-org-msg-a (&rest _) + :before #'mu4e-compose-new + :before #'mu4e-compose-reply + :before #'mu4e-compose-forward + :before #'mu4e-compose-resend + (+mu4e-compose-org-msg-handle-toggle (/= 1 (or current-prefix-arg 0)))) + ;; HACK: ... (defadvice! +mu4e-draft-open-signature-a (fn &rest args) "Prevent `mu4e-compose-signature' from being used with `org-msg-mode'." :around #'mu4e-draft-open (let ((mu4e-compose-signature (unless org-msg-mode mu4e-compose-signature))) (apply fn args))) - (map! :map org-msg-edit-mode-map - "TAB" #'org-msg-tab) ; only bound by default - (defvar +org-msg-accent-color "#c01c28" "Accent color to use in org-msg's generated CSS. Must be set before org-msg is loaded to take effect.") @@ -472,12 +463,11 @@ Must be set before org-msg is loaded to take effect.") (table `((margin-top . "6px") (margin-bottom . "6px") (border-left . "none") (border-right . "none") (border-top . "2px solid #222222") - (border-bottom . "2px solid #222222") - )) + (border-bottom . "2px solid #222222"))) (ftl-number `(,color ,bold (text-align . "left"))) (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp - fundamental ini json makefile man org plantuml - python sh xml)) + fundamental ini json makefile man org plantuml + python sh xml)) (inline-src `((background-color . "rgba(27,31,35,.05)") (border-radius . "3px") (padding . ".2em .4em") From 48a6b30f4868b04a1564ebff1c6a4c775ebabd31 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 03:31:32 -0400 Subject: [PATCH 10/15] refactor(mu4e): replace +mu4e-backend w/ +offlineimap/+mbsync flags `+mu4e-backend` is now deprecated and will be removed in v3.0. --- modules/email/mu4e/README.org | 48 +++++++++++++++++------------------ modules/email/mu4e/config.el | 16 +++++++----- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 30a204df8..4666c72ab 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -37,6 +37,10 @@ This module makes Emacs an email client, using [[https://www.djcbsoftware.nl/cod - +gmail :: Enable gmail-specific configuration for mail ~To~ or ~From~ a gmail address, or a maildir with ~gmail~ in the name. +- +mbsync :: + Use [[https://isync.sourceforge.io/][mbsync]] to synchronize with mu. +- +offlineimap :: + Use [[https://www.offlineimap.org/about/][offlineimap]] to synchronize with mu. - +org :: Use [[doom-package:org-msg]] for composing email in Org, then sending a multipart text (ASCII export) and HTML message. @@ -124,34 +128,30 @@ programs.emacs = { #+end_quote ** offlineimap -This module uses =mbsync= by default. To use =offlineimap=, change -~+mu4e-backend~: -#+begin_src emacs-lisp -(setq +mu4e-backend 'offlineimap) -#+end_src +Enable this module with the =+offlineimap= flag, then [[https://www.offlineimap.org/doc/quick_start.html][write a configuration file]] +for =offlineimap= ([[https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf][a sample config file can be found in offlineimap's repo]]). -Next, you need to write a configuration file for =offlineimap=. Mine can be -found [[https://github.com/hlissner/dotfiles/blob/be0dce5dae8f3cbafaac0cc44269d84b4a742c46/shell/mu/][in my dotfiles repository]]. It is configured to download mail to -~\~/.mail~. I use [[https://www.passwordstore.org/][unix pass]] to securely store my login credentials. You can find -a *very* detailed configuration [[https://github.com/OfflineIMAP/offlineimap/blob/master/offlineimap.conf][here]]. +Next, download your email with ~$ offlineimap -o~. This may take a while, +depending on how many emails need downloading. -Next you can download your email with ~$ offlineimap -o~. This may take a while, -especially if you have thousands of mails. - -You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section. +Then proceed to the "mu and mu4e" section below. ** mbsync -The steps needed to set up =mu4e= with =mbsync= are very similar to the ones for -[[#offlineimap][offlineimap]]. +After this module has been enabled with the =+mbsync= flag, the steps to set up +=mbsync= are similar to the ones for offlineimap: -Start with writing a =~/.mbsyncrc=. An example for Gmail can be found on -[[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-Gmail example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual -page]] contains all needed information to set up your own. +Start with writing a =~/.mbsyncrc=. Here are some examples: -Next you can download your email with ~$ mbsync --all~. This may take a while, -but should be quicker than =offlineimap= ;). +- [[https://pragmaticemacs.wordpress.com/2016/03/22/migrating-from-offlineimap-to-mbsync-for-mu4e/][For Gmail accounts]], +- [[https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/][For Fastmail accounts]], +- [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][A more generic example for other services]]. -You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section. +The [[http://isync.sourceforge.net/mbsync.html][manual page]] contains all needed information to set up your own. + +Next, download your email with ~$ mbsync --all~. This may take a while, but +should be quicker than =offlineimap= ;). + +Then proceed to the "mu and mu4e" section below. *** Faster syncing It's possible to use IMAP IDLE to be quickly notified of updates, then use a @@ -161,11 +161,9 @@ If this is of interest, this approach can be seen [[https://tecosaur.github.io/e [[https://gitlab.com/shackra/goimapnotify][goimapnotify]] is used for this. ** Fetching your mail in other ways -You also have the possiblity to invoke an arbitary shell command to fetch your -mail by disabling this module's backend selection and setting the value of the -~mu4e-get-mail-command~ to the command you want to execute: +Mu4e can be configured to call an arbitary shell command to fetch your email. To +use it, set [[var:mu4e-get-mail-command]]: #+begin_src emacs-lisp -(setq +mu4e-backend nil) (after! mu4e (setq mu4e-get-mail-command "your_command")) #+end_src diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 40e4cabb5..4b6cef449 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -2,6 +2,7 @@ (defvar +mu4e-backend 'mbsync "Which backend to use. Can either be offlineimap, mbsync or nil (manual).") +(make-obsolete-variable '+mu4e-backend "Use the :email mu4e module's +mbsync or +offlineimap flags instead" "3.0.0") (defvar +mu4e-personal-addresses 'nil "Alternative to mu4e-personal-addresses that can be set for each account (mu4e context).") @@ -23,6 +24,14 @@ (lambda (&rest _) (expand-file-name ".attachments" (mu4e-root-maildir)))) :config + (cond ((or (modulep! +mbsync) + (eq +mu4e-backend 'mbsync)) + (setq mu4e-get-mail-command "mbsync -a" + mu4e-change-filenames-when-moving t)) + ((or (modulep! +offlineimap) + (eq +mu4e-backend 'offlineimap)) + (setq mu4e-get-mail-command "offlineimap -o -q"))) + (when (version< mu4e-mu-version "1.8") ;; Define aliases to maintain backwards compatibility. The list of suffixes ;; were obtained by comparing mu4e~ and mu4e-- functions in `obarray'. @@ -67,13 +76,6 @@ is non-nil." mu4e-view-image-max-width 800 mu4e-view-use-gnus t)) - (pcase +mu4e-backend - (`mbsync - (setq mu4e-get-mail-command "mbsync -a" - mu4e-change-filenames-when-moving t)) - (`offlineimap - (setq mu4e-get-mail-command "offlineimap -o -q"))) - (setq mu4e-update-interval nil mu4e-notification-support t mu4e-sent-messages-behavior 'sent From 60e94479a7952a9939b349dc478378ea47289fa9 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 03:53:37 -0400 Subject: [PATCH 11/15] feat(mu4e): add mu4e-compat package (And remove vestigial ref to mu4e-alert in docs) Fix: #6906 Fix: #7860 --- modules/email/mu4e/README.org | 2 +- modules/email/mu4e/config.el | 8 ++++++++ modules/email/mu4e/packages.el | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 4666c72ab..3931bdf47 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -46,7 +46,7 @@ This module makes Emacs an email client, using [[https://www.djcbsoftware.nl/cod export) and HTML message. ** Packages -- [[doom-package:mu4e-alert]] +- [[doom-package:mu4e-compat]] - [[doom-package:org-msg]] if [[doom-module:+org]] ** TODO Hacks diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 4b6cef449..7f24f6ebd 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -24,6 +24,14 @@ (lambda (&rest _) (expand-file-name ".attachments" (mu4e-root-maildir)))) :config + ;; Ensures backward/forward compatibility for mu4e, which is prone to breaking + ;; updates, and also cannot be pinned, because it's bundled with mu (which you + ;; must install via your OS package manager). + (with-demoted-errors "%s" (require 'mu4e-compat nil t)) + ;; For users on older mu4e. + (unless (boundp 'mu4e-headers-buffer-name) + (defvar mu4e-headers-buffer-name "*mu4e-headers*")) + (cond ((or (modulep! +mbsync) (eq +mu4e-backend 'mbsync)) (setq mu4e-get-mail-command "mbsync -a" diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index bfe302b06..4df5d05fc 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -1,5 +1,8 @@ ;; -*- no-byte-compile: t; -*- ;;; email/mu4e/packages.el +(package! mu4e-compat + :recipe (:host github :repo "tecosaur/mu4e-compat") + :pin "a33345cb8ef83554f01510bbc8f5c7323713aa8d") (when (modulep! +org) (package! org-msg :pin "59e2042e5f23e25f31c6aef0db1e70c6f54f117d")) From 5c0211d635daedbd31fc69f64f6712d930170ce5 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 04:04:01 -0400 Subject: [PATCH 12/15] refactor(mu4e): mu4e config In preparation for all the work I have in store for this module. --- modules/email/mu4e/config.el | 100 +++++++++++++++++------------------ 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 7f24f6ebd..7af288f95 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -20,10 +20,10 @@ (version< mu4e-mu-version "1.4")) (setq mu4e-maildir "~/.mail" mu4e-user-mail-address-list nil)) - (setq mu4e-attachment-dir - (lambda (&rest _) - (expand-file-name ".attachments" (mu4e-root-maildir)))) :config + ;; mu4e now uses `display-buffer-alist' so we need to add some rules of our own + (set-popup-rule! "^\\*mu4e-\\(main\\|headers\\)\\*" :ignore t) + ;; Ensures backward/forward compatibility for mu4e, which is prone to breaking ;; updates, and also cannot be pinned, because it's bundled with mu (which you ;; must install via your OS package manager). @@ -233,50 +233,46 @@ is non-nil." ;; Wrap text in messages (setq-hook! 'mu4e-view-mode-hook truncate-lines nil) - ;; mu4e now uses `display-buffer-alist' so we need to add some rules of our own - (set-popup-rule! "^\\*mu4e-\\(main\\|headers\\)\\*" :ignore t) - ;; Html mails might be better rendered in a browser (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser)) (when (fboundp 'make-xwidget) (add-to-list 'mu4e-view-actions '("xwidgets view" . mu4e-action-view-in-xwidget))) ;; Detect empty subjects, and give users an opotunity to fill something in - (defun +mu4e-check-for-subject () - "Check that a subject is present, and prompt for a subject if not." - (save-excursion - (goto-char (point-min)) - (search-forward "--text follows this line--") - (re-search-backward "^Subject:") ; this should be present no matter what - (let ((subject (string-trim (substring (thing-at-point 'line) 8)))) - (when (string-empty-p subject) - (end-of-line) - (insert (read-string "Subject (optional): ")) - (message "Sending..."))))) + (add-hook! 'message-send-hook + (defun +mu4e-check-for-subject () + "Check that a subject is present, and prompt for a subject if not." + (save-excursion + (goto-char (point-min)) + (search-forward "--text follows this line--") + (re-search-backward "^Subject:") ; this should be present no matter what + (let ((subject (string-trim (substring (thing-at-point 'line) 8)))) + (when (string-empty-p subject) + (end-of-line) + (insert (read-string "Subject (optional): ")) + (message "Sending...")))))) - (add-hook 'message-send-hook #'+mu4e-check-for-subject) - - ;; The header view needs a certain amount of horizontal space to - ;; actually show you all the information you want to see - ;; so if the header view is entered from a narrow frame, - ;; it's probably worth trying to expand it - (defun +mu4e-widen-frame-maybe () - "Expand the mu4e-headers containing frame's width to `+mu4e-min-header-frame-width'." - (dolist (frame (frame-list)) - (when (and (string= (buffer-name (window-buffer (frame-selected-window frame))) - mu4e-headers-buffer-name) - (< (frame-width) +mu4e-min-header-frame-width)) - (set-frame-width frame +mu4e-min-header-frame-width)))) - (add-hook 'mu4e-headers-mode-hook #'+mu4e-widen-frame-maybe) + ;; The header view needs a certain amount of horizontal space to actually show + ;; you all the information you want to see so if the header view is entered + ;; from a narrow frame, it's probably worth trying to expand it + (defvar +mu4e-min-header-frame-width 120 + "Minimum reasonable with for the header view.") + (add-hook! 'mu4e-headers-mode-hook + (defun +mu4e-widen-frame-maybe () + "Expand the mu4e-headers containing frame's width to `+mu4e-min-header-frame-width'." + (dolist (frame (frame-list)) + (when (and (string= (buffer-name (window-buffer (frame-selected-window frame))) + mu4e-headers-buffer-name) + (< (frame-width) +mu4e-min-header-frame-width)) + (set-frame-width frame +mu4e-min-header-frame-width))))) (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) - (when (modulep! :ui workspaces) - (map! :map mu4e-main-mode-map - :ne "h" #'+workspace/other)) - - (map! :map mu4e-headers-mode-map + (map! (:when (modulep! :ui workspaces) + :map mu4e-main-mode-map + :ne "h" #'+workspace/other) + :map mu4e-headers-mode-map :vne "l" #'+mu4e/capture-msg-to-agenda) ;; Functionality otherwise obscured in mu4e 1.6 @@ -354,18 +350,19 @@ Acts like a singular `mu4e-view-save-attachments', without the saving." :desc "save draft" "S" #'message-dont-send :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 - ;; want to use in and evil selection, this can be easily fixed. - (when (modulep! :editor evil) - (map! :map mu4e-headers-mode-map - :v "*" #'mu4e-headers-mark-for-something - :v "!" #'mu4e-headers-mark-for-read - :v "?" #'mu4e-headers-mark-for-unread - :v "u" #'mu4e-headers-mark-for-unmark)) + ;; 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 want to use in and evil selection, this can be easily + ;; fixed. + (map! :map mu4e-headers-mode-map + :v "*" #'mu4e-headers-mark-for-something + :v "!" #'mu4e-headers-mark-for-read + :v "?" #'mu4e-headers-mark-for-unread + :v "u" #'mu4e-headers-mark-for-unmark) - (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address-h) + (add-hook 'mu4e-compose-pre-hook #'+mu4e-set-from-address-h) + ;; HACK (defadvice! +mu4e-ensure-compose-writeable-a (&rest _) "Ensure that compose buffers are writable. This should already be the case yet it does not always seem to be." @@ -375,15 +372,14 @@ This should already be the case yet it does not always seem to be." :before #'mu4e-compose-resend (read-only-mode -1)) - ;; process lock control + ;; HACK: process lock control (when (featurep :system 'windows) - (setq - +mu4e-lock-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock") - +mu4e-lock-request-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock_request"))) + (setq +mu4e-lock-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock") + +mu4e-lock-request-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock_request"))) (add-hook 'kill-emacs-hook #'+mu4e-lock-file-delete-maybe) - (advice-add 'mu4e--start :around #'+mu4e-lock-start) - (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) + (advice-add #'mu4e--start :around #'+mu4e-lock-start) + (advice-add #'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) (use-package! org-msg From 139591172e1838c9a9a6712ace5aa7511ab96594 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 04:05:22 -0400 Subject: [PATCH 13/15] fix(mu4e): add mu4e-debug to doom-debug-variables --- modules/email/mu4e/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 7af288f95..0b7faf792 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -21,6 +21,7 @@ (setq mu4e-maildir "~/.mail" mu4e-user-mail-address-list nil)) :config + (add-to-list 'doom-debug-variables 'mu4e-debug) ;; mu4e now uses `display-buffer-alist' so we need to add some rules of our own (set-popup-rule! "^\\*mu4e-\\(main\\|headers\\)\\*" :ignore t) From c6479574e6d324d788e3bc2f6240440010373956 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 04:11:38 -0400 Subject: [PATCH 14/15] feat(mu4e): respect XDG for mbsync config file Support for this was only added in isync 1.5, but this way, users on older can benefit from it through Emacs. Ref: https://sourceforge.net/p/isync/isync/ci/cf13630a00e4761e26f054b37875085958800eeb/ --- modules/email/mu4e/config.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 0b7faf792..34f5d83b1 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -35,7 +35,12 @@ (cond ((or (modulep! +mbsync) (eq +mu4e-backend 'mbsync)) - (setq mu4e-get-mail-command "mbsync -a" + (setq mu4e-get-mail-command + (format "mbsync --all --config %S" + ;; XDG support was added to isync 1.5, but this lets + ;; users on older benefit from it sooner. + (or (file-exists-p! "isyncrc" (or (getenv "XDG_CONFIG_HOME") "~/.config")) + "~/.mbsyncrc")) mu4e-change-filenames-when-moving t)) ((or (modulep! +offlineimap) (eq +mu4e-backend 'offlineimap)) From 424b7af45fa2c96bbee9b06f33c6cd0fc13412ac Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Thu, 5 Sep 2024 04:25:57 -0400 Subject: [PATCH 15/15] fix(mu4e): duplicate "view in browser" actions These are already present in newer versions of mu4e. By making them match, `add-to-list` won't add a duplicate. Fix: #6328 --- modules/email/mu4e/config.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 34f5d83b1..4f91e1486 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -240,9 +240,9 @@ is non-nil." (setq-hook! 'mu4e-view-mode-hook truncate-lines nil) ;; Html mails might be better rendered in a browser - (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser)) - (when (fboundp 'make-xwidget) - (add-to-list 'mu4e-view-actions '("xwidgets view" . mu4e-action-view-in-xwidget))) + (add-to-list 'mu4e-view-actions '("view in browser" . mu4e-action-view-in-browser)) + (when (fboundp 'xwidget-webkit-browse-url) + (add-to-list 'mu4e-view-actions '("xview in xwidget" . mu4e-action-view-in-xwidget))) ;; Detect empty subjects, and give users an opotunity to fill something in (add-hook! 'message-send-hook