changeset 59432:b6b9daefbc42

(Vshow_nonbreak_escape): New lisp var. (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.
author Kim F. Storm <storm@cua.dk>
date Sun, 09 Jan 2005 02:05:41 +0000
parents 2f2c5349bc03
children 100bcbece57b
files src/xdisp.c
diffstat 1 files changed, 114 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/xdisp.c	Sun Jan 09 02:05:20 2005 +0000
+++ b/src/xdisp.c	Sun Jan 09 02:05:41 2005 +0000
@@ -318,6 +318,10 @@
 
 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 @@
 /* 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 @@
 
   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 @@
 		  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 @@
 		       ? ((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 @@
 		 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 @@
 		  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);
+		    {
+		      /* Merge the escape-glyph face into the current face.  */
+		      face_id = merge_into_realized_face (it->f, Qescape_glyph,
+							  0, it->face_id);
+		      g = '^';
+		    }
+
 		  XSETINT (it->ctl_chars[0], g);
-
-		  g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
+		  g = it->c ^ 0100;
 		  XSETINT (it->ctl_chars[1], g);
 		  ctl_len = 2;
-		}
-	      else if (it->c == 0x8a0 || it->c == 0x8ad)
-		{
-		  /* 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);
-
-		  g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
-		  XSETINT (it->ctl_chars[1], g);
-		  ctl_len = 2;
+		  goto display_control;
+		}
+
+	      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));
+		  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
 		{
-		  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);
-
-		  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.  */
+		  /* 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 = '\\';
+		}
+
+	      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;
+		}
+
+	      {
+		unsigned char str[MAX_MULTIBYTE_LENGTH];
+		int len;
+		int i;
+
+		/* 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 @@
 			}
 		    }
 
-		  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 @@
   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 @@
       /* 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)
-	{
-	  /* 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;
+      if (it->dpvec_face_id >= 0)
+	it->face_id = it->dpvec_face_id;
+      else
+	{
+	  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 @@
   *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 @@
 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',