diff options
| author | Miles Bader | 2008-07-01 09:39:28 +0000 |
|---|---|---|
| committer | Miles Bader | 2008-07-01 09:39:28 +0000 |
| commit | c4f4682b57dae3d869fe2764e9d6c00143bed1d2 (patch) | |
| tree | e5b59c0bdbb0419c5ebf9f38abc6651f8901c0cc /src | |
| parent | 3726988dc8389b0ad209536a8871f9f69d3817b7 (diff) | |
| download | emacs-c4f4682b57dae3d869fe2764e9d6c00143bed1d2.tar.gz emacs-c4f4682b57dae3d869fe2764e9d6c00143bed1d2.zip | |
Implement display-time wrap/line-prefix feature
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1305
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 17 | ||||
| -rw-r--r-- | src/dispextern.h | 10 | ||||
| -rw-r--r-- | src/xdisp.c | 137 |
3 files changed, 156 insertions, 8 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 78ee4596e9b..3a4f08e00cc 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,20 @@ | |||
| 1 | 2008-06-30 Miles Bader <Miles Bader <miles@gnu.org>> | ||
| 2 | |||
| 3 | * dispextern.h (struct glyph, struct it, struct iterator_stack_entry): | ||
| 4 | Add `avoid_cursor_p' field. | ||
| 5 | |||
| 6 | * xdisp.c (push_it, pop_it): Save/restore avoid_cursor_p field. | ||
| 7 | (set_cursor_from_row): Skip glyphs with avoid_cursor_p set. | ||
| 8 | (append_glyph, append_composite_glyph, produce_image_glyph) | ||
| 9 | (append_stretch_glyph): Initialize avoid_cursor_p | ||
| 10 | (get_it_property): Renamed from `get_line_height_property'. | ||
| 11 | (x_produce_glyphs): Use get_it_property. | ||
| 12 | (handle_line_prefix, push_display_prop): New functions. | ||
| 13 | (display_line, move_it_in_display_line_to): Handle line/wrap prefixes. | ||
| 14 | (Vwrap_prefix, Qwrap_prefix, Vline_prefix, Qline_prefix): New | ||
| 15 | variables. | ||
| 16 | (syms_of_xdisp): Initialize them. | ||
| 17 | |||
| 1 | 2008-06-30 Kenichi Handa <handa@m17n.org> | 18 | 2008-06-30 Kenichi Handa <handa@m17n.org> |
| 2 | 19 | ||
| 3 | * xftfont.c (xftfont_open): Don't call FcConfigSubstitute and | 20 | * xftfont.c (xftfont_open): Don't call FcConfigSubstitute and |
diff --git a/src/dispextern.h b/src/dispextern.h index 1761bede3e2..041d54ffdc3 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -366,7 +366,11 @@ struct glyph | |||
| 366 | doesn't have a glyph in a font. */ | 366 | doesn't have a glyph in a font. */ |
| 367 | unsigned glyph_not_available_p : 1; | 367 | unsigned glyph_not_available_p : 1; |
| 368 | 368 | ||
| 369 | #define FACE_ID_BITS 21 | 369 | |
| 370 | /* Non-zero means don't display cursor here. */ | ||
| 371 | unsigned avoid_cursor_p : 1; | ||
| 372 | |||
| 373 | #define FACE_ID_BITS 20 | ||
| 370 | 374 | ||
| 371 | /* Face of the glyph. This is a realized face ID, | 375 | /* Face of the glyph. This is a realized face ID, |
| 372 | an index in the face cache of the frame. */ | 376 | an index in the face cache of the frame. */ |
| @@ -1887,6 +1891,9 @@ struct it | |||
| 1887 | this is 1 if we're doing an ellipsis. Otherwise meaningless. */ | 1891 | this is 1 if we're doing an ellipsis. Otherwise meaningless. */ |
| 1888 | unsigned ellipsis_p : 1; | 1892 | unsigned ellipsis_p : 1; |
| 1889 | 1893 | ||
| 1894 | /* True means cursor shouldn't be displayed here. */ | ||
| 1895 | unsigned avoid_cursor_p : 1; | ||
| 1896 | |||
| 1890 | /* Display table in effect or null for none. */ | 1897 | /* Display table in effect or null for none. */ |
| 1891 | struct Lisp_Char_Table *dp; | 1898 | struct Lisp_Char_Table *dp; |
| 1892 | 1899 | ||
| @@ -1987,6 +1994,7 @@ struct it | |||
| 1987 | unsigned multibyte_p : 1; | 1994 | unsigned multibyte_p : 1; |
| 1988 | unsigned string_from_display_prop_p : 1; | 1995 | unsigned string_from_display_prop_p : 1; |
| 1989 | unsigned display_ellipsis_p : 1; | 1996 | unsigned display_ellipsis_p : 1; |
| 1997 | unsigned avoid_cursor_p : 1; | ||
| 1990 | 1998 | ||
| 1991 | /* properties from display property that are reset by another display property. */ | 1999 | /* properties from display property that are reset by another display property. */ |
| 1992 | Lisp_Object space_width; | 2000 | Lisp_Object space_width; |
diff --git a/src/xdisp.c b/src/xdisp.c index 1527ba096d9..692db8b4999 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -262,6 +262,9 @@ Lisp_Object Qfontification_functions; | |||
| 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 | ||
| @@ -853,6 +856,10 @@ 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)); |
| 855 | 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 *)); | ||
| 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 |
| @@ -5210,6 +5217,7 @@ push_it (it) | |||
| 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; |
| @@ -5271,6 +5279,7 @@ pop_it (it) | |||
| 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; |
| @@ -6677,6 +6686,12 @@ move_it_in_display_line_to (struct it *it, | |||
| 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 | { |
| @@ -12222,7 +12237,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos) | |||
| 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 | { |
| @@ -16290,6 +16306,78 @@ cursor_row_p (w, row) | |||
| 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 |
| @@ -16348,6 +16436,13 @@ display_line (it) | |||
| 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); |
| 16350 | } | 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); | ||
| 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. */ |
| @@ -20310,6 +20405,7 @@ append_glyph (it) | |||
| 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; |
| @@ -20348,6 +20444,7 @@ append_composite_glyph (it) | |||
| 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; |
| @@ -20529,6 +20626,7 @@ produce_image_glyph (it) | |||
| 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; |
| @@ -20573,6 +20671,7 @@ append_stretch_glyph (it, object, width, height, 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; |
| @@ -20740,12 +20839,10 @@ produce_stretch_glyph (it) | |||
| 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 | { |
| @@ -21048,7 +21145,7 @@ x_produce_glyphs (it) | |||
| 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)) |
| @@ -21110,7 +21207,7 @@ x_produce_glyphs (it) | |||
| 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)) |
| @@ -24924,6 +25021,32 @@ The enable predicate for a menu binding should check this variable. */); | |||
| 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; |