<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/tests/test-dev-fkeys--f6-test-runner-cmd-for.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-16T08:55:49+00:00</updated>
<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>fix: shell-quote F6 test-runner command arguments</title>
<updated>2026-05-04T00:44:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-04T00:44:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=59094e944b4a9e8c5e1a20724c2681ffe9b6155c'/>
<id>urn:sha1:59094e944b4a9e8c5e1a20724c2681ffe9b6155c</id>
<content type='text'>
`cj/--f6-test-runner-cmd-for` was building shell command strings with raw paths and stems via `format`. For ordinary names (`tests/test_foo.py`, `pkg/foo`) that worked fine. But a path with spaces or a stem with shell metacharacters would break or misbehave once the string hit `compile`. A Python test file under `dir with spaces/` would get tokenized as separate arguments.

I added `cj/--f6-shell-quote-argument` that escapes only when the argument doesn't match `cj/--f6-shell-safe-argument-regexp` (alphanumerics, slash, dot, dash, plus a small handful of safe punctuation). Ordinary paths skip the quoter and stay readable. Risky paths route through `shell-quote-argument`.

I wrapped the four interpolations in the test-runner builder: the elisp `FILE=` basename, the elisp `TEST=^test-stem-` regex, both pytest paths, and the Go `./rel-dir`. The Go branch also handles an empty rel-dir explicitly so the result stays `go test ./` instead of constructing `./` via format with an empty string.

I added three boundary tests: a Python path with spaces, an elisp stem with `;`, and a Go directory with spaces. Existing tests for ordinary paths continue to pass since the safe regex covers them.
</content>
</entry>
<entry>
<title>fix(dev-fkeys): F6 elisp runner uses basename, not rel-path</title>
<updated>2026-05-03T22:39:10+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-03T22:39:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=0c085f2935418f365f6abd39ce008909dc13ed3c'/>
<id>urn:sha1:0c085f2935418f365f6abd39ce008909dc13ed3c</id>
<content type='text'>
I shipped Phase 2a with `cj/--f6-test-runner-cmd-for' building `make test-file FILE=&lt;rel-path&gt;' for elisp test files (e.g., FILE=tests/test-foo.el). The project Makefile prepends `tests/' to FILE itself, so the full invocation expands to `tests/tests/test-foo.el' and emacs reports "Cannot open load file". The bug surfaced on a live-test in step 7 of the Phase 2a smoke plan.

Fix: pass `(file-name-nondirectory rel-path)' so the Makefile gets just `test-foo.el' and re-prepends `tests/' itself.

Two unit tests in `test-dev-fkeys--f6-test-runner-cmd-for.el' had encoded the wrong expectation (the rel-path form). Two orchestrator tests in `test-dev-fkeys--f6-current-file-tests-impl.el' inherited the same wrong assertion via integration. Updated all four to assert the basename form.

Verified: full suite green, including the 4 updated tests. Live re-test on `tests/test-dev-fkeys--f6-language-detect.el' should now produce the working `make test-file FILE=test-dev-fkeys--f6-language-detect.el'.
</content>
</entry>
<entry>
<title>feat(dev-fkeys): add F6 test runner menu (Phase 2a)</title>
<updated>2026-05-03T22:20:54+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-03T22:20:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1d9d252e8b9e1385337cd0af087a7007f8e62da8'/>
<id>urn:sha1:1d9d252e8b9e1385337cd0af087a7007f8e62da8</id>
<content type='text'>
I extended `dev-fkeys.el` with the F6 dispatcher half of the spec. F6 prompts via `completing-read` between two candidates: "All tests" delegates to `projectile-test-project`, and "Current file's tests" detects the buffer's language by extension, derives the runner command, and pipes through `compile' from the projectile root. C-F6 is the fast path straight to "Current file's tests".

Per-language coverage:

- Elisp source files map to `make test-name TEST=^test-&lt;stem&gt;-`. Elisp test files run with `make test-file FILE=&lt;rel-path&gt;` so a per-helper file like `test-foo--bar.el' runs only its own tests.
- Python source files map to `pytest tests/test_&lt;stem&gt;.py'. Python test files run with `pytest &lt;rel-path&gt;'.
- Go runs the package containing the file: `go test ./&lt;rel-dir&gt;'. Source and test files use the same command since Go test scope is per-package. Limit: this runs every `_test.go' in the package, not just the buffer's file. Phase 2b can refine via test-name discovery.
- TypeScript and JavaScript are detected but punted for v1. The runner-command builder returns nil and the orchestrator signals a user-error rather than guessing.

The F6 binding moved from the Phase 1 stopgap (`projectile-test-project') to `cj/f6-test-runner'. C-F6 is newly bound to `cj/f6-current-file-tests'. M-F6 stays unbound, reserved for Phase 2b's "Run a test..." menu entry.

TDD: 68 new tests across 7 files. Production code split into small testable internals (`cj/--f6-language-detect', `cj/--f6-buffer-is-test-file-p', `cj/--f6-source-stem', `cj/--f6-test-runner-cmd-for', `cj/--f6-current-file-tests-impl') plus two thin interactive wrappers. Smoke tests confirm bindings register on load.

I also updated the module commentary with the Phase 2b plan, the capture-then-filter approach for tree-sitter discovery, and a pointer to Emacs bug #79687. The bug is the predicate-syntax mismatch that breaks `:match' / `:equal' / `:pred' queries on Emacs 30.2 with libtree-sitter 0.26. The fix lives on Emacs master (commit b0143530), targets Emacs 31, and has not been backported to the emacs-30 branch as of today. Phase 2b will use queries without predicates and filter results in Elisp, sidestepping the issue. Mike Olson's `treesit-predicate-rewrite.el' applies the same idea to font-lock if you want it before Phase 2b lands.
</content>
</entry>
</feed>
