]> git.eshelyaron.com Git - emacs.git/commitdiff
Support MS-Windows build and reversed rows in GUI frames; add initial docs.
authorEli Zaretskii <eliz@gnu.org>
Mon, 29 Mar 2010 12:26:24 +0000 (08:26 -0400)
committerEli Zaretskii <eliz@gnu.org>
Mon, 29 Mar 2010 12:26:24 +0000 (08:26 -0400)
 doc/emacs/mule.texi (International): Mention support of
 bidirectional editing.
 (Bidirectional Editing): New section.
 etc/HELLO: Reorder Arabic and Hebrew into logical order, and
 insert RLM before the opening paren, to make the display more
 reasonable.  Add setting for bidi-display-reordering in the local
 variables section.
 lisp/files.el: Make bidi-display-reordering safe variable for
 boolean values.
 src/xdisp (append_glyph): If the glyph row is reversed, prepend the
 glyph rather than appending it.
 src/makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O).
 ($(BLD)/bidi.$(O)): New target.

doc/emacs/mule.texi
etc/HELLO
etc/NEWS
lisp/files.el
src/ChangeLog.bidi
src/makefile.w32-in
src/xdisp.c

index 00aa9047aecf686465be6c0f8264736e8de12877..6420132e0ce75643bfafdf91ae5a700b909e7534 100644 (file)
@@ -66,6 +66,12 @@ displays (@pxref{Terminal Coding}).  If some characters are displayed
 incorrectly, refer to @ref{Undisplayable Characters}, which describes
 possible problems and explains how to solve them.
 
+@item
+Characters from scripts whose natural ordering of text is from right
+to left are reordered for display (@pxref{Bidirectional Editing}).
+These scripts include Arabic, Hebrew, Syriac, Thaana, and a few
+others.
+
 @item
 You can insert non-@acronym{ASCII} characters or search for them.  To do that,
 you can specify an input method (@pxref{Select Input Method}) suitable
@@ -107,6 +113,7 @@ to make sure Emacs interprets keyboard input correctly; see
 * Unibyte Mode::            You can pick one European character set
                               to use without multibyte characters.
 * Charsets::                How Emacs groups its internal character codes.
+* Bidirectional Editing::   Support for right-to-left scripts.
 @end menu
 
 @node International Chars
@@ -1653,6 +1660,84 @@ older Emacs versions.
 point before it and type @kbd{C-u C-x =} (@pxref{International
 Chars}).
 
+@node Bidirectional Editing
+@section Bidirectional Editing
+@cindex bidirectional editing
+@cindex right-to-left text
+
+  Emacs supports editing text written in scripts, such as Arabic and
+Hebrew, whose natural ordering of horizontal text for display is from
+right to left.  However, digits and Latin text embedded in these
+scripts are still displayed left to right.  It is also not uncommon to
+have small portions of text in Arabic or Hebrew embedded in otherwise
+Latin document, e.g., as comments and strings in a program source
+file.  For these reasons, text that uses these scripts is actually
+@dfn{bidirectional}: a mixture of runs of left-to-right and
+right-to-left characters.
+
+  This section describes the facilities and options provided by Emacs
+for editing bidirectional text.
+
+@cindex logical order
+@cindex visual order
+  Emacs stores right-to-left and bidirectional text in the so-called
+@dfn{logical} (or @dfn{reading}) order: the buffer or string position
+of the first character you read precedes that of the next character.
+Reordering of bidirectional text into the @dfn{visual} order happens
+at display time.  As result, character positions no longer increase
+monotonically with their positions on display.  Emacs implements the
+Unicode Bidirectional Algorithm described in the Unicode Standard
+Annex #9, for reordering of bidirectional text for display.
+
+@vindex bidi-display-reordering
+  The buffer-local variable @code{bidi-display-reordering} controls
+whether text in the buffer is reordered for display.  If its value is
+non-@code{nil}, Emacs reorders characters that have right-to-left
+directionality when they are displayed.  The default value is
+@code{nil}.
+
+  Each paragraph of bidirectional text can have its own @dfn{base
+direction}, either right-to-left or left-to-right.  (Paragraph
+boundaries are defined by the regular expressions
+@code{paragraph-start} and @code{paragraph-separate}, see
+@ref{Paragraphs}.)  Text in left-to-right paragraphs begins at the
+left margin of the window and is truncated or continued when it
+reaches the right margin.  By contrast, text in right-to-left
+paragraphs begins at the right margin and is continued or truncated at
+the left margin.
+
+@vindex bidi-paragraph-direction
+  Emacs determines the base direction of each paragraph dynamically,
+based on the text at the beginning of the paragraph.  However,
+sometimes a buffer may need to force a certain base direction for its
+paragraphs.  The variable @code{bidi-paragraph-direction}, if
+non-@code{nil}, disables the dynamic determination of the base
+direction, and instead forces all paragraphs in the buffer to have the
+direction specified by its buffer-local value.  The value can be either
+@code{right-to-left} or @code{left-to-right}.  Any other value is
+interpreted as @code{nil}.
+
+@cindex LRM
+@cindex RLM
+  Alternatively, you can control the base direction of a paragraph by
+inserting special formatting characters in front of the paragraph.
+The special character @code{RIGHT-TO-LEFT MARK}, or @sc{rlm}, forces
+the right-to-left direction on the following paragraph, while
+@code{LEFT-TO-RIGHT MARK}, or @sc{lrm} forces the left-to-right
+direction.  (You can use @kbd{C-x 8 RET} to insert these characters.)
+In a GUI session, the @sc{lrm} and @sc{rlm} characters display as
+blanks.
+
+  Because characters are reordered for display, Emacs commands that
+operate in the logical order or on stretches of buffer positions may
+produce unusual effects.  For example, @kbd{C-f} and @kbd{C-b}
+commands move point in the logical order, so the cursor will sometimes
+jump when point traverses reordered bidirectional text.  Similarly, a
+highlighted region covering a contiguous range of character positions
+may look discontinuous if the region spans reordered text.  This is
+normal and similar to behavior of other programs that support
+bidirectional text.
+
 @ignore
    arch-tag: 310ba60d-31ef-4ce7-91f1-f282dd57b6b3
 @end ignore
