If I use isearch to search for the word "accommodating" in my document, I have to type acc before the cursor jumps to the word. When I press enter the cursor is on the the second "c" as in acCommodating. This strikes me as rather unintuitive because I have to go back two characters to begin editing the word. In Vim, search puts the cursor at the start of the word. Can I replicate this behaviour in Emacs?
3 Answers
There's really nothing to replicate, I think. You somehow have to tell Isearch that you're done typing text for the search string - you have to hit some key to tell it that. So at a minimum you have C-s acc <SOME KEY>
.
You can end Isearch with any key that is not already bound to something in isearch-mode-map
. (And even then, you can rebind any keys that are already bound.) And the key that ends Isearch can do whatever you like, including move back to a word beginning.
So you can end it with M-b
(that key isn't bound for Isearch, by default), which goes back to the beginning of the current word:
C-s acc M-b
That's not so hard. Whether you find it "intuitive" probably has to do with what you're already used to. There are a zillion use cases for Isearch, only one of which is wanting to move to the beginning of a matching word.
C-h k M-b
tells you:
M-b
runs the commandbackward-word
(found inglobal-map
), which is an interactive compiled Lisp function insimple.el
.It is bound to
M-b
,ESC left
.
(backward-word &optional ARG)
Move backward until encountering the beginning of a word.
With argument
ARG
, do this that many times. IfARG
is omitted ornil
, move point backward one word.The word boundaries are normally determined by the buffer’s syntax table and character script (according to
char-script-table
), butfind-word-boundary-function-table
, such as set up bysubword-mode
, can change that. If a Lisp program needs to move by words determined strictly by the syntax table, it should usebackward-word-strictly
instead. See Info node (elisp) Word Motion for details.
-
2
M-b
is not very useful here if search term is not in the beginning of the word. In such casesC-r
will help:C-s acc C-r <RET>
. Sep 8, 2019 at 19:44 -
@muffinmad: You seem to be saying that if the search string matches, say, the middle of a word, then point should be returned to the match beginning, not the word beginning. That would do what dangom's answer does. But that's not what was requested. Maybe the OP prefers that, dunno, the request was to put point at the word beginning.– DrewSep 9, 2019 at 1:24
-
1I must say that I did find this answer very useful. It helped me to think about quitting isearch differently than I had before.– EdmanSep 10, 2019 at 19:21
-
(OP) FYI: The answer you accepted does not answer the question that you posed. You said you wanted to go back to the beginning of the word that Isearch ended at. The answer you accepted goes back to the beginning of the search-string match. That coincides with the beginning of the word only if your search string matches also the beginning of the word. If it matches in the middle of the word, that answer doesn't take you to the word beginning.– DrewSep 10, 2019 at 22:48
-
1
As Drew pointed out in his answer you can also end the search with another key such as M-b
or M-f
, which for words boundaries works good, but my solution is kind of more general: define a key to put the cursor at the beginning (or end) of the pattern I'm searching:
(use-package isearch
:bind (:map isearch-mode-map
("C-<return>" . isearch-done-opposite))
:init (defun isearch-done-opposite (&optional nopush edit)
"End current search in the opposite side of the match."
(interactive)
(funcall #'isearch-done nopush edit)
(when isearch-other-end (goto-char isearch-other-end))))
UPDATE: or in case you don't use use-package
:
(define-key isearch-mode-map (kbd "<C-return>")
(defun isearch-done-opposite (&optional nopush edit)
"End current search in the opposite side of the match."
(interactive)
(funcall #'isearch-done nopush edit)
(when isearch-other-end (goto-char isearch-other-end))))
Basically, map C-Ret
to another function isearch-done-opposite
which checks the variable isearch-other-end
which is defined in isearch.el
as:
(defvar isearch-other-end nil) ; Start (end) of match if forward (backward).
This will work with forward and backward searches.
-
Is there some purpose to using
use-package
for a loaded-by-default library? I don't see any reason to introduce the dependency... a works-for-everyone answer would seem better.– philsSep 8, 2019 at 11:21 -
Luckily this has been studied by Malabarba and published in his blog, Endless. I have the following in my config:
(use-package isearch
:no-require t
:demand t
;; Go to the start of current isearch match. (adapted from Endless)
:hook (isearch-mode-end . (lambda ()
(when (and isearch-forward
(number-or-marker-p isearch-other-end)
(not mark-active)
(not isearch-mode-end-hook-quit))
(goto-char isearch-other-end)))))
Check the blog entry for other solutions as well.