#+title: Doom Emacs literal configuration #+STARTUP: content * Table of Contents :TOC_3:noexport: - [[#misc][Misc]] - [[#lexical-bindings][Lexical bindings]] - [[#dir-local-variables][Dir local variables]] - [[#taking-svg-screenshots][Taking SVG screenshots]] - [[#theme][Theme]] - [[#main-theme][Main theme]] - [[#dark-theme-toggle][Dark theme toggle]] - [[#font][Font]] - [[#line-numbers][Line numbers]] - [[#battery-indicator][Battery indicator]] - [[#programming][Programming]] - [[#tridactyl-mode][Tridactyl mode]] - [[#smart-parens][Smart parens]] - [[#rust][Rust]] - [[#column-width][Column width]] - [[#run-clippy-in-rust-analyzer][Run clippy in rust-analyzer]] - [[#enable-proc-macro-support][Enable proc macro support]] - [[#cc][C/C++]] - [[#default-style][Default style]] - [[#nix][Nix]] - [[#formatting][Formatting]] - [[#lilypond][LilyPond]] - [[#org-mode][Org mode]] - [[#directory][Directory]] - [[#appearance][Appearance]] - [[#fancier-ellipsis-indicator][Fancier ellipsis indicator]] - [[#logging][Logging]] - [[#archiving][Archiving]] - [[#agenda-setup][Agenda setup]] - [[#default-task-keywords][Default task keywords]] - [[#org-capture-setup][Org capture setup]] - [[#main-agenda-view][Main agenda view]] - [[#habits][Habits]] - [[#save-all-org-buffers-shortcut][Save all org buffers shortcut]] - [[#script-to-open-agenda-window-automatically][Script to open agenda window automatically]] - [[#roam][Roam]] - [[#roam-directory][Roam Directory]] - [[#org-roam-ui][org-roam-ui]] - [[#export-backends][Export backends]] - [[#doom-specific][Doom specific]] - [[#enable-some-link-modules-that-doom-disables-by-default][Enable some link modules that doom disables by default]] - [[#bugfix][Bugfix]] - [[#magit][Magit]] - [[#gitlab-ci-skip-flag][Gitlab CI skip flag]] - [[#email][Email]] - [[#account-configuration][Account configuration]] - [[#sending-mail][Sending mail]] - [[#reading-plain-text][Reading plain text]] - [[#org-msg-setup][=org-msg= setup]] - [[#message-quoting-style][Message quoting style]] - [[#disable-formatflowed][Disable format=flowed]] - [[#dont-permanently-delete-when-trashing-mails][Don't permanently delete when trashing mails]] - [[#add-git-apply-path-to-mu4e-actions][Add git-apply-path to mu4e actions]] - [[#enable-auto-updates][Enable auto updates]] - [[#ask-which-address-to-send-with-when-composing-a-new-mail][Ask which address to send with when composing a new mail]] - [[#only-fetch-main-directories-by-default][Only fetch main directories by default]] - [[#headers-view-format][Headers view format]] - [[#message-view-fields][Message view fields]] - [[#mailing-list-pretty-names][Mailing list pretty names]] - [[#fix-attachment-icon-with-light-theme][Fix attachment icon with light theme]] - [[#bookmarks][Bookmarks]] - [[#apply-marks-on-quit][Apply marks on quit]] * Misc ** Lexical bindings Enable lexical binding, of course... #+BEGIN_SRC emacs-lisp ;;; -*- lexical-binding: t; -*- #+END_SRC ** Dir local variables Disable these because I don't use them and don't want to get prompted by them in some projects. #+BEGIN_SRC emacs-lisp (setq enable-dir-local-variables nil) #+END_SRC ** Taking SVG screenshots Since Emacs 27, we can take SVG screenshots! Emacs needs to be built with =cairo= to support this. #+begin_src emacs-lisp (defun my/screenshot-svg () "Save a screenshot of the current frame as an SVG image. Saves to a temp file and puts the filename in the kill ring." (interactive) (let ((filename (make-temp-file "Emacs" nil ".svg")) (data (x-export-frames nil 'svg))) (with-temp-file filename (insert data)) (kill-new filename) (message filename))) #+end_src * Theme ** Main theme A list of all doom themes can be found here: https://github.com/hlissner/emacs-doom-themes #+BEGIN_SRC emacs-lisp (setq doom-theme 'doom-one-light) #+END_SRC ** Dark theme toggle I've come to prefer using a light theme during the day, and a dark theme at night. Using a dark theme with daylight leads to cranking up the screen brightness, which hurts my eyes more than using the light theme. Set my light and dark themes: #+BEGIN_SRC emacs-lisp (setq my/light-theme doom-theme my/dark-theme 'doom-one) #+END_SRC Function to toggle between the two easily: #+BEGIN_SRC emacs-lisp (defun my/toggle-dark-theme () (interactive) (if (eq my/dark-theme doom-theme) (load-theme my/light-theme t) (load-theme my/dark-theme t))) #+END_SRC Bind this to =SPC t d=: #+BEGIN_SRC emacs-lisp (map! :leader (:prefix-map ("t" . "toggle") :desc "Dark theme" "d" #'my/toggle-dark-theme)) #+END_SRC ** Font Doom exposes five (optional) variables for controlling fonts in Doom. Here are the three important ones: - =doom-font= - =doom-variable-pitch-font= - =doom-big-font= -- used for =doom-big-font-mode=; use this for presentations or streaming. They all accept either a font-spec, font string (=Input Mono-12=), or xlfd font string. You generally only need these two: #+BEGIN_SRC emacs-lisp (setq doom-font (font-spec :family "Iosevka Fixed" :size 10.0 :weight 'medium)) #+END_SRC ** Line numbers Possible values of =display-line-numbers-type= are =nil=, =t=, and ='relative=. #+BEGIN_SRC emacs-lisp (setq display-line-numbers-type 'relative) #+END_SRC ** Battery indicator I'm on a laptop, so let's display my battery in the modeline: #+BEGIN_SRC emacs-lisp (display-battery-mode 1) #+END_SRC * Programming ** Tridactyl mode #+begin_src emacs-lisp (defvar tridactylrc-font-lock-keywords `( ;; Line comment ("^[\t ]*\\(\"\\)\\(.*\\)$" (1 font-lock-comment-delimiter-face) (2 font-lock-comment-face)) ;; Trailing comment ("[\t ]+\\(\"\\)\\([^\"\r\n]*\\)$" (1 font-lock-comment-delimiter-face) (2 font-lock-comment-face)) ;; String start: ("\\(\"[^\n\r\"]*\"\\)\\|\\('[^\n\r]*'\\)" (0 font-lock-string-face)) ;; String end; )) (defvar tridactylrc-mode-syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?' "\"" table) (modify-syntax-entry ?\" "<" table) (modify-syntax-entry ?\n ">" table) table)) (define-derived-mode tridactylrc-mode prog-mode "tridactylrc" "Major mode for editing tridactylrc configuration files." :group 'tridactylrc-mode :syntax-table tridactylrc-mode-syntax-table (font-lock-add-keywords nil tridactylrc-font-lock-keywords) (setq-local comment-start "\"") (setq-local comment-end "")) #+end_src ** Smart parens Disable smart parens because half of the time it doesn't do what I want: #+BEGIN_SRC emacs-lisp (remove-hook 'doom-first-buffer-hook #'smartparens-global-mode) #+END_SRC ** Rust *** Column width =rustfmt= limits lines to 100 characters, let's display it correctly. #+BEGIN_SRC emacs-lisp (add-hook! rustic-mode (set-fill-column 100)) #+END_SRC *** Run clippy in rust-analyzer The default is ~"check"~, but I want clippy lints as well. #+begin_src emacs-lisp (setq lsp-rust-analyzer-cargo-watch-command "clippy") #+end_src *** Enable proc macro support By default lsp-mode disable these, I want them. #+begin_src emacs-lisp (setq lsp-rust-analyzer-experimental-proc-attr-macros t) (setq lsp-rust-analyzer-proc-macro-enable t) #+end_src ** C/C++ *** Default style Setup the default format for C/C++ editing. #+BEGIN_SRC emacs-lisp (add-hook! (c-mode c++-mode) (setq c-default-style "gnu") (setq c-basic-offset 2)) #+END_SRC ** Nix *** Formatting Use [[https://github.com/kamadorueda/alejandra][alejandra]] to format Nix code. #+begin_src emacs-lisp (set-formatter! 'alejandra '("alejandra" "--quiet") :modes '(nix-mode)) #+end_src ** LilyPond Just load the lilypond mode #+begin_src emacs-lisp (require 'lilypond-init) #+end_src * Org mode ** Directory Set a default directory for all my org-mode files. #+BEGIN_SRC emacs-lisp (setq org-directory "~/org/") #+END_SRC ** Appearance *** Fancier ellipsis indicator #+BEGIN_SRC emacs-lisp (setq org-ellipsis " ▼ ") #+END_SRC ** Logging Log state changes in a src_org{:LOGBOOK:} drawer so that it doesn't pollute the main content. #+begin_src emacs-lisp (after! org (setq org-log-into-drawer t)) #+end_src ** Archiving I don't want to see archival files appearing when listing files in the current directory, so hide them by default. #+begin_src emacs-lisp (after! org (setq org-archive-location ".%s_archive::")) #+end_src ** Agenda setup *** Default task keywords Here are the [[https://orgmode.org/manual/TODO-Extensions.html#TODO-Extensions][keywords]] I'm using to track task progress. I'm also making use of some automatic [[https://orgmode.org/manual/Tracking-TODO-state-changes.html#Tracking-TODO-state-changes][state changes]]. | keyword | meaning | |-------------+----------------------------------------------------------| | =TODO= | Self explanatory | | =DONE= | This task is finished, no longer displayed in the agenda | | =CANCELLED= | This task isn't finished but is no longer relevant | #+BEGIN_SRC emacs-lisp (after! org (setq org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d!)" "CANCELLED(c@/!)") (sequence "[ ](T)" "|" "[X](D)")))) #+END_SRC *** Org capture setup Of course I also need to setup [[https://orgmode.org/manual/Capture-templates.html][capture templates]]: The first one just prompts me for a new task to add to my inbox, I can then [[https://orgmode.org/guide/Refile-and-Copy.html][refile]] them where I want later. The second one exists because I like to keep a separate list of articles / papers / books to read. #+BEGIN_SRC emacs-lisp (after! org (setq org-capture-templates '(("t" "New entry" entry (file "inbox.org") "* TODO %?") ("T" "Task" entry (file+headline "tasks.org" "Misc") "* TODO %?") ("r" "Reading" entry (file "reading.org") "* TODO %x" :immediate-finish t) ("w" "Watching" entry (file "watching.org") "* TODO %x" :immediate-finish t)))) #+END_SRC I also change [[https://github.com/hlissner/doom-emacs/blob/134554dd69d9b1cea3d2190422de580fddf40ecd/modules/config/default/%2Bevil-bindings.el#L265][the default Doom binding]] for ~#'org-capture~ to be =SPC x= instead of =SPC X=. Also need to rebind what was [[https://github.com/hlissner/doom-emacs/blob/134554dd69d9b1cea3d2190422de580fddf40ecd/modules/config/default/%2Bevil-bindings.el#L264][previously bound]] to =SPC x=, to =SPC X=. #+BEGIN_SRC emacs-lisp (map! :leader :desc "Org Capture" "x" #'org-capture :desc "Pop up scratch buffer" "X" #'doom/open-scratch-buffer) #+END_SRC *** Main agenda view All these tasks, once captured, are then centralized in my [[https://orgmode.org/guide/Agenda-Views.html][agenda view]]. I'm using multiple categories to organize tasks, depending on their triage / status (inspired by [[https://blog.jethro.dev/posts/org_mode_workflow_preview/]]). #+BEGIN_SRC emacs-lisp (after! org-agenda (setq org-agenda-custom-commands '((" " "Agenda" ((agenda "" ((org-agenda-span 'day) (org-agenda-start-day nil) (org-deadline-warning-days 365))) (todo "TODO" ((org-agenda-overriding-header "Triage") (org-agenda-files '("~/org/inbox.org")))) (todo "TODO" ((org-agenda-overriding-header "Job") (org-agenda-files '("~/org/job.org")) (org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline 'scheduled)))) (todo "TODO" ((org-agenda-overriding-header "Tasks") (org-agenda-files '("~/org/tasks.org")) (org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline 'scheduled)))) ))))) #+END_SRC I want the default agenda view to be a weekly view, with a log of what I've done during the day. #+BEGIN_SRC emacs-lisp (after! org-agenda (setq org-agenda-span 'week) (setq org-agenda-start-on-weekday 1) (setq org-agenda-start-with-log-mode '(clock))) #+END_SRC I also remove the block separators in the agenda view: #+BEGIN_SRC emacs-lisp (after! org-agenda (setq org-agenda-block-separator "")) #+END_SRC *** Habits Let's enable the =org-habit= module: #+BEGIN_SRC emacs-lisp (add-to-list 'org-modules 'org-habit) (after! org-agenda (setq org-habit-show-all-today t)) #+END_SRC *** Save all org buffers shortcut By default bound to =C-x C-s=, rebind it to =SPC m s= in =org-agenda-mode= : #+BEGIN_SRC emacs-lisp (map! :after org-agenda :map org-agenda-mode-map :localleader "s" #'org-save-all-org-buffers) #+END_SRC *** Script to open agenda window automatically I use this script to automatically open the agenda when pressing a specific key binding in my window manager. #+begin_src emacs-lisp :tangle "launch-agenda.el" (find-file org-directory) (with-selected-window (split-window-horizontally) ;; need to wait for the window to appear (sleep-for 0.1) (org-agenda nil " ")) #+end_src ** Roam Setup for [[https://github.com/jethrokuan/org-roam][org-roam]]. *** Roam Directory First, set a directory where =org-roam= will index things. #+BEGIN_SRC emacs-lisp (setq org-roam-directory (expand-file-name "notes/" org-directory)) #+END_SRC *** org-roam-ui Setup [[https://github.com/org-roam/org-roam-ui][org-roam-ui]] #+begin_src emacs-lisp (use-package! websocket :after org-roam) (use-package! org-roam-ui :after org-roam :config (setq org-roam-ui-sync-theme t org-roam-ui-follow t org-roam-ui-update-on-save t org-roam-ui-open-on-start t)) #+end_src ** Export backends Sometimes I need to export an Org subtree to a file, which is quite easy with the =org= export backend. It doesn't seem to be enabled by default, so let's add it to the list: #+BEGIN_SRC emacs-lisp (after! org (add-to-list 'org-export-backends 'org)) #+END_SRC ** Doom specific Doom makes some changes to org-id behaviour which I don't like / think are necessary. #+begin_src emacs-lisp (after! org (setq org-id-locations-file (expand-file-name "~/.config/emacs/.org-id-locations")) (setq org-id-locations-file-relative nil)) #+end_src Doom replaces the default tab behavior on headings, this restores the default one. Taken from [[https://github.com/hlissner/doom-emacs/tree/develop/modules/lang/org#hacks][here]]. #+BEGIN_SRC emacs-lisp (after! evil-org (remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h)) #+END_SRC *** Enable some link modules that doom disables by default #+begin_src emacs-lisp (add-to-list 'org-modules 'ol-info) (add-to-list 'org-modules 'ol-doi) #+end_src *** Bugfix Fix a bug with capture mode not working correctly when agenda is opened, stolen from https://github.com/hlissner/doom-emacs/issues/5714#issuecomment-1018788028 #+begin_src emacs-lisp (after! org (defadvice! dan/+org--restart-mode-h-careful-restart (fn &rest args) :around #'+org--restart-mode-h (let ((old-org-capture-current-plist (and (bound-and-true-p org-capture-mode) (bound-and-true-p org-capture-current-plist)))) (apply fn args) (when old-org-capture-current-plist (setq-local org-capture-current-plist old-org-capture-current-plist) (org-capture-mode +1))))) #+end_src * Magit ** Gitlab CI skip flag This option tells GitLab to skip the CI run for this push, in case I know it's not ready yet. #+BEGIN_SRC emacs-lisp (after! magit (transient-append-suffix 'magit-push "-n" '(4 "-s" "Skip GitLab CI" "--push-option=ci.skip"))) #+END_SRC GitLab push options are documented [[https://docs.gitlab.com/ee/user/project/push_options.html][here]]. * Email #+begin_src emacs-lisp :noweb no-export (after! mu4e <>) #+end_src ** Account configuration Setup my main email account. #+begin_src emacs-lisp (set-email-account! "alarsyo" '((mu4e-sent-folder . "/alarsyo/Sent") (mu4e-drafts-folder . "/alarsyo/Drafts") (mu4e-refile-folder . "/alarsyo/Archive") (mu4e-trash-folder . "/alarsyo/Trash") (user-mail-address . "antoine@alarsyo.net") (user-full-name . "Antoine Martin") (mu4e-compose-signature . "Antoine Martin")) t) (set-email-account! "lrde" '((mu4e-sent-folder . "/lrde/Sent") (mu4e-drafts-folder . "/lrde/Drafts") (mu4e-trash-folder . "/lrde/Trash") (user-mail-address . "amartin@lrde.epita.fr") (user-full-name . "Antoine Martin") (mu4e-compose-signature . "Antoine Martin")) nil) (set-email-account! "prologin" '((mu4e-sent-folder . "/prologin/Sent") (mu4e-drafts-folder . "/prologin/Drafts") (mu4e-trash-folder . "/prologin/Trash") (user-mail-address . "antoine.martin@prologin.org") (user-full-name . "Antoine Martin") (mu4e-compose-signature . "Antoine Martin")) nil) #+end_src ** Sending mail I use =msmtp= as a SMTP forwarder #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq sendmail-program (executable-find "msmtp") send-mail-function #'smtpmail-send-it message-sendmail-f-is-evil t message-sendmail-extra-arguments '("--read-envelope-from") message-send-mail-function #'message-send-mail-with-sendmail) #+end_src I don't want something like ~ws-butler~ to mess with my formatting, especially the trailing space after a signature delimiter: #+BEGIN_SRC emacs-lisp (add-hook! mu4e-compose-mode (ws-butler-mode -1)) #+END_SRC ** Reading plain text Ask the =gnus-view= (default viewer used by =mu4e=) to avoid HTML whenever possible. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (add-to-list 'mm-discouraged-alternatives "text/html") (add-to-list 'mm-discouraged-alternatives "text/richtext") #+end_src ** =org-msg= setup Add =-:nil= to the export options list, otherwise the =--= in the signature gets converted to a single hyphen when exporting to utf-8. See [[info:org#Export settings]] #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq org-msg-options (concat org-msg-options " -:nil")) #+end_src Setup signature as well. The double backslashes are there to make sure that the linebreak is preserved even in the html export, which otherwise wraps the signature lines as a single paragraph. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq org-msg-signature "\n#+begin_signature\n-- \\\\\nAntoine Martin\n#+end_signature") #+end_src I don't want to send HTML emails at all unless I choose to explicitely. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq org-msg-default-alternatives '((new utf-8) (reply-to-text utf-8) (reply-to-html utf-8))) #+end_src ** Message quoting style Has to be duplicated because =mu4e= doesn't use ~message-cite-style~'s values. #+begin_src emacs-lisp (defconst message-cite-style-custom '((message-cite-function 'message-cite-original-without-signature) (message-citation-line-function 'message-insert-formatted-citation-line) (message-cite-reply-position 'traditional) (message-yank-prefix "> ") (message-yank-cited-prefix "> ") (message-yank-empty-prefix ">") (message-citation-line-format "%f writes:")) "Message citation style used for email. Use with `message-cite-style'.") (after! message (setq message-cite-style message-cite-style-custom message-cite-function 'message-cite-original-without-signature message-citation-line-function 'message-insert-formatted-citation-line message-cite-reply-position 'traditional message-yank-prefix "> " message-yank-cited-prefix "> " message-yank-empty-prefix ">" message-citation-line-format "%f writes:")) #+end_src ** Disable format=flowed #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-compose-format-flowed nil) #+end_src ** Don't permanently delete when trashing mails By default =mu4e= sets the =trashed= flag on emails trashed using the =d= keybinding. This just replaces the action to just move the message to the trash instead. See https://github.com/djcb/mu/issues/1136#issuecomment-1066303788, the code will have to be adapted soon. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (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--server-move docid (mu4e--mark-check-target target) "-N")))) #+end_src ** Add git-apply-path to mu4e actions #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no ;; TODO: upstream this, Doom emacs adds a view in browser action but it seems ;; to be present by default now. (setq mu4e-view-actions (remove '("View in browser" . mu4e-action-view-in-browser) mu4e-view-actions)) (add-to-list 'mu4e-view-actions '("GitApply" . mu4e-action-git-apply-patch) t) (add-to-list 'mu4e-view-actions '("MboxGitApply" . mu4e-action-git-apply-mbox) t) #+end_src ** Enable auto updates =mu4e= refreshes my email in the background. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-update-interval 900) #+end_src If it fetches new mail while I'm browsing some messages, it will refresh the headers view, potentially loosing context (like some messages that got marked as read because I skimmed over them, but that I don't want to see disappear yet). So let's disable this automatic update of headers: #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-auto-update nil) #+end_src Additionally, don't show all new mail in the modeline, only relevant ones: #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-alert-interesting-mail-query "flag:unread AND NOT flag:list") #+end_src ** Ask which address to send with when composing a new mail #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-compose-context-policy 'ask) #+end_src ** Only fetch main directories by default I have a lot (100+) directories on my main email account, I only want to fetch the "important" ones (i.e. those coming from real individuals, addressed to me directly) when I ask for a refresh explicitely (updating everything in the background is fine the rest of the time). Let's define a new function that does just that: #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (defun my/mu4e-update-main-mail-and-index (run-in-background) "Get mail for all folders, not just the main ones" (interactive "P") (let ((mu4e-get-mail-command "mbsync alarsyo-main lrde prologin-main")) (mu4e-update-mail-and-index run-in-background))) #+end_src Let's also bind it to =u= in the main view, overriding the default binding (which I'll remap to =U=). #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (map! :map mu4e-main-mode-map :ne "u" #'my/mu4e-update-main-mail-and-index :ne "U" #'mu4e-update-mail-and-index) #+end_src ** Headers view format Use "french" date format in header view: #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-date-format "%d/%m/%y") #+end_src Set the time display to 24h: #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-time-format "%T") #+end_src Setup the headers view columns how I like them #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-fields '((:account-stripe . 1) ;; just enough room for dd/mm/yy or hh:mm:ss (:human-date . 8) (:flags . 6) (:mailing-list . 30) (:maildir . 30) (:from-or-to . 30) (:subject))) #+end_src ** Message view fields #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-view-fields '(:from :to :cc :subject :flags :date :mailing-list :maildir :path :size :tags :attachments :user-agent :signature :decryption)) #+end_src ** Mailing list pretty names #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-mailing-list-patterns '("[0-9]+\\.\\(.+\\)\\.gitlab\\.lrde\\.epita\\.fr" "[0-9]+\\.\\(.+\\)\\.gitlab\\.com" "\\(.+\\)\\.github\\.com") mu4e-user-mailing-lists '(("info.prologin.org" . "Infos Prologin") ("membres.ml.prologin.org" . "Membres Prologin"))) #+end_src ** Fix attachment icon with light theme #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-attach-mark (cons "a" (+mu4e-normalised-icon "file-text-o" :color "cyan"))) #+end_src ** Bookmarks Let's not display messages from mailing lists in main views, leave them to specific bookmarks. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-bookmarks '((:name "Unread messages" :query "flag:unread AND NOT flag:list" :key ?u) (:name "Today's messages" :query "date:today..now AND NOT flag:list" :key ?t) (:name "Last 7 days" :query "date:7d..now AND NOT flag:list" :hide-unread t :key ?w) (:name "Messages with images" :query "mime:image/* AND NOT flag:list" :key ?p) (:name "All unread messages" :query "flag:unread AND NOT maildir:/prologin/*" :key ?U) (:name "All Prologin messages" :query "flag:unread AND maildir:/prologin/*" :key ?P) (:name "Today's messages (lists included)" :query "date:today..now" :key ?T) (:name "Last 7 days (lists included)" :query "date:7d..now" :hide-unread t :key ?W) (:name "Orgmode mailing list new posts" :query "list:emacs-orgmode.gnu.org AND flag:unread" :key ?o) (:name "All messages with images" :query "mime:image/*" :key ?P))) #+end_src ** Apply marks on quit I don't want confirm to apply marks everytime I quit the headers view. #+begin_src emacs-lisp :noweb-ref after-mu4e :tangle no (setq mu4e-headers-leave-behavior 'apply) #+end_src