aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* chore(todo): close dashboard preview icons/items task (font embedded, items ↵Craig Jennings15 hours1-5/+2
| | | | themeable)
* feat(theme-studio): bind dashboard preview list items to dashboard-items-faceCraig Jennings15 hours2-22/+22
| | | | The dashboard preview rendered the project/bookmark/recent rows as plain text, so editing dashboard-items-face didn't recolor them. Wrap those rows in dashboard-items-face so the preview reflects the face. It inherits widget-button (unspecified) while unset, so the rows stay bare until the face is themed -- this only makes the preview responsive. Completes the dashboard preview's face coverage.
* chore(todo): close calendar-sync robustness + org-roam refile-freeze bugsCraig Jennings16 hours1-9/+6
|
* fix(calendar-sync): atomic writes, curl --fail, and zero-event vs garbageCraig Jennings16 hours3-17/+104
| | | | Three robustness fixes from the config audit. (1) calendar-sync--write-file and --save-state now write a temp file in the same directory and rename it into place, so org-agenda or chime reading mid-write never sees a half-written calendar. (2) The two curl fetches gain --fail, so an HTTP 404/500 error page exits non-zero instead of flowing its HTML into conversion. (3) calendar-sync--parse-ics distinguishes a healthy zero-event calendar (a real iCalendar with BEGIN:VCALENDAR and no in-window events returns the header) from garbage (no VCALENDAR returns nil), so a near-empty calendar no longer reports "parse failed". New robustness tests; the empty-calendar boundary test updated to the corrected behavior. Verified against the live feed: all three calendars fetch and write cleanly.
* fix(org-roam): drop the redundant refile-targets build that froze first idleCraig Jennings16 hours1-2/+4
| | | | org-roam is :defer 1, and its :config called cj/build-org-refile-targets, running the multi-file refile scan synchronously at the 1s idle on a cold cache, which froze Emacs at first idle. org-refile-config already schedules the same build on a 5s idle timer, so the org-roam call was a duplicate. Removed it; the 5s timer covers it.
* chore(dashboard): use the nf-cod-library codicon for the Calibre launcherCraig Jennings16 hours2-2/+4
| | | | Closer to the actual Calibre logo than the faicon book-open. Switches the launcher's icon function to nerd-icons-codicon, adds the matching declare-function, and adds nerd-icons-codicon to the test's icon mock.
* chore(todo): mark color-strip phase 1 done, list phase-2 themeable-face gapsCraig Jennings16 hours1-372/+377
|
* refactor: strip all literal colors from config modulesCraig Jennings16 hours7-51/+41
| | | | Remove every hardcoded color from the config so nothing assigns a non-themeable value. Stripped: the org-faces defface defaults (28 hex foregrounds, which the theme overrides at runtime anyway), the hl-todo keyword colors, the eshell prompt gray/white, the org-noter and music active-window #1d1b19 bg tint (face-remap is now a no-op), the pdf-view midnight palette, and the calibredb/nov epub sepia. The config now renders with default/theme faces, which surfaces where theming support is missing. Those gaps are tracked in todo.org as the next phase. 0 hex colors remain; validate-modules clean and the org-faces/build-theme/face-diagnostic tests pass.
* chore(todo): close dirvish stray-buffers task (popup reap-on-frame-close fix)Craig Jennings17 hours1-2/+3
|
* fix(dirvish): reap the Super+F popup session on any frame closeCraig Jennings17 hours1-0/+16
| | | | The popup's q (cj/dirvish-popup-quit) reaps the session's dired buffers, but closing the Hyprland float directly or letting it lose focus bypasses q and orphans them, which is the "leaves a load of buffers around" symptom. A delete-frame-functions hook scoped to the "dirvish" popup frame runs dirvish-quit on every close path. Regular C-x d sessions, where multiple dired buffers are wanted for mark-and-move, and the global dired-kill-when-opening-new-dired-buffer (deliberately off for that same reason) are both untouched. Verified: a navigated popup session drops back to baseline when the frame closes without q.
* chore(todo): file dirvish single-instance/buffer-hygiene task (inbox zero)Craig Jennings20 hours1-0/+2
|
* chore(todo): close eww UA injection bug (lexical special-var trap, real ↵Craig Jennings20 hours1-2/+3
| | | | production fix)
* fix(eww): inject the User-Agent reliably under byte-compilationCraig Jennings20 hours1-0/+7
| | | | eww-config.el is lexical-binding and the User-Agent advice let-binds url.el's url-request-extra-headers, but the file never declared it special. The byte-compiler then bound it lexically, so the injected header never reached url-retrieve and the desktop User-Agent silently dropped in compiled production (eww kept working, just with the default UA). A top-level (defvar url-request-extra-headers) makes the compiler treat it as dynamic so the binding propagates. The advice tests, which exercise the compiled path, now pass.
* chore(todo): close collapse-split isolation bug (root-caused and fixed)Craig Jennings20 hours1-2/+3
|
* test(ai-term): isolate layout-capture globals in collapse-split testsCraig Jennings20 hours1-2/+12
| | | | The multi-window and single-window collapse tests call cj/ai-term, which captures the current layout into cj/--ai-term-last-direction / cj/--ai-term-last-size on toggle-off, but only let-bound cj/--ai-term-last-was-bury. They leaked last-direction into the display-rule test, whose display-saved action reads those globals to choose the split direction, so its agent buffer split below instead of right and the assertion failed. Let-bind last-direction and last-size to nil, matching the roundtrip test in the same file. Full ai-term suite is green.
* chore(todo): close ai-term detached-step task, file live VERIFY + ↵Craig Jennings20 hours1-2/+11
| | | | collapse-split isolation task
* feat(ai-term): step into detached sessions too, attaching themCraig Jennings20 hours5-112/+166
| | | | The next-agent step (C-; a n / M-SPC) cycled only live agent buffers, so a detached session (alive in tmux, no Emacs buffer) was reachable only through the picker. Now the queue is every active agent, live buffer or live session, keyed on the project dir and ordered by buffer name. Stepping onto a detached one attaches it: show-or-create recreates the terminal, which reattaches the tmux session. The live-buffer swap path is unchanged. I replaced the buffer-rotation helper with a dir-based one and added an active-agent enumerator, with 10 tests.
* chore(todo): park clear-palette (no target) and Slack (defer to Messenger ↵Craig Jennings21 hours1-5/+5
| | | | unification)
* chore(todo): close LSP smoke-test task (done)Craig Jennings27 hours1-7/+2
|
* test(lsp): narrow startup smoke test for prog-lsp config resolutionCraig Jennings27 hours1-0/+66
| | | | Pins the load-time invariants of the central LSP module: lsp-enable-remote stays nil (no auto-start on TRAMP files), the file-watch-ignore defaults live in one idempotent helper, the eldoc provider is stripped from the global hook, and no mode accrues a duplicate lsp-deferred entry. Tests the top-level :init and helper surface, since :config defaults defer to lsp-mode's own load under make test.
* fix(theme-studio): restrict the cursor UI row to fg + bgCraig Jennings27 hours3-12/+56
| | | | Emacs draws the cursor as a rectangle: its foreground colors the glyph sitting on it and its background is the cursor color, but weight/slant/underline/strike and box are no-ops on it. The UI table now shows only the fg and bg swatches for the cursor row and mutes the style and box cells to a dash, so the studio stops presenting controls Emacs drops. New #cursorrowtest gate; styletest/boxtest retargeted off cursor (it was UI_FACES[0], their generic subject) onto the first styled face.
* feat: add avy (in-buffer jump) and wgrep (editable grep)Craig Jennings28 hours2-0/+20
| | | | The two clear wins from the package-list review. avy fills the in-buffer motion gap (C-: jump-to-char-timer, M-g w/l for word/line) that windmove and isearch leave open; wgrep turns a consult-grep / embark-export result into an editable, write-back-across-files refactor (C-c C-p to edit, C-c C-c to apply).
* chore(todo): file F12-EAT task, close terminal-themeability comparison ↵Craig Jennings28 hours1-2/+5
| | | | (researched)
* chore(todo): file eww User-Agent advice test failure (pre-existing, Emacs 30 ↵Craig Jennings28 hours1-0/+2
| | | | derived-mode-p)
* chore(google-keep): mark v1 implemented, file live-setup VERIFY, record in specCraig Jennings28 hours2-4/+27
|
* feat(google-keep): org-page renderer, refresh command, keybindings (Phase 2-3)Craig Jennings28 hours4-0/+359
| | | | The elisp side of the Keep integration: a pure JSON-to-org core (parse, tag/heading/render helpers) kept free of .emacs.d specifics for later extraction, plus the IO runner cj/keep-refresh (async make-process + sentinel, atomic temp-then-rename write to keep-file, stderr-token to display-warning) and the glue (C-c k prefix, executable warning, require in init.el). 15 ERT tests over the core and the parse-render-write chain. Read-only v1; live fetch needs the one-time gkeepapi + token setup.
* feat(google-keep): gkeepapi data bridge with JSON contract (Phase 1)Craig Jennings28 hours2-0/+244
|
* docs(spec): round 2 review clean, google-keep spec ReadyCraig Jennings28 hours1-1/+5
|
* docs(spec): fold round-1 review into google-keep spec (rubric Ready)Craig Jennings28 hours1-30/+90
|
* docs(spec): resolve google-keep decisions (read-only v1 to write v2, ↵Craig Jennings28 hours2-53/+52
| | | | gkeepapi, authinfo)
* chore(todo): close calendar-sync fix, cancel dirvish-previews taskCraig Jennings29 hours1-4/+6
|
* fix(calendar-sync): re-derive status from a declined occurrence overrideCraig Jennings29 hours2-1/+46
| | | | A recurring event declined for one occurrence still synced with :STATUS: accepted, because apply-single-exception merged the override attendees but never re-derived the user's status from them, so filter-declined never dropped it. Re-derive :status via find-user-status when the exception overrides :attendees, leaving the inherited status when the override doesn't name the user. Four new tests cover declined, accepted, no-attendee, and user-absent overrides.
* chore(todo): file calendar-sync declined-occurrence bug (from chime handoff)Craig Jennings30 hours1-0/+2
|
* fix(dirvish): point the bg wallpaper command at set-wallpaper on WaylandCraig Jennings30 hours2-6/+7
| | | | The Wayland branch of cj/--wallpaper-program-for returned swww, but this system's wallpaper daemon is awww, so dirvish "bg" silently no-opped. Point it at the set-wallpaper script (on PATH via dotfiles), which wraps awww img and persists the choice to waypaper's config. X11 still uses feh. Updated the wallpaper-program test to match.
* docs(spec): google-keep in-editor integration spec (draft, 5 open decisions)Craig Jennings30 hours2-1/+155
|
* chore(todo): close converter/face-list/tier-2 items, reframe google-keep as ↵Craig Jennings30 hours1-8/+8
| | | | build-it-here
* feat(ledger): un-orphan ledger-config and rewrite clean-on-saveCraig Jennings30 hours2-14/+27
| | | | ledger-config.el was never required in init.el, so the whole module was dead code. I added the require (which installs ledger-mode, flycheck-ledger, and company-ledger via the global ensure) and rewrote the clean-on-save: instead of rebinding C-x C-s to a clean-then-save command, a buffer-local before-save-hook tidies the buffer on every save path, gated by cj/ledger-clean-on-save. The reports shell out to the ledger CLI, so a load-time check now warns when it isn't on PATH. Added ledger-highlight-xact-under-point.
* chore(todo): inbox-zero — file 5 emacs roam items as tasksCraig Jennings34 hours1-0/+10
|
* chore(todo): log controls.js extraction (tier 2)Craig Jennings34 hours1-1/+3
|
* refactor(theme-studio): extract control factories to controls.js, drop dead ↵Craig Jennings34 hours6-234/+221
| | | | | | | | previewFaceAttrs I split the custom dropdown, detail-editor, and expander factories out of app.js into controls.js (205 lines), spliced back at a CONTROLS_J token by generate.py. The token sits at the exact extraction point, so the assembled page is byte-identical and every gate passes unchanged. app.js drops from 927 to 721 lines. I also removed previewFaceAttrs (function, export, and test). It was test-only dead code whose docstring stalely claimed the gate calls it. The gate uses assertPreviewFaces instead.
* chore(todo): log theme-studio tier-1 simplification completionCraig Jennings35 hours1-0/+4
|
* refactor(theme-studio): tier-1 simplification passCraig Jennings35 hours8-82/+81
| | | | | | | | These are behavior-preserving cleanups from the refactor/simplify assessment, all test-verified. I merged syncMockHeight and syncPkgHeight into one syncPaneHeight(tableId, paneId), inlined the two single-use displayHex/displayName closures, dropped a pkgbody guard that buildPkgTable already does, and had paintUI call worstCellHtml instead of rebuilding the covered-contrast cell. I deleted the dead generatorHues "manual" branch (a copy of the fallback) and locateInfoLine (orphaned when I removed the preview info line earlier today). The two nerd-icons loaders now share _load_nerd_icons_artifact, with a sentinel so a null-file edge keeps its exact behavior. face_coverage.classify reads through named locals now, guarded by a new characterization test. Two assessment findings were wrong and skipped after I checked them against the code: LOCATE_REG is live (read by previewSpan), and normalizePaletteEntryCore doesn't exist.
* fix(theme-studio): gold nav arrows for the language and preview dropdownsCraig Jennings35 hours2-4/+10
| | | | The gold viewnav style was scoped to .pkgbar, so the arrows on the .langbar selectors (language and preview) fell back to default gray. I broadened the rule to .langbar and added a dimmed-gold disabled state for the single-pane preview.
* style(theme-studio): unify nav dropdowns to gold-on-darkCraig Jennings36 hours3-6/+12
| | | | The view, language, and preview selects share a navsel class matching their flanking arrow buttons (dark bg, gold bold-mono text), so each select and its arrows read as one control.
* feat(theme-studio): visible size-nav buttons + 48 pt gallery scaleCraig Jennings36 hours5-53/+83
| | | | | | | | | | The preview dropdown gets flanking nav buttons, matching the view selector, so the size steps with a click. Left/Right arrows do the same when the dropdown is focused. Both clamp at the ends and disable on a single-pane app. I extended the size scale to 32 and 48 pt for inspecting a glyph's detail. The cell width scales with the size, so beyond about 48 pt the grid is mostly scrolling. I removed the separate hover info line beside the dropdown. Each glyph's own title tooltip already shows its face and color, so the line was redundant. A new computed-style gate confirms the point size renders to the right pixels (24 pt is 32 px), so the pt label isn't lying.
* chore(todo): reorganize the Emacs task listCraig Jennings37 hours1-847/+884
|
* chore: refresh synced agent rules and hooksCraig Jennings37 hours8-9/+116
|
* chore(theme-studio): update WIP theme snapshotCraig Jennings37 hours2-107/+141
|
* feat(theme-studio): nerd-icons gallery as a hue-ordered icon gridCraig Jennings37 hours13-187/+2366
| | | | | | | | | | The nerd-icons pane is now a grid: one row per color face, the rows ordered by hue so families cluster, distinct icons (deduped within a color) drawn in their color with the icon's nerd-font name beneath. A "preview:" dropdown above the grid picks the glyph size in points, with Left/Right arrows to step it. Single-pane apps show it disabled, naming the preview. This replaces the v1 legend in the pane, whose data is still captured for round-trip. build-nerd-icons-legend.el is now a library. A cj/nerd-icons-write-legend entry point requires nerd-icons only at write time, so the capture logic loads and unit-tests without it. It dedupes icons by name within a face, computes each face's native hue, and orders the groups by hue. Writing the test surfaced a latent bug: face-hsl used (cadr (assoc t spec)), which grabs the first keyword instead of the plist. It only worked because the real faces fall through to the face-foreground branch. I fixed it to a correct t-clause parse. Coverage: 7 ERT capture tests (dedupe, hue order, lightness tiebreak, name sort, skip rules), 4 Python validator edges, and browser gates for the grid and the size dropdown. Locate stays color-level: clicking a color flashes its icons, and clicking an icon flashes its color row. Icons aren't individually editable, so there's nothing per-icon to select.
* fix(theme-studio): render nerd-icon glyphs in previews instead of tofuCraig Jennings39 hours7-12/+151
| | | | | | | | The legend, dashboard, and package previews drew nerd-icon glyphs as empty boxes. The font-family never reached them: PREVIEW_FONT was spliced into inline style="..." attributes with a double-quoted family name, so the inner quote closed the attribute early and the font was silently dropped. Dropping the quotes fixes it. A no-space family name needs none. I embedded the glyph font directly: Symbols Nerd Font Mono, encoded with fontTools (woff2_compress output is rejected by headed Chrome and Firefox), inlined as a data: URI under the unique family name ThemeStudioNerd so it resolves to the embed rather than a system-installed copy of the same name. The page is self-contained and renders on any clone. I added a #fonttest gate that parses previewLines output and asserts the resolved font-family plus glyph coverage, plus a make font target that re-encodes the woff2 with fontTools.