<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/font-config.el, branch main</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-05-25T23:29:31+00:00</updated>
<entry>
<title>fix(font-config): theme-aware browser labels and daemon-safe emoji fontset</title>
<updated>2026-05-25T23:29:31+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-25T23:29:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=7ce43f29a754d68db5a3c8683f01e7f9698a32e8'/>
<id>urn:sha1:7ce43f29a754d68db5a3c8683f01e7f9698a32e8</id>
<content type='text'>
Two font-config robustness fixes. The font-browser (cj/display-available-fonts) hardcoded a "Light Blue" foreground for each family label, which goes nearly unreadable on a light theme. I switched it to font-lock-keyword-face so the label follows the theme's contrast, keeping it bold.

The emoji-fontset cond ran once at module load behind (env-gui-p). In daemon mode there's no GUI frame at load, so env-gui-p is nil and the fontset never gets set — a later emacsclient -c GUI frame then has no emoji font. I wrapped it in cj/setup-emoji-fontset (GUI-guarded, idempotent) and, mirroring how the fontaine preset is already applied, run it from server-after-make-frame-hook in daemon mode and directly otherwise. The daemon TTY-then-GUI path can't be exercised in batch, so I left a manual-test entry for it.
</content>
</entry>
<entry>
<title>docs(load-graph): classify UI and core-UX modules</title>
<updated>2026-05-24T21:28:07+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T21:28:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=e1789025131b048049777542a91fb7eb55195ce5'/>
<id>urn:sha1:e1789025131b048049777542a91fb7eb55195ce5</id>
<content type='text'>
Fourth classification batch: the modules that shape the first interactive frame — ui-config, ui-theme, ui-navigation, font-config, selection-framework, modeline-config, mousetrap-mode, popper-config, dashboard-config, nerd-icons-config. I annotated each header, added a Batch 4 table to the inventory, and extended the validation allowlist. 33 of 102 modules are now classified.

These mostly stay eager: each has a real first-frame reason (theme, font, modeline, completion stack, landing page). No new hidden dependencies. popper-config carries the spec's open question about its enabled/disabled state, noted for the deferral phase.
</content>
</entry>
<entry>
<title>chore(modules): pass validate-modules in batch by adding requires</title>
<updated>2026-05-08T00:25:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-08T00:25:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=a41ef9774f6550da446a3ae8fbbcbcd5bf6c23c4'/>
<id>urn:sha1:a41ef9774f6550da446a3ae8fbbcbcd5bf6c23c4</id>
<content type='text'>
`make validate-modules` had 19 module-load failures, all the same shape: a module references a symbol or feature owned by another module without saying so. Production was fine because init.el orders requires correctly. The batch target loads each module in isolation, though, and surfaces the gap.

I added explicit `(require 'keybindings)` or `(require 'user-constants)` to each affected module. The requires are idempotent at runtime, so production load order is unchanged. For three optional packages (elpa-mirror, mu4e, org-contacts), I switched to `(require 'X nil t)` so the modules load cleanly when those packages aren't installed. The activation calls become no-ops in that case.

`make validate-modules` now reports 0 failures.
</content>
</entry>
<entry>
<title>fix: restore daemon icons and consolidate nerd-icons setup</title>
<updated>2026-05-07T14:05:54+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-07T14:05:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=4ece1ebb4487d3e565642e45d586f97172fe97ce'/>
<id>urn:sha1:4ece1ebb4487d3e565642e45d586f97172fe97ce</id>
<content type='text'>
I replaced the load-time icon-stub block in keyboard-compat with per-call :around advice that checks display-graphic-p against the rendering frame. The old block ran at module-load. Under daemon startup no frame exists yet, so display-graphic-p returned nil and the empty-string stubs installed permanently. Every GUI client connecting to that daemon then saw blanks. The new shape lets one daemon serve real icons to GUI clients and blanks to terminal clients.

