summaryrefslogtreecommitdiff
path: root/modules
AgeCommit message (Collapse)Author
13 daysfeat(recording): validate system audio device before recordingCraig Jennings
Add pre-recording validation that catches stale or drifted system audio devices before they cause silent recordings. When the default audio output changes (Bluetooth reconnect, device switch) between setup and recording, the monitor device is auto-updated. Warns if no audio is currently playing through the monitored sink. Co-Authored-By: Craig Jennings <c@cjennings.net>
14 daysfix(pdf): move pdf-tools-install to eval-after-load and revert stale buffersCraig Jennings
pdf-tools-install was in use-package :config for pdf-tools, but opening a PDF only loads pdf-view.el — never pdf-tools.el — so the server never started. Move it to with-eval-after-load 'pdf-view and revert any PDF buffers that opened before the server was ready.
14 daysfeat(buffer): add open-with-default-app and open-with-program keybindingsCraig Jennings
Wire cj/xdg-open (C-; b o) and cj/open-this-file-with (C-; b O) into the buffer keymap. Fix xdg-open fallback to try buffer-file-name before dired context. Remove old C-c x o binding from external-open.
2026-02-23chore: rename chime.el references to ChimeCraig Jennings
Update load-path, GitHub URL, and all project/package name references to reflect the chime.el → Chime rename.
2026-02-21fix(user-constants): create calendar data files on first launchCraig Jennings
org-agenda-list prompts interactively for missing files, which hangs the async subprocess chime uses to fetch events. Create empty placeholders at init so calendar-sync can populate them on first sync.
2026-02-21fix(keybindings): make C-z a prefix map instead of unsetting itCraig Jennings
Unsetting C-z bound it to nil, which blocked font-config.el from binding C-z F. This cascaded through init and prevented alert and chime from loading.
2026-02-21fix(music): force case-insensitive search when adding songsCraig Jennings
Bind orderless-smart-case to nil in cj/music-fuzzy-select-and-add so typing uppercase characters doesn't switch to case-sensitive matching.
2026-02-20fix(mousetrap): use buffer-local keymaps via emulation-mode-map-alistsCraig Jennings
minor-mode-map-alist is global, so the last buffer to set its keymap won for all buffers. Dashboard's scroll+primary profile was immediately overwritten by other buffers' disabled profile. Switch to emulation-mode-map-alists with a buffer-local variable so each buffer gets its own independent keymap. Fixes dashboard click navigation.
2026-02-20chore: enable wttrin debug, clean up lorem-optimum startupCraig Jennings
- Enable wttrin-debug in weather-config.el - Remove redundant lipsum chain reset at startup (silences noisy message) - Improve learn message to identify lorem-optimum as source - Delete unused lipsum-generator.el (superseded by lorem-optimum)
2026-02-18feat(restclient): add REST API client for interactive API explorationCraig Jennings
restclient.el + restclient-jq integration with SkyFi API templates, tutorial file, auto key injection from authinfo, 17 ERT tests.
2026-02-18fix(org): remap date picker keys — . for today, <> for days, M-,/. for monthsCraig Jennings
Unbind comma, restore . to goto-today, use angle brackets for day navigation, and M-comma/M-dot for month navigation.
2026-02-16chore(yasnippet): move snippets into emacs.d for source controlCraig Jennings
Relocate snippets-dir from ~/sync/org/snippets/ to ~/.emacs.d/snippets/ and restore 28 snippet files from backup.
2026-02-16feat(org-noter): overhaul keybindings, dynamic split, background highlightCraig Jennings
- Move all org-noter bindings to C-; n prefix with which-key labels - Remove F6 global binding, add i in pdf-view-mode for insert-note-dwim - Auto-detect split direction from frame aspect ratio (threshold 1.4) - Add background highlight on notes window focus (matches music-config) - Fix session start to use find-file-noselect (keeps PDF visible) - Fix split fraction (70/30 doc/notes) - Replace hardcoded path with roam-dir from user-constants - Update commentary to reflect new workflow
2026-02-15fix(pdf): move keybindings to eval-after-load, add page-only scrollingCraig Jennings
use-package :config for pdf-tools never ran because opening a PDF loads pdf-view.el (provides 'pdf-view), not pdf-tools.el. Moved keybindings to with-eval-after-load 'pdf-view. Arrow keys now scroll within page only; C-up/C-down change pages.
2026-02-15fix(chrono-tools): correct undefined variable in timer reset messageCraig Jennings
notification-package → notification-sound in cj/tmr-reset-sound-to-default. Also remove 10 untestable modules from ERT checklist [13/14].
2026-02-15test: add 86 new tests, fix 3 production bugs, fix 8 stale testsCraig Jennings
New test coverage (86 tests across 7 files): - custom-case: 43 tests (title-case-region, upcase-dwim, downcase-dwim) - custom-datetime: 10 tests (all insert methods with mocked time) - config-utilities: 11 tests (format-build-time type branching) - org-capture-config: 22 tests (date-prefix + event-content) Production bugs found and fixed: - custom-case: title-case-region crashes on whitespace/punctuation-only input (char-after returns nil when no word chars found) - org-capture-config: browser branch missing empty-string guard on :initial plist value, producing stray newline in capture output - mousetrap-mode: keymap never registered in minor-mode-map-alist, so mode was silently not blocking any mouse events. Now pushes/removes on toggle. Additional fixes: - local-repository: fix cons cell syntax bug in localrepo-initialize (was calling vars as functions instead of using cons) - dupre-theme tests: update rainbow-delimiter color expectations - mousetrap tests: update dashboard profile (primary-click → scroll+primary) - music completion test: bind completion-ignore-case to prevent pollution - Delete redundant interactive recording test (duplicate of ERT version) Refactoring: - org-capture-config: extract cj/org-capture--date-prefix pure function from cj/org-capture-format-event-headline for testability Test checklist: todo.org updated to [11/25], removed untestable modules
2026-02-15fix(reveal): suppress date/caps on title slide, move transition to init optionsCraig Jennings
- Add date:nil, timestamp:nil, author:t to template OPTIONS - Set global CSS override (text-transform:none) via org-reveal-head-preamble - Move transition from obsolete REVEAL_TRANS to REVEAL_INIT_OPTIONS - Default transition changed to "none" - Global init options now reference cj/reveal-default-transition constant
2026-02-15fix(keybindings): remove auth-cache binding from C-; ACraig Jennings
Resolves conflict with align-regexp on the same key. Auth cache reset is accessible via M-x cj/reset-auth-cache.
2026-02-15feat(music): add playlist UI with header overlay, track styling, and testsCraig Jennings
Replace raw file paths with clean track descriptions (Artist - Title [M:SS]), add multi-line header overlay showing playlist info, now-playing, mode indicators with gold/muted toggle states, and keybinding hints. Style non-playing tracks in Dupre steel, playing track in Dupre gold. Playlist window now opens from the bottom at 50% height with subtle background highlight on focus. Unit tests for format-duration (13 tests) and track-description (16 tests).
2026-02-15feat(dashboard,calibredb): reorganize nav buttons, tweak display settingsCraig Jennings
Dashboard: reorder nav rows (Code/Email/Agenda/Files/Music, Feeds/IRC/ Flashcards/Books/Terminal), show 10 recent files with filename only, exclude EMMS history from recents. Calibredb: use bookmark emoji for favorites, change favorite keyword to in-progress.
2026-02-15docs(music): add ncmpcpp keybinding comparison table to commentaryCraig Jennings
Document playlist-mode keybindings with ncmpcpp default alignment status (83% match). Note intentional divergences (SPC/p swap, x=consume vs crossfade) and EMMS-only features.
2026-02-15feat(music): align EMMS keybindings with ncmpcpp, add consume modeCraig Jennings
Reconcile playlist-mode bindings with ncmpcpp defaults: add ncmpcpp- compatible aliases (>/<, +, S-up/S-down, c), new toggles (r repeat, t repeat-track, z random, x consume), info keys (i, o), and relocate radio (r→R), reload (R→g), shuffle (x→Z). Add consume mode that removes tracks from playlist after playback via emms-player-finished- hook. Fix buffer-local bug where emms-playlist-selected-marker was checked outside with-current-buffer. 13 ERT tests.
2026-02-14feat(dashboard): add recent files section to startup dashboardCraig Jennings
Added 5 most recent files below projects and bookmarks using dashboard's built-in recentf integration.
2026-02-14perf(calendar-sync): replace shell-out timezone conversion with pure ElispCraig Jennings
convert-tz-to-local was spawning a `date` subprocess per timestamp, causing ~15s parse freezes on Proton (223 events) and ~10s on Google (1543 events). Replaced with encode-time/decode-time ZONE argument — same TZ database, no subprocess overhead. Parse times now 0.2-2.8s. Also adds phase timing instrumentation behind cj/debug-modules flag.
2026-02-14feat(reveal): add org-reveal presentation workflow with ERT testsCraig Jennings
Replaced pandoc-based reveal.js export with native ox-reveal integration. New org-reveal-config.el module provides offline, self-contained HTML export with keybindings under C-; p. Includes setup script for reveal.js 5.1.0 and 34 ERT tests covering header template and title-to-filename helpers.
2026-02-14test: add ERT coverage for modeline-config and hugo-configCraig Jennings
Add 67 tests across 6 new test files for modeline and hugo modules. Refactor hugo-config: extract post-file-path and post-template helpers from interactive new-post function for testability. Update todo.org with test audit (31 modules), priority adjustments, and task cleanup.
2026-02-14feat(hugo): extract hugo-config module with C-; h keybindingsCraig Jennings
Standalone module for ox-hugo blog workflow. One-file-per-post structure with keybindings for new post, export, open dir (dirvish and system file manager), and toggle draft.
2026-02-13feat(export): add ox-hugo config with capture templateCraig Jennings
Enable ox-hugo for Hugo blog workflow. Adds C-c c h capture template for quick post creation with auto-generated slug and date.
2026-02-13fix(agenda): scope file scan to immediate subdirs of ~/projectsCraig Jennings
Replace recursive directory-files-recursively with shallow scan that only checks ~/projects/*/todo.org. Excludes nested archive todo.org files and keeps ~/code and ~/.emacs.d out of agenda.
2026-02-09fix(keyboard): support daemon mode for M-S- key translationsCraig Jennings
GUI key translations (M-O → M-S-o, etc.) were never installed in daemon mode because env-gui-p returns nil at startup with no frame. Use server-after-make-frame-hook for daemon, emacs-startup-hook otherwise. Also adds timestamps to assemblyai-transcribe output.
2026-02-09fix(font): prevent HarfBuzz SIGSEGV crash on emoji in mu4e headersCraig Jennings
Emacs 30.2 + HarfBuzz 12.3.2 segfaults when arabic-shape-gstring is called on emoji characters during mu4e header rendering. Disable Arabic composition ranges, set inhibit-compacting-font-caches, and disable auto-composition in mu4e-headers-mode. Remove duplicate bidi settings from system-defaults.el (already in early-init.el).
2026-02-06fix(test): add missing testutil require for sanitize-org-body testsCraig Jennings
2026-02-06feat(recording): rewrite device setup, fix video stop, update modeline iconsCraig Jennings
Video stop fix: kill wf-recorder (producer) first on Wayland so ffmpeg gets clean EOF, then signal process group. Replaces sit-for with poll-based wait-for-exit. Fixes zero-byte output files. Device selection: rewrite quick setup to show all available mics with PulseAudio descriptions, auto-detect default sink monitor for system audio. Skip confirmation dialog, add Cancel option to mic list. Modeline: replace red dot emoji with nerd font icons (mic/camcorder). Rename quick-setup-for-calls to quick-setup, rebind C-; r s / C-; r S. 173 recording tests pass (was 165).
2026-02-06fix(calendar-sync): increase fetch timeout for large calendarsCraig Jennings
Google calendar (7k+ events, 4.5MB) was hitting the 30s hard-coded curl timeout. Use configurable calendar-sync-fetch-timeout (default 120s) with a separate 10s connect-timeout for fast failure on unreachable hosts.
2026-02-06fix(calendar-sync): sanitize description text to prevent org heading corruptionCraig Jennings
Event descriptions containing lines starting with * were being interpreted as org headings, breaking file structure. Replace leading asterisks with dashes before writing descriptions.
2026-02-05fix(calendar-sync): fix heading order, continuation lines, and exception ↵Craig Jennings
text cleaning Three bugs found during manual verification of calendar sync output: 1. Heading/timestamp order reversed in event-to-org — nreverse pattern put timestamp before the org heading. Swap initial list order. 2. get-property continuation line regex broken — the ^ anchor in "^\n[ \t]" prevented matching at the correct position, truncating long DESCRIPTION values at the first ICS line fold. Remove anchor, add explicit position check (matching get-all-property-lines pattern). 3. collect-recurrence-exceptions didn't clean text — exception instances got raw ICS text (literal \n, HTML tags) replacing the cleaned base event text. Wrap summary/description/location in clean-text.
2026-02-05feat(calendar-sync): add event details — attendees, organizer, status, URLCraig Jennings
Add ICS text unescaping (RFC 5545), HTML stripping, and new fields (attendees/status, organizer, meeting URL) to calendar-sync.el. event-to-org now outputs org property drawers. 88 new tests across 10 test files, 146/146 pass. Also fix pre-existing test require order and keymap guard issues.
2026-02-05feat(dirvish): add TrueNAS backups quick access shortcutCraig Jennings
Add rbk shortcut to access /mnt/vault/backups on truenas.local
2026-02-04chore: minor housekeeping updatesCraig Jennings
- Add typo correction: should't -> shouldn't - Add dirvish shortcut pcr for career project - Rename pc -> pcl for clipper project - Minor whitespace cleanup in init.el
2026-02-04fix(email): require mm-decode at load time for macro availabilityCraig Jennings
mm-handle-type is a macro that must be available when the code is read, not just at runtime. Changed from declare-function to require.
2026-02-04fix(email): improve MIME handle parsing for email viewerCraig Jennings
- Add helper functions for robust MIME structure navigation - cj/--email-handle-is-type-p: check handle content type - cj/--email-find-displayable-part: recursively find HTML/plain text - Handle both leaf handles and nested multipart structures - Add 9 unit tests covering normal, boundary, and error cases
2026-02-04style(dirvish): normalize indentation and add TrueNAS shortcutsCraig Jennings
- Convert tabs to spaces for consistent formatting - Add quick-access entries for truenas.local and truenas (tailscale)
2026-02-04refactor(calendar): move calendar URLs into calendar-sync.elCraig Jennings
Consolidate calendar configuration within the module itself rather than requiring setup in init.el. Improves module encapsulation.
2026-02-04feat(buffer): add EWW and email viewing functionsCraig Jennings
- cj/view-buffer-in-eww (C-; b w): render HTML files in EWW - cj/view-email-in-buffer (C-; b e): parse MIME and render .eml files - Add forward declarations for mm-decode functions - Fix wide docstring in cj/diff-buffer-with-file
2026-02-04feat(lsp): disable LSP on remote/TRAMP filesCraig Jennings
Prevents slow startup and project root prompts when editing files over TRAMP connections. - Add lsp-enable-remote nil in :init (before lsp-mode loads) - Add explicit remote check in shell script setup hook
2026-02-03fix(video-recording): kill orphan wf-recorder on WaylandCraig Jennings
On Wayland, video recording uses a shell pipeline: wf-recorder | ffmpeg. When stopping, SIGINT only reaches ffmpeg, leaving wf-recorder running as an orphan. This blocks subsequent recordings (0-byte files or no file). Fix: - On stop: explicitly pkill wf-recorder before interrupting ffmpeg - On start: kill any orphan wf-recorder from previous crashes - Increase finalization wait from 0.2s to 0.5s for proper cleanup
2026-02-03fix(video-recording): use generic 'Built-in Audio' labelCraig Jennings
Renamed 'Built-in Laptop Audio' to 'Built-in Audio' since PCI audio devices are used on both laptops and desktops.
2026-02-03fix(video-recording): correct wf-recorder flags for Wayland pipelineCraig Jennings
The wf-recorder command had several incorrect flags: - `--no-audio`: not a valid option (wf-recorder doesn't record audio by default) - `-c h264`: wrong encoder name, should be `libx264` - `-f matroska -o -`: `-o` is for selecting monitor, `-f` is for output file Fixed to use: `-y -c libx264 -m matroska -f /dev/stdout` - `-y`: auto-confirm overwrite (avoids prompt for /dev/stdout) - `-c libx264`: correct encoder name - `-m matroska`: set container format - `-f /dev/stdout`: output file to stdout for piping to ffmpeg
2026-02-03perf(lorem-optimum): fix O(n²) tokenization algorithmCraig Jennings
The tokenizer was creating substring copies on every iteration: - (substring text pos (1+ pos)) for whitespace check - (substring text pos) for regex matching - copies ALL remaining text This caused 10K word tokenization to take 727ms instead of 6ms. Fix: Use string-match with start position parameter and check characters directly with aref instead of creating substrings. Performance improvement: - Tokenize 10K words: 727ms → 6ms (120x faster) - Learn 10K words: 873ms → 15ms (59x faster) - Learn 100K words: 70s → 208ms (341x faster)
2026-02-03feat(calendar-sync): add EXDATE support for excluded recurring event datesCraig Jennings
When someone deletes a single instance of a recurring meeting in Google Calendar, the calendar exports an EXDATE property marking that date as excluded. Previously, calendar-sync expanded the RRULE without filtering out these excluded dates, causing deleted instances to appear in org output. New functions: - calendar-sync--get-exdates: Extract all EXDATE values from event - calendar-sync--get-exdate-line: Get full EXDATE line with parameters - calendar-sync--parse-exdate: Parse EXDATE into datetime list - calendar-sync--collect-exdates: Collect excluded dates with TZ conversion - calendar-sync--exdate-matches-p: Check if occurrence matches an EXDATE - calendar-sync--filter-exdates: Filter out excluded dates from occurrences Modified calendar-sync--expand-recurring-event to collect and filter EXDATEs after RRULE expansion. Includes 47 new tests covering extraction, parsing, collection, filtering, and integration with RECURRENCE-ID exceptions.