Something like the following should work
(defun my-lenient-y-or-n-p (prompt)
(let ((query-replace-map (copy-keymap query-replace-map)))
(define-key query-replace-map [t] 'skip)
(y-or-n-p prompt)))
If you look at the documentation of y-or-n-p
, it mentions that it looks up the query-replace-map
to decide which action to take for a given key. I am quoting it here for completeness (emphasis mine)
(...)
To be precise, this function translates user input into responses by
consulting the bindings in query-replace-map
; see the documentation
of that variable for more information. In this case, the useful
bindings are act
, skip
, recenter
, scroll-up
, scroll-down
,
and quit
. An act
response means yes, and a skip
response means
no. A quit
response means to invoke keyboard-quit
. If the user
enters recenter
, scroll-up
, or scroll-down
responses, perform
the requested window recentering or scrolling and ask again.
(...)
So basically if we can invoke y-or-n-p
with modified query-replace-map
which defines the binding skip
as the default we should get what you want.
We can achieve this by copying the query-replace-map
(so that global value is unchanged) and defining the binding skip
for all undefined keys. So how do we define a default binding in a keymap, for this see the documentation of define-keymap
(emphasis mine)
(...) KEY is a string or a vector of symbols and characters, representing a
sequence of keystrokes and events. Non-ASCII characters with codes
above 127 (such as ISO Latin-1) can be represented by vectors. Two
types of vector have special meanings: [remap COMMAND] remaps any key
binding for COMMAND. [t] creates a default definition, which applies
to any event with no other definition in KEYMAP.
So binding [t]
to skip
in the copy of query-replace-map
should do the trick for us. Of course we let bind the new keymap around the call to y-or-no-p
so that the modified keymap is used instead of the global definition
emacs-startup-hook