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,