<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/external-open.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:26:06+00:00</updated>
<entry>
<title>docs(load-graph): classify core libraries and command modules</title>
<updated>2026-05-24T21:26:06+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T21:26:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=67d8040ad19461cf2a393af95268f92b784d7ece'/>
<id>urn:sha1:67d8040ad19461cf2a393af95268f92b784d7ece</id>
<content type='text'>
Third classification batch: the remaining core and library command modules from init.el's early block — external-open, media-utils, auth-config, keyboard-macros, system-utils, text-config, undead-buffers. I annotated each with the load-graph header contract, added a Batch 3 table to the inventory, and extended the validation allowlist. 23 of 102 modules are now classified.

No new hidden dependencies in this batch. auth-config stays eager because other modules need credentials early; the command libraries (external-open, media-utils, keyboard-macros) are eager only by init order and flagged as Phase 4 deferral candidates.
</content>
</entry>
<entry>
<title>refactor(custom-editing): five hygiene fixes from the module-by-module re-review</title>
<updated>2026-05-16T07:48:18+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T07:48:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=a9a4d8c7148c115a242a7b35d16dd536f9c0c700'/>
<id>urn:sha1:a9a4d8c7148c115a242a7b35d16dd536f9c0c700</id>
<content type='text'>
- Guard `cj/duplicate-line-or-region' when COMMENT is non-nil but the
  current mode has no `comment-start' (e.g. fundamental-mode).
  Previously the function silently produced malformed output via
  `comment-region'; now it signals a clear `user-error'.

- Factor the `find-file' advice install in external-open.el into
  `cj/external-open-install-advice'.  Same idempotent shape
  (remove-then-add) but the intent is named.

- Add `cj/--validate-decoration-char' in custom-comments.el and
  wire it into all six divider / border / box helpers.  Rejects
  multi-char strings, empty strings, and control characters like
  newline/tab that would corrupt subsequent `M-q' flows.  Updated
  the five nil-decoration ERT tests from `:type 'wrong-type-argument'
  (the old crash signal from `string-to-char' on nil) to
  `:type 'user-error', since the validator produces a clear
  message instead of a deep crash.

- Extract `cj/--require-spell-checker' in flyspell-and-abbrev.el.
  Both `cj/flyspell-toggle' and `cj/flyspell-then-abbrev' now call
  the shared helper; the checker list lives in
  `cj/--spell-checker-executables', so adding nuspell or any other
  checker is a one-line edit.

- Preserve trailing newlines in custom-ordering output.  Both
  `cj/--arrayify' and `cj/--unarrayify' now detect a trailing
  newline on the input region and re-append it to the result,
  matching the pattern custom-text-enclose.el already uses.
</content>
</entry>
<entry>
<title>refactor(external-open): extract external-open-lib for shared helpers</title>
<updated>2026-05-10T20:37:36+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-10T20:37:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=618bc7813b9acfcf1dfccc9c6590f6f5aece86cf'/>
<id>urn:sha1:618bc7813b9acfcf1dfccc9c6590f6f5aece86cf</id>
<content type='text'>
Same shared-helpers split-pattern that ai-vterm/vterm-config use
through cj-window-toggle-lib and that calendar-sync uses through
cj-org-text-lib.  Pull the two pure dispatch helpers out of the
external-open feature module into a sibling library so consumers
that only need the dispatch don't have to require the whole feature.

