]> git.eshelyaron.com Git - emacs.git/commitdiff
(Vshow_nonbreak_escape): New lisp var.
authorKim F. Storm <storm@cua.dk>
Sun, 9 Jan 2005 02:05:41 +0000 (02:05 +0000)
committerKim F. Storm <storm@cua.dk>
Sun, 9 Jan 2005 02:05:41 +0000 (02:05 +0000)
(syms_of_xdisp): DEFVAR_LISP it.
(escape_glyph_face): Remove var.
(redisplay_window): Don't initialize it.
(setup_for_ellipsis, get_next_display_element):
Set it->dpvec_face_id to -1.
(get_next_display_element): Test Vshow_nonbreak_escape.
Do not setup escape_glyph_face.
Properly merge escape-glyph face or face from display table with
current face for escape and control characters.  Set
it->dpvec_face_id to relevant face id instead of adding it to each
element of display vector.
(next_element_from_display_vector): If it->dpvec_face_id is set,
use that instead of lface_id from glyph itself.

src/xdisp.c

index e4c231c3083388c4d29de03cb0733a44af0e3d10..be0baecd76b3ed29ccc44146a2defbc5ebf0067a 100644 (file)
@@ -318,6 +318,10 @@ extern Lisp_Object Qcursor;
 
 Lisp_Object Vshow_trailing_whitespace;
 
+/* Non-nil means escape non-break space and hyphens.  */
+
+Lisp_Object Vshow_nonbreak_escape;
+
 #ifdef HAVE_WINDOW_SYSTEM
 extern Lisp_Object Voverflow_newline_into_fringe;
 
@@ -345,7 +349,6 @@ Lisp_Object Qtrailing_whitespace;
 /* Name and number of the face used to highlight escape glyphs.  */
 
 Lisp_Object Qescape_glyph;
-int escape_glyph_face;
 
 /* The symbol `image' which is the car of the lists used to represent
    images in Lisp.  */
@@ -3265,6 +3268,7 @@ setup_for_ellipsis (it, len)
 
   it->dpvec_char_len = len;
   it->current.dpvec_index = 0;
+  it->dpvec_face_id = -1;
 
   /* Remember the current face id in case glyphs specify faces.
      IT's face is restored in set_iterator_to_next.  */
@@ -4911,6 +4915,7 @@ get_next_display_element (it)
                  it->dpvec = v->contents;
                  it->dpend = v->contents + v->size;
                  it->current.dpvec_index = 0;
+                 it->dpvec_face_id = -1;
                  it->saved_face_id = it->face_id;
                  it->method = next_element_from_display_vector;
                  it->ellipsis_p = 0;
@@ -4945,8 +4950,8 @@ get_next_display_element (it)
                       ? ((it->c >= 127
                           && it->len == 1)
                          || !CHAR_PRINTABLE_P (it->c)
-                         || it->c == 0x8ad
-                         || it->c == 0x8a0)
+                         || (!NILP (Vshow_nonbreak_escape)
+                             && (it->c == 0x8ad || it->c == 0x8a0)))
                       : (it->c >= 127
                          && (!unibyte_display_via_language_environment
                              || it->c == unibyte_char_to_multibyte (it->c)))))
@@ -4958,21 +4963,8 @@ get_next_display_element (it)
                 display.  Then, set IT->dpvec to these glyphs.  */
              GLYPH g;
              int ctl_len;
