19

I often use multiple invocations of forward-word followed by a single backward-word to move point to the beginning of a word on a line. I guess I never got used to the way forward-word differs from vim's w and even after years of using Emacs I cannot get used to the difference.

Is there a function I could use instead of forward-word that doesn't jump over words but stops at the beginning of a word as well? Are there other strategies to move to the beginning of a word when moving point forward that don't involve repeatedly executing forward-char?

1

5 Answers 5

24

The misc package (shipped with emacs) has the built-in function forward-to-word, which does what I think you want:

forward-to-word is an interactive compiled Lisp function in `misc.el'.

It is bound to M-f.

(forward-to-word ARG)

Move forward until encountering the beginning of a word.
With argument, do this that many times.

To use it, first add (require 'misc) to your config file.

3
  • Thanks, this is useful. Unfortunately, this doesn't also stop at the end of a word, though.
    – user2005
    Dec 10, 2014 at 21:08
  • 1
    True, but neither does vim's w. As far as I can see, there is an almost perfect vim-to-emacs mapping: w = forward-to-word; e = forward-word; b = backward-word; ge = backward-to-word. But I'm not an expert vim user, so maybe there is some subtlety I am missing.
    – deprecated
    Dec 11, 2014 at 3:28
  • Heh, you are in fact right. I guess whenever I'm in vim w, e, and b just blur away and I just move around. Weird. I was certain w stopped at both points! So, I'll accept your answer, because it exactly fits my question :)
    – user2005
    Dec 11, 2014 at 7:47
4

You can bind the below function to M-f and bind the original forward-word to M-F. This function simply takes the arg and passes it on to the forward-word function. So the universal arguments will work just as fine as with the original function.

(defun modi/forward-word-begin (arg)
  "Move forward a word and end up with the point being at the beginning of the
next word.  Move point forward ARG words (backward if ARG is negative).
If ARG is omitted or nil, move point forward one word."
  (interactive "p")
  (forward-word arg)
  (forward-word 1)
  (backward-word 1))

Word of caution though that the above function might not always do the right thing; it's very much dependent on if the point is already on the beginning of a word or not.


Here's another way of implementing the above where the word boundary is not as per the syntax table but strictly on whitespace separation:

(defun modi/forward-word-begin (arg)
  "Move forward ARG (defaults to 1) number of words.
Here 'words' are defined as characters separated by whitespace."
  (interactive "p")
  (dotimes (_ arg)
    (forward-whitespace 1)))

Credit goes to @glucas for this idea.

1

After a long and painful search for the perfect 'forward/backward-word' functions I found the following with which I am now very happy:

(progn
  (defun boundary ()
    (and      (= (char-syntax (char-after))  ?w)
         (not (= (char-syntax (char-before)) ?w))))
  (defun my-forward-word ()
    (interactive) 
    (while (progn (forward-char)  (not (boundary)))))
  (defun my-backward-word ()
    (interactive) 
    (while (progn (backward-char) (not (boundary)))))
  (global-set-key [M-right] 'my-forward-word)
  (global-set-key [M-left]  'my-backward-word)
  )
0

If you're willing to use evil, w in normal state is bound to evil-forward-word-begin, which is the Vim-style functionality you're after.

1
  • 1
    I used to use evil a long time ago, but since a while I use god-mode and regular Emacs bindings instead.
    – user2005
    Dec 10, 2014 at 17:19
0

I often use multiple invocations of forward-word followed by a single backward-word to move point to the beginning of a word on a line.

As you mention, the trick is to go two words forward, then one word backwards.

The following should do the trick and should respect other modes like subword mode.

(define-key global-map (kbd  "M-f")
  (lambda ()
    (interactive)
    (forward-word)
    (forward-word)
    (backward-word)))

This is a rudimentary version of https://emacs.stackexchange.com/a/4272/508 that doesn't cover some cases, but easier to comprehend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.