aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* chore(todo): close the calendar-sync and video-audio split tasksCraig Jennings14 hours1-2/+4
| | | | | | Mark the two structural-refactor split tasks done as dated event-log entries: calendar-sync.el into ics/recurrence/org/source layers (54250d95) and video-audio-recording.el into devices + capture layers (c1227a36). The original task specs stay under each entry as the record. Claude-Session: https://claude.ai/code/session_014fyKMTTqLrZpL3rDF3dYc3
* refactor: split video-audio-recording.el into layered modulesCraig Jennings14 hours4-719/+754
| | | | | | | | | | | | | Break the 1025-line video-audio-recording.el into a thin public face plus two layered libraries, moving every function verbatim so behavior and public names are unchanged: - video-audio-recording-devices.el — base layer: PulseAudio source and sink discovery, the pactl output parsers, device labeling and sort/status helpers for completing-read, and the lookup predicates. Pure string and shell-query helpers with no dependency on recording state, config, or the engine. This is the heavily-tested core. - video-audio-recording-capture.el — engine: ffmpeg/wf-recorder command construction, the recording process lifecycle (sentinel, producer-first shutdown, exit polling), the modeline indicator, dependency checks, device acquisition and validation, and the start/stop entry points. Requires the devices layer. video-audio-recording.el keeps configuration and the recording process-handle state, the device-diagnostic and device-test commands, the toggle commands, and the C-; r keymap, and requires the two layers. The engine reads and updates the config and process-handle variables, which the top module owns, through forward declarations, so no layer requires the top module back. No function call crosses from a layer up into the top module, so the split needs no forward-declared functions. Every public name is preserved, so all 323 existing video-audio-recording tests pass unchanged through the require chain. The two new modules carry the load-graph and package headers and join the header-contract allowlist. Claude-Session: https://claude.ai/code/session_014fyKMTTqLrZpL3rDF3dYc3
* refactor: split calendar-sync.el into layered modulesCraig Jennings14 hours6-1349/+1529
| | | | | | | | | | | | | | | Break the 1724-line calendar-sync.el into a thin public face plus four layered libraries, moving every function verbatim so behavior and public names are unchanged: - calendar-sync-ics.el — base parsing: RFC 5545 text cleaning, VEVENT property extraction, attendee/organizer/URL parsing, timezone and timestamp conversion, date arithmetic, single-event parsing. Depends on neither of the other new modules. - calendar-sync-recurrence.el — RRULE/EXDATE/RECURRENCE-ID expansion. - calendar-sync-org.el — Org rendering and atomic file output. - calendar-sync-source.el — sync state and persistence, async .ics fetch, the batch conversion worker, and the Google Calendar API path. calendar-sync.el keeps configuration, the parse orchestrator, sync dispatch, the user commands, the timer, and the C-; g keymap, and requires the four layers. Each layer forward-declares the config defvars it reads, so no layer requires the top module back. The batch worker loads the whole graph, so source forward-declares the two functions it calls there. Every public name is preserved, so all 574 existing calendar-sync tests pass unchanged through the require chain. The four new modules carry the load-graph and package headers and join the header-contract allowlist. Claude-Session: https://claude.ai/code/session_014fyKMTTqLrZpL3rDF3dYc3
* test: fix restart-emacs no-service mock to survive native-compCraig Jennings14 hours2-4/+11
| | | | | | test-system-cmd-restart-emacs-no-service-aborts mocked cj/system-cmd--emacs-service-available-p directly, but cj/system-cmd-restart-emacs reaches that helper through a native-comp intra-file direct call that bypasses the symbol-function redefinition. The mock silently no-opped, the real check ran, and on any machine that has emacs.service it returned non-nil, so restart proceeded and the should-error saw no error. I mock executable-find to nil instead, driving the real helper to nil at a boundary its subr trampoline honors, matching the passing sibling tests. The test now passes whether or not emacs.service is installed.
* refactor: split custom-misc.el into focused modulesCraig Jennings15 hours16-252/+290
| | | | | | custom-misc.el was an incoherent grab-bag, so anything small defaulted to landing there. I split its eight commands by concern. Three moved into new modules: custom-format (region/buffer reformat), custom-counts (word and character counts), and custom-text-transform (fraction glyphs). The other three went to existing homes: the previous-buffer toggle to custom-buffer-file, the delimiter jump to custom-line-paragraph, and the align-regexp space advice with its alignment and fill bindings to custom-whitespace. The C-; bindings, which-key labels, and the six test files moved with their functions, and custom-misc.el is deleted. No behavior change: every command keeps its name and its C-; key.
* refactor: prefix two collision-prone helpers, document naming auditCraig Jennings15 hours6-30/+121
| | | | | | Two owned helpers carried unprefixed generic names that risk colliding in the single Emacs namespace: car-member (local-repository.el) and unpropertize-kill-ring (system-defaults.el). I renamed them to localrepo--car-member and cj/--unpropertize-kill-ring and updated their callers and tests. Both are non-interactive and contained, so no alias was needed. docs/design/naming-audit.org records the rest of the scan: the allowlist of deliberate module prefixes, the foreign forward-declarations that aren't owned definitions, and a deferred list (keybound commands, the with-timer macro, the ui-theme defcustoms, the user-constants paths) that each want a focused pass rather than an unattended rename.
* chore(todo): file restart-emacs no-service test failureCraig Jennings15 hours1-0/+3
|
* refactor: normalize module package headers and enforce themCraig Jennings15 hours34-33/+131
| | | | | | The first-line header on 33 modules named the file without its .el extension (;;; font-config --- ... rather than ;;; font-config.el --- ...), the form checkdoc and package-lint expect and the other modules already use. I normalized all 33 to the canonical ;;; name.el --- summary shape. The change is line 1 only. A new test, test-meta-package-headers.el, locks the convention. It checks every module for the canonical first line, Commentary before Code, a provide footer, and no BOM, and unit-tests the checker against each malformed shape so the guard itself is proven.
* chore(font): bump laptop default preset one point to 130Craig Jennings19 hours1-1/+1
|
* chore(todo): file structural-refactor backlog from 2026-06-28 reviewCraig Jennings20 hours1-0/+370
|
* docs: add bug-priority matrix, project aliases, location-lookup ruleCraig Jennings20 hours3-0/+95
|
* fix(music): define the playlist-header facesCraig Jennings20 hours2-0/+40
| | | | The route-colors pass dropped the literal cj/music-* face definitions but left the playlist header referencing them, so every header render spammed "Invalid face reference". I restored the five as deffaces that inherit themed base faces, so the theme still owns their colors. A test asserts each referenced face is defined.
* chore(todo): file pdf-view epdfinfo crash taskCraig Jennings28 hours1-0/+4
|
* fix(ai-term): keep agent buffers alive through the kill-all sweepCraig Jennings28 hours3-3/+85
| | | | | | F1 (cj/dashboard-only) kills every other buffer, burying only those on the undead list. Agent buffers were never registered, so the sweep killed live agents and detached their sessions. Agent buffers are a dynamic family ("agent [<project>]") that an exact-name list can't pre-enumerate, so undead-buffers gains a regexp list (cj/undead-buffer-regexps) and a centralized cj/--buffer-undead-p predicate. Both kill paths route through it. ai-term registers the "agent [" pattern, so every agent -- current or future, however created -- is buried rather than killed.
* feat(calibre): open calibredb filtered to the in-progress booksCraig Jennings28 hours2-1/+90
| | | | | | Every calibredb launch (the dashboard "b", M-x, anywhere) now opens filtered to the in-progress books rather than the whole library, via an :after advice on calibredb. Clear with L or x to see everything. The filter scopes to the tag field (calibredb-tag-filter-p), not a bare keyword search. A bare keyword matches any field, which surfaced books that only mention "in-progress" in their description.
* feat(reading): reformat PDF bookmark names like EPUBsCraig Jennings29 hours2-58/+84
| | | | | | Bookmark reformatting to "Author, Title" was nov-only, so PDF bookmarks kept the raw filename. PDFs open in pdf-view-mode, whose pdf-view-bookmark-make-record carried no advice. I added a parallel :filter-return advice there, reusing the same extension-agnostic filename parser, and renamed the helpers off the nov- prefix to reading- since they now serve both EPUB and PDF. New tests cover a PDF filename and a PDF-shaped record.
* chore(todo): close dashboard weather launcher taskCraig Jennings29 hours1-2/+3
|
* feat(dashboard): add a weather launcher (wttrin)Craig Jennings29 hours2-14/+23
| | | | | | A Weather launcher joins the dashboard's top row after Agenda, on key w, drawn with the nf-weather-day_sunny_overcast Weather Icons glyph. It opens the wttrin forecast through call-interactively so wttrin's location prompt runs. A bare (wttrin) call errors, since the command takes the location as a required argument that its interactive form supplies. Row sizes move from 4-4-3-3 to 5-4-3-3. The launcher table stays the single source for both the navigator icons and the keymap.
* fix(ai-term): summon restores the agent's last fullscreen stateCraig Jennings30 hours3-7/+168
| | | | | | Summoning the agent (M-SPC) into a single-window frame docked it at the default fraction even when it was last fullscreen, because the size-memory model only captured split geometry at toggle-off and a sole window has no dock size to record. A window-configuration-change-hook tracker now records whether the displayed agent fills its frame (cj/--ai-term-last-fullscreen), and display-saved restores it in place when that flag and a single-window frame both hold. The tracker records only that flag, not dock geometry: re-capturing the dock size on every window change fed a capture/replay loop that drifted the dock height a couple rows per cycle. The restore guard uses (one-window-p t) so an active minibuffer (a picker prompt mid-summon) isn't counted as a second window, which otherwise misfired the restore into a dock and cascaded.
* chore(todo): archive resolved tasksCraig Jennings31 hours1-115/+103
|
* chore(todo): cancel the ai-term summon taskCraig Jennings31 hours1-1/+3
| | | | Dropped the fullscreen-on-summon and single-agent-toggle approach in favor of binding M-arrow to the general window pull-away.
* feat(windows): bind M-arrow to the window pull-away and resizeCraig Jennings31 hours2-2/+57
| | | | | | M-<arrow> now mirrors C-; b <arrow>. From a sole window it pulls a sliver split open on the opposite edge, revealing the previous buffer. In a multi-window layout it nudges the divider via windsize. cj/window-resize-sticky derives the arrow with event-basic-type, so one command serves both chords. M-up/down were unbound, and M-left/right shed word-motion, which stays on C-left/right. org and other modes that own M-arrow still shadow it, so C-; b remains the universal binding.
* fix(dashboard): drop per-item list icons so bookmarks render uniformlyCraig Jennings32 hours2-3/+4
| | | | URL bookmarks have no filename, so dashboard's filename-based per-item icon left them bare next to file bookmarks. Rather than special-case a URL glyph, I dropped per-item icons from the recents, bookmarks, and projects lists (dashboard-set-file-icons nil). The section-heading icons and the launcher row keep theirs.
* chore(todo): file inbox items as tasksCraig Jennings33 hours1-0/+20
| | | | Filed eight tasks from the inbox. Four under Theme-Studio Open Work: surface font-lock faces, contrast against distant-foreground, flag a face inheriting from itself, and outline the auto-dim text in the live preview. Four under Emacs Open Work: ai-term fullscreen-on-summon plus single-agent toggle, dashboard icons for URL bookmarks, a dashboard weather entry, and a nov sepia reading view. Each carries its findings in the body. Also folded an offline-capable Google Keep idea into the existing google-keep task as v2+ scope.
* refactor(weather): load wttrin from the local release/0.4.0 checkoutCraig Jennings33 hours1-9/+9
| | | | Load wttrin via :load-path from the local checkout instead of package-vc, so edits in the checkout are testable without a pull. The wttrin-auto-fit-font defcustom exists on release/0.4.0, so the placeholder setq becomes setopt, which also drops the byte-compile free-variable warning the setq carried. The :vc block stays as a commented fallback for production tracking.
* chore(todo): close the wttrin theme-studio taskCraig Jennings36 hours1-5/+8
| | | | Recorded wttrin's inventory capture, the two non-blocking residuals (a full clean-daemon regen for the other local checkouts, and the eval-defined wttrin-instructions-header), and filed the studio visual confirm.
* feat(theme-studio): make wttrin themeable in the package inventoryCraig Jennings36 hours2-1/+7
| | | | wttrin loads from an unversioned local checkout (elpa/wttrin/), which the inventory regex already learned to capture (a5fd0b4d). This long-lived daemon's wttrin face attribution was scrambled by the session's theme reloading, so rather than regenerate the whole inventory from a disturbed daemon I added wttrin's four file-loaded faces from a clean batch load and regenerated the studio. wttrin is now a previewable app, and all studio gates stay green.
* docs: finish the commentary/comment audit tailCraig Jennings36 hours3-11/+9
| | | | Condensed early-init's debug-flags note and added a why for the deferred global-font-lock, rewrote three vcf-conversion-helpers comments to name the real intent (keeping the reverse-order-to-preserve-positions rationale), and gave the archived testutil-filesystem a real summary while deleting its line-by-line narration comments.
* chore: delete unused c-boxes.elCraig Jennings37 hours1-407/+0
| | | | Dead vendored code for reboxing C block comments (1991). Nothing requires or loads it, it has no provide footer, and none of its commands are bound or called. Removing the orphan.
* docs: normalize generated-file headers and prune obvious commentsCraig Jennings39 hours11-54/+21
| | | | The theme-studio and browser-choice generators now stamp their output with a header that names the authoritative source and says to regenerate rather than hand-edit. I regenerated both files to match. I also deleted six obvious "describe the next form" comments, replaced two stale placeholders in titlecase.el and an incomplete FIXME in org-checklist.el with real rationale, and condensed early-init's header and Commentary.
* docs: fix blank package summaries and normalize more module headersCraig Jennings39 hours12-222/+57
| | | | More of the commentary/comment audit. The custom-* command modules, weather-config, and mousetrap-mode had empty package summary lines and verbose summary paragraphs. I filled the summaries and condensed the prose while keeping each module's load-contract metadata. dwim-shell-config and auth-config had malformed ;; headers (now ;;;), local-repository had a leading BOM, and two test files had blank summaries.
* chore(todo): close the ai-term docs and system-power tasksCraig Jennings40 hours1-4/+6
| | | | I closed the ai-term F9-commentary fix and the system-power keybinding removal, both shipped.
* docs: condense module commentaries to the terse header contractCraig Jennings40 hours22-1038/+187
| | | | 22 module headers carried long user-manual commentaries (quick-starts, keybinding matrices, setup walkthroughs) that belong in user docs, not source. Each now states the purpose, load contract, and entry points tersely. ai-term also drops its stale F9 keybinding references (the scheme is C-; a plus M-SPC now) and a header line claiming a vertical-split that's really host-aware.
* refactor(system-commands): bind C-; ! to the menu, drop the leaf keysCraig Jennings40 hours2-47/+27
| | | | C-; ! was a prefix map with per-command leaf keys (s/r/e/l/L/E/S) I rarely use. I bound C-; ! directly to the completing-read menu instead and removed the leaf keys, reclaiming the real-estate. Every command stays reachable through the menu. Updated the commentary and the two keymap tests to the new contract.
* feat(weather): opt into wttrin auto-fit font scalingCraig Jennings40 hours1-0/+6
| | | | I set wttrin-auto-fit-font so the weather font scales to the window width, clamped to wttrin's min/max floor and cap. The option lands when the wttrin package gains the defcustom. Until then it's a harmless no-op the old code ignores, and the later defcustom won't clobber it.
* chore(todo): audit solo tags and close shipped tasksCraig Jennings40 hours1-20/+35
| | | | | | I tagged the open tasks for solo eligibility: solo means the work needs no decision or preference input, only manual validation afterward. I added solo where the work is self-contained and dropped it where a design or palette decision gates it. I closed the tasks that shipped (eat zoom-out binding, ledger wiring, transcription stderr, EAT diff darkening), filed the ledger guardrail-UX audit, and added the manual-validation checks for the failing-transcription log and the diff darkness.
* fix(theme-studio): darken the EAT diff line backgroundsCraig Jennings40 hours2-0/+14
| | | | | | The added and removed line backgrounds in Claude Code diffs read too bright. I added eat-term-color-22 (added green) and eat-term-color-52 (removed red) to the WIP theme at about half their former brightness: #005F00 to #002f00, #5F0000 to #2f0000. EAT uses each face's foreground as the palette value for both text and background paint, so darkening the foreground darkens the diff background. The green index is confirmed. The red is the symmetric counterpart. The brighter within-line word-highlight shades are different indices, left until I sample them live.
* fix(transcription): write stderr to the error log instead of a phantom bufferCraig Jennings40 hours2-8/+69
| | | | | | make-process :stderr was a file path, but :stderr takes a buffer, so Emacs made a buffer named after the path instead of writing the file. The "Errored. Logs in <file>" notification pointed at a log with no error text, and that hidden buffer leaked one per transcription. I now route stderr through an explicit, erased buffer: passed to :stderr, threaded to the sentinel, drained into the log, then killed. That keeps stderr off the stdout :buffer, so the transcript stays clean.
* chore(todo): re-scope wttrin task to the verified root causeCraig Jennings43 hours1-1/+4
| | | | Replaces the wrong "blocked on shipping" read. The real cause was the inventory capture matching only versioned package dirs, fixed in a5fd0b4d and verified on a clean load. Remaining work is a clean-Emacs inventory regen and getting the new face into the checkout source.
* fix(theme-studio): capture unversioned local checkouts in the package inventoryCraig Jennings43 hours1-1/+4
| | | | build-inventory.el grouped faces by their defining file and pulled the package name only from versioned directories (/elpa/PKG-VERSION/). Locally-developed packages live in unversioned directories (/elpa/PKG/), so every one of them was silently excluded from the studio. Make the version suffix optional so unversioned checkouts are captured too. Verified against a clean wttrin load: wttrin-key resolves to /elpa/wttrin/wttrin.elc and the regex extracts "wttrin". The inventory itself needs regenerating in a clean Emacs to pick these up.
* chore(todo): re-scope the wttrin theme-studio task to its real shapeCraig Jennings45 hours1-2/+2
| | | | Investigation showed wttrin is not a studio app at all: package-inventory.json is generated from installed packages, has no wttrin entry, and wttrin is on an unmerged feature branch so the capture cannot see it. So it is a from-scratch build blocked on wttrin shipping, not the one-line face add the handoff implied.
* fix(eat): bind zoom-out and reset in eat-semi-char-mode-mapCraig Jennings45 hours1-0/+13
| | | | In eat-semi-char-mode, C-- was bound to eat-self-input and forwarded to the terminal, so it never reached text-scale-decrease and the font could only grow. A session climbed to text-scale 17 (~20x, unreadable) with no in-buffer way down. Bind C-- to text-scale-decrease and C-0 to a reset helper. C-= and C-+ already passed through. Low cost: the terminal program and tmux don't use Ctrl+-, and C-0 shadows digit-argument inside eat buffers only.
* chore(todo): file inbox handoffs as tasksCraig Jennings45 hours1-0/+5
| | | | Two actionable items from the inbox: eat semi-char mode swallows zoom-out (home-emacs, with the proposed binding fix in the body) and a new wttrin-instructions-header face for the theme-studio wttrin preview (emacs-wttrin). The other two emacs-wttrin notes were informational changes that already landed in weather-config.el and verified live, so they only needed marking processed.
* chore(todo): close the dirvish preview rebuild taskCraig Jennings45 hours1-2/+2
| | | | Shipped this session in 61b68fcf and visually verified, so the sub-task becomes a dated event-log entry under the Theme-Studio project.
* chore(theme): WIP set nerd-icons-completion-dir-face to goldCraig Jennings45 hours2-2/+3
| | | | Gold completing-read folders against the silver file and dirvish icons. The nerd-icons-config override is what lets this face win over the global dir advice.
* fix(nerd-icons): color completing-read folders via the completion dir faceCraig Jennings45 hours1-1/+14
| | | | The cj/--nerd-icons-color-dir advice forces nerd-icons-yellow onto every dir icon, which wins over nerd-icons-completion's inherit-behind dir face, so setting nerd-icons-completion-dir-face had no visible effect and folders just followed nerd-icons-yellow. Redefine the file-category completion icon to copy the dir icon and prepend nerd-icons-completion-dir-face so it takes the foreground. The copy keeps nerd-icons' memoized original untouched, so dired and dirvish folders are unaffected. Now completing-read folders carry their own color while file icons keep their type face.
* chore(theme-studio): refresh face-coverage reportCraig Jennings2 days1-196/+1256
| | | | The committed report was dated 2026-06-18 and 457 faces behind the current set (1293 to 1750 tracked, 43 to 51 package groups). Regenerated from current face data.
* chore(theme): WIP palette pass over nerd-icons and dirvish facesCraig Jennings2 days2-121/+146
| | | | Region background to #424f5e, highlight distant-foreground, a few ui face locks, plus a sweep of the nerd-icons color palette (the d/l/alt variants) and several dirvish faces (file-modes, free-space, hl-line, inactive).
* feat(theme-studio): rebuild the dirvish preview as a realistic two-paneCraig Jennings2 days2-24/+106
| | | | The preview was a flat catalog dumping every face on labeled lines. It's now a believable two-pane dirvish: an active directory listing (the real nerd-icon glyph and color per file type, dir-entry counts, file sizes, the hl-line on the selected row, a dimmed backup) beside an ls-l preview of the selected dir. Faces that don't fit a calm listing (vc, git, subtree, media, proc, narrow, emerge) moved to a labeled extras strip below, so all 38 dirvish faces stay covered. Glyphs and colors mirror what nerd-icons actually emits per type.
* chore(todo): file the session's deferred work, close ghostel consolidationCraig Jennings2 days1-5/+30
| | | | Add seven tasks for the deferred changes from the EAT, dirvish, and completion-category work: darken the EAT diff colors, rebuild the theme-studio dirvish preview (under the Theme-Studio project), root-cause webm previews, completion categories for the mu4e attachment picker and the file-basename pickers, and two watchlist items at #D (the Claude Code upstream bleed and the occur/xref font-lock question). Close Consolidate on EAT now that Phase 5 shipped this session.