<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/keyboard-compat.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-24T21:13:01+00:00</updated>
<entry>
<title>docs(load-graph): seed module inventory and annotate foundation headers</title>
<updated>2026-05-24T21:13:01+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T21:13:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=2d83f8f55977dbf69f4f80e490ed0b96aeea4eee'/>
<id>urn:sha1:2d83f8f55977dbf69f4f80e490ed0b96aeea4eee</id>
<content type='text'>
I started the init.el load-graph classification with the foundation batch. I added docs/design/module-inventory.org as the living per-module inventory and annotated the seven foundation modules (system-lib, user-constants, host-environment, system-defaults, keyboard-compat, keybindings, config-utilities) with the load-graph header contract: layer, category, load shape, eager reason, top-level side effects, runtime requires, and direct-test-load safety.

I changed no load order, so init.el keeps its current eager order. The inventory records one hidden dependency for Phase 2: system-defaults uses host-environment and user-constants symbols at load while declaring them eval-when-compile, so the compiled module cannot load standalone.
</content>
</entry>
<entry>
<title>refactor(prog): six programming-track hygiene fixes from re-review</title>
<updated>2026-05-16T08:55:49+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T08:55:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=d84aa4374af5e3447445377a836c66cc07d7a223'/>
<id>urn:sha1:d84aa4374af5e3447445377a836c66cc07d7a223</id>
<content type='text'>
- prog-lsp.el: rename `cj/lsp--remove-eldoc-provider' →
  `cj/lsp--remove-eldoc-provider-global' and call it once from the
  lsp-mode `:config' block instead of attaching it per-buffer via
  `lsp-managed-mode-hook'.  The previous per-buffer remove with the
  buffer-local flag raced lsp-mode's own population of the local
  hook; removing the provider from the global default before any LSP
  buffer attaches makes the absence stick.  Two existing tests
  updated to the new contract (remove-from-default + idempotent
  re-run).

- prog-webdev.el / prog-python.el: warn at load time when
  `prettier' or `pyright' is missing on PATH via
  `cj/executable-find-or-warn'.  Both modules now `(require
  'system-lib)' to expose the helper.  Missing dependencies surface
  up front instead of mid-edit at first format/LSP attach.

- keyboard-compat.el: document existing idempotence.  The hook
  install uses a named function so `add-hook' deduplicates, and the
  hook body only calls `define-key' (latest binding wins, same
  value) -- adding a comment so future readers don't re-question.

- dev-fkeys.el: add a `typescript' clause to
  `cj/--f6-test-runner-cmd-for'.  F6 now runs `npx --no-install
  vitest &lt;path&gt;' when vitest is on PATH, otherwise `npx --no-install
  jest &lt;path&gt;'.  Updates the matching test from "returns nil" to
  cover both code paths; the impl-level test now asserts the routed
  command instead of expecting a user-error.

- flycheck-config.el: build the LanguageTool wrapper path with
  `(expand-file-name "scripts/languagetool-flycheck"
  user-emacs-directory)' instead of a hardcoded `~/.emacs.d/...'.
  Survives a non-standard `user-emacs-directory'.

- latex-config.el: replace the hardcoded Zathura viewer with
  `cj/--latex-select-pdf-viewer', which walks
  `cj/--latex-pdf-viewer-candidates' (zathura → evince → okular →
  SumatraPDF → xdg-open) and falls back to "PDF Tools" when nothing
  is on PATH.  Each entry maps an executable to the matching
  TeX-view-program-list name so AUCTeX's defaults handle the
  actual viewer invocation.
</content>
</entry>
<entry>
<title>refactor(ui-navigation): drop redundant M-S-s window-swap binding</title>
<updated>2026-05-08T00:25:22+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-08T00:25:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=93b033a313c5a7ad56293c192ef69b567d344178'/>
<id>urn:sha1:93b033a313c5a7ad56293c192ef69b567d344178</id>
<content type='text'>
`window-swap-states` on M-S-s overlapped with `buffer-move` (C-M-arrows), which I actually use. I cleared the binding plus the M-S -&gt; M-S-s translation in keyboard-compat.el so the keyboard table stays in sync.
</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>fix(keyboard): support daemon mode for M-S- key translations</title>
<updated>2026-02-09T22:11:42+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-09T22:11:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1361215c177bb8b230d470badfc51d3499f414f5'/>
<id>urn:sha1:1361215c177bb8b230d470badfc51d3499f414f5</id>
<content type='text'>
GUI key translations (M-O → M-S-o, etc.) were never installed in daemon
mode because env-gui-p returns nil at startup with no frame. Use
server-after-make-frame-hook for daemon, emacs-startup-hook otherwise.
Also adds timestamps to assemblyai-transcribe output.
</content>
</entry>
<entry>
<title>feat(keyboard): add GUI key translation for M-S- bindings</title>
<updated>2026-02-02T14:34:36+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-02T14:34:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=7de7885ba13e616eb796de77cb2cf44a37884402'/>
<id>urn:sha1:7de7885ba13e616eb796de77cb2cf44a37884402</id>
<content type='text'>
Rename terminal-compat.el to keyboard-compat.el and add GUI support.

Problem: M-S-o and other Meta+Shift bindings didn't work in GUI mode.
GUI Emacs receives M-O (uppercase) but bindings use M-S-o syntax.
Terminal can't use M-O due to arrow key escape sequence conflicts.

Solution: Use key-translation-map in GUI mode to translate M-O -&gt; M-S-o
for all 18 Meta+Shift keybindings. Terminal fixes unchanged.

Also fix two test issues:
- Remove expected-fail from expand-weekly test (timezone fix resolved it)
- Add helpful install messages to dependency-checking tests
</content>
</entry>
</feed>
