Have nobreak-char-display handle U+2010 and U+2011.
[bpt/emacs.git] / src / xdisp.c
index 8609855..7576361 100644 (file)
@@ -6371,8 +6371,8 @@ get_next_display_element (struct it *it)
        {
          Lisp_Object dv;
          struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
-         enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
-         nbsp_or_shy = char_is_other;
+         int nonascii_space_p = 0;
+         int nonascii_hyphen_p = 0;
          int c = it->c;        /* This is the character to display.  */
 
          if (! it->multibyte_p && ! ASCII_CHAR_P (c))
@@ -6424,10 +6424,15 @@ get_next_display_element (struct it *it)
              goto get_next;
            }
 
+         /* If `nobreak-char-display' is non-nil, we display
+            non-ASCII spaces and hyphens specially.  */
          if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
-           nbsp_or_shy = (c == 0xA0   ? char_is_nbsp
-                          : c == 0xAD ? char_is_soft_hyphen
-                          :             char_is_other);
+           {
+             if (c == 0xA0)
+               nonascii_space_p = 1;
+             else if (c == 0xAD || c == 0x2010 || c == 0x2011)
+               nonascii_hyphen_p = 1;
+           }
 
          /* Translate control characters into `\003' or `^C' form.
             Control characters coming from a display table entry are
@@ -6435,7 +6440,8 @@ get_next_display_element (struct it *it)
             the translation.  This could easily be changed but I
             don't believe that it is worth doing.
 
-            NBSP and SOFT-HYPEN are property translated too.
+            The characters handled by `nobreak-char-display' must be
+            translated too.
 
             Non-printable characters and raw-byte characters are also
             translated to octal form.  */
@@ -6446,14 +6452,15 @@ get_next_display_element (struct it *it)
                      && it->glyph_row
                      && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
                  || (c != '\n' && c != '\t'))
-              : (nbsp_or_shy
+              : (nonascii_space_p
+                 || nonascii_hyphen_p
                  || CHAR_BYTE8_P (c)
                  || ! CHAR_PRINTABLE_P (c))))
            {
-             /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
-                or a non-printable character which must be displayed
-                either as '\003' or as `^C' where the '\\' and '^'
-                can be defined in the display table.  Fill
+             /* C is a control character, non-ASCII space/hyphen,
+                raw-byte, or a non-printable character which must be
+                displayed either as '\003' or as `^C' where the '\\'
+                and '^' can be defined in the display table.  Fill
                 IT->ctl_chars with glyphs for what we have to
                 display.  Then, set IT->dpvec to these glyphs.  */
              Lisp_Object gc;
@@ -6502,17 +6509,14 @@ get_next_display_element (struct it *it)
                  goto display_control;
                }
 
-             /* Handle non-break space in the mode where it only gets
+             /* Handle non-ascii space in the mode where it only gets
                 highlighting.  */
 
-             if (EQ (Vnobreak_char_display, Qt)
-                 && nbsp_or_shy == char_is_nbsp)
+             if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
                {
-                 /* Merge the no-break-space face into the current face.  */
+                 /* Merge `nobreak-space' into the current face.  */
                  face_id = merge_faces (it->f, Qnobreak_space, 0,
                                         it->face_id);
-
-                 c = ' ';
                  XSETINT (it->ctl_chars[0], ' ');
                  ctl_len = 1;
                  goto display_control;
@@ -6552,25 +6556,21 @@ get_next_display_element (struct it *it)
                  last_escape_glyph_merged_face_id = face_id;
                }
 
-             /* Handle soft hyphens in the mode where they only get
-                highlighting.  */
+             /* Draw non-ASCII hyphen with just highlighting: */
 
-             if (EQ (Vnobreak_char_display, Qt)
-                 && nbsp_or_shy == char_is_soft_hyphen)
+             if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
                {
                  XSETINT (it->ctl_chars[0], '-');
                  ctl_len = 1;
                  goto display_control;
                }
 
-             /* Handle non-break space and soft hyphen
-                with the escape glyph.  */
+             /* Draw non-ASCII space/hyphen with escape glyph: */
 
-             if (nbsp_or_shy)
+             if (nonascii_space_p || nonascii_hyphen_p)
                {
                  XSETINT (it->ctl_chars[0], escape_glyph);
-                 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
-                 XSETINT (it->ctl_chars[1], c);
+                 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
                  ctl_len = 2;
                  goto display_control;
                }
@@ -7148,7 +7148,6 @@ get_visually_first_element (struct it *it)
     }
   else if (it->bidi_it.charpos == bob
           || (!string_p
-              /* FIXME: Should support all Unicode line separators.  */
               && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
                   || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
     {
@@ -8769,7 +8768,10 @@ move_it_vertically_backward (struct it *it, int dy)
         reordering.  We want to get to the character position
         that is immediately after the newline of the previous
         line.  */
-      if (it->bidi_p && IT_CHARPOS (*it) > BEGV
+      if (it->bidi_p
+         && !it->continuation_lines_width
+         && !STRINGP (it->string)
+         && IT_CHARPOS (*it) > BEGV
          && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
        {
          EMACS_INT nl_pos =
@@ -18428,9 +18430,10 @@ static int
 push_display_prop (struct it *it, Lisp_Object prop)
 {
   struct text_pos pos =
-    (it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos;
+    STRINGP (it->string) ? it->current.string_pos : it->current.pos;
 
   xassert (it->method == GET_FROM_BUFFER
+          || it->method == GET_FROM_DISPLAY_VECTOR
           || it->method == GET_FROM_STRING);
 
   /* We need to save the current buffer/string position, so it will be
@@ -18647,7 +18650,12 @@ find_row_edges (struct it *it, struct glyph_row *row,
                    seen_this_string = 1;
                }
              else
-               abort ();
+               /* If all the glyphs of the previous row were inserted
+                  by redisplay, it means the previous row was
+                  produced from a single newline, which is only
+                  possible if that newline came from the same string
+                  as the one which produced this ROW.  */
+               seen_this_string = 1;
            }
          else
            {
@@ -18663,7 +18671,7 @@ find_row_edges (struct it *it, struct glyph_row *row,
                    seen_this_string = 1;
                }
              else
-               abort ();
+               seen_this_string = 1;
            }
        }
       /* Take note of each display string that covers a newline only
@@ -19480,6 +19488,7 @@ See also `bidi-paragraph-direction'.  */)
            bytepos--;
        }
       bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
+      itb.paragraph_dir = NEUTRAL_DIR;
       itb.string.s = NULL;
       itb.string.lstring = Qnil;
       itb.string.bufpos = 0;
@@ -27992,12 +28001,18 @@ The face used for trailing whitespace is `trailing-whitespace'.  */);
   Vshow_trailing_whitespace = Qnil;
 
   DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
-    doc: /* *Control highlighting of nobreak space and soft hyphen.
-A value of t means highlight the character itself (for nobreak space,
-use face `nobreak-space').
-A value of nil means no highlighting.
-Other values mean display the escape glyph followed by an ordinary
-space or ordinary hyphen.  */);
+    doc: /* Control highlighting of non-ASCII space and hyphen chars.
+If the value is t, Emacs highlights non-ASCII chars which have the
+same appearance as an ASCII space or hyphen, using the `nobreak-space'
+or `escape-glyph' face respectively.
+
+U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
+U+2011 (non-breaking hyphen) are affected.
+
+Any other non-nil value means to display these characters as a escape
+glyph followed by an ordinary space or hyphen.
+
+A value of nil means no special handling of these characters.  */);
   Vnobreak_char_display = Qt;
 
   DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,