*Welcome!* You found my (Marcel Kapfer aka mmk2410) personal Emacs configuration file. Please feel free to read through it, use it or get inspiration! If you would (for some very strange reason) like to read it online: I [[https://mmk2410.org/2022/01/30/publishing-my-emacs-configuration/][published]] it to [[https://config.mmk2410.org][config.mmk2410.org]]
This file (=config.org=) is written in [[https://orgmode.org/][org-mode]] and converted as Emacs Lisp to =config.el= on startup. This is achieved on org-babel and tangle (see the =init.el= file).
There are many people that I should thank for giving me the help needed to write this config. Two of them need to be mentioned here since many parts are either copied or heavily inspired by their configurations:
- [[https://karl-voit.at/][Karl Voit]] especially for his [[https://karl-voit.at/2021/06/01/Thunderbird-to-Evolution][Evolution email workflow]] and this [[https://karl-voit.at/2017/06/03/emacs-org/][setup approach]] ([[https://github.com/novoid/dot-emacs/blob/master/config.org][his Emacs config]])
- [[https://daviwil.com/][David Wilson]] and his [[https://www.youtube.com/c/SystemCrafters][System Crafters]] YouTube channel for his [[https://www.youtube.com/c/SystemCrafters/videos][Emacs videos]] ([[https://config.daviwil.com/emacs][his Emacs config]])
/Note: Elisp blocks which are marked as =:tangle no= are not evaluated./
* A few words on setup
Writing the initial "stable" version of this configuration took nearly two years. I used it constantly during this time after I declared Emacs bankruptcy with [[https://git.mmk2410.org/mmk2410/dotfiles/src/commit/f6d220554ab0946a1a4efb7e3400194139a99550/emacs/emacs.el][my old configuration]]. During this time many things happened and changed Back in March 2019 when I started I never imaged using this configuration on a native Microsoft® Windows® installation of Emacs. But in 2021 when I started using some creative tools that are only available on Windows® I first did and only later switched completely to the Windows Subsystem for Linux. Therefore /some/ parts are compatible with a native installation of Emacs on Windows®.
For Microsoft(R) Windows(R) users it is highly adviced to set the =HOME= environment variable to the users home directory. This can be done by opening the file explorer =WIN+e=, right clicking on "This PC" and choosing "Properties". In the opening window it is possible to open "Advanced system settings" in the sidebar. In the then appearing dialg ther is a button labeled "Environment Variables...". Using the "New..." button in the "User variables" section of the "Environment Variables" dialog it is possible to add a new one. Enter as name =HOME= and use the "Browse Directory.." button for choosing your user home directory. Accept all the changes by clicking on "OK" until there are no more open dialogs left.
* General settings
Settings for Emacs in general as well as for my personal setup.
Enable aspell. Options set according to [[https://www.emacswiki.org/emacs/FlySpell][Emacswiki: FlySpell]]
#+begin_src emacs-lisp
(setq-default ispell-program-name "aspell")
(setq ispell-list-command "--list")
#+end_src
For using spell checking on Microsoft(R) Windows(R) a little bit more work is apparently needed. First of all some spell checking program is needed and when trying to install either ispell, aspell or hunspell I run into the problem that all three of them are primarily developed for Linux systems.
For installing aspell and the required dictionaries I decided to use [[https://www.msys2.org/][MSYS2]]. After installing this and following the initial setup guide on their website I installed aspell using =pacman -S mingw-w64-x86_64-aspell= in an MSYS2 terminal (for the next steps it was also necessary to install the =make= program with =pacman -S make=). The installation itself does not make the program available to my Emacs installation (see [[*A few words on setup][A few words on setup]]) but I needed to add the =C:\msys64\mingw64\bin= directory to the Windows =Path= variable. Therefore I opened an explorer (=WIN+e=), right-clicked "This PC" and then properties. In the appearing window I continued by clicking "Advanced system settings" in the sidebar. In the now appearing window I continued by clicking the "Environment Variables..." button. There I edited the =Path=*system* variable. By clicking on "New" first and then clicking on "Browse..." I was able to add the previously named directory to the path. Afterwards it is possible to check weather this was successful by either opening a PowerShell or CMD prompt and executing =aspell --version=.
While Emacs now finds aspell (at least after a restart of Emacs) it does not find any dictionaries and therefore not work. This is quite understandable since by default non are installed. Apparently compared to some Linux distributions MSYS2 does not provide any dictionaries through their repositories. So I downloaded the ones I needed from the [[https://ftp.gnu.org/gnu/aspell/dict/0index.html][aspell dictionaries website]]. Using the *MSYS2 MinGW 64-bit* terminal (this is important, the MSYS MSYS2 one does not work for this) I could extract them with =tar xjf aspell6-en-2020.12.07-0.tar.bz2= and switch to the extracted directory. Following the provided README I first run =./configure= and the executed =make=. Since the =make install= step fails by default I needed to adjust the Makefile by deleting the *two* lines that change the directory and execute =chmod 664= in the =install= rule. Afterwards running =make install= succeeded without any errors.
After re-visiting the current file or opening another one spell checking in Emacs works!
** scratch-buffer
I prefer that the mode of my scratch buffer is org and don't want any initial lines.
I get scroll bars when using Emacs with emacsclient. So I disable the =scroll-bar-mode= explicitly when creating a new frame, but only on graphical systems. The same fix is also applied for the typeface.
#+begin_src emacs-lisp
(when (fboundp 'tool-bar-mode)
(tool-bar-mode -1))
(when (fboundp 'menu-bar-mode)
(menu-bar-mode -1))
(when (fboundp 'scroll-bar-mode)
(scroll-bar-mode -1))
#+end_src
** Highlight matching parenthesis
#+begin_src emacs-lisp
(show-paren-mode 1)
#+end_src
** Fix wrong Emacs size in some window managers
I have the problem in BSPWM that Emacs always starts floating and does not obey my rule to start in tiling mode.
Setting =frame-resize-pixelwise= to non-nil (as described in [[https://github.com/baskerville/bspwm/issues/551][GitHub: baskerville/bspwm #551]]) solves this problem.
#+begin_src emacs-lisp
(setq frame-resize-pixelwise t)
#+end_src
** Set typeface
My typeface is not loading when using emacsclient.So I set it explicitly when creating a frame. The same fix is applied for the scroll bars.
Sometimes (most often a work) I share my screen during a video call to discuss some code. Since I personally like to see larger fonts on video calls and I don't know what display size and resolution the other participants have I wrote two functions for resizing Emacs.
Add a slight transparency to the frames. Code provided by David Wilson / System Crafters [[https://github.com/daviwil/emacs-from-scratch/blob/master/Emacs.org][Emacs from Scratch]] video series.
During the last weeks I got used to using a light theme during daytime and a dark theme during nighttime. Luckily the themes based on Atom One are to my liking and the doom package provides a dark and light variant. One thing that was difficult with Emacs was actually switching theme since it involved disabling all current ones (for some reason on one machine there are two enabled while on the other machine its only one) and then loading the correct one. These functions try to make that process easier, at least for now. The long-term goal is to automatically change the theme based on the current system-wide setting.
Additionally to that I also like to know, in which column I am.
#+begin_src emacs-lisp
(column-number-mode 1)
#+end_src
** Customize tab-bar
Since version 27 Emacs has a new tab-bar feature for keeping multiple window configurations open in different tabs. By default each tab has a close button and the tab bar includes an add button. I prefer not having either one.
=C-z= by default (as known from terminal applications) suspends the current frame. Since I use Emacs as GUI and not in terminal I do not want this behavior.
#+begin_src emacs-lisp
(unbind-key "C-z")
#+end_src
** The evil side
I currently try out =evil-mode= for evaluating if it is any better for my hand.
Treemacs is a package for displaying a directory tree in a (side) buffer. While browsing a project using =project.el= is also possible and perhaps fast, I think that the tree approach especially helps discovering a new project.
Deft is a nice tool for searching for files (in my case my notes). Since it searches not only through the title of files but also through the contents it may be useful for me.
Replace the three dots for collapsed stuff with a nicer symbol.
#+begin_src emacs-lisp
(setq org-ellipsis " ▼")
#+end_src
Hide emphasis markers. While this sometimes is very distracting it mostly looks absolutely beautiful.
#+begin_src emacs-lisp
(setq org-hide-emphasis-markers t)
#+end_src
** Org font adjustments
I like to have larger headlines in Org for better identifying them. The configuration of [[https://config.daviwil.com/emacs#fonts-and-bullets][David Wilson]] was a large help in this regard.
Add =scratcl= KOMA-Script class as available LaTeX class.
#+begin_src emacs-lisp
(with-eval-after-load 'ox-latex
(add-to-list 'org-latex-classes
'("scrartcl"
"\\documentclass{scrartcl}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))))
#+end_src
Set the scrartcl class as default.
#+begin_src emacs-lisp
(setq org-latex-default-class "scrartcl")
#+end_src
Us LuaLaTeX as default LaTeX compiler.
#+begin_src emacs-lisp
(setq org-latex-compiler "lualatex")
#+end_src
Customize LaTeX packages and configurations.
#+begin_src emacs-lisp
(setq org-latex-packages-alist
'(
("" "booktabs" t)
("" "amsmath" t)
("AUTO" "polyglossia" t)
("colorlinks" "hyperref" t)
"\\setmainfont{Linux Libertine O}"
"\\setsansfont{Linux Biolinum O}"
"\\setmonofont[Scale=0.9]{JetBrainsMono}"))
#+end_src
Configure minted source code listings for LaTeX export. For actually using the configuration it is necessary to set =org-latex-listings= to ='minted= using a local variable and to add the =minted= and =xcolor= package to =org-latex-packages-alist=. This is not done by default since I don't need it for all files and it requires =--shell-escape= for the LaTeX compile process.
Set a predefined tags. The first group is the list of GTD contexts. These are (by nature) exclusive and since a project is also an exclusive state I added it to the group even if it is not a context.
By default, org-mode separates "blocks" (e.g. an agenda view and a todo view) with a horizontal line of equal signs and adding some headlines. Since I have more current tasks and projects than my screen is high I like to keep it as compact as possible.
For determining the current state of my tasks I found it helpful to not only define one org-agenda view and use it always (the "Agenda" view with the shortcut "o" was in a very similar form my default for years). That's why I decided to define additional more precise lists for todays and upcoming tasks as well as for on overview of started, waiting and next tasks.
#+begin_src emacs-lisp
(setq org-agenda-custom-commands
'(("o" "Agenda"
((todo "STARTED")
(agenda "")
(todo "NEXT")))
("u" "Upcoming tasks"
agenda "" ((org-agenda-span 'week)))
("d" "Today tasks"
agenda "" ((org-agenda-span 'day)))
("b" "Started tasks" todo "STARTED")
("w" "Waiting for tasks" todo "WAITING")
("n" "Next tasks" todo "NEXT")))
#+end_src
For easily choosing the next thing to work on I give each of my tasks a context (following the GTD methodology). For quickly getting a list of all actionable tasks for a context I'd like to have a quick keyboard shortcut to view a custom agenda. For this I defined a list of contexts and their shortcut and iterated over them to create an additional ~org-agenda-custom-commands~ entry for each.
Given the fact that I run Emacs using Emacsclient all the time I though it would be quite helpful to have the ability to capture a to-do from everywhere, e.g. a sudden thought crossing my mind while developing photos or browsing the web. Thanks to the help of an [[https://www.reddit.com/r/emacs/comments/74gkeq/system_wide_org_capture][Reddit post]] by [[https://www.reddit.com/user/lebitso][u/lebitso]] I was able to achieve this goal and I put the code in an extra package that is loaded here.
#+begin_src emacs-lisp
(use-package org-quick-capture
:load-path "packages/")
#+end_src
To use this, I wrote a small shell script that I'm assigning a keyboard shortcut in my window manager / desktop environment. The shell script essentially runs the following command:
I am currently exploring the option in Org mode to export a file (or some entries) to an ics-file which I can then in turn import into my calendar. For reliably creating (and most importantly: updating) entries it is necessary that each one has an unique ID. To create a ID for the current entry I could just run =M-x org-id-get-create= and for an entire file execute the following Emacs Lisp ~(org-map-entries 'org-id-get-create)~. Of course this is not an ideal solution. But adding this s-expression to ~org-mode-hook~ would create IDs in all Org file I edit which I also don't like. Since the amount of files I do want the automatic creation is (currently) not that large it is OK for me to do some work on my own, at least if it is only a one time setup.
The idea which I had to achieve this goal was to create a file-local variable (called ~mmk2410/org-create-uuids~) that I set to ~t~ in the buffers I need the automatic adding of IDs and adding a hook to ~org-mode-hook~ that in turn adds a hook to ~before-save-hook~ for calling the function ~mmk2410/org-create-all-uuids~ that executes the previously named s-expression to add a ID to each entry in the buffer.
#+begin_src emacs-lisp
(setq mmk2410/org-create-uuids nil)
(defun mmk2410/org-create-all-uuids ()
"Create UUIDs for all entries in the current org-mode buffer."
Until now I did not think that I needed to keep a (personal) journal. But since I is recommended to keep a journal of whom you met due to the corona pandemic I started thinking about setting up one. Further use cases came then to my mind and so I decided to give it a try. Therefore the configuration is still in a very early state and may change quite soon.
Part of my workflow with org journal is in the meantime to clock the time I work in the different entries using =org-clock=. At the end of the day I like to create a summary for that. Currently the process for this includes a table with to formulas I created some time ago and copy every day from the previous one (while the first formula calculates the times the second is just there to clean the fields). While this is certainly improvable in many ways the only thing that really annoyed me was the calculation of the time. Since I try to follow the 52:17 methodology I have to add many numbers around 52 up to get the usual hour:minutes format. Although this is certainly a good brain training it has been shown that the calculation is very error-prone and calculating this twice does not make it more fun.
Therefore I created a little interactive helper function to sum these times up. The function =mmk2410/org-journal-worktime= reads a list of space separated minute values (so the time 1:04 must be entered as 64) and returns it as an minibuffer message in the required format (hh:mm).
#+begin_src emacs-lisp
(defun mmk2410/org-journal-worktime (workmins)
"Sum up the entered minutes and return it in hh:mm format."
(interactive "Show many minutes did you work today? ")
I am quite sure that the function can be improved in various ways. I am not a Lisp hacker and have not written very much in it. But at the moment it fits my needs (and I currently do not have more time to spare on this).
** Org Drill
org-drill is a package for spaced repetition in Emacs using org-mode files.
Since [[https://mmk2410.org/2020/05/15/switching-my-website-to-hugo-using-ox-hugo/][May 2020]] I'm using [[https://gohugo.io/][hugo]] with [[https://ox-hugo.scripter.co/][ox-hugo]] as a org-mode based static site generator for my [[https://mmk2410.org][mmk2410.org]] site. You can find the source code for the website [[https://git.mmk2410.org/mmk2410/mmk2410.org][on my Gitea instance]] (and also [[https://gitlab.com/mmk2410/mmk2410.org][GitLab]] and [[https://github.com/mmk2410/mmk2410.org][GitHub]] if you prefer that). First of all I need to include =ox-hugo= by [[https://scripter.co/][Kaushal Modi]]:
After I wrote an [[https://mmk2410.org/2022/01/15/improving-my-new-blog-post-creation/][own capture template]] for starting a new blog post, Kashual Modi, the creator of =ox-hugo=, made me aware of [[https://ox-hugo.scripter.co/doc/org-capture-setup/][an existing template in the documentation]] that also handles the automatic creation of the =EXPORT_FILE_NAME= property. I copied if from there and made some very slight adjustments to fit my needs.
Lisp languages involve many parentheses and it might get hard to know which one are on the same “level”. The rainbow-delimiters package is here to help with this problem.
Flycheck is a syntax checking extension for Emacs which uses specialized command line tools for the languages it supports. Next to the linting and highlighting of errors it does on its own it also integrates nicely into lsp-mode.
I use Docker and more importantly docker-compose for development. Thanks to [[https://github.com/Silex][Philippe Vaucher]] I can manage it from within Emacs.
For joining IRC channels I use ERC. For connecting with the network (using my ZNC bouncer) I would like to just press a keybinding. Therefore I warp the call to =erc-tls= with the correct arguments in the following function (which is later bound to =C-c i j=).
#+begin_src emacs-lisp
(defun mmk2410/erc-connect ()
"Start a IRC session with ERC by connecting to my ZNC bouncer."
Now the configuration for ERC. Some stuff I found in the deepest depths of the internet. Worth mentioning is the [[https://www.emacswiki.org/emacs/ERC][EmacsWiki]] and the following two videos by David Wilson on the [[https://www.youtube.com/c/SystemCrafters][System Crafters YouTube channel]]: [[https://www.youtube.com/watch?v=qWHTZIYTA4s][Chat Like the 90's in Emacs with ERC]] and [[https://www.youtube.com/watch?v=Qci8t_jpVGA][System Crafters Live! - Improving the IRC Experience in ERC]].
Normally I use Firefox for browsing the web, but when I am working with full focus in Emacs I sometimes prefer eww. For example while reading a paper and taking notes on it. In this case I don't want to lose my focus while switching to a web browser (and potentially see some open tabs from another project).
In recent times I have gotten really bad search results on DuckDuckGo (either I can't search anymore or they really got worse). So I'm using Startpage at the moment.
More important for me while reading a paper is looking up some things on Wikipedia. So I defined -- additionally to a simple keybinding for eww itself -- a function and a keybinding for searching on the English Wikipedia.
Since now I used many different RSS feed solutions. I started with Feedly back in 2013/14, switched later to a self-hosted TinyTinyRSS and then to Nextcloud News. After some time using this solution, its many bugs annoyed me more and more and I finally switched to FreshRSS in early 2021. Since early October I'm trying Miniflux. Although I had no problems with FreshRSS the interface of Miniflux (especially on mobile) is IMO nicer (though a little bit more eye-candy would be nice).
Mostly I use Miniflux through its web app---on mobile and on the desktop as well. But I have used and liked elfeed in the past and so I keep it configured properly.
** elfeed package
This is the elfeed program itself.
As with email I prefer showing older entries first so I can catch-up with these first before getting to newer stuff. Other than the binding to =C-c e= there is nothing interesting left to see here.
*Currently I am not using this since I need the actual articles offline for reading in some situation and therefore currently rely on Pocket.*
I like to call myself quite an avid org-mode user and so I also want to store RSS articles I read with Elfeed in a reading list. Since from time to time I prefer to use my tablet or smartphone to read instead of sitting at the computer and it is a little bit cumbersome to use Emacs with Elfeed using Termux I prefer using the fantastic Orgzly app. The problem is now that I cannot just =org-store-link= in the org-capture template for Elfeed entries since this would store a link to the corresponding Elfeed entry. While I can open such links at my desktop I cannot in Orgzly. And also on desktop I most likely will open the article in my web browser instead of viewing just the RSS entry. Therefore it would be very practical if the capture template would not store a Elfeed link but directly the web link. Additionally would also like to store the Feed title as part of the note.
Therefore I need a org-capture template which fetches these functions. And since I can only get the Elfeed entry properties in the buffer with the entry I cannot just use the =%(EXP)= option alone but need a function that switches to the Elfeed buffer, gets the property and then inserts the value in the capture template. For this I wrote the following function which does exactly this (thanks to [[https://emacs.stackexchange.com/a/55268][RichieHH]] who put me on the right track).
=elfeed-protocol= is a addition to Elfeed which enables the usage of some cloud RSS services (e.g. Nextcloud News, TT-RSS).
I currently use it in combination with my Miniflux instance (previously I used it with Nextcloud News and FreshRSS). The reason why I not only use elfeed with a local feed list (managed for example by elfeed-org) is that a cloud service can check for new feed articles continuously and I can read articles on any device.
Managing e-mails is maybe one of the most critical tasks in my life. Over the last years I tried countless different clients, including the famous (neo)mutt, KMail, and Thunderbird. But it seems that I always go back to one specific: mu4e. Maybe because it is integrated in Emacs and Org-mode, maybe because I like using a keyboard-focused client and that's where I end. I don't now. But what I know is: I enjoy using it!
Not all systems that I use have mu/mu4e installed. Either because I cannot really use it at work or because I'm running a native Windows instance or because I didn't completely setup the machine. Therefore I only load/execute the complete mu4e configuration if Emacs can find a =mu= executable.
Not all distributions that I use have a enough up-to-date package of mu/maildir-utils in their repositories. Therefore on some system I compile and install it myself which ends in =/usr/local= instead of just =/usr.= Therefore I have a small function that finds the correct load-path for the mu4e package.
Using the determined load path I now load mu4e itself and bind it to a handy keybinding. Since I don't close the parenthesis of the ~use-package~ everything that follows this source code blocks is part of the config section.
:config ;; final closing parens at th end of the file
#+end_src
Once it is loaded I'd like to set mu4e as my default mail program in Emacs.
#+begin_src emacs-lisp
(setq mail-user-agent 'mu4e-user-agent)
#+end_src
** Fetching new mail
I use mbsync for synchronising my messages and prefer that I can trigger the refresh from mu4e. Normally I use a [[https://git.mmk2410.org/mmk2410/dotfiles/src/branch/main/systemd][SystemD user service and timer]] for running mbsync every five minutes.
Apparently mbsync requires a filename change, when moving mails.
#+begin_src emacs-lisp
(setq mu4e-get-mail-command "mbsync -a"
mu4e-change-filenames-when-moving t)
#+end_src
** Header view customizations
I'd like to use the IS-8601 date format.
#+begin_src emacs-lisp
(setq mu4e-headers-date-format "%Y-%m-%d %H:%M")
#+end_src
For settings my header fields, I want to define a custom header field, which shows just an excerpt of my maildir path. My paths -- created by mbsync -- begin with the account name, which I want to shorten to just one letter. Since I archive my mail but let mu4e show me related mails, I want also to shorten the "Archive" path to "A". So the maildir path my be a short as e.g "m/INBOX" or "m/A".
I want to use the IMO improved =:from-or-to= header field instead of only a =:from=. Next to that I prefer to show the subject in a thread only once for a cleaner overview.
#+begin_src emacs-lisp
(setq mu4e-headers-fields
'((:human-date . 16)
(:flags . 4)
(:mdir . 12)
(:mailing-list . 10)
(:from-or-to . 22)
(:thread-subject)))
#+end_src
Additionally I prefer to change the sorting directory so that older messages are displayed on top. Since I try to keep an empty inbox and either reply to mails instantly or create a todo from them handling "old" mails should one the one hand be rare and on the other hand much more urgent. Actually I want them to distract and annoy me so that I handle them sooner than later.
#+begin_src emacs-lisp
(setq mu4e-headers-sort-direction 'ascending)
#+end_src
As already said, I like to archive my mail and have as few mailboxes as possible. Since I get some mails over different addresses and in different mailboxes mu4e displays only one and doesn't show the duplicate. So when I mark the message I see for archiving and refresh the list while applying the mark the then hidden duplicate is now shown and I have to mark that again for archiving. Since the mailbox is shown I also can tell which one to archive if necessary. That is why I disable the skipping of duplicates:
#+begin_src emacs-lisp
(setq mu4e-headers-skip-duplicates nil)
#+end_src
** Message view customizations
By default mu4e jumps to the next message when pressing =SPC= at the end of a message. I explicitly do not want that behavior.
#+begin_src emacs-lisp
(setq mu4e-view-scroll-to-next nil)
#+end_src
I like to keep my Downloads folder quite empy and also download everything that I don't intent to keep to =/tmp=.
#+begin_src emacs-lisp
(setq mu4e-attachment-dir "/tmp")
#+end_src
The mu4e manual says, that viewing inline images may be not always correct. Let's try it anyway and find out how bad it really is. Additionally it is recommended, that =imagemagick-register-types= is called.
#+begin_src emacs-lisp
(setq mu4e-view-show-images t)
(when (fboundp 'imagemagick-register-types)
(imagemagick-register-types))
#+end_src
I like to see the complete addresses and not just the name.
#+begin_src emacs-lisp
(setq mu4e-view-show-addresses t)
#+end_src
** Compose messages
I prefer to BCC myself in mail so I now that a message was handled by the mail server and thereby I can also put all mails of a thread in the same folder which makes searching a bit easier. So I let mu4e automatically set the BCC header when I start to compose a message.
Since I already have a msmtp client configured and would also use it in case I would use mutt, I want to use it also in mu4e. Setting msmtp as default SMTP client is quite easy but is it a little bit harder to set the account that should be used for sending. Therefore I wrote a lambda function that chooses the account and passes it as extra arguments based on the senders email address.
I don't really like the default bookmarks that mu4e sets. Thats why I overwrite the =mu4e-bookmarks= variable completely instead of just appending new bookmarks.
The [[https://github.com/org-mime/org-mime][org-mime]] package thankfully allows sending HTML mails from mu4e. Not that I like HTML mails but I need to have a special HTML message signature for work.
Mu4e displays a message in the minibuffer after refreshing. And since I run mbsync and mu index (through emacsclient) automatically every few minutes these messages can get quite distracting. Luckily mu4e provides an option to disable these index messages.
#+begin_src emacs-lisp
(setq mu4e-hide-index-messages t)
#+end_src
Mu4e show its current search in the modeline and as you may have already noticed, my default searches tend to be large. So I increase the shown characters from 30 to 60.
#+begin_src emacs-lisp
(setq mu4e-modeline-max-width 60)
#+end_src
It is maybe not surprising that I am subscribed to some mailing lists. Some of these have quite some long names and so I would like to use a some alias for the display of these names. Thanks god mu4e also provides a possibility for this!
Since my work place is using Microsoft Outlook for Email including its appointment features I sadly needed to switch away from mu4e to Evolution, as recommended by [[https://karl-voit.at/2021/06/01/Thunderbird-to-Evolution/][Karl Voit]]. Using [[https://github.com/novoid/dot-emacs/blob/master/config.org][his configuration]] as an inspiration and source I could setup the following workflow.
Since version 27 Emacs features a tab bar. In contrast to e.g. a browser a tab does not display just one file/buffer/window but an Emacs tab features an entire window configuration. Since I use Emacs not just for programming but (perhaps even mainly) for personal information management (including mail, agenda, journal, IRC and RSS) I had the idea to have one Emacs frame open with different tabs for all these things. Therefore I wrote a small package found in =packages/mmk2410-tab-bar-helpers.el= which I explain in a [[https://mmk2410.org/2022/02/11/using-emacs-tab-bar-mode/][dedicated blog post]].