Implement display-time wrap/line-prefix feature
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1305
This commit is contained in:
parent
3726988dc8
commit
c4f4682b57
6 changed files with 207 additions and 8 deletions
|
|
@ -1,3 +1,8 @@
|
|||
2008-07-01 Miles Bader <miles@gnu.org>
|
||||
|
||||
* text.texi (Special Properties):
|
||||
* display.texi (Truncation): Add wrap-prefix and line-prefix.
|
||||
|
||||
2008-06-28 Johan Bockgård <bojohan@gnu.org>
|
||||
|
||||
* display.texi (Other Image Types): Fix copy/paste error; say
|
||||
|
|
|
|||
|
|
@ -191,6 +191,29 @@ If it is non-@code{nil}, these lines are truncated; otherwise,
|
|||
When horizontal scrolling (@pxref{Horizontal Scrolling}) is in use in
|
||||
a window, that forces truncation.
|
||||
|
||||
@defvar wrap-prefix
|
||||
If this buffer-local variable is non-@code{nil}, the prefix it defines
|
||||
will be added at display-time to the beginning of every continuation
|
||||
line due to text wrapping (so if lines are truncated, the wrap-prefix
|
||||
is never used). It may be a string, an image, or a stretch-glyph such
|
||||
as used by the `display' text-property. @xref{Display Property}.
|
||||
|
||||
A wrap-prefix may also be specified for regions of text using the
|
||||
@code{wrap-prefix} text-property (which takes precedence over the
|
||||
value of the @code{wrap-prefix} variable). @xref{Special Properties}.
|
||||
@end defvar
|
||||
|
||||
@defvar line-prefix
|
||||
If this buffer-local variable is non-@code{nil}, the prefix it defines
|
||||
will be added at display-time to the beginning of every
|
||||
non-continuation line It may be a string, an image, or a stretch-glyph
|
||||
such as used by the `display' text-property. @xref{Display Property}.
|
||||
|
||||
A line-prefix may also be specified for regions of text using the
|
||||
@code{line-prefix} text-property (which takes precedence over the
|
||||
value of the @code{line-prefix} variable). @xref{Special Properties}.
|
||||
@end defvar
|
||||
|
||||
If your buffer contains @emph{very} long lines, and you use
|
||||
continuation to display them, just thinking about them can make Emacs
|
||||
redisplay slow. The column computation and indentation functions also
|
||||
|
|
|
|||
|
|
@ -3167,6 +3167,29 @@ A newline can have a @code{line-height} text or overlay property that
|
|||
controls the total height of the display line ending in that newline.
|
||||
@xref{Line Height}.
|
||||
|
||||
@item wrap-prefix
|
||||
If text has a @code{wrap-prefix} property, the prefix it defines will
|
||||
be added at display-time to the beginning of every continuation line
|
||||
due to text wrapping (so if lines are truncated, the wrap-prefix is
|
||||
never used). It may be a string, an image, or a stretch-glyph such as
|
||||
used by the @code{display} text-property. @xref{Display Property}.
|
||||
|
||||
A wrap-prefix may also be specified for an entire buffer using the
|
||||
@code{wrap-prefix} buffer-local variable (however, a
|
||||
@code{wrap-prefix} text-property takes precedence over the value of
|
||||
the @code{wrap-prefix} variable). @xref{Truncation}.
|
||||
|
||||
@item line-prefix
|
||||
If text has a @code{line-prefix} property, the prefix it defines will
|
||||
be added at display-time to the beginning of every non-continuation
|
||||
line. It may be a string, an image, or a stretch-glyph such as used
|
||||
by the @code{display} text-property. @xref{Display Property}.
|
||||
|
||||
A line-prefix may also be specified for an entire buffer using the
|
||||
@code{line-prefix} buffer-local variable (however, a
|
||||
@code{line-prefix} text-property takes precedence over the value of
|
||||
the @code{line-prefix} variable). @xref{Truncation}.
|
||||
|
||||
@item modification-hooks
|
||||
@cindex change hooks for a character
|
||||
@cindex hooks for changing a character
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
2008-06-30 Miles Bader <Miles Bader <miles@gnu.org>>
|
||||
|
||||
* dispextern.h (struct glyph, struct it, struct iterator_stack_entry):
|
||||
Add `avoid_cursor_p' field.
|
||||
|
||||
* xdisp.c (push_it, pop_it): Save/restore avoid_cursor_p field.
|
||||
(set_cursor_from_row): Skip glyphs with avoid_cursor_p set.
|
||||
(append_glyph, append_composite_glyph, produce_image_glyph)
|
||||
(append_stretch_glyph): Initialize avoid_cursor_p
|
||||
(get_it_property): Renamed from `get_line_height_property'.
|
||||
(x_produce_glyphs): Use get_it_property.
|
||||
(handle_line_prefix, push_display_prop): New functions.
|
||||
(display_line, move_it_in_display_line_to): Handle line/wrap prefixes.
|
||||
(Vwrap_prefix, Qwrap_prefix, Vline_prefix, Qline_prefix): New
|
||||
variables.
|
||||
(syms_of_xdisp): Initialize them.
|
||||
|
||||
2008-06-30 Kenichi Handa <handa@m17n.org>
|
||||
|
||||
* xftfont.c (xftfont_open): Don't call FcConfigSubstitute and
|
||||
|
|
|
|||
|
|
@ -366,7 +366,11 @@ struct glyph
|
|||
doesn't have a glyph in a font. */
|
||||
unsigned glyph_not_available_p : 1;
|
||||
|
||||
#define FACE_ID_BITS 21
|
||||
|
||||
/* Non-zero means don't display cursor here. */
|
||||
unsigned avoid_cursor_p : 1;
|
||||
|
||||
#define FACE_ID_BITS 20
|
||||
|
||||
/* Face of the glyph. This is a realized face ID,
|
||||
an index in the face cache of the frame. */
|
||||
|
|
@ -1887,6 +1891,9 @@ struct it
|
|||
this is 1 if we're doing an ellipsis. Otherwise meaningless. */
|
||||
unsigned ellipsis_p : 1;
|
||||
|
||||
/* True means cursor shouldn't be displayed here. */
|
||||
unsigned avoid_cursor_p : 1;
|
||||
|
||||
/* Display table in effect or null for none. */
|
||||
struct Lisp_Char_Table *dp;
|
||||
|
||||
|
|
@ -1987,6 +1994,7 @@ struct it
|
|||
unsigned multibyte_p : 1;
|
||||
unsigned string_from_display_prop_p : 1;
|
||||
unsigned display_ellipsis_p : 1;
|
||||
unsigned avoid_cursor_p : 1;
|
||||
|
||||
/* properties from display property that are reset by another display property. */
|
||||
Lisp_Object space_width;
|
||||
|
|
|
|||
137
src/xdisp.c
137
src/xdisp.c
|
|
@ -262,6 +262,9 @@ Lisp_Object Qfontification_functions;
|
|||
cursor moves into it. */
|
||||
Lisp_Object Vmouse_autoselect_window;
|
||||
|
||||
Lisp_Object Vwrap_prefix, Qwrap_prefix;
|
||||
Lisp_Object Vline_prefix, Qline_prefix;
|
||||
|
||||
/* Non-zero means draw tool bar buttons raised when the mouse moves
|
||||
over them. */
|
||||
|
||||
|
|
@ -853,6 +856,10 @@ static int cursor_row_p P_ ((struct window *, struct glyph_row *));
|
|||
static int redisplay_mode_lines P_ ((Lisp_Object, int));
|
||||
static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
|
||||
|
||||
static Lisp_Object get_it_property P_ ((struct it *it, Lisp_Object prop));
|
||||
|
||||
static void handle_line_prefix P_ ((struct it *));
|
||||
|
||||
#if 0
|
||||
static int invisible_text_between_p P_ ((struct it *, int, int));
|
||||
#endif
|
||||
|
|
@ -5210,6 +5217,7 @@ push_it (it)
|
|||
p->string_nchars = it->string_nchars;
|
||||
p->area = it->area;
|
||||
p->multibyte_p = it->multibyte_p;
|
||||
p->avoid_cursor_p = it->avoid_cursor_p;
|
||||
p->space_width = it->space_width;
|
||||
p->font_height = it->font_height;
|
||||
p->voffset = it->voffset;
|
||||
|
|
@ -5271,6 +5279,7 @@ pop_it (it)
|
|||
it->string_nchars = p->string_nchars;
|
||||
it->area = p->area;
|
||||
it->multibyte_p = p->multibyte_p;
|
||||
it->avoid_cursor_p = p->avoid_cursor_p;
|
||||
it->space_width = p->space_width;
|
||||
it->font_height = p->font_height;
|
||||
it->voffset = p->voffset;
|
||||
|
|
@ -6677,6 +6686,12 @@ move_it_in_display_line_to (struct it *it,
|
|||
|| (it->method == GET_FROM_DISPLAY_VECTOR \
|
||||
&& it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
|
||||
|
||||
/* If there's a line-/wrap-prefix, handle it. */
|
||||
if (it->hpos == 0 && it->method == GET_FROM_BUFFER
|
||||
&& it->current_y < it->last_visible_y)
|
||||
{
|
||||
handle_line_prefix (it);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
|
@ -12222,7 +12237,8 @@ set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
|
|||
while (glyph < end
|
||||
&& !INTEGERP (glyph->object)
|
||||
&& (!BUFFERP (glyph->object)
|
||||
|| (last_pos = glyph->charpos) < pt_old))
|
||||
|| (last_pos = glyph->charpos) < pt_old
|
||||
|| glyph->avoid_cursor_p))
|
||||
{
|
||||
if (! STRINGP (glyph->object))
|
||||
{
|
||||
|
|
@ -16290,6 +16306,78 @@ cursor_row_p (w, row)
|
|||
return cursor_row_p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Push the display property PROP so that it will be rendered at the
|
||||
current position in IT. */
|
||||
|
||||
static void
|
||||
push_display_prop (struct it *it, Lisp_Object prop)
|
||||
{
|
||||
push_it (it);
|
||||
|
||||
/* Never display a cursor on the prefix. */
|
||||
it->avoid_cursor_p = 1;
|
||||
|
||||
if (STRINGP (prop))
|
||||
{
|
||||
if (SCHARS (prop) == 0)
|
||||
{
|
||||
pop_it (it);
|
||||
return;
|
||||
}
|
||||
|
||||
it->string = prop;
|
||||
it->multibyte_p = STRING_MULTIBYTE (it->string);
|
||||
it->current.overlay_string_index = -1;
|
||||
IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
|
||||
it->end_charpos = it->string_nchars = SCHARS (it->string);
|
||||
it->method = GET_FROM_STRING;
|
||||
it->stop_charpos = 0;
|
||||
}
|
||||
else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
|
||||
{
|
||||
it->method = GET_FROM_STRETCH;
|
||||
it->object = prop;
|
||||
}
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
else if (IMAGEP (prop))
|
||||
{
|
||||
it->what = IT_IMAGE;
|
||||
it->image_id = lookup_image (it->f, prop);
|
||||
it->method = GET_FROM_IMAGE;
|
||||
}
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
else
|
||||
{
|
||||
pop_it (it); /* bogus display property, give up */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* See if there's a line- or wrap-prefix, and if so, push it on IT. */
|
||||
|
||||
static void
|
||||
handle_line_prefix (struct it *it)
|
||||
{
|
||||
Lisp_Object prefix;
|
||||
if (it->continuation_lines_width > 0)
|
||||
{
|
||||
prefix = get_it_property (it, Qwrap_prefix);
|
||||
if (NILP (prefix))
|
||||
prefix = Vwrap_prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = get_it_property (it, Qline_prefix);
|
||||
if (NILP (prefix))
|
||||
prefix = Vline_prefix;
|
||||
}
|
||||
if (! NILP (prefix))
|
||||
push_display_prop (it, prefix);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Construct the glyph row IT->glyph_row in the desired matrix of
|
||||
IT->w from text at the current position of IT. See dispextern.h
|
||||
|
|
@ -16348,6 +16436,13 @@ display_line (it)
|
|||
move_it_in_display_line_to (it, ZV, it->first_visible_x,
|
||||
MOVE_TO_POS | MOVE_TO_X);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We only do this when not calling `move_it_in_display_line_to'
|
||||
above, because move_it_in_display_line_to calls
|
||||
handle_line_prefix itself. */
|
||||
handle_line_prefix (it);
|
||||
}
|
||||
|
||||
/* Get the initial row height. This is either the height of the
|
||||
text hscrolled, if there is any, or zero. */
|
||||
|
|
@ -20310,6 +20405,7 @@ append_glyph (it)
|
|||
glyph->descent = it->descent;
|
||||
glyph->voffset = it->voffset;
|
||||
glyph->type = CHAR_GLYPH;
|
||||
glyph->avoid_cursor_p = it->avoid_cursor_p;
|
||||
glyph->multibyte_p = it->multibyte_p;
|
||||
glyph->left_box_line_p = it->start_of_box_run_p;
|
||||
glyph->right_box_line_p = it->end_of_box_run_p;
|
||||
|
|
@ -20348,6 +20444,7 @@ append_composite_glyph (it)
|
|||
glyph->descent = it->descent;
|
||||
glyph->voffset = it->voffset;
|
||||
glyph->type = COMPOSITE_GLYPH;
|
||||
glyph->avoid_cursor_p = it->avoid_cursor_p;
|
||||
glyph->multibyte_p = it->multibyte_p;
|
||||
glyph->left_box_line_p = it->start_of_box_run_p;
|
||||
glyph->right_box_line_p = it->end_of_box_run_p;
|
||||
|
|
@ -20529,6 +20626,7 @@ produce_image_glyph (it)
|
|||
glyph->descent = it->descent;
|
||||
glyph->voffset = it->voffset;
|
||||
glyph->type = IMAGE_GLYPH;
|
||||
glyph->avoid_cursor_p = it->avoid_cursor_p;
|
||||
glyph->multibyte_p = it->multibyte_p;
|
||||
glyph->left_box_line_p = it->start_of_box_run_p;
|
||||
glyph->right_box_line_p = it->end_of_box_run_p;
|
||||
|
|
@ -20573,6 +20671,7 @@ append_stretch_glyph (it, object, width, height, ascent)
|
|||
glyph->descent = height - ascent;
|
||||
glyph->voffset = it->voffset;
|
||||
glyph->type = STRETCH_GLYPH;
|
||||
glyph->avoid_cursor_p = it->avoid_cursor_p;
|
||||
glyph->multibyte_p = it->multibyte_p;
|
||||
glyph->left_box_line_p = it->start_of_box_run_p;
|
||||
glyph->right_box_line_p = it->end_of_box_run_p;
|
||||
|
|
@ -20740,12 +20839,10 @@ produce_stretch_glyph (it)
|
|||
take_vertical_position_into_account (it);
|
||||
}
|
||||
|
||||
/* Get line-height and line-spacing property at point.
|
||||
If line-height has format (HEIGHT TOTAL), return TOTAL
|
||||
in TOTAL_HEIGHT. */
|
||||
/* Return the character-property PROP at the current position in IT. */
|
||||
|
||||
static Lisp_Object
|
||||
get_line_height_property (it, prop)
|
||||
get_it_property (it, prop)
|
||||
struct it *it;
|
||||
Lisp_Object prop;
|
||||
{
|
||||
|
|
@ -21048,7 +21145,7 @@ x_produce_glyphs (it)
|
|||
it->pixel_width = 0;
|
||||
it->nglyphs = 0;
|
||||
|
||||
height = get_line_height_property(it, Qline_height);
|
||||
height = get_it_property(it, Qline_height);
|
||||
/* Split (line-height total-height) list */
|
||||
if (CONSP (height)
|
||||
&& CONSP (XCDR (height))
|
||||
|
|
@ -21110,7 +21207,7 @@ x_produce_glyphs (it)
|
|||
spacing = calc_line_height_property(it, total_height, font, boff, 0);
|
||||
else
|
||||
{
|
||||
spacing = get_line_height_property(it, Qline_spacing);
|
||||
spacing = get_it_property(it, Qline_spacing);
|
||||
spacing = calc_line_height_property(it, spacing, font, boff, 0);
|
||||
}
|
||||
if (INTEGERP (spacing))
|
||||
|
|
@ -24924,6 +25021,32 @@ The enable predicate for a menu binding should check this variable. */);
|
|||
doc: /* Non-nil means don't update menu bars. Internal use only. */);
|
||||
inhibit_menubar_update = 0;
|
||||
|
||||
DEFVAR_LISP ("wrap-prefix", &Vwrap_prefix,
|
||||
doc: /* Prefix added to the beginning of all continuation lines at display-time.
|
||||
May be a string, an image, or a stretch-glyph such as used by the
|
||||
`display' text-property.
|
||||
|
||||
This variable is overridden by any `wrap-prefix' text-property.
|
||||
|
||||
To add a prefix to non-continuation lines, use the `line-prefix' variable. */);
|
||||
Vwrap_prefix = Qnil;
|
||||
staticpro (&Qwrap_prefix);
|
||||
Qwrap_prefix = intern ("wrap-prefix");
|
||||
Fmake_variable_buffer_local (Qwrap_prefix);
|
||||
|
||||
DEFVAR_LISP ("line-prefix", &Vline_prefix,
|
||||
doc: /* Prefix added to the beginning of all non-continuation lines at display-time.
|
||||
May be a string, an image, or a stretch-glyph such as used by the
|
||||
`display' text-property.
|
||||
|
||||
This variable is overridden by any `line-prefix' text-property.
|
||||
|
||||
To add a prefix to continuation lines, use the `wrap-prefix' variable. */);
|
||||
Vline_prefix = Qnil;
|
||||
staticpro (&Qline_prefix);
|
||||
Qline_prefix = intern ("line-prefix");
|
||||
Fmake_variable_buffer_local (Qline_prefix);
|
||||
|
||||
DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
|
||||
doc: /* Non-nil means don't eval Lisp during redisplay. */);
|
||||
inhibit_eval_during_redisplay = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue