diff options
| author | Eli Zaretskii <eliz@gnu.org> | 2010-05-15 16:23:48 +0300 |
|---|---|---|
| committer | Eli Zaretskii <eliz@gnu.org> | 2010-05-15 16:23:48 +0300 |
| commit | d20e1419fda6f29478d79f69db8e128d043d4ee1 (patch) | |
| tree | 6c3d55edc1c753f3578111b10802397974fc61cc /src | |
| parent | 98d8b17e45bb1246df61e51f8917b98faa9f1cdd (diff) | |
| download | emacs-d20e1419fda6f29478d79f69db8e128d043d4ee1.tar.gz | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/bidi.c | 5 | ||||
| -rw-r--r-- | src/cmds.c | 16 | ||||
| -rw-r--r-- | src/xdisp.c | 79 |
4 files changed, 101 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index a9757cd02b4..32413ae11c3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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> diff --git a/src/bidi.c b/src/bidi.c index c4cb4c599df..6939e51159f 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -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; diff --git a/src/cmds.c b/src/cmds.c index 5d450fe9a13..b8a65324e9f 100644 --- a/src/cmds.c +++ b/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; { diff --git a/src/xdisp.c b/src/xdisp.c index fd1b1eaab21..6b3097c9a1a 100644 --- a/src/xdisp.c +++ b/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"); |
