Keep cursor at beginning of isearch result
Here's what I use. It moves the cursor to the beginning of the result
every time the result is updated. That way, you can always move to a
precise location when searching forward. The cursor will always be at
the beginning of your search result, and typing more characters to
narrow the result won't change where the cursor lands.
Source: Endless
Parentheses
(defun endless/goto-match-beginning ()
"Go to the start of current isearch match.
Use in `isearch-mode-end-hook'."
(when (and (not (eq this-command 'isearch-exit))
isearch-forward
(number-or-marker-p isearch-other-end)
(not mark-active)
(not isearch-mode-end-hook-quit))
(goto-char isearch-other-end)))
;; Keep cursor at start of search result.
(add-hook 'isearch-update-post-hook
#'endless/goto-match-beginning)
Exiting the search with <return> or an edit command
Once your cursor reaches the desired location, you can exit isearch
with the "<return>" key and make whatever changes you wanted to make
there. In addition, the use of any keybinding which is not in
isearch-mode-map
will exit isearch without you having to press
"<return>" at all. So you can jump to a spot and use "C-d", "C-t",
"C-k", etc. without having to explicitly exit isearch-mode
first.
One thing I noticed was that "M-c" is bound to
isearch-toggle-case-fold
in isearch-mode-map
, but that command has
a duplicate binding at "M-s c". "M-c" conflicts with
capitalize-word
(or capitalize-dwim
if you prefer). So I removed
the "M-c" binding, and now I can exit isearch with any of the
letter-case bindings ("M-u", "M-l" and "M-c").
(define-key isearch-mode-map (kbd "M-c") nil)
As far as I can tell, this leaves "C-w" and "C-y" as the only keys
left in isearch-mode-map
that conflict with editing commands bound
in the global-map
. So if you want to cut or paste, you'll have to
exit isearch-mode
first. But you can do any other type of edit as
soon as the cursor lands there.
Exiting at the beginning or end of the search result
But what if you do want to explicitly exit isearch-mode
before
proceeding? And what if sometimes you want to exit with point at the
beginning of the result (which we just ensured), but also sometimes
you want to exit at the end?
Emacs's default approach requires moving to the other end of the
result before exiting the search. But why not do that in one keypress
instead of two?
(defun my-isearch-bor-exit ()
"Ensure point is at beginning of isearch result and exit."
(interactive)
(when (< isearch-other-end (point))
(goto-char isearch-other-end))
(call-interactively 'isearch-exit))
(defun my-isearch-eor-exit ()
"Ensure point is at end of isearch result and exit."
(interactive)
(when (>= isearch-other-end (point))
(goto-char isearch-other-end))
(call-interactively 'isearch-exit))
(define-key isearch-mode-map (kbd "C-m") 'my-isearch-bor-exit) ; left
(define-key isearch-mode-map (kbd "<return>") 'my-isearch-eor-exit) ; right
The "<return>" keybinding will probably not work if you use Emacs in a
terminal, though it works fine in the GUI. In a terminal, "C-m"
represents the return key. So if you will ever use Emacs in a
terminal, pick a different key besides "<return>" for exiting at the
end of the result.
C-r
before theRET
.advice-add
and defining a new function, but it doesn't work. Maybe am I doing something wrong withisearch-mode-map
? @Drew sorry if it's a dup, my Google-fu couldn't provide an answer. Can you point me to an already existing answer source?(defun _isearch-repeat-backward (&rest _) (isearch-repeat-backward))
and then(advice-add 'isearch-exit :before #'_isearch-repeat-backward)
works (for some value of "works"), It works in the simple case where the search is successful, but It gets really confusing when you try to exit from an unsuccessful search. My question is: why do you want this behavior? The standard behavior is carefully thought out and I think you are better off NOT changing it. But if you can describe the use case, somebody might have a better idea of how to do what you want.