1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-03 11:33:37 +00:00

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
This commit is contained in:
Eli Zaretskii 2010-05-15 16:23:48 +03:00
parent 98d8b17e45
commit d20e1419fd
8 changed files with 136 additions and 7 deletions

View File

@ -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.

View File

@ -1,5 +1,10 @@
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

View File

@ -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)

View File

@ -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

View File

@ -1,5 +1,11 @@
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>

View File

@ -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;

View File

@ -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;
{

View File

@ -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");