diff options
| author | Eli Zaretskii | 2010-05-15 16:23:48 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2010-05-15 16:23:48 +0300 |
| commit | d20e1419fda6f29478d79f69db8e128d043d4ee1 (patch) | |
| tree | 6c3d55edc1c753f3578111b10802397974fc61cc /src | |
| parent | 98d8b17e45bb1246df61e51f8917b98faa9f1cdd (diff) | |
| download | emacs-d20e1419fda6f29478d79f69db8e128d043d4ee1.tar.gz emacs-d20e1419fda6f29478d79f69db8e128d043d4ee1.zip | |
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 @@ | |||
| 1 | 2010-05-15 Eli Zaretskii <eliz@gnu.org> | 1 | 2010-05-15 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | * bidi.c (bidi_paragraph_init): Don't leave alone garbage values | ||
| 4 | of bidi_it->paragraph_dir. Call bidi_initialize if needed. | ||
| 5 | |||
| 6 | * xdisp.c (Fcurrent_bidi_paragraph_direction): New function. | ||
| 7 | (syms_of_xdisp): Defsubr it. | ||
| 8 | |||
| 3 | * Makefile.in: Fix MSDOS-related comments. | 9 | * Makefile.in: Fix MSDOS-related comments. |
| 4 | 10 | ||
| 5 | 2010-05-15 Glenn Morris <rgm@gnu.org> | 11 | 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) | |||
| 890 | EMACS_INT pos; | 890 | EMACS_INT pos; |
| 891 | bidi_type_t type; | 891 | bidi_type_t type; |
| 892 | 892 | ||
| 893 | if (!bidi_initialized) | ||
| 894 | bidi_initialize (); | ||
| 895 | |||
| 893 | /* If we are inside a paragraph separator, we are just waiting | 896 | /* If we are inside a paragraph separator, we are just waiting |
| 894 | for the separator to be exhausted; use the previous paragraph | 897 | for the separator to be exhausted; use the previous paragraph |
| 895 | direction. But don't do that if we have been just reseated, | 898 | 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) | |||
| 957 | /* Contrary to UAX#9 clause P3, we only default the paragraph | 960 | /* Contrary to UAX#9 clause P3, we only default the paragraph |
| 958 | direction to L2R if we have no previous usable paragraph | 961 | direction to L2R if we have no previous usable paragraph |
| 959 | direction. */ | 962 | direction. */ |
| 960 | if (bidi_it->paragraph_dir == NEUTRAL_DIR) | 963 | if (bidi_it->paragraph_dir != L2R && bidi_it->paragraph_dir != R2L) |
| 961 | bidi_it->paragraph_dir = L2R; /* P3 and ``higher protocols'' */ | 964 | bidi_it->paragraph_dir = L2R; /* P3 and ``higher protocols'' */ |
| 962 | if (bidi_it->paragraph_dir == R2L) | 965 | if (bidi_it->paragraph_dir == R2L) |
| 963 | bidi_it->level_stack[0].level = 1; | 966 | 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, | |||
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p", | 59 | DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p", |
| 60 | doc: /* Move point right N characters (left if N is negative). | 60 | doc: /* Move point N characters forward (backward if N is negative). |
| 61 | On reaching end of buffer, stop and signal error. */) | 61 | On reaching end or beginning of buffer, stop and signal error. |
| 62 | |||
| 63 | Depending on the bidirectional context, the movement may be to the | ||
| 64 | right or to the left on the screen. This is in contrast with | ||
| 65 | \\[right-arrow-command], which see. */) | ||
| 62 | (n) | 66 | (n) |
| 63 | Lisp_Object n; | 67 | Lisp_Object n; |
| 64 | { | 68 | { |
| @@ -93,8 +97,12 @@ On reaching end of buffer, stop and signal error. */) | |||
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p", | 99 | DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p", |
| 96 | doc: /* Move point left N characters (right if N is negative). | 100 | doc: /* Move point N characters backward (forward if N is negative). |
| 97 | On attempt to pass beginning or end of buffer, stop and signal error. */) | 101 | On attempt to pass beginning or end of buffer, stop and signal error. |
| 102 | |||
| 103 | Depending on the bidirectional context, the movement may be to the | ||
| 104 | right or to the left on the screen. This is in contrast with | ||
| 105 | \\[left-arrow-command], which see. */) | ||
| 98 | (n) | 106 | (n) |
| 99 | Lisp_Object n; | 107 | Lisp_Object n; |
| 100 | { | 108 | { |
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) | |||
| 18241 | return row->displays_text_p; | 18241 | return row->displays_text_p; |
| 18242 | } | 18242 | } |
| 18243 | 18243 | ||
| 18244 | DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction, | ||
| 18245 | Scurrent_bidi_paragraph_direction, 0, 1, 0, | ||
| 18246 | doc: /* Return paragraph direction at point in BUFFER. | ||
| 18247 | Value is either `left-to-right' or `right-to-left'. | ||
| 18248 | If BUFFER is omitted or nil, it defaults to the current buffer. | ||
| 18249 | |||
| 18250 | Paragraph direction determines how the text in the paragraph is displayed. | ||
| 18251 | In left-to-right paragraphs, text begins at the left margin of the window | ||
| 18252 | and the reading direction is generally left to right. In right-to-left | ||
| 18253 | paragraphs, text begins at the right margin and is read from right to left. | ||
| 18254 | |||
| 18255 | See also `bidi-paragraph-direction'. */) | ||
| 18256 | (buffer) | ||
| 18257 | Lisp_Object buffer; | ||
| 18258 | { | ||
| 18259 | struct buffer *buf; | ||
| 18260 | struct buffer *old; | ||
| 18261 | |||
| 18262 | if (NILP (buffer)) | ||
| 18263 | buf = current_buffer; | ||
| 18264 | else | ||
| 18265 | { | ||
| 18266 | CHECK_BUFFER (buffer); | ||
| 18267 | buf = XBUFFER (buffer); | ||
| 18268 | old = current_buffer; | ||
| 18269 | } | ||
| 18270 | |||
| 18271 | if (NILP (buf->bidi_display_reordering)) | ||
| 18272 | return Qleft_to_right; | ||
| 18273 | else if (!NILP (buf->bidi_paragraph_direction)) | ||
| 18274 | return buf->bidi_paragraph_direction; | ||
| 18275 | else | ||
| 18276 | { | ||
| 18277 | /* Determine the direction from buffer text. We could try to | ||
| 18278 | use current_matrix if it is up to date, but this seems fast | ||
| 18279 | enough as it is. */ | ||
| 18280 | struct bidi_it itb; | ||
| 18281 | EMACS_INT pos = BUF_PT (buf); | ||
| 18282 | EMACS_INT bytepos = BUF_PT_BYTE (buf); | ||
| 18283 | |||
| 18284 | if (buf != current_buffer) | ||
| 18285 | set_buffer_temp (buf); | ||
| 18286 | /* Find previous non-empty line. */ | ||
| 18287 | if (pos >= ZV && pos > BEGV) | ||
| 18288 | { | ||
| 18289 | pos--; | ||
| 18290 | bytepos = CHAR_TO_BYTE (pos); | ||
| 18291 | } | ||
| 18292 | while (FETCH_BYTE (bytepos) == '\n') | ||
| 18293 | { | ||
| 18294 | if (bytepos <= BEGV_BYTE) | ||
| 18295 | break; | ||
| 18296 | bytepos--; | ||
| 18297 | pos--; | ||
| 18298 | } | ||
| 18299 | while (!CHAR_HEAD_P (FETCH_BYTE (bytepos))) | ||
| 18300 | bytepos--; | ||
| 18301 | itb.charpos = pos; | ||
| 18302 | itb.bytepos = bytepos; | ||
| 18303 | itb.first_elt = 1; | ||
| 18304 | |||
| 18305 | bidi_paragraph_init (NEUTRAL_DIR, &itb); | ||
| 18306 | if (buf != current_buffer) | ||
| 18307 | set_buffer_temp (old); | ||
| 18308 | switch (itb.paragraph_dir) | ||
| 18309 | { | ||
| 18310 | case L2R: | ||
| 18311 | return Qleft_to_right; | ||
| 18312 | break; | ||
| 18313 | case R2L: | ||
| 18314 | return Qright_to_left; | ||
| 18315 | break; | ||
| 18316 | default: | ||
| 18317 | abort (); | ||
| 18318 | } | ||
| 18319 | } | ||
| 18320 | } | ||
| 18321 | |||
| 18244 | 18322 | ||
| 18245 | 18323 | ||
| 18246 | /*********************************************************************** | 18324 | /*********************************************************************** |
| @@ -25940,6 +26018,7 @@ syms_of_xdisp () | |||
| 25940 | #endif | 26018 | #endif |
| 25941 | defsubr (&Sformat_mode_line); | 26019 | defsubr (&Sformat_mode_line); |
| 25942 | defsubr (&Sinvisible_p); | 26020 | defsubr (&Sinvisible_p); |
| 26021 | defsubr (&Scurrent_bidi_paragraph_direction); | ||
| 25943 | 26022 | ||
| 25944 | staticpro (&Qmenu_bar_update_hook); | 26023 | staticpro (&Qmenu_bar_update_hook); |
| 25945 | Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook"); | 26024 | Qmenu_bar_update_hook = intern_c_string ("menu-bar-update-hook"); |