Mercurial > emacs
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; |