Commit d20e1419 authored by Eli Zaretskii's avatar Eli Zaretskii

Implement bidi-sensitive movement with arrow keys.

 src/bidi.c (bidi_paragraph_init): Don't leave alone garbage values
 of bidi_it->paragraph_dir.  Call bidi_initialize if needed.
 src/xdisp.c (Fcurrent_bidi_paragraph_direction): New function.
 (syms_of_xdisp): Defsubr it.
 src/cmds.c (Fforward_char, Fbackward_char): Doc fix.
 src/subr.el (right-arrow-command, left-arrow-command): New functions.
 src/bindings.el (global-map): Bind them to right and left arrow keys.
 etc/NEWS: Mention current-bidi-paragraph-direction
parent 98d8b17e
......@@ -63,6 +63,9 @@ according to the value of this variable. Possible values are
default), Emacs determines the base direction of each paragraph from
its text, as specified by the Unicode Bidirectional Algorithm.
The function `current-bidi-paragraph-direction' returns the actual
value of paragraph base direction at point.
Reordering of bidirectional text for display in Emacs is a "Full
bidirectionality" class implementation of the Unicode Bidirectional
Algorithm.
......
2010-05-15 Eli Zaretskii <eliz@gnu.org>
Bidi-sensitive movement with arrow keys.
* subr.el (right-arrow-command, left-arrow-command): New functions.
* bindings.el (global-map): Bind them to right and left arrow keys.
Don't override standard definition of convert-standard-filename.
* files.el (convert-standard-filename): Call
w32-convert-standard-filename and dos-convert-standard-filename on
......
......@@ -828,9 +828,9 @@ is okay. See `mode-line-format'.")
(define-key global-map [C-home] 'beginning-of-buffer)
(define-key global-map [M-home] 'beginning-of-buffer-other-window)
(define-key esc-map [home] 'beginning-of-buffer-other-window)
(define-key global-map [left] 'backward-char)
(define-key global-map [left] 'left-arrow-command)
(define-key global-map [up] 'previous-line)
(define-key global-map [right] 'forward-char)
(define-key global-map [right] 'right-arrow-command)
(define-key global-map [down] 'next-line)
(define-key global-map [prior] 'scroll-down-command)
(define-key global-map [next] 'scroll-up-command)
......
......@@ -3804,5 +3804,30 @@ which is higher than \"1alpha\"."
(prin1-to-string (make-hash-table)))))
(provide 'hashtable-print-readable))
;; Moving with arrows in bidi-sensitive direction.
(defun right-arrow-command (&optional n)
"Move point N characters to the right (to the left if N is negative).
On reaching beginning or end of buffer, stop and signal error.
Depending on the bidirectional context, this may move either forward
or backward in the buffer. This is in contrast with \\[forward-char]
and \\[backward-char], which see."
(interactive "^p")
(if (eq (current-bidi-paragraph-direction) 'left-to-right)
(forward-char n)
(backward-char n)))
(defun left-arrow-command ( &optional n)
"Move point N characters to the left (to the right if N is negative).
On reaching beginning or end of buffer, stop and signal error.
Depending on the bidirectional context, this may move either backward
or forward in the buffer. This is in contrast with \\[backward-char]
and \\[forward-char], which see."
(interactive "^p")
(if (eq (current-bidi-paragraph-direction) 'left-to-right)
(backward-char n)
(forward-char n)))
;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc
;;; subr.el ends here
2010-05-15 Eli Zaretskii <eliz@gnu.org>
* bidi.c (bidi_paragraph_init): Don't leave alone garbage values
of bidi_it->paragraph_dir. Call bidi_initialize if needed.
* xdisp.c (Fcurrent_bidi_paragraph_direction): New function.
(syms_of_xdisp): Defsubr it.
* Makefile.in: Fix MSDOS-related comments.
2010-05-15 Glenn Morris <rgm@gnu.org>
......
......@@ -890,6 +890,9 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
EMACS_INT pos;
bidi_type_t type;
if (!bidi_initialized)
bidi_initialize ();
/* If we are inside a paragraph separator, we are just waiting
for the separator to be exhausted; use the previous paragraph
direction. But don't do that if we have been just reseated,
......@@ -957,7 +960,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it)
/* Contrary to UAX#9 clause P3, we only default the paragraph
direction to L2R if we have no previous usable paragraph
direction. */
if (bidi_it->paragraph_dir == NEUTRAL_DIR)
if (bidi_it->paragraph_dir != L2R && bidi_it->paragraph_dir != R2L)
bidi_it->paragraph_dir = L2R; /* P3 and ``higher protocols'' */
if (bidi_it->paragraph_dir == R2L)
bidi_it->level_stack[0].level = 1;
......
......@@ -57,8 +57,12 @@ DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
}
DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
doc: /* Move point right N characters (left if N is negative).
On reaching end of buffer, stop and signal error. */)
doc: /* Move point N characters forward (backward if N is negative).
On reaching end or beginning of buffer, stop and signal error.
Depending on the bidirectional context, the movement may be to the
right or to the left on the screen. This is in contrast with
\\[right-arrow-command], which see. */)
(n)
Lisp_Object n;
{
......@@ -93,8 +97,12 @@ On reaching end of buffer, stop and signal error. */)
}
DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
doc: /* Move point left N characters (right if N is negative).
On attempt to pass beginning or end of buffer, stop and signal error. */)
doc: /* Move point N characters backward (forward if N is negative).
On attempt to pass beginning or end of buffer, stop and signal error.
Depending on the bidirectional context, the movement may be to the
right or to the left on the screen. This is in contrast with
\\[left-arrow-command], which see. */)
(n)
Lisp_Object n;
{
......
......@@ -18241,6 +18241,84 @@ display_line (it)
return row->displays_text_p;
}
DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
Scurrent_bidi_paragraph_direction, 0, 1, 0,
doc: /* Return paragraph direction at point in BUFFER.
Value is either `left-to-right' or `right-to-left'.
If BUFFER is omitted or nil, it defaults to the current buffer.
Paragraph direction determines how the text in the paragraph is displayed.
In left-to-right paragraphs, text begins at the left margin of the window
and the reading direction is generally left to right. In right-to-left
paragraphs, text begins at the right margin and is read from right to left.
See also `bidi-paragraph-direction'. */)
(buffer)
Lisp_Object buffer;
{
struct buffer *buf;
struct buffer *old;
if (NILP (buffer))
buf = current_buffer;
else
{
CHECK_BUFFER (buffer);
buf = XBUFFER (buffer);
old = current_buffer;
}
if (NILP (buf->bidi_display_reordering))
return Qleft_to_right;
else if (!NILP (buf->bidi_paragraph_direction))
return buf->bidi_paragraph_direction;
else
{
/* Determine the direction from buffer text. We could try to
use current_matrix if it is up to date, but this seems fast
enough as it is. */
struct bidi_it itb;
EMACS_INT pos = BUF_PT (buf);
EMACS_INT bytepos = BUF_PT_BYTE (buf);
if (buf != current_buffer)
set_buffer_temp (buf);
/* Find previous non-empty line. */
if (pos >= ZV && pos > BEGV)
{
pos--;
bytepos = CHAR_TO_BYTE (pos);
}
while (FETCH_BYTE (bytepos) == '\n')
{
if (bytepos <= BEGV_BYTE)
break;
bytepos--;
pos--;
}
while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
bytepos--;
itb.charpos = pos;
itb.bytepos = bytepos;
itb.first_elt = 1;
bidi_paragraph_init (NEUTRAL_DIR, &itb);
if (buf != current_buffer)
set_buffer_temp (old);
switch (itb.paragraph_dir)
{
case L2R:
return Qleft_to_right;
break;
case R2L:
return Qright_to_left;
break;
default:
abort ();
}
}
}
/***********************************************************************
......@@ -25940,6 +26018,7 @@ syms_of_xdisp ()
#endif
defsubr (&Sformat_mode_line);
defsubr (&Sinvisible_p);
defsubr (&Scurrent_bidi_paragraph_direction);
staticpro (&Qmenu_bar_update_hook);
Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment