| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
F2 is now the universal preview key across modes. markdown-mode already binds F2 to markdown-preview. Org-mode now binds it to org-reveal instead of F5. A follow-up ticket reworks the rest of the F-key block to consolidate the dev-loop keys (compile+run, debug, test, coverage).
|
| |
|
|
| |
Several lines in the header were stale. The default preset is BerkeleyMono, not FiraCode, and the height is now machine-dependent (120 on laptops, 140 on desktops). The default preset's variable-pitch font is Lexend. Merriweather is only the fallback for unnamed presets. The fontaine preset keybinding is M-S-f, not M-F. The emoji bindings (C-c E i, C-c E l) weren't listed.
|
| |
|
|
|
|
|
|
| |
`env-laptop-p` treated any `battery-format "%B"` value that wasn't literally "N/A" as "has a battery." On a Linux desktop using `battery-upower`, the result is "unknown". The AC adapter and USB-C power entries exist in /sys but there's no BAT*. That made desktops look like laptops. The per-machine font height switch in `font-config.el` broke as a result.
The fix uses /sys/class/power_supply/BAT* as the canonical Linux signal. That's what the kernel exposes, and what upower itself reads. Other platforms keep the `battery-format` path, but the fallback now checks for a live battery status char ("!", "+", "-") instead of only excluding "N/A".
Two pure helpers (`env--battery-status-char-indicates-battery-p`, `env--power-supply-has-battery-p`) keep the logic testable. The new test file covers Normal, Boundary, and Error cases for each helper.
|
| |
|
|
|
|
| |
The default fontaine preset now picks its height based on `env-laptop-p`. Laptop: 120 (12pt). Desktop: 140 (14pt), matches foot's `size=14`. Text reads at the same size across Emacs and the terminal.
This reuses `env-laptop-p` from `host-environment.el` instead of adding a gitignored local override.
|
| |
|
|
|
|
|
|
| |
Two gaps in cj/hugo-preview surfaced during manual testing.
First, the browser opened one second after start-process returned. On any non-trivial site, Hugo takes several seconds to finish its initial build before it binds port 1313. The browser requested the page before the server existed and got ERR_CONNECTION_REFUSED. Replaced the fixed one-second run-at-time with a process filter that watches Hugo's output for "Web Server is available at" — the line Hugo prints once it has actually bound the port. The browser now opens at the right moment regardless of build time. The filter clears itself after firing so subsequent output does not re-open tabs.
Second, if Hugo exited on its own (for example a template error in the theme), the preview command went silent with no indication that anything was wrong. Added a process sentinel that clears cj/hugo--preview-process on any exit and prints "hugo server crashed (exit N) — see *hugo-server* buffer" when the exit status is non-zero. User-initiated stops arrive as signal status and remain silent because cj/hugo-preview already prints its own stop message.
|
| |
|
|
|
|
|
|
|
|
| |
Two small cleanups on hugo-config.el after the feature commits.
The file header listed only five bindings (n, e, o, O, d) and called the lowercase-d binding "Toggle draft." Both are now wrong. Replaced the listing with a pointer to the keybindings section at the bottom and to the which-key panel, which are the real sources of truth and do not rot.
The functions used to live under one generic "Hugo Blog Functions" header. Regrouped them by purpose: Post Creation, Post Export, Directory Navigation, Draft Management, Preview and Publish. Moved the two picker helpers (cj/hugo--post-metadata and cj/hugo--collect-drafts) into the Draft Management section. No behavior change.
All seven ERT tests still pass.
|
| |
|
|
|
|
|
|
| |
wip.el held commented-out scratch code (efrit, buffer-same-mode, easy-hugo) plus one active pomm use-package block. The require in init.el was itself commented out, so the file compiled on every make compile pass but nothing in it ever ran at startup.
The easy-hugo block motivated the new preview and publish commands that landed in the previous commit. The other entries (efrit, buffer-same-mode) have been dead code for months.
Also removes the "Cannot load pomm" warning that has been appearing on every make compile run.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Put the full Hugo workflow inside Emacs. All of it lives in modules/hugo-config.el.
New functions:
- cj/hugo-open-draft reads all .org files under content-org/log, finds those with #+hugo_draft: true, and offers a completing-read picker.
- cj/hugo-preview toggles a local hugo server subprocess and opens the preview URL in the browser. A second press stops the server.
- cj/hugo-publish opens magit-status on the website repo. The server-side post-receive hook on cjennings.net already rebuilds and deploys on push, so committing and pushing is the deploy.
Two pure helpers support the picker: cj/hugo--post-metadata parses the front matter region of a post, and cj/hugo--collect-drafts walks a directory and filters to drafts. Seven ERT tests cover both helpers across normal, boundary, and error cases.
Keybinding note: C-; h d and C-; h D have swapped roles. Lowercase d now opens the draft picker. Uppercase D toggles the draft flag in the current buffer. The previous lowercase-d binding was toggle.
|
| |
|
|
|
|
|
|
| |
Set load-prefer-newer in early-init.el. Emacs was loading the older .elc files even when the .el source was newer, warning on every load but still using the stale byte code.
Point weather-config.el's wttrin :load-path at /home/cjennings/code/emacs-wttrin. The previous value was /home/cjennings/code/wttrin, which does not exist, so use-package could not load the package.
Add (package-initialize) to the Makefile compile target. Without it, batch byte-compile cannot see ELPA packages like git-gutter, git-timemachine, forge, and difftastic, which produced "Cannot load" warnings on every run.
|
| | |
|
| |
|
|
| |
Default preset (BerkeleyMono) 140→120, fallback preset (FiraCode) 110→120.
|
| |
|
|
|
|
| |
.gitignore: rename the private-tooling entry from /docs/ to /.ai/.
CLAUDE.md: expand Layout to list /.ai/ (gitignored) and docs/
(reserved for real project documentation, if/when created).
|
| | |
|
| |
|
|
| |
refactor-for-testability, interactive/internal split
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Picks up upstream bundle changes:
- New .claude/rules/commits.md: no AI attribution, conventional prefixes.
- settings.json: attribution.commit and attribution.pr empty strings
(suppresses Claude Code default attribution).
- CLAUDE.md: Git Workflow references commits.md instead of the
(gitignored) docs/protocols.org.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Re-installed the elisp ruleset from ~/code/rulesets, picking up three
upstream bundle fixes:
- validate-el.sh now calls (package-initialize) so byte-compile can
resolve external packages (dash, etc.) via ~/.emacs.d/elpa/.
- validate-el.sh Phase 2 (test runner) now matches any .el file
outside tests/, not just modules/*.el. Supports flat-layout
projects (Elisp package repos where sources live at project root).
- .claude/rules/testing.md is now generic TDD principles (was
Python/TS specific); language-specific testing rules live in
elisp-testing.md, python-testing.md, etc.
elisp-testing.md gained a line referencing testing.md as the base.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Swap blanket /CLAUDE.md + /.claude/ gitignore rules for personal-only
overrides (.claude/settings.local.json, .claude/.cache/). Add the
tracked bundle content from ~/code/rulesets install-elisp:
- CLAUDE.md (project instructions)
- .claude/rules/elisp.md
- .claude/rules/elisp-testing.md
- .claude/rules/verification.md
- .claude/hooks/validate-el.sh (portable via $CLAUDE_PROJECT_DIR)
- .claude/settings.json (allowlist + hook wiring)
Hooks now use $CLAUDE_PROJECT_DIR with script-relative fallback, so a
fresh clone of this repo works on any machine without path edits.
Project-local skills under .claude/skills/ were stale DeepSat-flavored
copies; deleted and replaced with symlinks into ~/.claude/skills/ via
the rulesets repo's global install.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Portable setup: pre-commit lives in githooks/ (tracked), activated
by `make install-hooks` which sets core.hooksPath. Survives fresh
clones.
The hook does two things on staged changes:
- Scans added lines for common credential patterns (AWS keys, sk-*
tokens, BEGIN PRIVATE KEY blocks, api_key/password literals)
- Runs check-parens on staged .el files
Bypass with `git commit --no-verify` for confirmed false positives.
|
| |
|
|
|
|
|
|
|
|
|
| |
Two cleanups round out the transcription-config refactor:
- cj/--running-transcriptions: the 'status = running' filter used by
cleanup and count helpers is now one function. Existing counter tests
cover both callers.
- cj/--format-transcription-entry: the 13-line dolist body inside
cj/transcriptions-buffer becomes a testable pure function. 6 tests
cover status-face mapping, basename-only rendering, duration format,
trailing newline.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Break cj/--transcription-sentinel's seven inline side-effects into named
helpers:
- cj/--write-transcript-on-success: writes process output to .txt on success
- cj/--append-to-log: appends event marker + process output to log
- cj/--update-transcription-status: marks tracking-list entry complete/error
- cj/--notify-completion: sends success or critical notification
Also: switch the tautological (cj/--should-keep-log t) to use the local
success-p (equivalent but matches the function signature), and rename
the unused audio-file sentinel arg to _audio-file.
Sentinel shrinks from 48 lines with 7 inline blocks to 14 lines of
straight-line helper calls. 10 tests cover the extracted helpers.
|
| |
|
|
|
|
|
|
|
|
|
| |
Pull two more helpers out of cj/--start-transcription-process:
- cj/--init-log-file: writes the initial log header with timestamp,
backend, audio file, script path
- cj/--track-transcription: pushes a running-status entry and refreshes
the modeline
Start-process shrinks from 58 lines with 4 levels of nesting to ~25 lines
mostly at depth 1-2. 10 tests cover the extracted helpers.
|
| |
|
|
|
|
| |
Pull the per-backend env-var assembly out of cj/--start-transcription-process
into a standalone pure function. 9 tests cover: the three backends, parent-env
preservation, non-mutation, missing-key user-error, unknown-backend error.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introduce cj/--transcription-backends alist mapping each backend to
(:script :auth-host :env-var). Replace:
- two near-identical cj/--get-{openai,assemblyai}-api-key functions with
a single parameterized cj/--auth-source-password helper
- the pcase in cj/--transcription-script-path with an alist lookup
- the pcase block in cj/--start-transcription-process that assembled
the API-key env var with an alist-driven assembly
Adding a new backend is now a single line in the alist. The existing
tests plus retargeted API-key tests (now 10, covering the parameterized
helper and the descriptor data) verify no behavior change.
|
| |
|
|
|
|
|
| |
8 tests pinning down current behavior of cj/--get-openai-api-key and
cj/--get-assemblyai-api-key (host query, string vs function secret,
missing-entry → nil). Baseline for upcoming consolidation into a
single parameterized helper.
|
| |
|
|
|
|
|
|
| |
cj/org-contacts-template-name and cj/org-contacts-template-email each
opened with (when (boundp 'cj/contact-name) ...) / (boundp 'cj/contact-email)
to pick up a caller-supplied preset. Neither variable is ever defined,
set, or let-bound anywhere in the config — the branches never ran. The
(or ...) fallbacks always took over, so behavior is unchanged.
|
| |
|
|
|
|
|
|
|
|
|
| |
The outer dolist in cj/check-for-open-work guarded its body with
(boundp 'base-dir), which always returns nil under lexical-binding
because base-dir is a lexical loop variable. Every repo under
projects-dir and code-dir was silently skipped; only org-dir and
user-emacs-directory (both top-level defvars) still got reconciled.
Remove the bogus boundp check. Add regression tests covering the
entry point itself — the existing suite only exercised the helpers.
|
| |
|
|
|
| |
Extract should-skip-p, pull-clean, pull-dirty from 6-level nested
reconcile-git-directory. Make find-git-repos recurse into sub-repos.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
New cj/todo-list-single-project prompts for a project, then shows the
daily agenda scoped to that project's todo.org plus calendars and inbox.
Moved cj/todo-list-all-agenda-files from C-f8 to s-f8.
|
| |
|
|
|
|
| |
Add nil bindings for F8 (agenda), F9 (gptel), and F10 (music) in
vterm-mode-map so these global keybindings aren't swallowed by vterm.
Also disable wttrin-debug and update abbreviations.
|
| |
|
|
|
|
| |
get-sink-index
Previously tested only indirectly via label-devices and sink-has-active-audio-p.
|
| |
|
|
|
| |
Cover occurrence-matches-exception-p (6), apply-single-exception (6),
exdate-matches-p (6), extract-cn (5), extract-email (4), unfold-continuation (5).
|
| |
|
|
|
| |
Replaced 4 copies of "if null calendars, warn" with a shared
calendar-sync--require-calendars predicate.
|
| |
|
|
|
| |
Deduplicated the folded-line handling loop from get-property and
get-all-property-lines into calendar-sync--unfold-continuation.
|
| |
|
|
|
| |
Extracted calendar-sync--extract-cn and calendar-sync--extract-email from
identical logic in parse-attendee-line and parse-organizer.
|
| |
|
|
| |
Function was defined but never called anywhere in the codebase.
|
| |
|
|
|
|
|
| |
Covers core parsing (parse-ics-datetime, parse-timestamp, format-timestamp,
split-events, parse-event), date utilities (add-months, add-days,
weekday-to-number, date-weekday, event-start-time), and timezone
(format-timezone-offset, convert-utc-to-local, localize-parsed-datetime).
|
| |
|
|
|
|
| |
Cover build-video-command (9 tests), select-from-labeled (5 tests),
and test-device (4 tests). All three were previously tested only
indirectly through their callers.
|
| |
|
|
|
|
| |
Extracted completing-read+cancel pattern into cj/recording--select-from-labeled.
Reduces quick-setup nesting from 5 to 3 levels and eliminates duplicated
completion table lambda.
|
| |
|
|
|
| |
Moved Wayland/X11 command string construction into cj/recording--build-video-command.
Reduces ffmpeg-record-video from 70 to 25 lines, nesting from 4 to 2 levels.
|
| |
|
|
|
|
|
| |
test-mic/test-monitor
Both functions had identical record-5-seconds-and-playback logic. Extracted to
cj/recording--test-device with device, prefix, and prompt-action parameters.
|
| |
|
|
|
|
|
| |
function
Identical 31-line parser logic differed only in "Source #" vs "Sink #" header.
Replaced with cj/recording--parse-pactl-verbose taking a record-type parameter.
|
| | |
|
| | |
|
| |
|
|
|
|
| |
Untrack .cask/, .localrepo/ (61M), emojis/ (7.2M), inbox/, todo.org,
v2mom.org, .time-zones.el. Move test-reporter-spec.org to docs/ (already
gitignored). Reduces tracked repo size significantly.
|
| |
|
|
|
|
|
|
|
|
| |
Music: random mode now respected by next/previous keys. Previous navigates
a 50-track play history ring buffer. Fixed playlist replacement bug.
24 new tests.
Calendar-sync: consolidated duplicate parse functions, extracted timezone
localization helper, unified expand-daily/monthly/yearly into parameterized
function, removed dead code. 33 new characterization tests. -90 lines.
|