comparison src/xdisp.c @ 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 0e57f1b0b700
children 85a7102acb30
comparison
equal deleted inserted replaced
59431:2f2c5349bc03 59432:b6b9daefbc42
316 316
317 /* Non-nil means highlight trailing whitespace. */ 317 /* Non-nil means highlight trailing whitespace. */
318 318
319 Lisp_Object Vshow_trailing_whitespace; 319 Lisp_Object Vshow_trailing_whitespace;
320 320
321 /* Non-nil means escape non-break space and hyphens. */
322
323 Lisp_Object Vshow_nonbreak_escape;
324
321 #ifdef HAVE_WINDOW_SYSTEM 325 #ifdef HAVE_WINDOW_SYSTEM
322 extern Lisp_Object Voverflow_newline_into_fringe; 326 extern Lisp_Object Voverflow_newline_into_fringe;
323 327
324 /* Test if overflow newline into fringe. Called with iterator IT 328 /* Test if overflow newline into fringe. Called with iterator IT
325 at or past right window margin, and with IT->current_x set. */ 329 at or past right window margin, and with IT->current_x set. */
343 Lisp_Object Qtrailing_whitespace; 347 Lisp_Object Qtrailing_whitespace;
344 348
345 /* Name and number of the face used to highlight escape glyphs. */ 349 /* Name and number of the face used to highlight escape glyphs. */
346 350
347 Lisp_Object Qescape_glyph; 351 Lisp_Object Qescape_glyph;
348 int escape_glyph_face;
349 352
350 /* The symbol `image' which is the car of the lists used to represent 353 /* The symbol `image' which is the car of the lists used to represent
351 images in Lisp. */ 354 images in Lisp. */
352 355
353 Lisp_Object Qimage; 356 Lisp_Object Qimage;
3263 it->dpend = default_invis_vector + 3; 3266 it->dpend = default_invis_vector + 3;
3264 } 3267 }
3265 3268
3266 it->dpvec_char_len = len; 3269 it->dpvec_char_len = len;
3267 it->current.dpvec_index = 0; 3270 it->current.dpvec_index = 0;
3271 it->dpvec_face_id = -1;
3268 3272
3269 /* Remember the current face id in case glyphs specify faces. 3273 /* Remember the current face id in case glyphs specify faces.
3270 IT's face is restored in set_iterator_to_next. */ 3274 IT's face is restored in set_iterator_to_next. */
3271 it->saved_face_id = it->face_id; 3275 it->saved_face_id = it->face_id;
3272 it->method = next_element_from_display_vector; 3276 it->method = next_element_from_display_vector;
4909 { 4913 {
4910 it->dpvec_char_len = it->len; 4914 it->dpvec_char_len = it->len;
4911 it->dpvec = v->contents; 4915 it->dpvec = v->contents;
4912 it->dpend = v->contents + v->size; 4916 it->dpend = v->contents + v->size;
4913 it->current.dpvec_index = 0; 4917 it->current.dpvec_index = 0;
4918 it->dpvec_face_id = -1;
4914 it->saved_face_id = it->face_id; 4919 it->saved_face_id = it->face_id;
4915 it->method = next_element_from_display_vector; 4920 it->method = next_element_from_display_vector;
4916 it->ellipsis_p = 0; 4921 it->ellipsis_p = 0;
4917 } 4922 }
4918 else 4923 else
4943 || (it->c != '\n' && it->c != '\t'))) 4948 || (it->c != '\n' && it->c != '\t')))
4944 || (it->multibyte_p 4949 || (it->multibyte_p
4945 ? ((it->c >= 127 4950 ? ((it->c >= 127
4946 && it->len == 1) 4951 && it->len == 1)
4947 || !CHAR_PRINTABLE_P (it->c) 4952 || !CHAR_PRINTABLE_P (it->c)
4948 || it->c == 0x8ad 4953 || (!NILP (Vshow_nonbreak_escape)
4949 || it->c == 0x8a0) 4954 && (it->c == 0x8ad || it->c == 0x8a0)))
4950 : (it->c >= 127 4955 : (it->c >= 127
4951 && (!unibyte_display_via_language_environment 4956 && (!unibyte_display_via_language_environment
4952 || it->c == unibyte_char_to_multibyte (it->c))))) 4957 || it->c == unibyte_char_to_multibyte (it->c)))))
4953 { 4958 {
4954 /* IT->c is a control character which must be displayed 4959 /* IT->c is a control character which must be displayed
4956 can be defined in the display table. Fill 4961 can be defined in the display table. Fill
4957 IT->ctl_chars with glyphs for what we have to 4962 IT->ctl_chars with glyphs for what we have to
4958 display. Then, set IT->dpvec to these glyphs. */ 4963 display. Then, set IT->dpvec to these glyphs. */
4959 GLYPH g; 4964 GLYPH g;
4960 int ctl_len; 4965 int ctl_len;
4961 int face_id = escape_glyph_face; 4966 int face_id, lface_id;
4962 4967 GLYPH escape_glyph;
4963 /* Find the face id if `escape-glyph' unless we recently did. */
4964 if (face_id < 0)
4965 {
4966 Lisp_Object tem = Fget (Qescape_glyph, Qface);
4967 if (INTEGERP (tem))
4968 face_id = XINT (tem);
4969 else
4970 face_id = 0;
4971 /* If there's overflow, use 0 instead. */
4972 if (FAST_GLYPH_FACE (FAST_MAKE_GLYPH (0, face_id)) != face_id)
4973 face_id = 0;
4974 escape_glyph_face = face_id;
4975 }
4976 4968
4977 if (it->c < 128 && it->ctl_arrow_p) 4969 if (it->c < 128 && it->ctl_arrow_p)
4978 { 4970 {
4979 /* Set IT->ctl_chars[0] to the glyph for `^'. */ 4971 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4980 if (it->dp 4972 if (it->dp
4981 && INTEGERP (DISP_CTRL_GLYPH (it->dp)) 4973 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4982 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp)))) 4974 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4983 g = XINT (DISP_CTRL_GLYPH (it->dp)); 4975 {
4976 g = XINT (DISP_CTRL_GLYPH (it->dp));
4977 lface_id = FAST_GLYPH_FACE (g);
4978 if (lface_id)
4979 {
4980 g = FAST_GLYPH_CHAR (g);
4981 /* The function returns -1 if lface_id is invalid. */
4982 face_id = ascii_face_of_lisp_face (it->f, lface_id);
4983 if (face_id >= 0)
4984 face_id = merge_into_realized_face (it->f, Qnil,
4985 face_id, it->face_id);
4986 }
4987 }
4984 else 4988 else
4985 g = FAST_MAKE_GLYPH ('^', face_id); 4989 {
4990 /* Merge the escape-glyph face into the current face. */
4991 face_id = merge_into_realized_face (it->f, Qescape_glyph,
4992 0, it->face_id);
4993 g = '^';
4994 }
4995
4986 XSETINT (it->ctl_chars[0], g); 4996 XSETINT (it->ctl_chars[0], g);
4987 4997 g = it->c ^ 0100;
4988 g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
4989 XSETINT (it->ctl_chars[1], g); 4998 XSETINT (it->ctl_chars[1], g);
4990 ctl_len = 2; 4999 ctl_len = 2;
5000 goto display_control;
4991 } 5001 }
4992 else if (it->c == 0x8a0 || it->c == 0x8ad) 5002
5003 if (it->dp
5004 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5005 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4993 { 5006 {
4994 /* Set IT->ctl_chars[0] to the glyph for `\\'. */ 5007 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4995 if (it->dp 5008 lface_id = FAST_GLYPH_FACE (escape_glyph);
4996 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp)) 5009 if (lface_id)
4997 && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp)))) 5010 {
4998 g = XINT (DISP_ESCAPE_GLYPH (it->dp)); 5011 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
4999 else 5012 /* The function returns -1 if lface_id is invalid. */
5000 g = FAST_MAKE_GLYPH ('\\', face_id); 5013 face_id = ascii_face_of_lisp_face (it->f, lface_id);
5001 XSETINT (it->ctl_chars[0], g); 5014 if (face_id >= 0)
5002 5015 face_id = merge_into_realized_face (it->f, Qnil,
5003 g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id); 5016 face_id, it->face_id);
5004 XSETINT (it->ctl_chars[1], g); 5017 }
5005 ctl_len = 2;
5006 } 5018 }
5007 else 5019 else
5008 { 5020 {
5009 unsigned char str[MAX_MULTIBYTE_LENGTH]; 5021 /* Merge the escape-glyph face into the current face. */
5010 int len; 5022 face_id = merge_into_realized_face (it->f, Qescape_glyph,
5011 int i; 5023 0, it->face_id);
5012 GLYPH escape_glyph; 5024 escape_glyph = '\\';
5013 5025 }
5014 /* Set IT->ctl_chars[0] to the glyph for `\\'. */ 5026
5015 if (it->dp 5027 if (it->c == 0x8a0 || it->c == 0x8ad)
5016 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp)) 5028 {
5017 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp)))) 5029 XSETINT (it->ctl_chars[0], escape_glyph);
5018 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp)); 5030 g = it->c == 0x8ad ? '-' : ' ';
5019 else 5031 XSETINT (it->ctl_chars[1], g);
5020 escape_glyph = FAST_MAKE_GLYPH ('\\', face_id); 5032 ctl_len = 2;
5021 5033 goto display_control;
5022 if (SINGLE_BYTE_CHAR_P (it->c)) 5034 }
5023 str[0] = it->c, len = 1; 5035
5024 else 5036 {
5025 { 5037 unsigned char str[MAX_MULTIBYTE_LENGTH];
5026 len = CHAR_STRING_NO_SIGNAL (it->c, str); 5038 int len;
5027 if (len < 0) 5039 int i;
5028 { 5040
5029 /* It's an invalid character, which 5041 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5030 shouldn't happen actually, but due to 5042 if (SINGLE_BYTE_CHAR_P (it->c))
5031 bugs it may happen. Let's print the char 5043 str[0] = it->c, len = 1;
5032 as is, there's not much meaningful we can 5044 else
5033 do with it. */ 5045 {
5046 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5047 if (len < 0)
5048 {
5049 /* It's an invalid character, which shouldn't
5050 happen actually, but due to bugs it may
5051 happen. Let's print the char as is, there's
5052 not much meaningful we can do with it. */
5034 str[0] = it->c; 5053 str[0] = it->c;
5035 str[1] = it->c >> 8; 5054 str[1] = it->c >> 8;
5036 str[2] = it->c >> 16; 5055 str[2] = it->c >> 16;
5037 str[3] = it->c >> 24; 5056 str[3] = it->c >> 24;
5038 len = 4; 5057 len = 4;
5039 } 5058 }
5040 } 5059 }
5041 5060
5042 for (i = 0; i < len; i++) 5061 for (i = 0; i < len; i++)
5043 { 5062 {
5044 XSETINT (it->ctl_chars[i * 4], escape_glyph); 5063 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5045 /* Insert three more glyphs into IT->ctl_chars for 5064 /* Insert three more glyphs into IT->ctl_chars for
5046 the octal display of the character. */ 5065 the octal display of the character. */
5047 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 5066 g = ((str[i] >> 6) & 7) + '0';
5048 face_id); 5067 XSETINT (it->ctl_chars[i * 4 + 1], g);
5049 XSETINT (it->ctl_chars[i * 4 + 1], g); 5068 g = ((str[i] >> 3) & 7) + '0';
5050 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 5069 XSETINT (it->ctl_chars[i * 4 + 2], g);
5051 face_id); 5070 g = (str[i] & 7) + '0';
5052 XSETINT (it->ctl_chars[i * 4 + 2], g); 5071 XSETINT (it->ctl_chars[i * 4 + 3], g);
5053 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 5072 }
5054 face_id); 5073 ctl_len = len * 4;
5055 XSETINT (it->ctl_chars[i * 4 + 3], g); 5074 }
5056 } 5075
5057 ctl_len = len * 4; 5076 display_control:
5058 }
5059
5060 /* Set up IT->dpvec and return first character from it. */ 5077 /* Set up IT->dpvec and return first character from it. */
5061 it->dpvec_char_len = it->len; 5078 it->dpvec_char_len = it->len;
5062 it->dpvec = it->ctl_chars; 5079 it->dpvec = it->ctl_chars;
5063 it->dpend = it->dpvec + ctl_len; 5080 it->dpend = it->dpvec + ctl_len;
5064 it->current.dpvec_index = 0; 5081 it->current.dpvec_index = 0;
5082 it->dpvec_face_id = face_id;
5065 it->saved_face_id = it->face_id; 5083 it->saved_face_id = it->face_id;
5066 it->method = next_element_from_display_vector; 5084 it->method = next_element_from_display_vector;
5067 it->ellipsis_p = 0; 5085 it->ellipsis_p = 0;
5068 goto get_next; 5086 goto get_next;
5069 } 5087 }
5275 xassert (it->dpvec && it->current.dpvec_index >= 0); 5293 xassert (it->dpvec && it->current.dpvec_index >= 0);
5276 5294
5277 if (INTEGERP (*it->dpvec) 5295 if (INTEGERP (*it->dpvec)
5278 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec))) 5296 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5279 { 5297 {
5280 int lface_id;
5281 GLYPH g; 5298 GLYPH g;
5282 5299
5283 g = XFASTINT (it->dpvec[it->current.dpvec_index]); 5300 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5284 it->c = FAST_GLYPH_CHAR (g); 5301 it->c = FAST_GLYPH_CHAR (g);
5285 it->len = CHAR_BYTES (it->c); 5302 it->len = CHAR_BYTES (it->c);
5286 5303
5287 /* The entry may contain a face id to use. Such a face id is 5304 /* The entry may contain a face id to use. Such a face id is
5288 the id of a Lisp face, not a realized face. A face id of 5305 the id of a Lisp face, not a realized face. A face id of
5289 zero means no face is specified. */ 5306 zero means no face is specified. */
5290 lface_id = FAST_GLYPH_FACE (g); 5307 if (it->dpvec_face_id >= 0)
5291 if (lface_id) 5308 it->face_id = it->dpvec_face_id;
5292 { 5309 else
5293 /* The function returns -1 if lface_id is invalid. */ 5310 {
5294 int face_id = ascii_face_of_lisp_face (it->f, lface_id); 5311 int lface_id = FAST_GLYPH_FACE (g);
5295 if (face_id >= 0) 5312 if (lface_id)
5296 it->face_id = face_id; 5313 {
5314 /* The function returns -1 if lface_id is invalid. */
5315 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5316 if (face_id >= 0)
5317 it->face_id = face_id;
5318 }
5297 } 5319 }
5298 } 5320 }
5299 else 5321 else
5300 /* Display table entry is invalid. Return a space. */ 5322 /* Display table entry is invalid. Return a space. */
5301 it->c = ' ', it->len = 1; 5323 it->c = ' ', it->len = 1;
11661 /* W must be a leaf window here. */ 11683 /* W must be a leaf window here. */
11662 xassert (!NILP (w->buffer)); 11684 xassert (!NILP (w->buffer));
11663 #if GLYPH_DEBUG 11685 #if GLYPH_DEBUG
11664 *w->desired_matrix->method = 0; 11686 *w->desired_matrix->method = 0;
11665 #endif 11687 #endif
11666
11667 /* Force this to be looked up again for each redisp of each window. */
11668 escape_glyph_face = -1;
11669 11688
11670 specbind (Qinhibit_point_motion_hooks, Qt); 11689 specbind (Qinhibit_point_motion_hooks, Qt);
11671 11690
11672 reconsider_clip_changes (w, buffer); 11691 reconsider_clip_changes (w, buffer);
11673 11692
22337 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace, 22356 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22338 doc: /* *Non-nil means highlight trailing whitespace. 22357 doc: /* *Non-nil means highlight trailing whitespace.
22339 The face used for trailing whitespace is `trailing-whitespace'. */); 22358 The face used for trailing whitespace is `trailing-whitespace'. */);
22340 Vshow_trailing_whitespace = Qnil; 22359 Vshow_trailing_whitespace = Qnil;
22341 22360
22361 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
22362 doc: /* *Non-nil means display escape character before non-break space and hyphen. */);
22363 Vshow_trailing_whitespace = Qt;
22364
22342 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer, 22365 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22343 doc: /* *The pointer shape to show in void text areas. 22366 doc: /* *The pointer shape to show in void text areas.
22344 Nil means to show the text pointer. Other options are `arrow', `text', 22367 Nil means to show the text pointer. Other options are `arrow', `text',
22345 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */); 22368 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22346 Vvoid_text_area_pointer = Qarrow; 22369 Vvoid_text_area_pointer = Qarrow;