-             int face_id = escape_glyph_face;
-
-             /* Find the face id if `escape-glyph' unless we recently did.  */
-             if (face_id < 0)
-               {
-                 Lisp_Object tem = Fget (Qescape_glyph, Qface);
-                 if (INTEGERP (tem))
-                   face_id = XINT (tem);
-                 else
-                   face_id = 0;
-                 /* If there's overflow, use 0 instead.  */
-                 if (FAST_GLYPH_FACE (FAST_MAKE_GLYPH (0, face_id)) != face_id)
-                   face_id = 0;
-                 escape_glyph_face = face_id;
-               }
+             int face_id, lface_id;
+             GLYPH escape_glyph;
 
              if (it->c < 128 && it->ctl_arrow_p)
                {
@@ -4980,57 +4972,84 @@ get_next_display_element (it)
                  if (it->dp
                      && INTEGERP (DISP_CTRL_GLYPH (it->dp))
                      && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
-                   g = XINT (DISP_CTRL_GLYPH (it->dp));
+                   {
+                     g = XINT (DISP_CTRL_GLYPH (it->dp));
+                     lface_id = FAST_GLYPH_FACE (g);
+                     if (lface_id)
+                       {
+                         g = FAST_GLYPH_CHAR (g);
+                         /* The function returns -1 if lface_id is invalid.  */
+                         face_id = ascii_face_of_lisp_face (it->f, lface_id);
+                         if (face_id >= 0)
+                           face_id = merge_into_realized_face (it->f, Qnil,
+                                                               face_id, it->face_id);
+                       }
+                   }
                  else
-                   g = FAST_MAKE_GLYPH ('^', face_id);
-                 XSETINT (it->ctl_chars[0], g);
+                   {
+                     /* Merge the escape-glyph face into the current face.  */
+                     face_id = merge_into_realized_face (it->f, Qescape_glyph,
+                                                         0, it->face_id);
+                     g = '^';
+                   }
 
-                 g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
+                 XSETINT (it->ctl_chars[0], g);
+                 g = it->c ^ 0100;
                  XSETINT (it->ctl_chars[1], g);
                  ctl_len = 2;
+                 goto display_control;
                }
-             else if (it->c == 0x8a0 || it->c == 0x8ad)
+
+             if (it->dp
+                 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
+                 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
                {
-                 /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
-                 if (it->dp
-                     && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
-                     && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp))))
-                   g = XINT (DISP_ESCAPE_GLYPH (it->dp));
-                 else
-                   g = FAST_MAKE_GLYPH ('\\', face_id);
-                 XSETINT (it->ctl_chars[0], g);
+                 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
+                 lface_id = FAST_GLYPH_FACE (escape_glyph);
+                 if (lface_id)
+                   {
+                     escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
+                     /* The function returns -1 if lface_id is invalid.  */
+                     face_id = ascii_face_of_lisp_face (it->f, lface_id);
+                     if (face_id >= 0)
+                       face_id = merge_into_realized_face (it->f, Qnil,
+                                                           face_id, it->face_id);
+                   }
+               }
+             else
+               {
+                 /* Merge the escape-glyph face into the current face.  */
+                 face_id = merge_into_realized_face (it->f, Qescape_glyph,
+                                                     0, it->face_id);
+                 escape_glyph = '\\';
+               }
 
-                 g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
+             if (it->c == 0x8a0 || it->c == 0x8ad)
+               {
+                 XSETINT (it->ctl_chars[0], escape_glyph);
+                 g = it->c == 0x8ad ? '-' : ' ';
                  XSETINT (it->ctl_chars[1], g);
                  ctl_len = 2;
+                 goto display_control;
                }
