]> git.eshelyaron.com Git - emacs.git/commitdiff
Handle `(space ...)' display spec as paragraph separator.
authorEli Zaretskii <eliz@gnu.org>
Thu, 25 Aug 2011 10:45:33 +0000 (13:45 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 25 Aug 2011 10:45:33 +0000 (13:45 +0300)
 src/xdisp.c (compute_display_string_pos): Return 2 in DISP_PROP when
 the display spec is of the form `(space ...)'.
 (handle_display_spec): Return the value returned by
 handle_single_display_spec, not just 1 or zero.
 (handle_single_display_spec): If the display spec is of the form
 `(space ...)', and specifies display in the text area, return 2
 rather than 1.
 src/dispextern.h (struct bidi_it): Rename the disp_prop_p member
 into disp_prop; all users changed.
 src/bidi.c (bidi_fetch_char): If compute_display_string_pos returns
 DISP_PROP = 2, substitute the u+2029 PARAGRAPH SEPARATOR character
 for the text covered by the display property.
 lisp/buff-menu.el (Buffer-menu-buffer+size): Remove calls to
 bidi-string-mark-left-to-right; they are unnecessary now.
 doc/lispref/display.texi (Specified Space): Mention that `space' specs
 influence bidi reordering.
 (Bidirectional Display): Explain how to use `(space . PROPS)' for
 separating fields with bidirectional content.

doc/lispref/ChangeLog
doc/lispref/display.texi
lisp/ChangeLog
lisp/buff-menu.el
src/ChangeLog
src/bidi.c
src/dispextern.h
src/xdisp.c

index 4bf615328b19695cac537e933287673bacc70ec7..ca9c93b563da88384046709e0a0e114cf0223211 100644 (file)
@@ -1,3 +1,10 @@
+2011-08-25  Eli Zaretskii  <eliz@gnu.org>
+
+       * display.texi (Specified Space): Mention that `space' specs
+       influence bidi reordering.
+       (Bidirectional Display): Explain how to use `(space . PROPS)' for
+       separating fields with bidirectional content.
+
 2011-08-24  Eli Zaretskii  <eliz@gnu.org>
 
        * display.texi (Bidirectional Display): Document return value in
index 0593eba8f05bc3e0560e5d03d8b6916c076accc4..bf7cd126a26d63fcc322c71434d1a06a97d6fb92 100644 (file)
@@ -3794,6 +3794,10 @@ with a @dfn{pixel ascent} specification (@pxref{Pixel Specification}).
 non-graphic terminals, but the other space properties in this section
 are not.
 
+  Note that space properties are treated as paragraph separators for
+the purposes of reordering bidirectional text for display.
+@xref{Bidirectional Display}, for the details.
+
 @node Pixel Specification
 @subsection Pixel Specification for Spaces
 @cindex spaces, pixel specification
@@ -6126,8 +6130,8 @@ with bidirectional content can be displayed @emph{to the left} of the
 preceding field, producing a jumbled display and messing up the
 expected layout.
 
-  To countermand this, you can use one of the following techniques for
-forcing correct order of fields on display:
+  To countermand this, we recommend that you use one of the following
+techniques for forcing correct order of fields on display:
 
 @itemize @minus
 @item
@@ -6146,6 +6150,15 @@ Include the tab character in the field separator.  The tab character
 plays the role of @dfn{segment separator} in the @acronym{UBA}
 reordering, whose effect is to make each field a separate segment, and
 thus reorder them separately.
+
+@cindex @code{space} display spec, and bidirectional text
+@item
+Separate fields with a @code{display} property or overlay with the
+property value of the form @code{(space . PROPS)} (@pxref{Specified
+Space}).  This display specification is treated by Emacs as a
+@dfn{paragraph separator}; the text before and after the separator is
+reordered separately, which avoids the influence of any field on its
+neighboring fields.
 @end itemize
 
 @defun bidi-string-mark-left-to-right string
index a42711dccc47ef56e8c18d5f442f88d7869aa73e..064e745d1f5005f115256e2bfddf648d3ffdca34 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-25  Eli Zaretskii  <eliz@gnu.org>
+
+       * buff-menu.el (Buffer-menu-buffer+size): Remove calls to
+       bidi-string-mark-left-to-right; they are unnecessary now.
+
 2011-08-25  Deniz Dogan  <deniz@dogan.se>
 
        * net/quickurl.el: Documentation typo fixes.
index 2eac33d8157aebfbcbf7ff5076b1911b8d7ab855..2be74cf5efb87b856daadf600a861d392bbd0429 100644 (file)
@@ -681,9 +681,9 @@ For more information, see the function `buffer-menu'."
                           (string-width tail)
                           2))
                       Buffer-menu-short-ellipsis
