I like binding M-n
to make-frame, so I have the following in my init file:
(bind-key* "M-n" 'make-frame)
The *
form of bind-key allows me to override other minor-mode M-n
bindings. But when I'm using the minibuffer (e.g. find-file), I'd rather M-n
retained it's original behavior and ran next-history-element
.
I'm currently using a workaround, but I'm hoping there's a better solution.
(defun ivan-unbind-make-frame () (bind-key* "M-n" nil))
(defun ivan-rebind-make-frame () (bind-key* "M-n" 'make-frame))
(add-to-list 'minibuffer-setup-hook #'ivan-unbind-make-frame)
(add-to-list 'minibuffer-exit-hook #'ivan-rebind-make-frame)
Another approach I considered was to create a keymap of the minibuffer bindings I want to take precedence over bind-key* bindings and put it in an entry at the front of emulation-mode-map-alists.
(defvar overriding-minibuffer-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "M-n") #'next-history-element)
map))
(defvar minibuffer-active-p nil)
(add-to-list 'emulation-mode-map-alists
`((minibuffer-active-p . ,overriding-minibuffer-map)))
(defun minibuffer-active-on () (setq minibuffer-active-p t))
(defun minibuffer-active-off () (setq minibuffer-active-p nil))
(add-to-list 'minibuffer-setup-hook #'minibuffer-active-on)
(add-to-list 'minibuffer-exit-hook #'minibuffer-active-off)
This is more complicated and still doesn't free me from using minibuffer setup/exit hooks (unless there's an existing variable that reflects whether the minibuffer is active, but I couldn't find one). It also makes the assumption that M-n
runs next-history-element in all minibuffer use-cases, and I'm not sure that's true.
Is there a better way to handle this, or should I stick with my current solution?