-             else
-               {
-                 unsigned char str[MAX_MULTIBYTE_LENGTH];
-                 int len;
-                 int i;
-                 GLYPH escape_glyph;
 
-                 /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
-                 if (it->dp
-                     && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
-                     && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
-                   escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
-                 else
-                   escape_glyph = FAST_MAKE_GLYPH ('\\', face_id);
+             {
+               unsigned char str[MAX_MULTIBYTE_LENGTH];
+               int len;
+               int i;
 
-                 if (SINGLE_BYTE_CHAR_P (it->c))
-                   str[0] = it->c, len = 1;
-                 else
-                   {
-                     len = CHAR_STRING_NO_SIGNAL (it->c, str);
-                     if (len < 0)
-                       {
-                         /* It's an invalid character, which
-                            shouldn't happen actually, but due to
-                            bugs it may happen.  Let's print the char
-                            as is, there's not much meaningful we can
-                            do with it.  */
+               /* Set IT->ctl_chars[0] to the glyph for `\\'.  */
+               if (SINGLE_BYTE_CHAR_P (it->c))
+                 str[0] = it->c, len = 1;
+               else
+                 {
+                   len = CHAR_STRING_NO_SIGNAL (it->c, str);
+                   if (len < 0)
+                     {
+                       /* It's an invalid character, which shouldn't
+                          happen actually, but due to bugs it may
+                          happen.  Let's print the char as is, there's
+                          not much meaningful we can do with it.  */
                          str[0] = it->c;
                          str[1] = it->c >> 8;
                          str[2] = it->c >> 16;
@@ -5039,29 +5058,28 @@ get_next_display_element (it)
                        }
                    }
 
-                 for (i = 0; i < len; i++)
-                   {
-                     XSETINT (it->ctl_chars[i * 4], escape_glyph);
-                     /* Insert three more glyphs into IT->ctl_chars for
-                        the octal display of the character.  */
-                     g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0',
-                                          face_id);
-                     XSETINT (it->ctl_chars[i * 4 + 1], g);
-                     g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0',
-                                          face_id);
-                     XSETINT (it->ctl_chars[i * 4 + 2], g);
-                     g = FAST_MAKE_GLYPH ((str[i] & 7) + '0',
-                                          face_id);
-                     XSETINT (it->ctl_chars[i * 4 + 3], g);
-                   }
-                 ctl_len = len * 4;
-               }
+               for (i = 0; i < len; i++)
+                 {
+                   XSETINT (it->ctl_chars[i * 4], escape_glyph);
+                   /* Insert three more glyphs into IT->ctl_chars for
+                      the octal display of the character.  */
+                   g = ((str[i] >> 6) & 7) + '0';
+                   XSETINT (it->ctl_chars[i * 4 + 1], g);
+                   g = ((str[i] >> 3) & 7) + '0';
+                   XSETINT (it->ctl_chars[i * 4 + 2], g);
+                   g = (str[i] & 7) + '0';
+                   XSETINT (it->ctl_chars[i * 4 + 3], g);
+                 }
+               ctl_len = len * 4;
+             }
 
+           display_control:
              /* Set up IT->dpvec and return first character from it.  */
              it->dpvec_char_len = it->len;
              it->dpvec = it->ctl_chars;
              it->dpend = it->dpvec + ctl_len;
              it->current.dpvec_index = 0;
+             it->dpvec_face_id = face_id;
              it->saved_face_id = it->face_id;
              it->method = next_element_from_display_vector;
              it->ellipsis_p = 0;
@@ -5277,7 +5295,6 @@ next_element_from_display_vector (it)
   if (INTEGERP (*it->dpvec)
       && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
     {
-      int lface_id;
       GLYPH g;
 
       g = XFASTINT (it->dpvec[it->current.dpvec_index]);
@@ -5287,13 +5304,18 @@ next_element_from_display_vector (it)
       /* The entry may contain a face id to use.  Such a face id is
         the id of a Lisp face, not a realized face.  A face id of
         zero means no face is specified.  */
-      lface_id = FAST_GLYPH_FACE (g);
-      if (lface_id)
+      if (it->dpvec_face_id >= 0)
+       it->face_id = it->dpvec_face_id;
+      else
        {
-         /* The function returns -1 if lface_id is invalid.  */
-         int face_id = ascii_face_of_lisp_face (it->f, lface_id);
-         if (face_id >= 0)
-           it->face_id = face_id;
+         int lface_id = FAST_GLYPH_FACE (g);
+         if (lface_id)
+           {
+             /* The function returns -1 if lface_id is invalid.  */
+             int face_id = ascii_face_of_lisp_face (it->f, lface_id);
+             if (face_id >= 0)
+               it->face_id = face_id;
+           }
        }
     }
   else
@@ -11664,9 +11686,6 @@ redisplay_window (window, just_this_one_p)
   *w->desired_matrix->method = 0;
 #endif
 
-  /* Force this to be looked up again for each redisp of each window.  */
-  escape_glyph_face = -1;
-
   specbind (Qinhibit_point_motion_hooks, Qt);
 
   reconsider_clip_changes (w, buffer);
@@ -22339,6 +22358,10 @@ wide as that tab on the display.  */);
 The face used for trailing whitespace is `trailing-whitespace'.  */);
   Vshow_trailing_whitespace = Qnil;
 
+  DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
+    doc: /* *Non-nil means display escape character before non-break space and hyphen.  */);
+  Vshow_trailing_whitespace = Qt;
+
   DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
     doc: /* *The pointer shape to show in void text areas.
 Nil means to show the text pointer.  Other options are `arrow', `text',