I also pulled the nerd-icons-completion and nerd-icons-ibuffer integrations, the package install, and a new tint helper into modules/nerd-icons-config.el. Per-feature use stays in the consuming module (dashboard, dirvish, keyboard-compat). The malformed cons-cell on the marginalia hook in selection-framework.el got fixed in the move.

Added a default darkgoldenrod tint, a :filter-return advice on nerd-icons-icon-for-dir so dir icons pick up a color face, and a buffer-local face-remap in dired-mode-hook so plain files in dired render in shadow grey.

13 tests across 3 new files cover the per-call gate, the dir-color helper (idempotent under nerd-icons' memoized return strings), and the bulk-tint helper.
</content>
</entry>
<entry>
<title>chore: stop emojifying org-mode buffers</title>
<updated>2026-05-04T05:02:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-04T04:58:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=31c913b26a9725595357f678e7197cc7efcd6c53'/>
<id>urn:sha1:31c913b26a9725595357f678e7197cc7efcd6c53</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs(font): sync font-config module header with current code</title>
<updated>2026-04-22T16:50:33+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-22T16:50:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=ae5fd59cb40f62cc850f8640d28b57632b8dd5e8'/>
<id>urn:sha1:ae5fd59cb40f62cc850f8640d28b57632b8dd5e8</id>
<content type='text'>
Several lines in the header were stale. The default preset is BerkeleyMono, not FiraCode, and the height is now machine-dependent (120 on laptops, 140 on desktops). The default preset's variable-pitch font is Lexend. Merriweather is only the fallback for unnamed presets. The fontaine preset keybinding is M-S-f, not M-F. The emoji bindings (C-c E i, C-c E l) weren't listed.
</content>
</entry>
<entry>
<title>feat(font): set default font height per machine</title>
<updated>2026-04-22T16:36:09+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-22T16:36:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=9896e7f5861beeb591ece48f38d1135ffdc6059b'/>
<id>urn:sha1:9896e7f5861beeb591ece48f38d1135ffdc6059b</id>
<content type='text'>
The default fontaine preset now picks its height based on `env-laptop-p`. Laptop: 120 (12pt). Desktop: 140 (14pt), matches foot's `size=14`. Text reads at the same size across Emacs and the terminal.

This reuses `env-laptop-p` from `host-environment.el` instead of adding a gitignored local override.
</content>
</entry>
<entry>
<title>style(font): set default and fallback font heights to 120</title>
<updated>2026-04-20T15:09:38+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-11T14:17:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=e0488054b2b83f3e989aefb5ccb01e942681a789'/>
<id>urn:sha1:e0488054b2b83f3e989aefb5ccb01e942681a789</id>
<content type='text'>
Default preset (BerkeleyMono) 140→120, fallback preset (FiraCode) 110→120.
</content>
</entry>
<entry>
<title>fix(font): prevent HarfBuzz SIGSEGV crash on emoji in mu4e headers</title>
<updated>2026-02-09T15:41:36+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-09T15:41:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c829a0a66c2c98fe634af2aa5d41bfc38c3608c0'/>
<id>urn:sha1:c829a0a66c2c98fe634af2aa5d41bfc38c3608c0</id>
<content type='text'>
Emacs 30.2 + HarfBuzz 12.3.2 segfaults when arabic-shape-gstring is
called on emoji characters during mu4e header rendering. Disable Arabic
composition ranges, set inhibit-compacting-font-caches, and disable
auto-composition in mu4e-headers-mode. Remove duplicate bidi settings
from system-defaults.el (already in early-init.el).
</content>
</entry>
<entry>
<title>style(font): increase default height to 140</title>
<updated>2026-02-01T07:44:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-01T07:44:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=8fb0460b70c245b33c766f93c82b9017dec39b8e'/>
<id>urn:sha1:8fb0460b70c245b33c766f93c82b9017dec39b8e</id>
<content type='text'>
Better readability at current display scaling.
</content>
</entry>
</feed>