index 0f582f6c40866398b119837c5b6069c05da58d75..9e0c66a02410b6f2275080b8b7d33a7c63ba7a4c 100644 (file)
--- a/etc/HELLO
+++ b/etc/HELLO
@@ -16,7 +16,7 @@ Non-ASCII examples:
 LANGUAGE (NATIVE NAME) HELLO
 ---------------------- -----
 Amharic (\e$,1O M[MmN{\e(B)      \e$,1M`MKM]\e(B
-Arabic (\e,GIqjHQYdG\e(B)        \e,GecjdY\e(B \e,GeGdqSdG\e(B
+Arabic \e$,1ro\e(B(\e,GGdYQHjqI\e(B)       \e,GecjdY\e(B \e,GeGdqSdG\e(B
 Bengali (\e$,17,7>6b727>\e(B)    \e$,17(7.787M6u7>70\e(B
 Braille        \e$,2(3(1('('(5\e(B
 Burmese (\e$,1H9HYH;H4HYrlH9HL\e(B)      \e$,1H9H$HYrmH"H<HLH5HL\e(B
@@ -34,7 +34,7 @@ Georgian (\e$,1JEJ0J@J7J5J4J:J8\e(B)    \e$,1J2J0J;J0J@JOJ=J1J0\e(B
 German (Deutsch)       Guten Tag / Gr\e,A|_\e(B Gott
 Greek (\e,Fekkgmij\\e(B) \e,FCei\\e(B \e,Fsar\e(B
 Gujarati (\e$,19W:!9\9p9~9d: \e(B)       \e$,19h9n9x:-9d:'\e(B
-Hebrew (\e,Hzixar\e(B)   \e,Hylem\e(B
+Hebrew \e$,1ro\e(B(\e$,1-",q-(,y-*\e(B)    \e,Hylem\e(B
 Hungarian (magyar)     Sz\e,Bi\e(Bp j\e,Bs\e(B napot!
 Hindi (\e$,15y5\7f5B5f6 \e(B)      \e$,15h5n5x6-5d6'\e(B / \e$,15h5n5x6-5U5~5p\e(B \e$,16D\e(B
 Italian (italiano)     Ciao / Buon giorno
@@ -91,4 +91,5 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Local Variables:
 ;;; tab-width: 32
+;;; bidi-display-reordering: t
 ;;; End:
index 1518f9ffc0cde9b46ee04f0a0f745c1958df1137..408ba236bf8bdb07dbc25a99eaf8adf077a213ef 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -36,6 +36,30 @@ lib-src/Makefile by hand in order to use the associated features.
 \f
 * Changes in Emacs 24.1
 
++++
+** Emacs now supports display and editing of bidirectional text.
+Warning: This is still very much experimental!  The existing support
+is minimal, and when it's turned on (see below), many features are
+likely to give unexpected results, or break, or even crash!  Use at
+your own risk!
+
+See the node "Bidirectional Editing" in the Emacs Manual for some
+initial documentation.
+
+To turn this on in any given buffer, set the buffer-local variable
+`bidi-display-reordering' to a non-nil value.  The default is nil.
+
+The buffer-local variable `bidi-paragraph-direction', if non-nil,
+forces each paragraph in the buffer to have its base direction
+according to the value of this variable.  Possible values are
+`right-to-left' and `left-to-right'.  If the value is nil (the
+default), Emacs determines the base direction of each paragraph from
+its text, as specified by the Unicode Bidirectional Algorithm.
+
+Reordering of bidirectional text for display in Emacs is a "Full
+bidirectionality" class implementation of the Unicode Bidirectional
+Algorithm.
+
 ** GTK scroll-bars are now placed on the right by default.
 Use `set-scroll-bar-mode' to change this.
 
index ed12d2a393ab845a31cdcf07174cb70e6b97761a..3b3bbe19bbbba62c013f603ffee3301af3661364 100644 (file)
@@ -2768,14 +2768,15 @@ asking you for confirmation."
 
 (mapc (lambda (pair)
        (put (car pair) 'safe-local-variable (cdr pair)))
-      '((buffer-read-only     . booleanp)   ;; C source code
-       (default-directory    . stringp)    ;; C source code
-       (fill-column          . integerp)   ;; C source code
-       (indent-tabs-mode     . booleanp)   ;; C source code
-       (left-margin          . integerp)   ;; C source code
-       (no-update-autoloads  . booleanp)
-       (tab-width            . integerp)   ;; C source code
-       (truncate-lines       . booleanp))) ;; C source code
+      '((buffer-read-only        . booleanp)   ;; C source code
+       (default-directory       . stringp)    ;; C source code
+       (fill-column             . integerp)   ;; C source code
+       (indent-tabs-mode        . booleanp)   ;; C source code
+       (left-margin             . integerp)   ;; C source code
+       (no-update-autoloads     . booleanp)
+       (tab-width               . integerp)   ;; C source code
+       (truncate-lines          . booleanp)   ;; C source code
+       (bidi-display-reordering . booleanp))) ;; C source code
 
 (put 'c-set-style 'safe-local-eval-function t)
 
index d27f747466b2028b594186408c10cfd00c12b73b..33982c214500851fd98085de6b61ae0690fc0a42 100644 (file)
@@ -1,5 +1,25 @@
+2010-03-29  Eli Zaretskii  <eliz@gnu.org>
+
+       * doc/emacs/mule.texi (International): Mention support of
+       bidirectional editing.
+       (Bidirectional Editing): New section.
+
 2010-03-28  Eli Zaretskii  <eliz@gnu.org>
 
+       * etc/HELLO: Reorder Arabic and Hebrew into logical order, and
+       insert RLM before the opening paren, to make the display more
+       reasonable.  Add setting for bidi-display-reordering in the local
+       variables section.
+
+       * lisp/files.el: Make bidi-display-reordering safe variable for
+       boolean values.
+
+       * xdisp (append_glyph): If the glyph row is reversed, prepend the
+       glyph rather than appending it.
+
+       * makefile.w32-in (OBJ1): Add $(BLD)/bidi.$(O).
+       ($(BLD)/bidi.$(O)): New target.
+
        * bidi.c (bidi_get_next_char_visually): Improve commentary.
 
        * dispextern.h (PRODUCE_GLYPHS): Set the reversed_p flag in the
index 156eddd60928431c5d8438f88cdf07a355636e8c..edb3f3f711b27fce83a8a65391868df603f7a34f 100644 (file)
@@ -115,6 +115,7 @@ OBJ1 =  $(BLD)/alloc.$(O)           \
        $(BLD)/vm-limit.$(O)            \
        $(BLD)/region-cache.$(O)        \
        $(BLD)/strftime.$(O)            \
+       $(BLD)/bidi.$(O)                \
        $(BLD)/charset.$(O)             \
        $(BLD)/character.$(O)           \
        $(BLD)/chartab.$(O)             \
@@ -338,6 +339,14 @@ $(BLD)/atimer.$(O) : \
        $(SRC)/syssignal.h \
        $(SRC)/systime.h
 
+$(BLD)/bidi.$(O) : \
+       $(SRC)/bidi.c \
+       $(CONFIG_H) \
+       $(SRC)/lisp.h \
+       $(SRC)/buffer.h \
+       $(SRC)/character.h \
+       $(SRC)/dispextern.h
+
 $(BLD)/buffer.$(O) : \
        $(SRC)/buffer.c \
        $(CONFIG_H) \
index 867018180aac969bf7c5df0d092ee27d9aab89cf..ed2db08905d9d5950bc1ac93645991602212f039 100644 (file)
@@ -17823,8 +17823,8 @@ display_line (it)
   ++it->vpos;
   ++it->glyph_row;
   /* The next row should use same value of the reversed_p flag as this
-     one.  set_iterator_to_next decides when it's a new paragraph and
-     recomputes the value of the flag accordingly.  */
+     one.  set_iterator_to_next decides when it's a new paragraph, and
+     PRODUCE_GLYPHS recomputes the value of the flag accordingly.  */
   it->glyph_row->reversed_p = row->reversed_p;
   it->start = row_end;
   return row->displays_text_p;
@@ -21355,6 +21355,17 @@ append_glyph (it)
   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
+      /* If the glyph row is reversed, we need to prepend the glyph
+        rather than append it.  */
+      if (it->glyph_row->reversed_p && area == TEXT_AREA)
+       {
+         struct glyph *g;
+
+         /* Make room for the additional glyph.  */
+         for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
+           g[1] = *g;
+         glyph = it->glyph_row->glyphs[area];
+       }
       glyph->charpos = CHARPOS (it->position);
       glyph->object = it->object;
       if (it->pixel_width > 0)
@@ -21391,6 +21402,11 @@ append_glyph (it)
            abort ();
          glyph->bidi_type = it->bidi_it.type;
        }
+      else
+       {
+         glyph->resolved_level = 0;
+         glyph->bidi_type = UNKNOWN_BT;
+       }
       ++it->glyph_row->used[area];
     }
   else