New `modules/external-open-lib.el' carries:
- `cj/external-open-command'
- `cj/external-open-launcher-p'

`modules/external-open.el' stays as the feature module: the
`default-open-extensions' defcustom, the `find-file' advice
(`cj/find-file-auto'), and the interactive commands (`cj/xdg-open',
`cj/open-this-file-with').  It now requires external-open-lib for
the dispatch helpers.

Migrate consumers:
- system-utils.el used to require `external-open' for
  `cj/external-open-launcher-p' alone -- now requires
  `external-open-lib' directly.
- dirvish-config.el calls `cj/external-open-command' from
  `cj/dirvish-open-file-manager-here' -- add an explicit
  `(require \='external-open-lib)'.

Test files renamed to match the system-lib naming pattern
(test-&lt;library&gt;-&lt;feature&gt;.el):
- test-external-open-command.el -&gt; test-external-open-lib-command.el
- test-external-open-launcher-p.el -&gt; test-external-open-lib-launcher-p.el

No behavior change.
</content>
</entry>
<entry>
<title>refactor(external-open): consolidate OS-open dispatch in external-open.el</title>
<updated>2026-05-10T19:42:04+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-10T19:42:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=16396d25c2795bd7f8822a695de111d07f588b26'/>
<id>urn:sha1:16396d25c2795bd7f8822a695de111d07f588b26</id>
<content type='text'>
Phase 4 of utility-consolidation. Three previously-overlapping helpers (system-utils' `cj/identify-external-open-command' and `cj/--open-with-is-launcher-p', plus the dirvish-only `cj/--file-manager-program-for' shipped earlier today) all answered "which OS-open program should I run?".  Pull the answer into one place: external-open.el.

Move and rename:

- `cj/--open-with-is-launcher-p' (system-utils) -&gt; `cj/external-open-launcher-p' (external-open). Public name now matches its module.
- `cj/identify-external-open-command' (system-utils) -&gt; `cj/external-open-command' (external-open). Returns nil for unsupported hosts instead of signaling -- callers that need a command must handle nil explicitly. The wrapper `cj/xdg-open' (also moved into external-open) converts nil to a `user-error' with a clear message, preserving the user-facing failure shape.
- Delete dirvish's `cj/--file-manager-program-for' helper. `cj/dirvish-open-file-manager-here' now calls `cj/external-open-command' directly. The shell-command fallback for nil-program preserves the previous escape hatch.

Break the system-utils &lt;-&gt; external-open recursive require by moving `cj/xdg-open' (the only system-utils function that external-open used) into external-open along with the dispatch.

Tests reorganized to match the move. Two new test files (`test-external-open-command.el', `test-external-open-launcher-p.el') replace the two system-utils-named test files. The dirvish file-manager-program test goes away with the helper. 11 tests covering Normal/Boundary/Error for the dispatch (plus the new "unsupported host returns nil" contract).

Add `(require \='external-open)' to system-utils.el and `(require \='system-lib)' to external-open.el (for `cj/file-from-context' which xdg-open uses).
</content>
</entry>
<entry>
<title>session: switch Python LSP to pyright, add Django web-mode config</title>
<updated>2026-03-04T07:52:45+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-03-04T07:52:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=956969442b83b2df4993b67d461c643bbf4e6670'/>
<id>urn:sha1:956969442b83b2df4993b67d461c643bbf4e6670</id>
<content type='text'>
Replaced pylsp with lsp-pyright in prog-python.el for better type inference,
especially for Django ORM. Added Django engine and indent settings to web-mode
in prog-webdev.el. Pyright already installed via pacman.
</content>
</entry>
<entry>
<title>feat(buffer): add open-with-default-app and open-with-program keybindings</title>
<updated>2026-02-25T18:07:12+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-25T18:07:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=e456e5c32984b4068a55910a3285231b22e700e2'/>
<id>urn:sha1:e456e5c32984b4068a55910a3285231b22e700e2</id>
<content type='text'>
Wire cj/xdg-open (C-; b o) and cj/open-this-file-with (C-; b O) into
the buffer keymap. Fix xdg-open fallback to try buffer-file-name before
dired context. Remove old C-c x o binding from external-open.
</content>
</entry>
<entry>
<title>feat:which-key: Add descriptive labels for custom keymaps</title>
<updated>2025-10-27T23:45:23+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-27T23:45:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=87034eab17625165b884128d8058c1158fc2f50f'/>
<id>urn:sha1:87034eab17625165b884128d8058c1158fc2f50f</id>
<content type='text'>
Enhance which-key integration by providing detailed descriptions for
new key bindings across multiple modules. This improves the
usability of custom keymaps by clarifying the purpose of each
keybinding, making it easier for users to navigate and understand
different menus and options available within the configuration.

This update ensures that all custom keymaps now display a
descriptive label in the which-key popup to explain their
functionality, aiding users in identifying keymap purposes promptly.
</content>
</entry>
<entry>
<title>refactor: external-open: Update key binding to use keymap-global-set</title>
<updated>2025-10-20T16:30:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-20T16:30:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=6486709e40a4a5fe1cf40e48f6ed327eff8420d5'/>
<id>urn:sha1:6486709e40a4a5fe1cf40e48f6ed327eff8420d5</id>
<content type='text'>
- Declare platform-specific functions for shell execution on Windows.
- Transition from `global-set-key` to `keymap-global-set` for improved clarity and consistency when binding the "C-c x o" shortcut.
</content>
</entry>
<entry>
<title>changing repositories</title>
<updated>2025-10-12T16:47:26+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-12T16:47:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=092304d9e0ccc37cc0ddaa9b136457e56a1cac20'/>
<id>urn:sha1:092304d9e0ccc37cc0ddaa9b136457e56a1cac20</id>
<content type='text'>
</content>
</entry>
</feed>
