aboutsummaryrefslogtreecommitdiff
path: root/modules
Commit message (Collapse)AuthorAgeFilesLines
* refactor(transcription): extract running-transcriptions and format-entryCraig Jennings2026-04-191-20/+25
| | | | | | | | | | | 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.
* refactor(transcription): extract four sentinel side-effect helpersCraig Jennings2026-04-191-40/+44
| | | | | | | | | | | | | | | | 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.
* refactor(transcription): extract init-log-file and track-transcriptionCraig Jennings2026-04-191-14/+16
| | | | | | | | | | | 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.
* refactor(transcription): extract cj/--build-process-environmentCraig Jennings2026-04-191-9/+15
| | | | | | 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.
* refactor(transcription): consolidate backends into descriptor alistCraig Jennings2026-04-191-39/+29
| | | | | | | | | | | | | | 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.
* refactor(org-contacts): remove dead boundp branchesCraig Jennings2026-04-191-16/+12
| | | | | | | | 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.
* fix(reconcile): restore repo iteration under projects-dir and code-dirCraig Jennings2026-04-191-1/+1
| | | | | | | | | | | 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.
* refactor(reconcile): extract helpers, add recursive repo discovery and 28 testsCraig Jennings2026-04-191-36/+48
| | | | | Extract should-skip-p, pull-clean, pull-dirty from 6-level nested reconcile-git-directory. Make find-git-repos recurse into sub-repos.
* fix: make this function recursiveCraig Jennings2026-04-181-4/+14
|
* fix: fix M-P by removing autoload cookie from keybindingCraig Jennings2026-04-181-1/+1
|
* feat(agenda): add project-filtered agenda view on C-f8Craig Jennings2026-04-091-2/+31
| | | | | | 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.
* feat(vterm): pass F8, F9, F10 through to EmacsCraig Jennings2026-04-072-1/+4
| | | | | | 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.
* refactor(calendar-sync): extract require-calendars guard from 4 locationsCraig Jennings2026-04-051-8/+10
| | | | | Replaced 4 copies of "if null calendars, warn" with a shared calendar-sync--require-calendars predicate.
* refactor(calendar-sync): extract RFC 5545 continuation line unfoldingCraig Jennings2026-04-051-17/+17
| | | | | Deduplicated the folded-line handling loop from get-property and get-all-property-lines into calendar-sync--unfold-continuation.
* refactor(calendar-sync): extract CN and email parsing from duplicated codeCraig Jennings2026-04-051-25/+19
| | | | | Extracted calendar-sync--extract-cn and calendar-sync--extract-email from identical logic in parse-attendee-line and parse-organizer.
* refactor(calendar-sync): remove dead function calendar-sync--timezone-nameCraig Jennings2026-04-051-5/+0
| | | | Function was defined but never called anywhere in the codebase.
* refactor(recording): extract select-from-labeled helper, flatten quick-setupCraig Jennings2026-04-051-33/+27
| | | | | | 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.
* refactor(recording): extract video command builder from ffmpeg-record-videoCraig Jennings2026-04-051-42/+42
| | | | | 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.
* refactor(recording): extract shared test-device helper from ↵Craig Jennings2026-04-051-21/+16
| | | | | | | 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.
* refactor(recording): unify parse-pactl-sources/sinks-verbose into single ↵Craig Jennings2026-04-051-45/+12
| | | | | | | 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.
* feat(music): add random-aware next/previous; refactor music + calendar-syncCraig Jennings2026-04-032-174/+136
| | | | | | | | | | 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.
* feat(org): add <cj structure template for daily prep comment blocksCraig Jennings2026-04-021-1/+3
| | | | Add org-tempo template expanding <cj TAB to #+begin_src cj: comment blocks.
* feat(music): add test coverage for 7 functions, refactor with extracted helpersCraig Jennings2026-04-011-36/+45
| | | | | | | | | | | | Add 47 new unit tests across 7 test files covering playlist-modified-p, assert-valid-playlist-file, playlist-tracks, create-radio-station, ensure-playlist-buffer, after-playlist-clear, and header-text. Extract three helpers to reduce duplication: assert-m3u-files-exist (dedupes 2 identical guards), sync-playlist-file (dedupes 3 state-sync patterns), and select-m3u-file (reusable M3U selection with cancel). Simplify append-track-to-playlist nesting from 6 to 4 levels. Delete unused cj/music-keymap-prefix variable.
* fix(slack): disable emojify in lui buffers, add org cache reset commandCraig Jennings2026-03-162-1/+27
| | | | | | Disable slack-buffer-emojify to prevent wrong-type-argument listp errors on emoji characters during lui-scroll-post-command recenter. Add C-; O c to reset org-element cache across all org-mode buffers.
* fix(slack): add error visibility to notification handlerCraig Jennings2026-03-141-8/+20
| | | | | | Websocket library silently swallows callback errors via condition-case. Wrap cj/slack-notify in condition-case to surface errors in *Messages*. Add cj/slack-test-notify command for pipeline verification.
* fix(slack): fix notification bug, add close-all-buffers commandCraig Jennings2026-03-101-1/+17
| | | | | Pass missing team arg to slack-message-mentioned-p (was breaking all channel notifications). Add cj/slack-close-all-buffers on C-; S Q.
* fix(music): place point on first track after playlist load/reloadCraig Jennings2026-03-101-2/+4
|
* fix(calendar-sync): handle variable-length date lists in RRULE UNTILCraig Jennings2026-03-092-5/+11
| | | | | | | date-to-time used (reverse date) which broke when RRULE UNTIL values were parsed as 5-element lists (year month day hour minute) from UTC timestamps. This caused recurring events with UTC UNTIL dates to expand to 0 occurrences, producing stale calendar entries.
* refactor(gptel): extract model-list and selection logic for testabilityCraig Jennings2026-03-061-20/+42
| | | | | | | - Extract cj/gptel--build-model-list from cj/gptel-change-model - Extract cj/gptel--current-model-selection from cj/gptel-change-model - Add test-ai-config-build-model-list.el (9 tests) - Add test-ai-config-current-model-selection.el (8 tests)
* refactor(gptel): lazy-load gptel-magit, rebind rewrite/context keysCraig Jennings2026-03-061-29/+47
| | | | | | | | | | - Replace use-package gptel-magit hook with autoloads via with-eval-after-load 'magit (loads gptel only on key press) - Move org header defuns above use-package to fix load order - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Add test-ai-config-gptel-magit-lazy-loading.el (8 tests) - Mark all ai-config cleanup items DONE in todo.org
* refactor(gptel): move config defuns to top level, rebind keys, set reasoningCraig Jennings2026-03-061-39/+34
| | | | | | | | | - Move cj/gptel--fresh-org-prefix, cj/gptel--refresh-org-prefix, cj/gptel-backend-and-model, cj/gptel-insert-model-heading out of use-package :config to top level (fixes byte-compile warnings) - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Update todo.org with completed cleanup items
* test(gptel): add unit tests for ai-config, remove dead cj/gptel-backendsCraig Jennings2026-03-061-6/+0
| | | | | | | | - Add testutil-ai-config.el with gptel stubs for batch testing - Add tests for cj/gptel--model-to-string (9 tests) - Add tests for cj/gptel--fresh-org-prefix (8 tests) - Add tests for cj/gptel-backend-and-model (8 tests) - Remove dead cj/gptel-backends defvar (duplicates cj/gptel--available-backends)
* fix(gptel): fix docstring warnings, rename model->string to model-to-stringCraig Jennings2026-03-061-15/+10
| | | | | | | | - Escape single quote in cj/ensure-gptel-backends docstring - Wrap cj/gptel--available-backends docstring to 80 chars - Add missing docstring to cj/gptel--model-to-string - Rename cj/gptel--model->string to cj/gptel--model-to-string - Mark stale model list task as DONE in todo.org
* fix(gptel): remove duplicate backend setter, fix commentary keybindingsCraig Jennings2026-03-061-10/+9
| | | | | | Remove redundant gptel-backend setq and orphaned section header. Fix commentary keybinding references: M-a → C-; a, correct buffer add (.) and rewrite (&) bindings.
* feat(gptel): update Claude models, fix default system promptCraig Jennings2026-03-061-5/+8
| | | | | | | | Update Anthropic model list to current: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001. Fix gptel--system-message not picking up the custom default.org directive (defvar set at load time before gptel-prompts replaces the default entry). Add cleanup tasks for ai-config, calibredb, and slack reaction workflow to todo.org.
* fix(slack): fix notification and mark-as-read bugsCraig Jennings2026-03-061-3/+12
| | | | | | Notifications silently failed: slack-room-im-p (nonexistent) replaced with slack-im-p; slack-message-to-string replaced with slack-message-body. Mark-as-read bound to nonexistent function; added cj/slack-mark-read-and-bury.
* feat: add Slack client module with dashboard integrationCraig Jennings2026-03-062-0/+149
| | | | | | Add emacs-slack config with auth-source credentials, DM/mention-only notifications via notify script, compose buffer workflow, and dashboard icon. Keybindings under C-; S prefix.
* session: switch Python LSP to pyright, add Django web-mode configCraig Jennings2026-03-043-120/+124
| | | | | | Replaced pylsp with lsp-pyright in prog-python.el for better type inference, especially for Django ORM. Added Django engine and indent settings to web-mode in prog-webdev.el. Pyright already installed via pacman.
* feat(json,yaml): add tree-sitter modes, formatting, and jq integrationCraig Jennings2026-03-024-16/+98
| | | | | | | New prog-json module: json-ts-mode with jq formatting (C-; f) and jq-interactively (C-c C-q). Upgraded prog-yaml to yaml-ts-mode with prettier formatting. Both use treesit-auto for grammar management. Includes 18 new tests (10 JSON, 8 YAML), 185/185 passing.
* feat(recording): intuitive labels, show muted devices, add app namesCraig Jennings2026-02-261-49/+105
| | | | | | | | | | | | | Rework quick-setup device picker: - Labels: [in use], [ready], [available], [muted] instead of PulseAudio jargon (RUNNING/IDLE/SUSPENDED) - Muted devices now shown (previously hidden) so users can see all connected hardware and understand why a device is unsuitable - Sink step shows which apps are playing through each output: "JDS Labs Element IV [in use] (Firefox, Spotify)" - Prompt changed from "audio output to monitor" to "audio output to capture" to avoid PulseAudio monitor terminology confusion - Sort order: in use → ready → available → muted
* feat(recording): replace icons with text state labels in quick-setupCraig Jennings2026-02-261-75/+60
| | | | | | | | | | | | Replace hard-to-distinguish nerd font icons with clear text labels: Jabra SPEAK 510 Mono [active - running] Shure MV7+ Analog Stereo [active - idle] Ryzen HD Audio Controller [inactive - suspended] Both mic and sink steps use the same labeling. Devices sorted running → idle → suspended. Removed mic-active-p and sink-active-p helpers — state now comes directly from the verbose pactl parsers via get-available-mics/sinks which return (name description state).
* feat(recording): add mic indicators and fix misleading sink iconCraig Jennings2026-02-261-17/+42
| | | | | | | | | Mic step now shows 󰍬 with green/dim coloring to indicate which mics are actively in use (RUNNING state), with active mics sorted to top. Changed sink inactive icon from 󰖁 (slashed speaker, reads as "broken/muted") to 󰖀 (plain speaker, reads as "no streams right now"). Active sinks still show 󰕾.
* fix(recording): remove drift detection that overrides explicit sink choiceCraig Jennings2026-02-261-22/+14
| | | | | | | | | | | | Validation Check 2 (default sink drifted) would silently replace the user's explicit sink selection from quick-setup with the default sink's monitor on every recording start. Removed it — if the device still exists, trust the user's choice. The no-audio warning (Check 3) already catches wrong-sink scenarios. Also fix commentary: device selection does not persist across sessions (both vars are plain defvar), and update validation section to match the two remaining checks.
* feat(recording): show sinks with active audio indicators in quick-setupCraig Jennings2026-02-261-35/+123
| | | | | | | | | | Quick-setup (C-; r s) is now a two-step flow: pick a mic, then pick an audio output sink. Sinks display 󰕾/󰖁 icons with green/dim coloring to indicate which have active audio streams, with active sinks sorted to the top. The chosen sink's .monitor is set as the system audio device. This replaces the old auto-default-sink approach, letting users see where audio is actually going and pick the right sink in one command.
* fix(recording): replace blocking y-or-n-p with non-blocking warningCraig Jennings2026-02-261-9/+20
| | | | | | | | The no-audio warning was a y-or-n-p prompt that blocked recording start. This fires too often in legitimate scenarios (starting before a meeting connects, during silence). Replace with a message in the echo area and diagnostic steps logged silently to *Messages*. Also add pre-recording validation to the Commentary section.
* feat(recording): validate system audio device before recordingCraig Jennings2026-02-261-0/+81
| | | | | | | | | | 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>
* fix(pdf): move pdf-tools-install to eval-after-load and revert stale buffersCraig Jennings2026-02-251-2/+11
| | | | | | | 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.
* feat(buffer): add open-with-default-app and open-with-program keybindingsCraig Jennings2026-02-253-10/+12
| | | | | | 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.
* chore: rename chime.el references to ChimeCraig Jennings2026-02-233-5/+5
| | | | | Update load-path, GitHub URL, and all project/package name references to reflect the chime.el → Chime rename.
* fix(user-constants): create calendar data files on first launchCraig Jennings2026-02-211-0/+6
| | | | | | 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.