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
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))