| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
Three defects in the saved-location store: removal shifted the slot vector but never freed the dropped register, and a later store allocated by next-index — a char a surviving slot still held — so it silently overwrote that slot's marker. jumper--with-marker-at also guarded only markerp, so a location whose buffer was killed made store and jump signal wrong-type errors. And the single-location toggle never returned: its already-there branch did nothing. Store now takes the first unused register char in the live slice, removal clears the freed register so its marker stops pinning the buffer, the marker guard checks buffer liveness so dead entries are skipped, and the toggle jumps to the last-location register when one is set.
|
| | |
|
| |
|
|
| |
simplecov reports absolute source paths while git diff emits repo-relative ones, so cj/--coverage-intersect joined them by exact key and matched nothing — every changed file read ":tracked nil" under the working-tree, staged, and branch scopes (whole-project worked only because both sides came from the same simplecov source). A new cj/--coverage-relativize-keys normalizes both tables to repo-relative in cj/--coverage-read-and-display before the intersect; the intersect stays pure. Covered by 5 unit tests plus an integration test that drives the real parsers with an absolute-key report and a relative-key diff.
|
| | |
|
| | |
|
| |
|
|
| |
A single-instance Dirvish popup frame (named "dirvish") for a Hyprland Super+F launcher, mirroring the org-capture popup. q closes the frame; in the popup, RET opens files through the OS handler so they launch independently, and the frame dismisses itself on focus loss. A second launch reuses the open popup instead of spawning another frame.
|
| | |
|
| |
|
|
| |
vterm-to-ghostel)
|
| | |
|
| |
|
|
| |
A reference for the native-comp + subr-mocking trap: the mechanism, the three failure modes, the research with URLs, and the decision (variadic mocks + a meta-test now, migrate off primitive-mocking long-term). Refines the CLAUDE.md codified insight, whose old 'don't mock subrs' framing was too broad, and points it at the new doc.
|
| |
|
|
|
|
|
|
| |
Re-enabling native-comp surfaced a suite-wide fragility. When a test redefines a C primitive (or a native-compiled function), native-comp routes native callers through a trampoline that calls the mock with the primitive's maximum arity. A fixed-arity mock narrower than the primitive then throws wrong-number-of-arguments, intermittently, as the eln-cache fills.
I swept every arity-narrow subr mock to append &rest _ (188 sites, preserving any named args the body uses), and added tests/test-meta-subr-mock-arity.el, which fails make test on any subr mock too narrow for the primitive's arity. The rule isn't "never mock a subr". The suite mocks message and completing-read freely. It's "a subr mock must accept the primitive's arity."
Background, the three failure modes, and the research are in docs/native-comp-subr-mocking.org.
|
| |
|
|
|
|
|
|
| |
The previous deferral (03d8b587) autoloaded malyon to games-config, but games-config doesn't define malyon. It leaves the command to the malyon package, so M-x malyon loaded games-config, found malyon still undefined, and errored "Autoloading games-config.el failed to define function malyon". Emacs won't chain through a second autoload.
malyon and 2048-game autoload their own commands via package.el, so games-config should never own them. init.el now loads games-config via (with-eval-after-load 'malyon ...), and games-config just sets malyon-stories-directory when malyon loads. M-x malyon loads the package as a real command, then games-config applies its config.
The earlier batch check loaded the files by hand and missed the autoload failure. The new test resolves the autoload the way M-x does (autoload-do-load), so the real path is covered now.
|
| | |
|
| |
|
|
|
|
| |
init.el eagerly required games-config at startup just to configure two on-demand game packages. package.el already autoloads malyon and 2048-game, so the eager require bought nothing but the one setting the module adds (malyon-stories-directory).
init.el now autoloads malyon and 2048-game to games-config instead of requiring it. The first game command loads the module, which configures then loads the package. Startup no longer touches games-config, and both the commands and the stories-directory setting still work. This is the first module of the Phase 4 low-risk batch.
|
| | |
|
| |
|
|
|
|
| |
erc-yank turned a paste over 5 lines in an ERC buffer into a public gist: it called gist -P (the clipboard paste flag) with no --private, behind only a single y-or-n-p and with no guard if the gist binary was missing. One reflexive keystroke published whatever sat on the system clipboard. It also gisted the clipboard rather than the kill-ring text being yanked.
I dropped the package. erc-mode-map binds no C-y of its own, so C-y now falls through to the ordinary global yank and a paste stays local. Gist a large snippet by hand when that's actually wanted.
|
| | |
|
| |
|
|
|
|
|
|
| |
early-init.el disabled JIT native compilation with (setq native-comp-deferred-compilation nil), the obsolete alias of native-comp-jit-compilation. Despite the comment, setting it nil turns JIT off entirely rather than making it synchronous. Most modules then ran interpreted for the daemon's lifetime, and the native-comp-speed/jobs settings in system-defaults.el were dead. The "Selecting deleted buffer" async race that prompted the disable was an Emacs 28/29 issue. This is 30.2. I re-enabled it with native-comp-jit-compilation t and silent async warnings.
GC was pinned at the stock 800KB: early-init restored it post-startup and the minibuffer setup/exit hooks bounced back to it. That's Emacs's bare-editor default, far too low for 184 packages, so GC pauses fired often during completion, agenda, and LSP/AI work. I replaced both hand-rolled mechanisms with gcmh, which keeps the threshold at 1GB during activity and collects on idle.
Verified a clean full launch in a throwaway daemon (JIT on, gcmh active, no backtrace) and gcmh's threshold cycle in batch.
|
| |
|
|
| |
The s-F9 commit moved server-shutdown off C-<f10> to C-x C and dropped C-<f10> from the ghostel keymap-exceptions. The regression test still asserted C-<f10> was present, so the full suite went red. I updated it to assert <f10> (music) stays an exception and C-<f10> is now absent, since C-x C deliberately forwards to the terminal program inside an agent buffer.
|
| |
|
|
|
|
|
|
| |
A resolved VERIFY at level 2 was rewritten to a dated org header (** 2026-... <desc>), following the old "VERIFY dates at all depths" rule. Dated headers at level 2 fall through every tool that keys on the keyword: --archive-done never moves them, task-review never selects them, and they pile up in Open Work.
The rule is now depth-split, matching ordinary tasks. VERIFY dates only at level 3 and deeper. At level 2 it closes with a DONE/CANCELLED keyword plus a CLOSED line, the answer in the body.
I fixed the two existing violations (the Dirvish d/D and C-; b pull-away VERIFYs, reverted from dated ** headers to ** DONE), and closed the two F9 GUI manual-test VERIFYs after confirming them.
|
| |
|
|
|
|
| |
s-F9 (cj/ai-term-next) steps through the open agent buffers in name order. It's the "switch among existing agents" surface F9's toggle never provided. The cycle logic lives in a pure helper (cj/--ai-term-next-agent-buffer) with Normal/Boundary/Error coverage. The command is a thin window-mutating wrapper.
I dropped the C-S-F9 close alias, leaving M-F9 as the sole close binding. I moved cj/server-shutdown off C-<f10> to C-x C so the key keeps forwarding to the terminal program inside an agent buffer. I also removed the now-unused F10 entries from term-config's ghostel exceptions.
|
| |
|
|
|
|
|
|
|
| |
program
- erc-yank public-gist privacy trap regraded [#B] → [#A], tagged :quick:solo:
- merged the unified-popup-policy and messenger-unification tasks into one [#A] task
- refactoring program marked DONE (item-8 plan() factory consciously skipped)
- stamped LAST_REVIEWED on the reviewed tasks
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
withSavedState
Seven gates (locktest, mocktest, gallerytest, safetest, ndtest, viewlocktest,
expandpersisttest) mutated PALETTE/MAP/SYNTAX/UIMAP/PKGMAP/LOCKED and restored
nothing, so opening the studio at one of those #hashes left its state corrupted
for interactive use. Wrap each in withSavedState(keys, body), scoped to the keys
that gate touches: snapshot the named globals, run the body, restore in a finally.
Uses a JSON-round-trip clone (the studio objects carry values structuredClone
throws on — the same clone the gates' own local saves use). The 14 gates that
already restore locally are left as-is. Verified: all 44 gates green, the restore
round-trip holds for reassignment + in-place + Set mutation, and a forced
assertion in a wrapped gate still reports FAIL.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The 38 standard gates each repeated the same ok flag, notes list, A(cond,note)
collector, and verdict postamble (title + result div), with the note separator
drifted across them (' | ' vs ' fails='). gate(id, body) owns all of it and
standardizes the note format to ' fails=note1,note2'; the gate name is the hash
uppercased, the div id is the hash, matching what each gate set by hand. Each
call site keeps its literal location.hash==='#NAMEtest' (run-tests.sh greps that
to discover gates). Six custom gates (selftest, cursortest, planetest, oklchtest,
readouttest, savetest) stay inline. Verified: all 44 gates green, and a forced
A(false) in a converted gate still reports FAIL (gate() can't manufacture greens).
|
| |
|
|
| |
harness rewrite
|
| |
|
|
|
|
|
|
|
|
|
| |
The #mdtest, #mupreviewtest, and #gnustest browser gates each copy-pasted the
same preview-face validation: render the preview, assert it exercises enough
data-faces, that every data-face is real for the package, and that the required
faces are present. Lift that into one assertPreviewFaces(A, html, faces, min,
name, required) helper. Each gate keeps its literal location.hash==='#NAMEtest'
check (run-tests.sh greps that to discover gates) and its own title/result-div.
Verified: all 44 gates green, and a deliberately-broken required face still makes
its gate report FAIL (the helper can't manufacture greens).
|
| |
|
|
|
|
|
|
|
|
| |
Importing generate.py ran the full assembly at module load -- DEFAULTS, the
package inventory, palette/syntax/uimap construction, and the HTML fill -- so
face_coverage.py, which imports it only for UI_FACES, paid the whole cost. Move
that derivation into a cached _build(); expose the built attributes (HTML, MAP,
APPS, ...) lazily via PEP 562 __getattr__. UI_FACES/CATS/COLS and the file bodies
stay cheap module constants, the file write stays __main__-guarded, and the page
is byte-identical (check-generated current; test_generate green via __getattr__).
|
| |
|
|
|
|
|
|
|
| |
Two test-DRY cleanups. The seven near-identical test_page_carries_*_verbatim
methods in test_generate.py collapse into one subTest loop over the inlined-body
names. The strip-exports helper -- reimplemented three times across the colormath,
app-core, and app-util inline-integrity tests, each annotated 'same strip
generate.py applies' -- moves to one shared inline-strip.mjs (stripInlinedBody),
so the three copies can no longer drift from generate.py's strip_exports.
|
| |
|
|
|
|
|
|
| |
dropdownRowTextColor was exported and unit-tested but had no runtime caller: it
computed text color for a vertical-list dropdown row, a UI replaced by the swatch
gallery popup (colored buttons, no per-row text), so its regression rationale is
moot. Remove the function, its export, and its four tests; regenerate the page
(theme-studio.html staged so check-generated stays green).
|
| |
|
|
|
|
|
|
|
| |
condition_matches encoded the same four display-condition rules twice -- once
for the dict spec shape, once for the list-of-clauses shape. Normalize both to a
single {key: values} mapping and run the rules once in _condition_clauses_pass.
Verified byte-identical over 31 representative conditions (dict, list, scalar,
and malformed). The pre-existing Pyright complaints in choose_gui_light are
unrelated and untouched.
|
| |
|
|
|
|
|
| |
bucket_from_source and bucket_of_source each re-derived the elpa/user/builtin/
other origin of a defface path. Lift that into one path_kind(path) classifier;
both functions now map its result to their own vocabulary. Verified byte-identical
bucket output over a representative path set before and after.
|
| |
|
|
|
|
|
|
|
| |
Three near-identical skeletons folded together: the simple divider becomes the
padded divider with zero text padding; the plain box and the heavy box share one
border/text/border emitter (cj/--comment-box-emit) with a HEAVY flag adding the
interior blank lines; and the repeated cmt-start/doubled-semicolon/space line
prologue becomes cj/--comment-emit-prefix. Output is byte-identical -- the
per-generator characterization suites stay green -- and the file drops ~65 lines.
|
| |
|
|
|
|
|
|
|
|
| |
Lift the command-string construction out of three :config commands whose
templates branch — video-trim (Beginning/End/Both), tar-gzip (single vs multi),
text-to-speech (darwin say vs espeak) — into top-level pure builders
cj/dwim-shell--video-trim-command / --tar-gzip-command / --text-to-speech-command,
leaving thin interactive wrappers that prompt and delegate. The builders are now
testable under make test (the :config defuns aren't), mirroring the existing
dated-backup/zip-single builders. Adds 8 Normal/Boundary/Error tests.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In a layout where the agent had its own split window (e.g. code on top, a
working window, and the agent below), toggling the agent off deleted its
window correctly, but toggling back on reused the working window at the edge
-- displacing its buffer and collapsing three windows to two. The slot-reuse
that avoids a third window on a fresh show was firing on a re-show after the
agent's own window was already deleted.
Flag the toggle-off that deletes the agent's own window; on the next
toggle-on, reuse-edge-window consumes the flag and falls through to a fresh
re-split, so the agent returns to its own window and the other windows are
untouched. The flag only changes the 3+ window case -- after a delete in a
2-window slot-reuse layout one window remains, where re-split and reuse-edge
already coincide, so the existing reuse-edge tests are unaffected.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The F9 toggle captured the agent window's body-height and replayed it as
body-lines. Body-height subtracts the mode line's pixel height, which differs
between an active and an inactive mode line; the agent is captured active but
redisplayed inactive, so under a theme whose mode-line-inactive is shorter than
a text line the window lost ~1 line per toggle.
Capture and replay total-height for the vertical axis instead, via the renamed
cj/window-replay-size. Total-height is identical active or inactive and has no
mode-line-pixel dependence, so the round-trip is a fixed point. Width keeps
body-width (total-width has the position-dependent divider problem that total-
height does not). The shared lib fix covers the F12 terminal toggle too.
The shrink only manifests in a GUI frame, so it is not reproducible in the
batch harness; the unit tests pin the new total-height contract.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Lift the three-branch capitalize-this-word predicate out of cj/title-case-region
into cj/--title-case-capitalize-word-p; the command now loops word boundaries and
delegates the decision, dropping its cyclomatic complexity. The 32-test
characterization suite is unchanged and green. The function is reindented from
tabs to the 2-space house style in the same pass, which accounts for the line
churn; no behavior change.
|
| |
|
|
|
|
|
| |
Lift the name-validate plus overwrite-prompt loop out of
cj/dired-create-playlist-from-marked into cj/--playlist-resolve-target, leaving
the command a flat filter -> resolve -> write. Add Normal/Boundary/Error tests
for the new seam (real temp music-dir, stubbed prompts only).
|
| |
|
|
|
|
|
| |
Lift the 14-binding let* body out of calendar-sync--collect-recurrence-exceptions
into calendar-sync--parse-exception-event, which returns the exception plist (or
nil) for one VEVENT; the collector's dolist becomes a thin uid + puthash. Add
Normal/Boundary/Error tests for the new pure helper.
|
| |
|
|
|
|
|
| |
Lift the F9 toggle-off branch (~50 lines) out of cj/ai-term into
cj/--ai-term-toggle-off, leaving the pcase arm a one-liner. Fold the three
copies of the most-recent-non-agent-buffer swap idiom (two in the toggle-off
cases, one in cj/--ai-term-close-buffer) into cj/--ai-term-swap-to-working-buffer.
|
| |
|
|
|
|
|
| |
Lift the render-preserving-position block and the margin/fringe block out of
cj/nov-update-layout into cj/nov--rerender-preserving-position and
cj/nov--center-in-window, dropping its nesting. Fold the thrice-repeated
#E8DCC0 sepia literal in cj/nov-apply-preferences into one local binding.
|
| |
|
|
| |
New foregrounds plus italic slant on orderless-match-face-0..3; source flips default to user.
|
| | |
|
| |
|
|
| |
cj/youtube-to-elfeed-feed-format hand-decoded an og:title with six sequential replace-regexp-in-string calls; extract cj/--decode-html-entities (alist-driven, & first) and call it. Also remove the leftover DEBUG cj/log-silently instrumentation from cj/extract-stream-url. Behavior unchanged; adds coverage of the decoder.
|
| |
|
|
| |
prog-webdev carried cj/--webdev-format-region, a third byte-identical copy of the format-region helper already extracted to system-lib in the prog-json/prog-yaml dedup. Drop it and call cj/format-region-with-program (system-lib is already required). Behavior unchanged; the existing format tests cover it.
|
| |
|
|
| |
cj/deadgrep-here and cj/deadgrep-in-dir repeated the same normalize-directory + read-term + invoke-deadgrep tail. Lift cj/deadgrep--initial-term out of :config and add cj/--deadgrep-run for the shared tail; each command resolves its root then delegates. Adds coverage for the term seeding and the run helper.
|