2

The documentation states the following:

(forward-word &optional ARG) is bound to M-f

(right-word &optional N) is bound to C-right

Could there be any difference between the two? It just doesn't seem right to me that a software as elegant as Emacs has two functions that do essentially the same thing... Thanks in advance!

  • 3
    Check the doc string of right-word with C-h v right-word RET: "Depending on the bidirectional context, this may move either forward or backward in the buffer. This is in contrast with M-f and M-b, which see." – NickD Oct 29 at 15:21
  • 1
    If you have a look at the source code of right-word you'll understand why :) – aadcg Oct 29 at 15:21
3

right-word may move the cursor left when there is bidirectional text like the documentation points out and so did @NickD (in the comments). Try it with the quoted sample text and you'll observe that the cursor moves left during the Urdu fragment since Urdu is read from left to right.

Mir says, "!ہے نام مجلسوں میں میرا میر بے دماغ", sarcastically in Urdu.

But either way, it is correct to say that the cursor moves forward (left to right in Urdu and right to left in English). You may look at the documentation like this C-h k C-<right>. I'll copy it here as well.

right-word is an interactive compiled Lisp function.

It is bound to <C-right>.

(right-word &optional N)

Move point N words to the right (to the left if N is negative).

Depending on the bidirectional context, this may move either forward
or backward in the buffer.  This is in contrast with M-f
and M-b, which see.

Value is normally t.
If an edge of the buffer or a field boundary is reached, point is left there
and the function returns nil.  Field boundaries are not noticed
if ‘inhibit-field-text-motion’ is non-nil.

[back]

Did some more research and it looks like, right-word just conditionally calls forward-word or backward-word. I found the source code:

(defun right-word (&optional n)
  (interactive "^p")
  (if (eq (current-bidi-paragraph-direction) 'left-to-right)
      (forward-word n)
    (backward-word n)))

forward-word however has a somewhat difficult implementation to read:

DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p",
       doc: /* ...  */)
  (Lisp_Object arg)
{
  Lisp_Object tmp;
  ptrdiff_t orig_val, val;

  if (NILP (arg))
    XSETFASTINT (arg, 1);
  else
    CHECK_FIXNUM (arg);

  val = orig_val = scan_words (PT, XFIXNUM (arg));
  if (! orig_val)
    val = XFIXNUM (arg) > 0 ? ZV : BEGV;

  /* Avoid jumping out of an input field.  */
  tmp = Fconstrain_to_field (make_fixnum (val), make_fixnum (PT),
                 Qnil, Qnil, Qnil);
  val = XFIXNAT (tmp);

  SET_PT (val);
  return val == orig_val ? Qt : Qnil;
}

So I am not sure what is up but I think right-word is the implementation that is `ought to be smart about bidirectional text, which is counter-intuitive in my opinion.

| improve this answer | |
  • Thank you... Emacs continues to amaze me, even with simple navigation binds :D – Chanhee Jeong Oct 30 at 1:55
  • 1
    Testing with this example on upstream emacs (updated yesterday) does not reveal any behavioral difference between the two though: they seem to be doing the same thing. Maybe something has changed in recent emacs? And I just checked with emacs 26.3 (and starting with -Q) and they both also behave the same way there. – NickD Oct 31 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.