mu4e module: bookmark duplicates on config reload
- Dominant language
- Emacs Lisp
- Stars
- 61
- Forks
- 37
- Avg merge
- 11h 19m
- Merged PRs (30d)
- 7
Description
### Describe your issue
The `+mu4e` module's bookmark entry accumulates duplicates on every Doom config reload (`doom/reload` or `SPC h r r`). After N reloads, "Flagged messages" appears N+1 times in the bookmark list.
#### Root Cause
Format mismatch between Doom's `add-to-list` and mu4e 1.14's `mu4e-bookmarks` variable.
**mu4e 1.14** defines `mu4e-bookmarks` as a `defcustom` using **plist format**:
```elisp
(defcustom mu4e-bookmarks
'(( :name "Unread messages"
:query "flag:unread AND NOT flag:trashed"
:key ?u)
...)
```
**Doom's module** (`modules/email/mu4e/config.el:180`) adds the bookmark in **old 3-element list format**:
```elisp
(add-to-list 'mu4e-bookmarks
'("flag:flagged" "Flagged messages" ?f) t)
```
`add-to-list` uses `equal` for comparison. Since `("flag:flagged" "Flagged messages" ?f)` (old format) is not `equal` to `(:name "Flagged messages" :query "flag:flagged" :key ?f)` (plist format), `add-to-list` fails to detect the existing entry and appends a duplicate.
On each config reload:
1. mu4e reinitializes `mu4e-bookmarks` to its defcustom default (plist format, no "Flagged messages")
2. Doom's `after!` block runs `add-to-list` → adds "Flagged messages" in old format
3. This accumulates if the variable isn't fully reset between reloads
Additionally, `mu4e-bookmark-define` (mu4e 1.14's new API) cannot remove old-format entries because it compares keys with `(plist-get bm :key)`, which returns `nil` on old-format lists.
#### Affected Code
`modules/email/mu4e/config.el:180-181`:
```elisp
(add-to-list 'mu4e-bookmarks
'("flag:flagged" "Flagged messages" ?f) t)
```
#### Suggested Fix
Replace with `mu4e-bookmark-define` (mu4e 1.14+):
```elisp
(mu4e-bookmark-define "flag:flagged" "Flagged messages" ?f)
```
Or if backward compatibility with mu4e < 1.14 is needed:
```elisp
(if (fboundp 'mu4e-bookmark-define)
(mu4e-bookmark-define "flag:flagged" "Flagged messages" ?f)
(add-to-list 'mu4e-bookmarks
'("flag:flagged" "Flagged messages" ?f) t))
```
#### Workaround
Add deduplication after bookmark definitions in user config:
```elisp
(setq mu4e-bookmarks
(cl-delete-duplicates mu4e-bookmarks
:key (lambda (bm) (cond ((keywordp (car bm)) (plist-get bm :key))
((listp bm) (nth 2 bm))
(t nil)))
:test #'=))
```
Note: `(listp bm)` alone is insufficient — plists are also lists, so `(nth 2 bm)` on `(:name ... :query ... :key ?f)` returns the keyword `:query`, causing `(wrong-type-argument number-or-marker-p :query)` with `:test #'=`. The `(keywordp (car bm))` check distinguishes plist from old format.
### Steps to reproduce
1. Add custom Bookmark(s) to config.el
2. Sync/reload emacs configuration
3. Open mu4e
### System information
[doominfo.txt](https://github.com/user-attachments/files/31872733/doominfo.txt)
- mu4e 1.14.2-pre1 (built from source)
### Disclosures
- [x] This issue was written with/by AI.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at modules/email/mu4e/config.el:180-181 and compare the current add-to-list call with mu4e 1.14's mu4e-bookmark-define API. Reload the Doom configuration repeatedly, then open mu4e and verify that "Flagged messages" appears only once; preserve the fallback behavior if older mu4e versions must remain supported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- emacs-lisp
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100