From 0b93863689038a385fd320440ac0a413ce81c4e1 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Fri, 31 Jul 2026 12:39:27 -0500 Subject: fix(prompts): make destructive confirms one keystroke I had to kill an Emacs session today over a prompt I could not answer. A second agent session held the selected window while "Overwrite hiroshi.m3u? (yes or no)" waited in another frame, so my keystrokes went to a terminal and the minibuffer stayed empty. Losing unsaved buffers is a far worse outcome than a mis-keyed confirm. So cj/confirm-strong becomes cj/confirm-destructive, and instead of binding use-short-answers to nil for a typed "yes" it reads a single y or n. Two things I kept: - No default. Only y and n answer, so a stray RET or space re-prompts rather than confirming a shutdown. - Pending input is discarded before the read. Without that the change would have been a bad trade: read-char-choice reads the input queue, so a key typed before the prompt painted would confirm instantly, where the old typed-"yes" absorbed it harmlessly. Worth being honest about what this does not fix. One keystroke does not make a prompt reachable when focus is elsewhere, and C-g is still the escape. It lowers the cost of the situation rather than preventing it. Six call sites: shutdown and reboot, shred, playlist overwrite and delete, and the two file overwrites. --- modules/music-config.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'modules/music-config.el') diff --git a/modules/music-config.el b/modules/music-config.el index 233bae72..92b04782 100644 --- a/modules/music-config.el +++ b/modules/music-config.el @@ -31,7 +31,7 @@ (require 'user-constants) (require 'keybindings) ;; provides cj/custom-keymap (require 'cj-window-toggle-lib) ;; side-window size memory (F10 toggle) -(require 'system-lib) ;; cj/confirm-strong (overwrite confirms) +(require 'system-lib) ;; cj/confirm-destructive (overwrite confirms) ;; Declare these foreign package vars special so `let'-binding them below ;; compiles as a dynamic bind, not a dead lexical local -- otherwise emms / @@ -833,7 +833,7 @@ reloaded playlist keeps its display name and cover art." (when (string-empty-p (string-trim chosen)) (user-error "Playlist name cannot be empty")) (when (and (file-exists-p full) - (not (cj/confirm-strong (format "Overwrite %s? " filename)))) + (not (cj/confirm-destructive (format "Overwrite %s? " filename)))) (user-error "Aborted saving playlist")) (make-directory dir t) (cj/music--write-playlist-file full tracks entries) @@ -875,7 +875,7 @@ clears its file association." (let ((file (cj/music--select-m3u-file "Delete playlist: "))) (if (not file) (message "Playlist deletion cancelled") - (unless (cj/confirm-strong (format "Delete playlist %s? " + (unless (cj/confirm-destructive (format "Delete playlist %s? " (file-name-nondirectory file))) (user-error "Aborted deleting playlist")) (cj/music--delete-playlist-file file) -- cgit v1.2.3