aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/config-utilities.el28
-rw-r--r--modules/dirvish-config.el10
-rw-r--r--modules/org-capture-config.el8
-rw-r--r--modules/prog-general.el8
-rw-r--r--modules/transcription-config.el22
-rw-r--r--modules/undead-buffers.el11
-rw-r--r--modules/video-audio-recording.el41
7 files changed, 70 insertions, 58 deletions
diff --git a/modules/config-utilities.el b/modules/config-utilities.el
index 4332f407..62fc29d0 100644
--- a/modules/config-utilities.el
+++ b/modules/config-utilities.el
@@ -196,27 +196,27 @@ Returns the count of files deleted."
count user-emacs-directory)))
(keymap-set cj/debug-config-keymap "c d" 'cj/delete-emacs-home-compiled-files)
-(defun cj/compile-this-elisp-buffer ()
- "Compile the current .el: prefer native (.eln), else .elc. Message if neither."
- (interactive)
- (unless (and buffer-file-name (string-match-p "\\.el\\'" buffer-file-name))
- (user-error "Not visiting a .el file"))
- (save-buffer)
- (let ((file buffer-file-name))
+(defun cj/--compile-elisp-file (file &optional available-p)
+ "Compile FILE: prefer async native, then sync native, then byte-compile.
+AVAILABLE-P decides which compilers exist; it defaults to `fboundp'. It is
+a parameter so tests can force each branch without redefining `fboundp':
+an `fset' on that subr pulls in comp-run and bytecomp, whose own `defun'
+of `byte-compile-file' then lands on top of any test double."
+ (let ((available-p (or available-p #'fboundp)))
(cond
;; Native compilation (async preferred)
- ((fboundp 'native-compile-async)
+ ((funcall available-p 'native-compile-async)
(native-compile-async file)
(message "Queued native compilation for %s" file))
;; Native compilation (sync, if async not available)
- ((fboundp 'native-compile)
+ ((funcall available-p 'native-compile)
(condition-case err
(progn
(native-compile file)
(message "Native-compiled %s" file))
(error (message "Native compile failed: %s" (error-message-string err)))))
;; Byte-compile fallback
- ((fboundp 'byte-compile-file)
+ ((funcall available-p 'byte-compile-file)
(let ((out (byte-compile-file file)))
(if out
(message "Byte-compiled -> %s" out)
@@ -224,6 +224,14 @@ Returns the count of files deleted."
;; Neither facility available
(t
(message "No compilation available (no native-compile, no byte-compile)")))))
+
+(defun cj/compile-this-elisp-buffer ()
+ "Compile the current .el: prefer native (.eln), else .elc. Message if neither."
+ (interactive)
+ (unless (and buffer-file-name (string-match-p "\\.el\\'" buffer-file-name))
+ (user-error "Not visiting a .el file"))
+ (save-buffer)
+ (cj/--compile-elisp-file buffer-file-name))
(keymap-set cj/debug-config-keymap "c ." 'cj/compile-this-elisp-buffer)
;; --------------------------- Information Reporting ---------------------------
diff --git a/modules/dirvish-config.el b/modules/dirvish-config.el
index 6c849198..e9b9fde6 100644
--- a/modules/dirvish-config.el
+++ b/modules/dirvish-config.el
@@ -29,7 +29,7 @@
;; - S: Study — start an org-drill session on the .org file at point
;; - M-D (Meta-Shift-d): DWIM shell commands menu
;; - TAB: Toggle subtree expansion
-;; - F11: Toggle sidebar view
+;; - F9: Toggle sidebar view
;;; Code:
@@ -653,7 +653,13 @@ no popup frame is live."
(("C-x d" . dirvish)
("C-x C-d" . dirvish)
("C-x D" . dirvish)
- ("<f11>" . dirvish-side)
+ ;; F9, not F11: F11 is stock Emacs's toggle-frame-fullscreen, the same key
+ ;; every other application uses, and the sidebar sat on it for years by
+ ;; shadowing that. F9 is the free bare F-key: ai-term left it for M-SPC
+ ;; in June 2026 and the recording chord came off it on 2026-09-22. F2 is
+ ;; the preview key (markdown-mode binds it) and F5 is reserved for the
+ ;; debug backend, so neither was a candidate.
+ ("<f9>" . dirvish-side)
:map dirvish-mode-map
("bg" . cj/set-wallpaper)
("/" . dirvish-narrow)
diff --git a/modules/org-capture-config.el b/modules/org-capture-config.el
index b7250f1e..8f5903fe 100644
--- a/modules/org-capture-config.el
+++ b/modules/org-capture-config.el
@@ -145,12 +145,16 @@ re-scanning large target files after the first successful lookup."
:around #'cj/org-capture--set-target-location-advice))
;; --------------------------- Capture F-Key Guard -----------------------------
-;; The global popup keys (F1 dashboard sweep, F10 music, F11 dirvish-side,
+;; The global popup keys (F1 dashboard sweep, F9 dirvish-side, F10 music,
;; F12 terminal, M-SPC agent swap) fire even while a capture is in progress
;; and pop their UI over the capture popup. org-capture-mode is a minor
;; mode active exactly for the capture's duration and its keymap shadows
;; the global map, so blocking the keys there scopes the guard precisely:
;; the moment the capture finalizes or aborts, the keys work again.
+;;
+;; The list follows the command, not the key. F11 was on it while it held
+;; dirvish-side; now that F11 is the frame fullscreen toggle it pops nothing
+;; over a capture and stays usable.
(defun cj/--org-capture-blocked-key ()
"Refuse a global popup key while a capture is in progress."
@@ -160,7 +164,7 @@ re-scanning large target files after the first successful lookup."
(defvar org-capture-mode-map)
(with-eval-after-load 'org-capture
- (dolist (key '("<f1>" "<f10>" "<f11>" "<f12>" "M-SPC"))
+ (dolist (key '("<f1>" "<f9>" "<f10>" "<f12>" "M-SPC"))
(keymap-set org-capture-mode-map key #'cj/--org-capture-blocked-key)))
;; ----------------------- Project-Aware Capture Target ------------------------
diff --git a/modules/prog-general.el b/modules/prog-general.el
index 77ff88a5..e9586a97 100644
--- a/modules/prog-general.el
+++ b/modules/prog-general.el
@@ -119,9 +119,11 @@ REGEXP must be a string or an rx form."
;; Manages tree-sitter grammars. Install is 'prompt, never t: with t,
;; merely opening a file could trigger a network download and a compiler
-;; build mid-edit. Batch/test runs never load treesit-auto (no package
-;; init), so they can never install. Fresh-machine bootstrap is the
-;; explicit `cj/install-treesit-grammars' command below.
+;; build mid-edit. `make test' runs with no package init and so never
+;; loads treesit-auto, but a test file that calls `package-initialize'
+;; itself does load it, and a tree-sitter mode then prompts for a missing
+;; grammar; such tests must skip on `treesit-ready-p'. Fresh-machine
+;; bootstrap is the explicit `cj/install-treesit-grammars' command below.
(defun cj/treesit-auto-pin-go-revision (recipes)
"Pin the Go grammar revision in treesit-auto RECIPES.
Return the updated Go recipe, or nil when RECIPES has no Go entry.
diff --git a/modules/transcription-config.el b/modules/transcription-config.el
index 944063b8..6d7e39b9 100644
--- a/modules/transcription-config.el
+++ b/modules/transcription-config.el
@@ -33,6 +33,11 @@
;; - 'assemblyai: Cloud transcription with speaker diarization
;; API key retrieved from authinfo.gpg (machine api.assemblyai.com)
;; - 'local-whisper: Local transcription (requires whisper installed)
+;; - 'ratio: Self-hosted whisper plus speaker diarization on my transcription
+;; host, via scripts/ratio-transcribe (ssh queue; falls back to a local
+;; worker when the host is unreachable). No API key. SPEAKERS=N in the
+;; environment pins the diarizer's speaker count; 1 is right for a
+;; recording that holds only one side of a call.
;;
;; NOTIFICATIONS:
;; - "Transcription started on <file>"
@@ -56,7 +61,8 @@
"Transcription backend to use.
- `openai-api': Fast cloud transcription via OpenAI API
- `assemblyai': Cloud transcription with speaker diarization via AssemblyAI
-- `local-whisper': Local transcription using installed Whisper")
+- `local-whisper': Local transcription using installed Whisper
+- `ratio': Self-hosted whisper plus diarization on my transcription host")
(defvar cj/transcription-keep-log-when-done nil
"Whether to keep log files after successful transcription.
@@ -74,9 +80,11 @@ Status: running, complete, error")
(defconst cj/--transcription-backends
'((openai-api :script "oai-transcribe" :auth-host "api.openai.com" :env-var "OPENAI_API_KEY")
(assemblyai :script "assemblyai-transcribe" :auth-host "api.assemblyai.com" :env-var "ASSEMBLYAI_API_KEY")
- (local-whisper :script "local-whisper" :auth-host nil :env-var nil))
+ (local-whisper :script "local-whisper" :auth-host nil :env-var nil)
+ (ratio :script "ratio-transcribe" :auth-host nil :env-var nil))
"Per-backend descriptors. Each entry: (SYMBOL :script S :auth-host H :env-var V).
-`:auth-host' and `:env-var' are nil for local backends that need no API key.")
+`:auth-host' and `:env-var' are nil for backends that need no API key: the
+local whisper install, and the self-hosted ratio queue reached over ssh.")
(defun cj/--backend-plist (backend)
"Return the descriptor plist for BACKEND, or signal if unknown."
@@ -470,9 +478,11 @@ duration is computed from START-TIME."
"Switch transcription backend.
Prompts with completing-read to select from available backends."
(interactive)
- (let* ((backends '(("assemblyai" . assemblyai)
- ("openai-api" . openai-api)
- ("local-whisper" . local-whisper)))
+ ;; Offer exactly the descriptor set. This used to carry its own list, so
+ ;; a backend added to the descriptors was reachable only by setq.
+ (let* ((backends (mapcar (lambda (entry)
+ (cons (symbol-name (car entry)) (car entry)))
+ cj/--transcription-backends))
(current (symbol-name cj/transcribe-backend))
(prompt (format "Transcription backend (current: %s): " current))
(choice (completing-read prompt backends nil t))
diff --git a/modules/undead-buffers.el b/modules/undead-buffers.el
index 21232e50..e6574a0e 100644
--- a/modules/undead-buffers.el
+++ b/modules/undead-buffers.el
@@ -40,7 +40,16 @@
;; unsupported, and emacsclient silently retried on $DISPLAY, so the first
;; frame of every 31.1 session opened on XWayland. I bury it instead, the
;; same choice desktop.el makes in `desktop-clear-preserve-buffers'.
- "*Warnings*")
+ "*Warnings*"
+ ;; The async native-compile log stays alive for the same reason, one
+ ;; buffer over. comp-run parks every compile worker on this buffer and
+ ;; the worker's sentinel reads it back before starting the next job.
+ ;; The startup sweep killed it, which SIGHUPs every :noquery worker under
+ ;; it; each sentinel then died in `with-current-buffer' on the dead
+ ;; buffer and `comp--run-async-workers' never ran again, so the queue
+ ;; sat stranded for the life of the daemon, nothing was ever cached, and
+ ;; every boot re-ran the same compile storm at the first frame.
+ "*Async-native-compile-log*")
"Buffer names to bury instead of killing (exact match).")
(defvar cj/undead-buffer-regexps nil
diff --git a/modules/video-audio-recording.el b/modules/video-audio-recording.el
index 65a8612f..8fd3d23b 100644
--- a/modules/video-audio-recording.el
+++ b/modules/video-audio-recording.el
@@ -300,40 +300,13 @@ Changes take effect on the next recording (not the current one)."
(cj/register-prefix-map "r" cj/record-map)
-;; Fast chords for the two toggles, alongside C-; r v and C-; r a. F9 is free:
-;; ai-term vacated the F9 family when its swap moved to M-SPC, and
-;; `test-ai-term-f9-family-removed-globally' keeps it vacated. Both commands
-;; still take a prefix argument, so C-u F9 prompts for the recording location.
-(keymap-global-set "<f9>" #'cj/video-recording-toggle)
-(keymap-global-set "S-<f9>" #'cj/audio-recording-toggle)
-
-(defvar eat-mode-map)
-(defvar eat-semi-char-mode-map)
-(defvar eat-char-mode-map)
-(defvar eat-eshell-char-mode-map)
-
-;; EAT builds each input mode's keymap from key categories, and which categories
-;; a mode claims is what decides whether a chord reaches Emacs at all.
-;;
-;; Semi-char mode -- the default, and where every agent buffer sits -- is built
-;; from :ascii, :arrow and :navigation. It never claims function keys, so F9
-;; already fell through to the global map. The semi-char entry below is
-;; belt-and-braces rather than the fix, which is why it reads as redundant.
-;;
-;; Char mode is the one that swallows F9. It adds :function, binding f1 through
-;; f63 to eat-self-input, and it is a minor mode, so its map outranks
-;; eat-mode-map. Without an entry here the pair splits in the worst possible
-;; way: :function claims only the unmodified keys, so S-F9 would toggle audio in
-;; a char-mode buffer while F9 went to the program under the cursor. That is a
-;; recording you believe you started and didn't.
-;;
-;; Claiming both costs a char-mode program the use of F9. I would rather pay
-;; that than ship a toggle that works for audio and silently fails for video.
-(with-eval-after-load 'eat
- (dolist (map (list eat-semi-char-mode-map eat-mode-map
- eat-char-mode-map eat-eshell-char-mode-map))
- (keymap-set map "<f9>" #'cj/video-recording-toggle)
- (keymap-set map "S-<f9>" #'cj/audio-recording-toggle)))
+;; The toggles live only under C-; r. They had a fast chord (F9 video, S-F9
+;; audio, claimed in every EAT map too) until 2026-09-22: with Fn Lock on the
+;; Framework 13 the F-key row sends plain function keys, and a bare F9 press
+;; started a screen recording. Both chords went together, because a lone S-F9
+;; on a live F-key row is one fat-finger from an unwanted audio recording.
+;; Both commands still take a prefix argument, so C-u C-; r v prompts for the
+;; recording location.
(with-eval-after-load 'which-key
(which-key-add-key-based-replacements