summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2010-05-15 16:23:48 +0300
committerEli Zaretskii <eliz@gnu.org>2010-05-15 16:23:48 +0300
commitd20e1419fda6f29478d79f69db8e128d043d4ee1 (patch)
tree6c3d55edc1c753f3578111b10802397974fc61cc
parent98d8b17e45bb1246df61e51f8917b98faa9f1cdd (diff)
downloademacs-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
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/bindings.el4
-rw-r--r--lisp/subr.el25
-rw-r--r--src/ChangeLog6
-rw-r--r--src/bidi.c5
-rw-r--r--src/cmds.c16
-rw-r--r--src/xdisp.c79
8 files changed, 136 insertions, 7 deletions
diff --git a/etc/NEWS b/etc/NEWS
index a60962cf1f4..715dc12c467 100644
--- a/etc/NEWS
+++ b/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.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 760e373d095..359cc63ca98 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -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
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'.")
(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)
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\"."
(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
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");