-                      (bidi-string-mark-left-to-right tail))))
+                      tail)))
     ;; Don't put properties on (buffer-name).
-    (setq name (bidi-string-mark-left-to-right name)))
+    (setq name (copy-sequence name)))
   (add-text-properties 0 (length name) name-props name)
   (add-text-properties 0 (length size) size-props size)
   (let ((name+space-width (- Buffer-menu-buffer+size-width
index 431a515def5ad641412192834089159494d36636..b2f2334427cfe06fdb2811652ce25b4aefb26eb4 100644 (file)
@@ -1,3 +1,20 @@
+2011-08-25  Eli Zaretskii  <eliz@gnu.org>
+
+       * xdisp.c (compute_display_string_pos): Return 2 in DISP_PROP when
+       the display spec is of the form `(space ...)'.
+       (handle_display_spec): Return the value returned by
+       handle_single_display_spec, not just 1 or zero.
+       (handle_single_display_spec): If the display spec is of the form
+       `(space ...)', and specifies display in the text area, return 2
+       rather than 1.
+
+       * dispextern.h (struct bidi_it): Rename the disp_prop_p member
+       into disp_prop; all users changed.
+
+       * bidi.c (bidi_fetch_char): If compute_display_string_pos returns
+       DISP_PROP = 2, substitute the u+2029 PARAGRAPH SEPARATOR character
+       for the text covered by the display property.
+
 2011-08-25  Chong Yidong  <cyd@stupidchicken.com>
 
        * buffer.c (Fbury_buffer_internal): Rename from Funrecord_buffer.
index 425a0be957846bcfe1d7ee3384475040f7ecc88c..79aaa03fb0b00c5f02b9db19663cc586ccb50d07 100644 (file)
@@ -540,7 +540,7 @@ bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
       bidi_cache[idx].next_for_ws = bidi_it->next_for_ws;
       bidi_cache[idx].ignore_bn_limit = bidi_it->ignore_bn_limit;
       bidi_cache[idx].disp_pos = bidi_it->disp_pos;
-      bidi_cache[idx].disp_prop_p = bidi_it->disp_prop_p;
+      bidi_cache[idx].disp_prop = bidi_it->disp_prop;
     }
 
   bidi_cache_last_idx = idx;
@@ -828,7 +828,7 @@ bidi_init_it (EMACS_INT charpos, EMACS_INT bytepos, int frame_window_p,
     bidi_it->prev_for_neutral.orig_type = UNKNOWN_BT;
   bidi_it->sor = L2R;   /* FIXME: should it be user-selectable? */
   bidi_it->disp_pos = -1;      /* invalid/unknown */
-  bidi_it->disp_prop_p = 0;
+  bidi_it->disp_prop = 0;
   /* We can only shrink the cache if we are at the bottom level of its
      "stack".  */
   if (bidi_cache_start == 0)
@@ -908,19 +908,22 @@ bidi_char_at_pos (EMACS_INT bytepos, const unsigned char *s, int unibyte)
 
 /* Fetch and return the character at BYTEPOS/CHARPOS.  If that
    character is covered by a display string, treat the entire run of
-   covered characters as a single character u+FFFC, and return their
-   combined length in CH_LEN and NCHARS.  DISP_POS specifies the
-   character position of the next display string, or -1 if not yet
-   computed.  DISP_PROP_P non-zero means that there's really a display
-   string at DISP_POS, as opposed to when we searched till DISP_POS
-   without findingone.  When the next character is at or beyond that
-   position, the function updates DISP_POS with the position of the
-   next display string.  STRING->s is the C string to iterate, or NULL
-   if iterating over a buffer or a Lisp string; in the latter case,
-   STRING->lstring is the Lisp string.  */
+   covered characters as a single character, either u+2029 or u+FFFC,
+   and return their combined length in CH_LEN and NCHARS.  DISP_POS
+   specifies the character position of the next display string, or -1
+   if not yet computed.  DISP_PROP non-zero means that there's really
+   a display string at DISP_POS, as opposed to when we searched till
+   DISP_POS without finding one.  If DISP_PROP is 2, it means the
+   display spec is of the form `(space ...)', which is replaced with
+   u+2029 to handle it as a paragraph separator.  When the next
+   character is at or beyond that position, the function updates
+   DISP_POS with the position of the next display string.  STRING->s
+   is the C string to iterate, or NULL if iterating over a buffer or a
+   Lisp string; in the latter case, STRING->lstring is the Lisp
+   string.  */
 static inline int
 bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
-                int *disp_prop_p, struct bidi_string_data *string,
+                int *disp_prop, struct bidi_string_data *string,
                 int frame_window_p, EMACS_INT *ch_len, EMACS_INT *nchars)
 {
   int ch;
@@ -934,7 +937,7 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
     {
       SET_TEXT_POS (pos, charpos, bytepos);
       *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
-                                             disp_prop_p);
+                                             disp_prop);
     }
 
   /* Fetch the character at BYTEPOS.  */
@@ -944,9 +947,9 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
       *ch_len = 1;
       *nchars = 1;
       *disp_pos = endpos;
-      *disp_prop_p = 0;
+      *disp_prop = 0;
     }
-  else if (charpos >= *disp_pos && *disp_prop_p)
+  else if (charpos >= *disp_pos && *disp_prop)
     {
       EMACS_INT disp_end_pos;
 
@@ -954,9 +957,23 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
         property.  Hopefully, it will never be needed.  */
       if (charpos > *disp_pos)
        abort ();
-      /* Return the Unicode Object Replacement Character to represent
-        the entire run of characters covered by the display string.  */
-      ch = 0xFFFC;
+      /* Text covered by `display' properties and overlays with
+        display properties or display strings is handled as a single
+        character that represents the entire run of characters
+        covered by the display property.  */
+      if (*disp_prop == 2)
+       {
+         /* `(space ...)' display specs are handled as paragraph
+            separators for the purposes of the reordering; see UAX#9
+            section 3 and clause HL1 in section 4.3 there.  */
+         ch = 0x2029;
+       }
+      else
+       {
+         /* All other display specs are handled as the Unicode Object
+            Replacement Character.  */
+         ch = 0xFFFC;
+       }
       disp_end_pos = compute_display_string_end (*disp_pos, string);
       *nchars = disp_end_pos - *disp_pos;
       if (*nchars <= 0)
@@ -1014,11 +1031,11 @@ bidi_fetch_char (EMACS_INT bytepos, EMACS_INT charpos, EMACS_INT *disp_pos,
   /* If we just entered a run of characters covered by a display
      string, compute the position of the next display string.  */
   if (charpos + *nchars <= endpos && charpos + *nchars > *disp_pos
-      && *disp_prop_p)
+      && *disp_prop)
     {
       SET_TEXT_POS (pos, charpos + *nchars, bytepos + *ch_len);
       *disp_pos = compute_display_string_pos (&pos, string, frame_window_p,
-                                             disp_prop_p);
+                                             disp_prop);
     }
 
   return ch;
@@ -1126,7 +1143,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
       int ch;
       EMACS_INT ch_len, nchars;
       EMACS_INT pos, disp_pos = -1;
-      int disp_prop_p = 0;
+      int disp_prop = 0;
       bidi_type_t type;
       const unsigned char *s;
 
@@ -1174,7 +1191,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
        bytepos = pstartbyte;
        if (!string_p)
          pos = BYTE_TO_CHAR (bytepos);
-       ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop_p,
+       ch = bidi_fetch_char (bytepos, pos, &disp_pos, &disp_prop,
                              &bidi_it->string,
                              bidi_it->frame_window_p, &ch_len, &nchars);
        type = bidi_get_type (ch, NEUTRAL_DIR);
@@ -1199,7 +1216,7 @@ bidi_paragraph_init (bidi_dir_t dir, struct bidi_it *bidi_it, int no_default_p)
              break;
            /* Fetch next character and advance to get past it.  */
            ch = bidi_fetch_char (bytepos, pos, &disp_pos,
-                                 &disp_prop_p, &bidi_it->string,
+                                 &disp_prop, &bidi_it->string,
                                  bidi_it->frame_window_p, &ch_len, &nchars);
            pos += nchars;
            bytepos += ch_len;
@@ -1336,7 +1353,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
       bidi_it->ch_len = 1;
       bidi_it->nchars = 1;
       bidi_it->disp_pos = (string_p ? bidi_it->string.schars : ZV);
-      bidi_it->disp_prop_p = 0;
+      bidi_it->disp_prop = 0;
     }
   else
     {
@@ -1344,7 +1361,7 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
         display string, treat the entire run of covered characters as
         a single character u+FFFC.  */
       curchar = bidi_fetch_char (bidi_it->bytepos, bidi_it->charpos,
-                                &bidi_it->disp_pos, &bidi_it->disp_prop_p,
+                                &bidi_it->disp_pos, &bidi_it->disp_prop,
                                 &bidi_it->string, bidi_it->frame_window_p,
                                 &bidi_it->ch_len, &bidi_it->nchars);
     }
@@ -2079,7 +2096,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
       struct bidi_string_data bs = bidi_it->string;
       bidi_type_t chtype;
       int fwp = bidi_it->frame_window_p;
-      int dpp = bidi_it->disp_prop_p;
+      int dpp = bidi_it->disp_prop;
 
       if (bidi_it->nchars <= 0)
        abort ();
index 084a3f9e07f9266902bb31c256a557ef1626da85..f5d20250fa7bfc0090368dc5b378f86dae158b73 100644 (file)
@@ -1860,8 +1860,9 @@ struct bidi_it {
   bidi_dir_t sor;              /* direction of start-of-run in effect */
   int scan_dir;                        /* direction of text scan, 1: forw, -1: back */
   EMACS_INT disp_pos;          /* position of display string after ch */
-  int disp_prop_p;             /* if non-zero, there really is a
-                                  `display' property/string at disp_pos */
+  int disp_prop;               /* if non-zero, there really is a
+                                  `display' property/string at disp_pos;
+                                  if 2, the property is a `space' spec */
   int stack_idx;               /* index of current data on the stack */
   /* Note: Everything from here on is not copied/saved when the bidi
      iterator state is saved, pushed, or popped.  So only put here
index 4ed08e72e19e4d19573f1d0e20c87146fdd38800..5cbc7747f2f7b7a2cc61416ef9afb13024702eb9 100644 (file)
@@ -3146,11 +3146,15 @@ next_overlay_change (EMACS_INT pos)
    text property whose value is a string.  STRING is data about the
    string to iterate; if STRING->lstring is nil, we are iterating a
    buffer.  FRAME_WINDOW_P is non-zero when we are displaying a window
-   on a GUI frame.  */
+   on a GUI frame.  DISP_PROP is set to zero if we searched
+   MAX_DISP_SCAN characters forward without finding any display
+   strings, non-zero otherwise.  It is set to 2 if the display string
+   uses any kind of `(space ...)' spec that will produce a stretch of
+   white space in the text area.  */
 EMACS_INT
 compute_display_string_pos (struct text_pos *position,
                            struct bidi_string_data *string,
-                           int frame_window_p, int *disp_prop_p)
+                           int frame_window_p, int *disp_prop)
 {
   /* OBJECT = nil means current buffer.  */
   Lisp_Object object =
@@ -3163,8 +3167,9 @@ compute_display_string_pos (struct text_pos *position,
   EMACS_INT lim =
     (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
   struct text_pos tpos;
+  int rv = 0;
 
-  *disp_prop_p = 1;
+  *disp_prop = 1;
 
   if (charpos >= eob
       /* We don't support display properties whose values are strings
@@ -3173,7 +3178,7 @@ compute_display_string_pos (struct text_pos *position,
       /* C strings cannot have display properties.  */
       || (string->s && !STRINGP (object)))
     {
-      *disp_prop_p = 0;
+      *disp_prop = 0;
       return eob;
     }
 
@@ -3190,9 +3195,11 @@ compute_display_string_pos (struct text_pos *position,
          || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
                                      object),
                  spec))
-      && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
-                             frame_window_p))
+      && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
+                                   frame_window_p)))
     {
+      if (rv == 2)
+       *disp_prop = 2;
       return charpos;
     }
 
@@ -3204,7 +3211,7 @@ compute_display_string_pos (struct text_pos *position,
     CHARPOS (tpos) = XFASTINT (pos);
     if (CHARPOS (tpos) >= lim)
       {
-       *disp_prop_p = 0;
+       *disp_prop = 0;
        break;
       }
     if (STRINGP (object))
@@ -3215,8 +3222,10 @@ compute_display_string_pos (struct text_pos *position,
     if (!STRINGP (object))
       bufpos = CHARPOS (tpos);
   } while (NILP (spec)
-          || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
-                                   frame_window_p));
+          || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
+                                         bufpos, frame_window_p)));
+  if (rv == 2)
+    *disp_prop = 2;
 
   return CHARPOS (tpos);
 }
@@ -4078,7 +4087,9 @@ handle_display_prop (struct it *it)
 /* Subroutine of handle_display_prop.  Returns non-zero if the display
    specification in SPEC is a replacing specification, i.e. it would
    replace the text covered by `display' property with something else,
-   such as an image or a display string.
+   such as an image or a display string.  If SPEC includes any kind or
+   `(space ...) specification, the value is 2; this is used by
+   compute_display_string_pos, which see.
 
    See handle_single_display_spec for documentation of arguments.
    frame_window_p is non-zero if the window being redisplayed is on a
@@ -4095,6 +4106,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
                     EMACS_INT bufpos, int frame_window_p)
 {
   int replacing_p = 0;
+  int rv;
 
   if (CONSP (spec)
       /* Simple specerties.  */
@@ -4113,11 +4125,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
     {
       for (; CONSP (spec); spec = XCDR (spec))
        {
-         if (handle_single_display_spec (it, XCAR (spec), object, overlay,
-                                         position, bufpos, replacing_p,
-                                         frame_window_p))
+         if ((rv = handle_single_display_spec (it, XCAR (spec), object,
+                                               overlay, position, bufpos,
+                                               replacing_p, frame_window_p)))
            {
-             replacing_p = 1;
+             replacing_p = rv;
              /* If some text in a string is replaced, `position' no
                 longer points to the position of `object'.  */
              if (!it || STRINGP (object))
@@ -4129,11 +4141,11 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
     {
       int i;
       for (i = 0; i < ASIZE (spec); ++i)
-       if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
-                                       position, bufpos, replacing_p,
-                                       frame_window_p))
+       if ((rv = handle_single_display_spec (it, AREF (spec, i), object,
+                                             overlay, position, bufpos,
+                                             replacing_p, frame_window_p)))
          {
-           replacing_p = 1;
+           replacing_p = rv;
            /* If some text in a string is replaced, `position' no
               longer points to the position of `object'.  */
            if (!it || STRINGP (object))
@@ -4142,9 +4154,10 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
     }
   else
     {
-      if (handle_single_display_spec (it, spec, object, overlay,
-                                     position, bufpos, 0, frame_window_p))
-       replacing_p = 1;
+      if ((rv = handle_single_display_spec (it, spec, object, overlay,
+                                           position, bufpos, 0,
+                                           frame_window_p)))
+       replacing_p = rv;
     }
 
   return replacing_p;
@@ -4520,8 +4533,17 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 
   if (valid_p && !display_replaced_p)
     {
+      int retval = 1;
+
       if (!it)
-       return 1;
+       {
+         /* Callers need to know whether the display spec is any kind
+            of `(space ...)' spec that is about to affect text-area
+            display.  */
+         if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
+           retval = 2;
+         return retval;
+       }
 
       /* Save current settings of IT so that we can restore them
         when we are finished with the glyph property value.  */
@@ -4579,6 +4601,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
          it->method = GET_FROM_STRETCH;
          it->object = value;
          *position = it->position = start_pos;
+         retval = 1 + (it->area == TEXT_AREA);
        }
 #ifdef HAVE_WINDOW_SYSTEM
       else
@@ -4596,7 +4619,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
        }
 #endif /* HAVE_WINDOW_SYSTEM */
 
-      return 1;
+      return retval;
     }
 
   /* Invalid property or property not supported.  Restore
@@ -5557,7 +5580,7 @@ forward_to_next_line_start (struct it *it, int *skipped_p,
              if (it->bidi_it.disp_pos < limit)
                {
                  it->bidi_it.disp_pos = limit;
-                 it->bidi_it.disp_prop_p = 0;
+                 it->bidi_it.disp_prop = 0;
                }
              do {
                bprev = it->bidi_it;