<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/tests/test-dev-fkeys--projectile-capture-cmd.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-04T02:32:09+00:00</updated>
<entry>
<title>test: re-point projectile revert tests at the decision helper</title>
<updated>2026-05-04T02:32:09+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-04T02:32:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=250db085bd2a2860636bb96c215dcbaa5efe91e9'/>
<id>urn:sha1:250db085bd2a2860636bb96c215dcbaa5efe91e9</id>
<content type='text'>
The legacy `cj/--projectile-revert-on-fail` wrapper and `cj/--projectile-revert-state` global were removed when the closure-based revert refactor landed (commit 2f8d898). The corresponding tests in `test-dev-fkeys--projectile-revert-on-fail.el` and the around-revert / capture-cmd files still referenced the legacy symbols, so 7 tests had been failing on `main` since that commit.

I re-pointed each test at `cj/--projectile-revert-state-on-fail`, the pure decision helper that the closure-based hook delegates to. Each test now passes the captured `state` plist as an explicit argument instead of binding the old global. Test names updated to match the new target.

I dropped two tests that no longer have a target. `revert-on-fail-clears-state` was specific to the wrapper clearing the global on completion, and there is no global to clear now. `revert-on-fail-removes-itself` was specific to the wrapper removing itself from `compilation-finish-functions`. The closure-based hook removes itself differently and is covered by the buffer-local hook tests in `test-dev-fkeys--projectile-around-revert.el`.

The around-revert and capture-cmd tests also lost their `cj/--projectile-revert-state nil` let-bindings since that variable no longer exists.

21 projectile-related tests pass together.
</content>
</entry>
<entry>
<title>fix: scope projectile cache revert state to each compile</title>
<updated>2026-05-04T02:11:26+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-04T02:11:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=31edc86a54d20c3c73d0ebad247fde2c35e6a964'/>
<id>urn:sha1:31edc86a54d20c3c73d0ebad247fde2c35e6a964</id>
<content type='text'>
The projectile compile/test/run cache-revert protection in `dev-fkeys.el` used a single global variable, `cj/--projectile-revert-state`. Two overlapping compiles could clobber each other's state. The second compile's capture would overwrite the first's. So when the first compile finished and ran the global finish-hook, it'd act on the wrong project's state, or revert nothing because the keys had drifted.

I moved the state into a closure. `cj/--projectile-capture-cmd` now returns the state plist instead of mutating the global. `cj/--projectile-around-revert` captures the state into a local, calls the projectile cmd-runner, and installs a one-shot buffer-local finish hook on the returned compilation buffer. The hook closes over its own state plist, so two compiles can finish in any order and each one acts on the right project.

I extracted three small helpers along the way. `cj/--projectile-revert-state-on-fail` is the pure decision (revert when failed AND modified AND prior was non-nil). `cj/--projectile-make-revert-on-fail-hook` builds the closure-based one-shot hook. `cj/--projectile-compilation-buffer` normalizes a buffer-or-process result from projectile into a buffer.

The legacy `cj/--projectile-revert-on-fail` function still reads the global `cj/--projectile-revert-state`. It stays around for the existing direct tests, but its core logic now delegates to the extracted state-on-fail helper. No production caller adds it to `compilation-finish-functions` anymore.

I added one regression test in `test-dev-fkeys--projectile-around-revert.el`: two projectile invocations on different projects, finishes triggered out of order, each compile reverts its own project's cache and leaves the other alone. The capture and around-advice tests were rewritten to match the new return-style API and to assert hooks land buffer-locally rather than globally. 19 projectile-related tests pass together.
</content>
</entry>
<entry>
<title>feat(dev-fkeys): revert projectile cache on failed-and-modified compile</title>
<updated>2026-05-03T23:25:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-03T23:25:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=475d6305e150c0a8ac61738eabe434c432acd991'/>
<id>urn:sha1:475d6305e150c0a8ac61738eabe434c432acd991</id>
<content type='text'>
Without this, a one-off typo at projectile's compile/test/run prompt poisons the per-project cache: every subsequent invocation pre-fills the broken value. I hit it during the Phase 2a live-test, where projectile's "All tests" prompt was replaying `go test ../.` and there was no clean way to get the prior known-good back.

Three pieces of machinery, all in `dev-fkeys.el`:

`cj/--projectile-capture-cmd' captures the current cached cmd at the project root before each invocation, stashing a plist with :map / :root / :prior in `cj/--projectile-revert-state'.

`cj/--projectile-revert-on-fail' is a `compilation-finish-functions' hook that reads that state. If the compile failed AND the cmd was modified from the captured prior value AND the prior was non-nil, it puts the prior back in projectile's cmd-map. Test-fails-because-of-real-bug (cmd unchanged through the run) leaves the cache alone. The hook self-removes on first invocation regardless of outcome and clears the state.

`cj/--projectile-around-revert' is the around-advice that wires the two together. I added the advice to all three projectile cmd-runners — `projectile-compile-project', `projectile-test-project', `projectile-run-project' — so the auto-revert applies whether the user invoked via F4 / F6 or directly via `M-x'.

Plus the manual escape-hatch: `cj/projectile-reset-cmds' clears compile/test/run cache for the current project. Bound to `C-; P' under the personal keymap. Use when projectile's auto-derived default was wrong from the start and you want to start fresh — the next F4 / F6 invocation re-derives projectile's project-type default.

TDD: 18 new tests across 4 files, one per helper. The around-advice tests build the capture/install/orig-fn flow against stub cmd-maps and verify state captured, hook installed, orig-fn invoked. The revert hook tests cover failure-and-modified (revert), success (leave alone), failure-but-unchanged (leave alone), nil prior (leave alone), nil state (no-op), and self-removal. The reset-cmds tests cover the all-three-maps clear, no-cached-entry no-op, and no-project user-error.
</content>
</entry>
</feed>
