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 | |
| 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
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/bindings.el | 4 | ||||
| -rw-r--r-- | lisp/subr.el | 25 | ||||
| -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 |
8 files changed, 136 insertions, 7 deletions
| @@ -63,6 +63,9 @@ according to the value of this variable. Possible values are | |||
| 63 | default), Emacs determines the base direction of each paragraph from | 63 | default), Emacs determines the base direction of each paragraph from |
| 64 | its text, as specified by the Unicode Bidirectional Algorithm. | 64 | its text, as specified by the Unicode Bidirectional Algorithm. |
| 65 | 65 | ||
| 66 | The function `current-bidi-paragraph-direction' returns the actual | ||
| 67 | value of paragraph base direction at point. | ||
| 68 | |||
| 66 | Reordering of bidirectional text for display in Emacs is a "Full | 69 | Reordering of bidirectional text for display in Emacs is a "Full |
| 67 | bidirectionality" class implementation of the Unicode Bidirectional | 70 | bidirectionality" class implementation of the Unicode Bidirectional |
| 68 | Algorithm. | 71 | Algorithm. |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 760e373d095..359cc63ca98 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | 2010-05-15 Eli Zaretskii <eliz@gnu.org> | 1 | 2010-05-15 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | Bidi-sensitive movement with arrow keys. | ||
| 4 | * subr.el (right-arrow-command, left-arrow-command): New functions. | ||
| 5 | |||
| 6 | * bindings.el (global-map): Bind them to right and left arrow keys. | ||
| 7 | |||
| 3 | Don't override standard definition of convert-standard-filename. | 8 | Don't override standard definition of convert-standard-filename. |
| 4 | * files.el (convert-standard-filename): Call | 9 | * files.el (convert-standard-filename): Call |
| 5 | w32-convert-standard-filename and dos-convert-standard-filename on | 10 | w32-convert-standard-filename and dos-convert-standard-filename on |
diff --git a/lisp/bindings.el b/lisp/bindings.el index 05a0ac8bc11..14cebfeda8f 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el | |||
| @@ -828,9 +828,9 @@ is okay. See `mode-line-format'.") | |||
| 828 | (define-key global-map [C-home] 'beginning-of-buffer) | 828 | (define-key global-map [C-home] 'beginning-of-buffer) |
| 829 | (define-key global-map [M-home] 'beginning-of-buffer-other-window) | 829 | (define-key global-map [M-home] 'beginning-of-buffer-other-window) |
| 830 | (define-key esc-map [home] 'beginning-of-buffer-other-window) | 830 | (define-key esc-map [home] 'beginning-of-buffer-other-window) |
| 831 | (define-key global-map [left] 'backward-char) | 831 | (define-key global-map [left] 'left-arrow-command) |
| 832 | (define-key global-map [up] 'previous-line) | 832 | (define-key global-map [up] 'previous-line) |
| 833 | (define-key global-map [right] 'forward-char) | 833 | (define-key global-map [right] 'right-arrow-command) |
| 834 | (define-key global-map [down] 'next-line) | 834 | (define-key global-map [down] 'next-line) |
| 835 | (define-key global-map [prior] 'scroll-down-command) | 835 | (define-key global-map [prior] 'scroll-down-command) |
| 836 | (define-key global-map [next] 'scroll-up-command) | 836 | (define-key global-map [next] 'scroll-up-command) |
diff --git a/lisp/subr.el b/lisp/subr.el index 0cc05a78bc7..1c399f89b9c 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -3804,5 +3804,30 @@ which is higher than \"1alpha\"." | |||
| 3804 | (prin1-to-string (make-hash-table))))) | 3804 | (prin1-to-string (make-hash-table))))) |
| 3805 | (provide 'hashtable-print-readable)) | 3805 | (provide 'hashtable-print-readable)) |
| 3806 | 3806 | ||
| 3807 | ;; Moving with arrows in bidi-sensitive direction. | ||
| 3808 | (defun right-arrow-command (&optional n) | ||
| 3809 | "Move point N characters to the right (to the left if N is negative). | ||
| 3810 | On reaching beginning or end of buffer, stop and signal error. | ||
| 3811 | |||
| 3812 | Depending on the bidirectional context, this may move either forward | ||
| 3813 | or backward in the buffer. This is in contrast with \\[forward-char] | ||
| 3814 | and \\[backward-char], which see." | ||
| 3815 | (interactive "^p") | ||
| 3816 | (if (eq (current-bidi-paragraph-direction) 'left-to-right) | ||
| 3817 | (forward-char n) | ||
| 3818 | (backward-char n))) | ||
| 3819 | |||
| 3820 | (defun left-arrow-command ( &optional n) | ||
| 3821 | "Move point N characters to the left (to the right if N is negative). | ||
| 3822 | On reaching beginning or end of buffer, stop and signal error. | ||
| 3823 | |||
| 3824 | Depending on the bidirectional context, this may move either backward | ||
| 3825 | or forward in the buffer. This is in contrast with \\[backward-char] | ||
| 3826 | and \\[forward-char], which see." | ||
| 3827 | (interactive "^p") | ||
| 3828 | (if (eq (current-bidi-paragraph-direction) 'left-to-right) | ||
| 3829 | (backward-char n) | ||
| 3830 | (forward-char n))) | ||
| 3831 | |||
| 3807 | ;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc | 3832 | ;; arch-tag: f7e0e6e5-70aa-4897-ae72-7a3511ec40bc |
| 3808 | ;;; subr.el ends here | 3833 | ;;; subr.el ends here |
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"); |