I wanted to change the behavior of isearch in the minibuffer, making Return both accept a search result (isearch-exit
) and submit it (minibuffer-complete-and-exit
). This is the behavior I've grown to like with Ctrl-R in the shell.
(defun ivan/isearch-exit ()
"Run isearch-exit, and if in the minibuffer, submit the search result as input."
(interactive)
(isearch-exit)
(if (minibuffer-window-active-p (selected-window))
(minibuffer-complete-and-exit)))
The first time isearch-mode
is entered, it binds Return to isearch-exit
in overriding-terminal-local-map
(which takes precedence over all other keymaps). So I'm remapping isearch-exit
to my custome ivan/isearch-exit
in that keymap.
The problem is, I can't simply do the remapping in my init file, because overriding-terminal-local-map
is nil at that point. To get around this, I've done the remapping in a hook:
(defun ivan/remap-isearch-exit ()
(define-key
overriding-terminal-local-map [remap isearch-exit] #'ivan/isearch-exit))
(add-hook 'isearch-mode-hook #'ivan/remap-isearch-exit)
This works, but it means I'm doing the remapping every time isearch starts, which is unnecessary. Not that it hurts anything (except maybe performance?), but I'd like to avoid doing so. Now I've added a variable to make sure the remap only occurs the first time isearch is entered.
(setq ivan/remapped-isearch-exit nil)
(defun ivan/remap-isearch-exit ()
(unless ivan/remapped-isearch-exit
(setq ivan/remapped-isearch-exit t)
(define-key
overriding-terminal-local-map [remap isearch-exit] #'ivan/isearch-exit)))
But it makes me wonder if there's a better way. Is there something I could hook into that's run when overriding-terminal-local-map
is first created? Or is there another approach altogether that I'm not aware of?
Update: Thanks to lawlist's answer, I now have the following:
(eval-after-load "isearch"
'(define-key isearch-mode-map [remap isearch-exit] #'ivan/isearch-exit))