<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/tests/test-org-webclipper-commands.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-25T22:51:17+00:00</updated>
<entry>
<title>fix(org): guard external-tool assumptions in export and publishing commands</title>
<updated>2026-05-25T22:51:17+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-25T22:51:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=d665582d6fc19c15a772c6ec24ff822e7e3c37f9'/>
<id>urn:sha1:d665582d6fc19c15a772c6ec24ff822e7e3c37f9</id>
<content type='text'>
Four export/publishing commands shelled out to external tools without checking they exist, so a missing tool surfaced as an opaque process error — or, for reveal.js, a silently broken presentation. I added a command-time guard to each that names the tool and what's needed:

- zathura, in the pandoc PDF export-and-open command
- the hugo binary and the platform file-manager opener, in hugo-config
- the local reveal.js checkout (run scripts/setup-reveal.sh), shared by the reveal export and preview commands
- pandoc, in the web-clip protocol handler

The checks run only when the command runs, so startup stays quiet. Each guard has a test asserting the user-error fires when the tool is absent, and the existing happy-path tests now stub the lookups so they exercise the real path rather than tripping the new guard.
</content>
</entry>
<entry>
<title>refactor(webclipper): scope clip URL/title to dynamic bindings</title>
<updated>2026-05-24T12:12:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T12:12:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=6dfc41af54551bf1fe13af6e1aae6e1e864060c0'/>
<id>urn:sha1:6dfc41af54551bf1fe13af6e1aae6e1e864060c0</id>
<content type='text'>
org-webclipper passed the org-protocol URL and title through globals cj/webclip-current-url / cj/webclip-current-title: the protocol handler setq them, and the "W" capture template plus its handler read them, with the handler clearing them afterward. An aborted or erroring capture left the stale values for the next clip.

Renamed them to cj/--webclip-url / cj/--webclip-title and let-bind them around the org-capture call in the protocol entry point instead of mutating globals. The template %(identity ...) forms and the handler run within that dynamic extent, so they see the values while the capture runs, and an abort/error unwinds the binding automatically — no stale state, no manual clear. This mirrors the quick-video-capture fix. Tests updated to the new contract: URL/title visible during the capture, nothing left bound after, and an aborted capture leaves no stale state.
</content>
</entry>
<entry>
<title>refactor(org-workflow): four hygiene fixes from the module-by-module re-review</title>
<updated>2026-05-16T08:45:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T08:45:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=a005c7636f30b710e27a6812ca989506d5df7531'/>
<id>urn:sha1:a005c7636f30b710e27a6812ca989506d5df7531</id>
<content type='text'>
- org-roam-config.el: extract `cj/--org-roam-should-copy-completed-task-p'
  and gate the `org-after-todo-state-change-hook' on it.  Skips
  fileless buffers (org-capture, indirect, temp Org) where
  `buffer-file-name' is nil and the downstream copy used to crash.
  Same gcal.org skip preserved.  Five existing tests updated to
  bind `buffer-file-name' inside `run-hooks' so the positive-case
  hook still fires.

- org-webclipper.el: drop the redundant
  `org-protocol-protocol-alist' registration inside
  `cj/webclipper-ensure-initialized'.  The
  `with-eval-after-load 'org-protocol' block at the bottom of the
  module is the single registration site now; comment in the
  initializer explains why.  Split the matching test into two:
  one for template registration (the initializer's actual job) and
  one for protocol registration (which now fires from the
  after-load block when `org-protocol' provides).

- org-webclipper.el: validate `:url' and `:title' in
  `cj/org-protocol-webclip'.  `:url' must be a non-empty string;
  `:title' must be a string when provided.  Signals `user-error'
  with the unexpected value instead of silently setting the
  globals to nil and failing downstream in the capture handler.

- mu4e-org-contacts-integration.el: declare `contacts-file' (via
  `eval-when-compile (defvar ...)') and `cj/get-all-contact-emails'
  (via `declare-function') near the top of the file.  Byte-compile
  in isolation no longer warns about free variables / unknown
  functions; the cross-module dependency is explicit at the top.
</content>
</entry>
<entry>
<title>test(org-webclipper): cover lazy init, protocol handler, EWW capture</title>
<updated>2026-05-14T08:37:11+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-14T08:37:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=34f5f0d946d1e394f9cda52d5cd5c0e2cf0243f0'/>
<id>urn:sha1:34f5f0d946d1e394f9cda52d5cd5c0e2cf0243f0</id>
<content type='text'>
Sibling `test-org-webclipper-process.el` covers the content-processing helper. This batch fills in the rest:

- `cj/webclipper-ensure-initialized`: registers the webclip protocol entry + the W and w capture templates on first call, is idempotent on subsequent calls.
- `cj/org-protocol-webclip`: stashes the url+title, triggers capture; missing title falls back to "Untitled".
- `cj/org-protocol-webclip-handler`: errors when no url stashed, returns processed org content on success (with the first heading stripped + subs demoted), wraps fetch failures in a "Failed to clip" error.
- `cj/org-webclipper-EWW`: routes through `org-eww-copy-for-org-mode` for eww-mode and `org-w3m-copy-for-org-mode` for w3m-mode; errors on any other source mode.

Top-level defvars for `org-protocol-protocol-alist`, `org-capture-templates`, and `webclipped-file` make let-bindings dynamic under lexical scope. org-web-tools and the eww/w3m copy commands are stubbed.
</content>
</entry>
</feed>
