Mercurial > emacs
comparison src/xdisp.c @ 96470:2af6e85f13d5
Implement display-time wrap/line-prefix feature
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1305
author | Miles Bader <miles@gnu.org> |
---|---|
date | Tue, 01 Jul 2008 09:39:28 +0000 |
parents | 307d2d89ee24 |
children | eee935c288d1 |
comparison
equal
deleted
inserted
replaced
96469:40d413a9e07b | 96470:2af6e85f13d5 |
---|---|
260 | 260 |
261 /* Non-nil means automatically select any window when the mouse | 261 /* Non-nil means automatically select any window when the mouse |
262 cursor moves into it. */ | 262 cursor moves into it. */ |
263 Lisp_Object Vmouse_autoselect_window; | 263 Lisp_Object Vmouse_autoselect_window; |
264 | 264 |
265 Lisp_Object Vwrap_prefix, Qwrap_prefix; | |
266 Lisp_Object Vline_prefix, Qline_prefix; | |
267 | |
265 /* Non-zero means draw tool bar buttons raised when the mouse moves | 268 /* Non-zero means draw tool bar buttons raised when the mouse moves |
266 over them. */ | 269 over them. */ |
267 | 270 |
268 int auto_raise_tool_bar_buttons_p; | 271 int auto_raise_tool_bar_buttons_p; |
269 | 272 |
850 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object)); | 853 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object)); |
851 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); | 854 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object)); |
852 static int cursor_row_p P_ ((struct window *, struct glyph_row *)); | 855 static int cursor_row_p P_ ((struct window *, struct glyph_row *)); |
853 static int redisplay_mode_lines P_ ((Lisp_Object, int)); | 856 static int redisplay_mode_lines P_ ((Lisp_Object, int)); |
854 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int)); | 857 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int)); |
858 | |
859 static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop)); | |
860 | |
861 static void handle_line_prefix P_ ((struct it *)); | |
855 | 862 |
856 #if 0 | 863 #if 0 |
857 static int invisible_text_between_p P_ ((struct it *, int, int)); | 864 static int invisible_text_between_p P_ ((struct it *, int, int)); |
858 #endif | 865 #endif |
859 | 866 |
5208 p->current = it->current; | 5215 p->current = it->current; |
5209 p->end_charpos = it->end_charpos; | 5216 p->end_charpos = it->end_charpos; |
5210 p->string_nchars = it->string_nchars; | 5217 p->string_nchars = it->string_nchars; |
5211 p->area = it->area; | 5218 p->area = it->area; |
5212 p->multibyte_p = it->multibyte_p; | 5219 p->multibyte_p = it->multibyte_p; |
5220 p->avoid_cursor_p = it->avoid_cursor_p; | |
5213 p->space_width = it->space_width; | 5221 p->space_width = it->space_width; |
5214 p->font_height = it->font_height; | 5222 p->font_height = it->font_height; |
5215 p->voffset = it->voffset; | 5223 p->voffset = it->voffset; |
5216 p->string_from_display_prop_p = it->string_from_display_prop_p; | 5224 p->string_from_display_prop_p = it->string_from_display_prop_p; |
5217 p->display_ellipsis_p = 0; | 5225 p->display_ellipsis_p = 0; |
5269 } | 5277 } |
5270 it->end_charpos = p->end_charpos; | 5278 it->end_charpos = p->end_charpos; |
5271 it->string_nchars = p->string_nchars; | 5279 it->string_nchars = p->string_nchars; |
5272 it->area = p->area; | 5280 it->area = p->area; |
5273 it->multibyte_p = p->multibyte_p; | 5281 it->multibyte_p = p->multibyte_p; |
5282 it->avoid_cursor_p = p->avoid_cursor_p; | |
5274 it->space_width = p->space_width; | 5283 it->space_width = p->space_width; |
5275 it->font_height = p->font_height; | 5284 it->font_height = p->font_height; |
5276 it->voffset = p->voffset; | 5285 it->voffset = p->voffset; |
5277 it->string_from_display_prop_p = p->string_from_display_prop_p; | 5286 it->string_from_display_prop_p = p->string_from_display_prop_p; |
5278 } | 5287 } |
6675 && IT_CHARPOS (*it) >= to_charpos \ | 6684 && IT_CHARPOS (*it) >= to_charpos \ |
6676 && (it->method == GET_FROM_BUFFER \ | 6685 && (it->method == GET_FROM_BUFFER \ |
6677 || (it->method == GET_FROM_DISPLAY_VECTOR \ | 6686 || (it->method == GET_FROM_DISPLAY_VECTOR \ |
6678 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) | 6687 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) |
6679 | 6688 |
6689 /* If there's a line-/wrap-prefix, handle it. */ | |
6690 if (it->hpos == 0 && it->method == GET_FROM_BUFFER | |
6691 && it->current_y < it->last_visible_y) | |
6692 { | |
6693 handle_line_prefix (it); | |
6694 } | |
6680 | 6695 |
6681 while (1) | 6696 while (1) |
6682 { | 6697 { |
6683 int x, i, ascent = 0, descent = 0; | 6698 int x, i, ascent = 0, descent = 0; |
6684 | 6699 |
12220 | 12235 |
12221 string_start = NULL; | 12236 string_start = NULL; |
12222 while (glyph < end | 12237 while (glyph < end |
12223 && !INTEGERP (glyph->object) | 12238 && !INTEGERP (glyph->object) |
12224 && (!BUFFERP (glyph->object) | 12239 && (!BUFFERP (glyph->object) |
12225 || (last_pos = glyph->charpos) < pt_old)) | 12240 || (last_pos = glyph->charpos) < pt_old |
12241 || glyph->avoid_cursor_p)) | |
12226 { | 12242 { |
12227 if (! STRINGP (glyph->object)) | 12243 if (! STRINGP (glyph->object)) |
12228 { | 12244 { |
12229 string_start = NULL; | 12245 string_start = NULL; |
12230 x += glyph->pixel_width; | 12246 x += glyph->pixel_width; |
16288 } | 16304 } |
16289 | 16305 |
16290 return cursor_row_p; | 16306 return cursor_row_p; |
16291 } | 16307 } |
16292 | 16308 |
16309 | |
16310 | |
16311 /* Push the display property PROP so that it will be rendered at the | |
16312 current position in IT. */ | |
16313 | |
16314 static void | |
16315 push_display_prop (struct it *it, Lisp_Object prop) | |
16316 { | |
16317 push_it (it); | |
16318 | |
16319 /* Never display a cursor on the prefix. */ | |
16320 it->avoid_cursor_p = 1; | |
16321 | |
16322 if (STRINGP (prop)) | |
16323 { | |
16324 if (SCHARS (prop) == 0) | |
16325 { | |
16326 pop_it (it); | |
16327 return; | |
16328 } | |
16329 | |
16330 it->string = prop; | |
16331 it->multibyte_p = STRING_MULTIBYTE (it->string); | |
16332 it->current.overlay_string_index = -1; | |
16333 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0; | |
16334 it->end_charpos = it->string_nchars = SCHARS (it->string); | |
16335 it->method = GET_FROM_STRING; | |
16336 it->stop_charpos = 0; | |
16337 } | |
16338 else if (CONSP (prop) && EQ (XCAR (prop), Qspace)) | |
16339 { | |
16340 it->method = GET_FROM_STRETCH; | |
16341 it->object = prop; | |
16342 } | |
16343 #ifdef HAVE_WINDOW_SYSTEM | |
16344 else if (IMAGEP (prop)) | |
16345 { | |
16346 it->what = IT_IMAGE; | |
16347 it->image_id = lookup_image (it->f, prop); | |
16348 it->method = GET_FROM_IMAGE; | |
16349 } | |
16350 #endif /* HAVE_WINDOW_SYSTEM */ | |
16351 else | |
16352 { | |
16353 pop_it (it); /* bogus display property, give up */ | |
16354 return; | |
16355 } | |
16356 } | |
16357 | |
16358 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */ | |
16359 | |
16360 static void | |
16361 handle_line_prefix (struct it *it) | |
16362 { | |
16363 Lisp_Object prefix; | |
16364 if (it->continuation_lines_width > 0) | |
16365 { | |
16366 prefix = get_it_property (it, Qwrap_prefix); | |
16367 if (NILP (prefix)) | |
16368 prefix = Vwrap_prefix; | |
16369 } | |
16370 else | |
16371 { | |
16372 prefix = get_it_property (it, Qline_prefix); | |
16373 if (NILP (prefix)) | |
16374 prefix = Vline_prefix; | |
16375 } | |
16376 if (! NILP (prefix)) | |
16377 push_display_prop (it, prefix); | |
16378 } | |
16379 | |
16380 | |
16293 | 16381 |
16294 /* Construct the glyph row IT->glyph_row in the desired matrix of | 16382 /* Construct the glyph row IT->glyph_row in the desired matrix of |
16295 IT->w from text at the current position of IT. See dispextern.h | 16383 IT->w from text at the current position of IT. See dispextern.h |
16296 for an overview of struct it. Value is non-zero if | 16384 for an overview of struct it. Value is non-zero if |
16297 IT->glyph_row displays text, as opposed to a line displaying ZV | 16385 IT->glyph_row displays text, as opposed to a line displaying ZV |
16345 if the first glyph is partially visible or if we hit a line end. */ | 16433 if the first glyph is partially visible or if we hit a line end. */ |
16346 if (it->current_x < it->first_visible_x) | 16434 if (it->current_x < it->first_visible_x) |
16347 { | 16435 { |
16348 move_it_in_display_line_to (it, ZV, it->first_visible_x, | 16436 move_it_in_display_line_to (it, ZV, it->first_visible_x, |
16349 MOVE_TO_POS | MOVE_TO_X); | 16437 MOVE_TO_POS | MOVE_TO_X); |
16438 } | |
16439 else | |
16440 { | |
16441 /* We only do this when not calling `move_it_in_display_line_to' | |
16442 above, because move_it_in_display_line_to calls | |
16443 handle_line_prefix itself. */ | |
16444 handle_line_prefix (it); | |
16350 } | 16445 } |
16351 | 16446 |
16352 /* Get the initial row height. This is either the height of the | 16447 /* Get the initial row height. This is either the height of the |
16353 text hscrolled, if there is any, or zero. */ | 16448 text hscrolled, if there is any, or zero. */ |
16354 row->ascent = it->max_ascent; | 16449 row->ascent = it->max_ascent; |
20308 } | 20403 } |
20309 glyph->ascent = it->ascent; | 20404 glyph->ascent = it->ascent; |
20310 glyph->descent = it->descent; | 20405 glyph->descent = it->descent; |
20311 glyph->voffset = it->voffset; | 20406 glyph->voffset = it->voffset; |
20312 glyph->type = CHAR_GLYPH; | 20407 glyph->type = CHAR_GLYPH; |
20408 glyph->avoid_cursor_p = it->avoid_cursor_p; | |
20313 glyph->multibyte_p = it->multibyte_p; | 20409 glyph->multibyte_p = it->multibyte_p; |
20314 glyph->left_box_line_p = it->start_of_box_run_p; | 20410 glyph->left_box_line_p = it->start_of_box_run_p; |
20315 glyph->right_box_line_p = it->end_of_box_run_p; | 20411 glyph->right_box_line_p = it->end_of_box_run_p; |
20316 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 20412 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
20317 || it->phys_descent > it->descent); | 20413 || it->phys_descent > it->descent); |
20346 glyph->pixel_width = it->pixel_width; | 20442 glyph->pixel_width = it->pixel_width; |
20347 glyph->ascent = it->ascent; | 20443 glyph->ascent = it->ascent; |
20348 glyph->descent = it->descent; | 20444 glyph->descent = it->descent; |
20349 glyph->voffset = it->voffset; | 20445 glyph->voffset = it->voffset; |
20350 glyph->type = COMPOSITE_GLYPH; | 20446 glyph->type = COMPOSITE_GLYPH; |
20447 glyph->avoid_cursor_p = it->avoid_cursor_p; | |
20351 glyph->multibyte_p = it->multibyte_p; | 20448 glyph->multibyte_p = it->multibyte_p; |
20352 glyph->left_box_line_p = it->start_of_box_run_p; | 20449 glyph->left_box_line_p = it->start_of_box_run_p; |
20353 glyph->right_box_line_p = it->end_of_box_run_p; | 20450 glyph->right_box_line_p = it->end_of_box_run_p; |
20354 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | 20451 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent |
20355 || it->phys_descent > it->descent); | 20452 || it->phys_descent > it->descent); |
20527 glyph->pixel_width = it->pixel_width; | 20624 glyph->pixel_width = it->pixel_width; |
20528 glyph->ascent = glyph_ascent; | 20625 glyph->ascent = glyph_ascent; |
20529 glyph->descent = it->descent; | 20626 glyph->descent = it->descent; |
20530 glyph->voffset = it->voffset; | 20627 glyph->voffset = it->voffset; |
20531 glyph->type = IMAGE_GLYPH; | 20628 glyph->type = IMAGE_GLYPH; |
20629 glyph->avoid_cursor_p = it->avoid_cursor_p; | |
20532 glyph->multibyte_p = it->multibyte_p; | 20630 glyph->multibyte_p = it->multibyte_p; |
20533 glyph->left_box_line_p = it->start_of_box_run_p; | 20631 glyph->left_box_line_p = it->start_of_box_run_p; |
20534 glyph->right_box_line_p = it->end_of_box_run_p; | 20632 glyph->right_box_line_p = it->end_of_box_run_p; |
20535 glyph->overlaps_vertically_p = 0; | 20633 glyph->overlaps_vertically_p = 0; |
20536 glyph->padding_p = 0; | 20634 glyph->padding_p = 0; |
20571 glyph->pixel_width = width; | 20669 glyph->pixel_width = width; |
20572 glyph->ascent = ascent; | 20670 glyph->ascent = ascent; |
20573 glyph->descent = height - ascent; | 20671 glyph->descent = height - ascent; |
20574 glyph->voffset = it->voffset; | 20672 glyph->voffset = it->voffset; |
20575 glyph->type = STRETCH_GLYPH; | 20673 glyph->type = STRETCH_GLYPH; |
20674 glyph->avoid_cursor_p = it->avoid_cursor_p; | |
20576 glyph->multibyte_p = it->multibyte_p; | 20675 glyph->multibyte_p = it->multibyte_p; |
20577 glyph->left_box_line_p = it->start_of_box_run_p; | 20676 glyph->left_box_line_p = it->start_of_box_run_p; |
20578 glyph->right_box_line_p = it->end_of_box_run_p; | 20677 glyph->right_box_line_p = it->end_of_box_run_p; |
20579 glyph->overlaps_vertically_p = 0; | 20678 glyph->overlaps_vertically_p = 0; |
20580 glyph->padding_p = 0; | 20679 glyph->padding_p = 0; |
20738 it->nglyphs = width > 0 && height > 0 ? 1 : 0; | 20837 it->nglyphs = width > 0 && height > 0 ? 1 : 0; |
20739 | 20838 |
20740 take_vertical_position_into_account (it); | 20839 take_vertical_position_into_account (it); |
20741 } | 20840 } |
20742 | 20841 |
20743 /* Get line-height and line-spacing property at point. | 20842 /* Return the character-property PROP at the current position in IT. */ |
20744 If line-height has format (HEIGHT TOTAL), return TOTAL | |
20745 in TOTAL_HEIGHT. */ | |
20746 | 20843 |
20747 static Lisp_Object | 20844 static Lisp_Object |
20748 get_line_height_property (it, prop) | 20845 get_it_property (it, prop) |
20749 struct it *it; | 20846 struct it *it; |
20750 Lisp_Object prop; | 20847 Lisp_Object prop; |
20751 { | 20848 { |
20752 Lisp_Object position; | 20849 Lisp_Object position; |
20753 | 20850 |
21046 | 21143 |
21047 it->override_ascent = -1; | 21144 it->override_ascent = -1; |
21048 it->pixel_width = 0; | 21145 it->pixel_width = 0; |
21049 it->nglyphs = 0; | 21146 it->nglyphs = 0; |
21050 | 21147 |
21051 height = get_line_height_property(it, Qline_height); | 21148 height = get_it_property(it, Qline_height); |
21052 /* Split (line-height total-height) list */ | 21149 /* Split (line-height total-height) list */ |
21053 if (CONSP (height) | 21150 if (CONSP (height) |
21054 && CONSP (XCDR (height)) | 21151 && CONSP (XCDR (height)) |
21055 && NILP (XCDR (XCDR (height)))) | 21152 && NILP (XCDR (XCDR (height)))) |
21056 { | 21153 { |
21108 | 21205 |
21109 if (!NILP (total_height)) | 21206 if (!NILP (total_height)) |
21110 spacing = calc_line_height_property(it, total_height, font, boff, 0); | 21207 spacing = calc_line_height_property(it, total_height, font, boff, 0); |
21111 else | 21208 else |
21112 { | 21209 { |
21113 spacing = get_line_height_property(it, Qline_spacing); | 21210 spacing = get_it_property(it, Qline_spacing); |
21114 spacing = calc_line_height_property(it, spacing, font, boff, 0); | 21211 spacing = calc_line_height_property(it, spacing, font, boff, 0); |
21115 } | 21212 } |
21116 if (INTEGERP (spacing)) | 21213 if (INTEGERP (spacing)) |
21117 { | 21214 { |
21118 extra_line_spacing = XINT (spacing); | 21215 extra_line_spacing = XINT (spacing); |
24922 | 25019 |
24923 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update, | 25020 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update, |
24924 doc: /* Non-nil means don't update menu bars. Internal use only. */); | 25021 doc: /* Non-nil means don't update menu bars. Internal use only. */); |
24925 inhibit_menubar_update = 0; | 25022 inhibit_menubar_update = 0; |
24926 | 25023 |
25024 DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix, | |
25025 doc: /* Prefix added to the beginning of all continuation lines at display-time. | |
25026 May be a string, an image, or a stretch-glyph such as used by the | |
25027 `display' text-property. | |
25028 | |
25029 This variable is overridden by any `wrap-prefix' text-property. | |
25030 | |
25031 To add a prefix to non-continuation lines, use the `line-prefix' variable. */); | |
25032 Vwrap_prefix = Qnil; | |
25033 staticpro (&Qwrap_prefix); | |
25034 Qwrap_prefix = intern ("wrap-prefix"); | |
25035 Fmake_variable_buffer_local (Qwrap_prefix); | |
25036 | |
25037 DEFVAR_LISP ("line-prefix", &Vline_prefix, | |
25038 doc: /* Prefix added to the beginning of all non-continuation lines at display-time. | |
25039 May be a string, an image, or a stretch-glyph such as used by the | |
25040 `display' text-property. | |
25041 | |
25042 This variable is overridden by any `line-prefix' text-property. | |
25043 | |
25044 To add a prefix to continuation lines, use the `wrap-prefix' variable. */); | |
25045 Vline_prefix = Qnil; | |
25046 staticpro (&Qline_prefix); | |
25047 Qline_prefix = intern ("line-prefix"); | |
25048 Fmake_variable_buffer_local (Qline_prefix); | |
25049 | |
24927 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay, | 25050 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay, |
24928 doc: /* Non-nil means don't eval Lisp during redisplay. */); | 25051 doc: /* Non-nil means don't eval Lisp during redisplay. */); |
24929 inhibit_eval_during_redisplay = 0; | 25052 inhibit_eval_during_redisplay = 0; |
24930 | 25053 |
24931 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces, | 25054 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces, |