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.
Did some more research and it looks like,
right-word just conditionally calls
backward-word. I found the source code:
(defun right-word (&optional n)
(if (eq (current-bidi-paragraph-direction) 'left-to-right)
forward-word however has a somewhat difficult implementation to read:
DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "^p",
doc: /* ... */)
ptrdiff_t orig_val, val;
if (NILP (arg))
XSETFASTINT (arg, 1);
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);
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.