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:
parent
98d8b17e45
commit
d20e1419fd
3
etc/NEWS
3
etc/NEWS
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
25
lisp/subr.el
25
lisp/subr.el
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
16
src/cmds.c
16
src/cmds.c
@ -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;
|
||||
{
|
||||
|
79
src/xdisp.c
79
src/xdisp.c
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user