extern int interrupt_input;
extern int command_loop_level;
+extern Lisp_Object do_mouse_tracking;
+
extern int minibuffer_auto_raise;
extern Lisp_Object Vminibuffer_list;
int auto_raise_tool_bar_buttons_p;
+/* Non-zero means to reposition window if cursor line is only partially visible. */
+
+int make_cursor_line_fully_visible_p;
+
/* Margin around tool bar buttons in pixels. */
Lisp_Object Vtool_bar_button_margin;
extern Lisp_Object Qheight;
extern Lisp_Object QCwidth, QCheight, QCascent;
extern Lisp_Object Qscroll_bar;
+extern Lisp_Object Qcursor;
/* Non-nil means highlight trailing whitespace. */
Lisp_Object Qtrailing_whitespace;
+/* Name and number of the face used to highlight escape glyphs. */
+
+Lisp_Object Qescape_glyph;
+int escape_glyph_face;
+
/* The symbol `image' which is the car of the lists used to represent
images in Lisp. */
\f
/* Function prototypes. */
-static void setup_for_ellipsis P_ ((struct it *));
+static void setup_for_ellipsis P_ ((struct it *, int));
static void mark_window_display_accurate_1 P_ ((struct window *, int));
-static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
+static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
static int cursor_row_p P_ ((struct window *, struct glyph_row *));
static int redisplay_mode_lines P_ ((Lisp_Object, int));
static void x_consider_frame_title P_ ((Lisp_Object));
static void handle_stop P_ ((struct it *));
static int tool_bar_lines_needed P_ ((struct frame *));
-static int single_display_prop_intangible_p P_ ((Lisp_Object));
+static int single_display_spec_intangible_p P_ ((Lisp_Object));
static void ensure_echo_area_buffers P_ ((void));
static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
static void reseat P_ ((struct it *, struct text_pos, int));
static void reseat_1 P_ ((struct it *, struct text_pos, int));
static void back_to_previous_visible_line_start P_ ((struct it *));
-static void reseat_at_previous_visible_line_start P_ ((struct it *));
+void reseat_at_previous_visible_line_start P_ ((struct it *));
static void reseat_at_next_visible_line_start P_ ((struct it *, int));
static int next_element_from_display_vector P_ ((struct it *));
static int next_element_from_string P_ ((struct it *));
Lisp_Object));
static int face_before_or_after_it_pos P_ ((struct it *, int));
static int next_overlay_change P_ ((int));
-static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
+static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
Lisp_Object, struct text_pos *,
int));
static int underlying_face_id P_ ((struct it *));
/* If drawing a tool-bar window, draw it over the internal border
at the top of the window. */
- if (s->w == XWINDOW (s->f->tool_bar_window))
+ if (WINDOWP (s->f->tool_bar_window)
+ && s->w == XWINDOW (s->f->tool_bar_window))
r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
}
* FRAME_LINE_HEIGHT (it->f));
else if (it->f->extra_line_spacing > 0)
it->extra_line_spacing = it->f->extra_line_spacing;
+ it->max_extra_line_spacing = 0;
}
/* If realized faces have been removed, e.g. because of face
it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
}
else if (display_ellipsis_p)
- setup_for_ellipsis (it);
+ setup_for_ellipsis (it, 0);
}
}
}
-/* Make iterator IT return `...' next. */
+/* Make iterator IT return `...' next.
+ Replaces LEN characters from buffer. */
static void
-setup_for_ellipsis (it)
+setup_for_ellipsis (it, len)
struct it *it;
+ int len;
{
- if (it->dp
- && VECTORP (DISP_INVIS_VECTOR (it->dp)))
+ /* Use the display table definition for `...'. Invalid glyphs
+ will be handled by the method returning elements from dpvec. */
+ if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
{
struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
it->dpvec = v->contents;
it->dpend = default_invis_vector + 3;
}
- /* The ellipsis display does not replace the display of the
- character at the new position. Indicate this by setting
- IT->dpvec_char_len to zero. */
- it->dpvec_char_len = 0;
-
+ it->dpvec_char_len = len;
it->current.dpvec_index = 0;
+
+ /* Remember the current face id in case glyphs specify faces.
+ IT's face is restored in set_iterator_to_next. */
+ it->saved_face_id = it->face_id;
it->method = next_element_from_display_vector;
}
***********************************************************************/
/* Set up iterator IT from `display' property at its current position.
- Called from handle_stop. */
+ Called from handle_stop.
+ We return HANDLED_RETURN if some part of the display property
+ overrides the display of the buffer text itself.
+ Otherwise we return HANDLED_NORMALLY. */
static enum prop_handled
handle_display_prop (it)
{
Lisp_Object prop, object;
struct text_pos *position;
+ /* Nonzero if some property replaces the display of the text itself. */
int display_replaced_p = 0;
if (STRINGP (it->string))
{
for (; CONSP (prop); prop = XCDR (prop))
{
- if (handle_single_display_prop (it, XCAR (prop), object,
+ if (handle_single_display_spec (it, XCAR (prop), object,
position, display_replaced_p))
display_replaced_p = 1;
}
{
int i;
for (i = 0; i < ASIZE (prop); ++i)
- if (handle_single_display_prop (it, AREF (prop, i), object,
+ if (handle_single_display_spec (it, AREF (prop, i), object,
position, display_replaced_p))
display_replaced_p = 1;
}
else
{
- if (handle_single_display_prop (it, prop, object, position, 0))
+ if (handle_single_display_spec (it, prop, object, position, 0))
display_replaced_p = 1;
}
}
-/* Set up IT from a single `display' sub-property value PROP. OBJECT
+/* Set up IT from a single `display' specification PROP. OBJECT
is the object in which the `display' property was found. *POSITION
is the position at which it was found. DISPLAY_REPLACED_P non-zero
- means that we previously saw a display sub-property which already
+ means that we previously saw a display specification which already
replaced text display with something else, for example an image;
- ignore such properties after the first one has been processed.
+ we ignore such properties after the first one has been processed.
- If PROP is a `space' or `image' sub-property, set *POSITION to the
- end position of the `display' property.
+ If PROP is a `space' or `image' specification, and in some other
+ cases too, set *POSITION to the position where the `display'
+ property ends.
Value is non-zero if something was found which replaces the display
of buffer or string text. */
static int
-handle_single_display_prop (it, prop, object, position,
+handle_single_display_spec (it, spec, object, position,
display_replaced_before_p)
struct it *it;
- Lisp_Object prop;
+ Lisp_Object spec;
Lisp_Object object;
struct text_pos *position;
int display_replaced_before_p;
{
- Lisp_Object value;
- int replaces_text_display_p = 0;
Lisp_Object form;
+ Lisp_Object location, value;
+ struct text_pos start_pos;
+ int valid_p;
- /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
- evaluated. If the result is nil, VALUE is ignored. */
+ /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
+ If the result is non-nil, use VALUE instead of SPEC. */
form = Qt;
- if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
+ if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
{
- prop = XCDR (prop);
- if (!CONSP (prop))
+ spec = XCDR (spec);
+ if (!CONSP (spec))
return 0;
- form = XCAR (prop);
- prop = XCDR (prop);
+ form = XCAR (spec);
+ spec = XCDR (spec);
}
if (!NILP (form) && !EQ (form, Qt))
if (NILP (form))
return 0;
- if (CONSP (prop)
- && EQ (XCAR (prop), Qheight)
- && CONSP (XCDR (prop)))
+ /* Handle `(height HEIGHT)' specifications. */
+ if (CONSP (spec)
+ && EQ (XCAR (spec), Qheight)
+ && CONSP (XCDR (spec)))
{
if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
return 0;
-
- /* `(height HEIGHT)'. */
- it->font_height = XCAR (XCDR (prop));
+
+ it->font_height = XCAR (XCDR (spec));
if (!NILP (it->font_height))
{
struct face *face = FACE_FROM_ID (it->f, it->face_id);
{
/* Evaluate IT->font_height with `height' bound to the
current specified height to get the new height. */
- Lisp_Object value;
int count = SPECPDL_INDEX ();
specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
if (new_height > 0)
it->face_id = face_with_height (it->f, it->face_id, new_height);
}
+
+ return 0;
}
- else if (CONSP (prop)
- && EQ (XCAR (prop), Qspace_width)
- && CONSP (XCDR (prop)))
+
+ /* Handle `(space_width WIDTH)'. */
+ if (CONSP (spec)
+ && EQ (XCAR (spec), Qspace_width)
+ && CONSP (XCDR (spec)))
{
- /* `(space_width WIDTH)'. */
if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
return 0;
- value = XCAR (XCDR (prop));
+ value = XCAR (XCDR (spec));
if (NUMBERP (value) && XFLOATINT (value) > 0)
it->space_width = value;
+
+ return 0;
}
- else if (CONSP (prop)
- && EQ (XCAR (prop), Qslice))
+
+ /* Handle `(slice X Y WIDTH HEIGHT)'. */
+ if (CONSP (spec)
+ && EQ (XCAR (spec), Qslice))
{
- /* `(slice X Y WIDTH HEIGHT)'. */
Lisp_Object tem;
if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
return 0;
- if (tem = XCDR (prop), CONSP (tem))
+ if (tem = XCDR (spec), CONSP (tem))
{
it->slice.x = XCAR (tem);
if (tem = XCDR (tem), CONSP (tem))
}
}
}
+
+ return 0;
}
- else if (CONSP (prop)
- && EQ (XCAR (prop), Qraise)
- && CONSP (XCDR (prop)))
+
+ /* Handle `(raise FACTOR)'. */
+ if (CONSP (spec)
+ && EQ (XCAR (spec), Qraise)
+ && CONSP (XCDR (spec)))
{
- /* `(raise FACTOR)'. */
if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
return 0;
#ifdef HAVE_WINDOW_SYSTEM
- value = XCAR (XCDR (prop));
+ value = XCAR (XCDR (spec));
if (NUMBERP (value))
{
struct face *face = FACE_FROM_ID (it->f, it->face_id);
* (FONT_HEIGHT (face->font)));
}
#endif /* HAVE_WINDOW_SYSTEM */
+
+ return 0;
}
- else if (!it->string_from_display_prop_p)
- {
- /* `((margin left-margin) VALUE)' or `((margin right-margin)
- VALUE) or `((margin nil) VALUE)' or VALUE. */
- Lisp_Object location, value;
- struct text_pos start_pos;
- int valid_p;
- /* Characters having this form of property are not displayed, so
- we have to find the end of the property. */
- start_pos = *position;
- *position = display_prop_end (it, object, start_pos);
- value = Qnil;
+ /* Don't handle the other kinds of display specifications
+ inside a string that we got from a `display' property. */
+ if (it->string_from_display_prop_p)
+ return 0;
- /* Let's stop at the new position and assume that all
- text properties change there. */
- it->stop_charpos = position->charpos;
+ /* Characters having this form of property are not displayed, so
+ we have to find the end of the property. */
+ start_pos = *position;
+ *position = display_prop_end (it, object, start_pos);
+ value = Qnil;
- if (CONSP (prop)
- && (EQ (XCAR (prop), Qleft_fringe)
- || EQ (XCAR (prop), Qright_fringe))
- && CONSP (XCDR (prop)))
- {
- unsigned face_id = DEFAULT_FACE_ID;
+ /* Stop the scan at that end position--we assume that all
+ text properties change there. */
+ it->stop_charpos = position->charpos;
- /* Save current settings of IT so that we can restore them
- when we are finished with the glyph property value. */
+ /* Handle `(left-fringe BITMAP [FACE])'
+ and `(right-fringe BITMAP [FACE])'. */
+ if (CONSP (spec)
+ && (EQ (XCAR (spec), Qleft_fringe)
+ || EQ (XCAR (spec), Qright_fringe))
+ && CONSP (XCDR (spec)))
+ {
+ int face_id = DEFAULT_FACE_ID;
+ int fringe_bitmap;
- /* `(left-fringe BITMAP FACE)'. */
- if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
- return 0;
+ if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
+ /* If we return here, POSITION has been advanced
+ across the text with this property. */
+ return 0;
#ifdef HAVE_WINDOW_SYSTEM
- value = XCAR (XCDR (prop));
- if (!NUMBERP (value)
- || !valid_fringe_bitmap_id_p (XINT (value)))
- return 0;
+ value = XCAR (XCDR (spec));
+ if (!SYMBOLP (value)
+ || !(fringe_bitmap = lookup_fringe_bitmap (value)))
+ /* If we return here, POSITION has been advanced
+ across the text with this property. */
+ return 0;
- if (CONSP (XCDR (XCDR (prop))))
- {
- Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
+ if (CONSP (XCDR (XCDR (spec))))
+ {
+ Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
+ int face_id2 = lookup_named_face (it->f, face_name, 'A', 0);
+ if (face_id2 >= 0)
+ face_id = face_id2;
+ }
- face_id = lookup_named_face (it->f, face_name, 'A');
- if (face_id < 0)
- return 0;
- }
+ /* Save current settings of IT so that we can restore them
+ when we are finished with the glyph property value. */
- push_it (it);
+ push_it (it);
- it->area = TEXT_AREA;
- it->what = IT_IMAGE;
- it->image_id = -1; /* no image */
- it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
- it->method = next_element_from_image;
- it->face_id = face_id;
+ it->area = TEXT_AREA;
+ it->what = IT_IMAGE;
+ it->image_id = -1; /* no image */
+ it->position = start_pos;
+ it->object = NILP (object) ? it->w->buffer : object;
+ it->method = next_element_from_image;
+ it->face_id = face_id;
- /* Say that we haven't consumed the characters with
- `display' property yet. The call to pop_it in
- set_iterator_to_next will clean this up. */
- *position = start_pos;
+ /* Say that we haven't consumed the characters with
+ `display' property yet. The call to pop_it in
+ set_iterator_to_next will clean this up. */
+ *position = start_pos;
- if (EQ (XCAR (prop), Qleft_fringe))
- {
- it->left_user_fringe_bitmap = XINT (value);
- it->left_user_fringe_face_id = face_id;
- }
- else
- {
- it->right_user_fringe_bitmap = XINT (value);
- it->right_user_fringe_face_id = face_id;
- }
-#endif /* HAVE_WINDOW_SYSTEM */
- return 1;
+ if (EQ (XCAR (spec), Qleft_fringe))
+ {
+ it->left_user_fringe_bitmap = fringe_bitmap;
+ it->left_user_fringe_face_id = face_id;
}
-
- location = Qunbound;
- if (CONSP (prop) && CONSP (XCAR (prop)))
+ else
{
- Lisp_Object tem;
+ it->right_user_fringe_bitmap = fringe_bitmap;
+ it->right_user_fringe_face_id = face_id;
+ }
+#endif /* HAVE_WINDOW_SYSTEM */
+ return 1;
+ }
- value = XCDR (prop);
- if (CONSP (value))
- value = XCAR (value);
+ /* Prepare to handle `((margin left-margin) ...)',
+ `((margin right-margin) ...)' and `((margin nil) ...)'
+ prefixes for display specifications. */
+ location = Qunbound;
+ if (CONSP (spec) && CONSP (XCAR (spec)))
+ {
+ Lisp_Object tem;
- tem = XCAR (prop);
- if (EQ (XCAR (tem), Qmargin)
- && (tem = XCDR (tem),
- tem = CONSP (tem) ? XCAR (tem) : Qnil,
- (NILP (tem)
- || EQ (tem, Qleft_margin)
- || EQ (tem, Qright_margin))))
- location = tem;
- }
+ value = XCDR (spec);
+ if (CONSP (value))
+ value = XCAR (value);
- if (EQ (location, Qunbound))
- {
- location = Qnil;
- value = prop;
- }
+ tem = XCAR (spec);
+ if (EQ (XCAR (tem), Qmargin)
+ && (tem = XCDR (tem),
+ tem = CONSP (tem) ? XCAR (tem) : Qnil,
+ (NILP (tem)
+ || EQ (tem, Qleft_margin)
+ || EQ (tem, Qright_margin))))
+ location = tem;
+ }
+
+ if (EQ (location, Qunbound))
+ {
+ location = Qnil;
+ value = spec;
+ }
- valid_p = (STRINGP (value)
+ /* After this point, VALUE is the property after any
+ margin prefix has been stripped. It must be a string,
+ an image specification, or `(space ...)'.
+
+ LOCATION specifies where to display: `left-margin',
+ `right-margin' or nil. */
+
+ valid_p = (STRINGP (value)
#ifdef HAVE_WINDOW_SYSTEM
- || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
+ || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
- || (CONSP (value) && EQ (XCAR (value), Qspace)));
+ || (CONSP (value) && EQ (XCAR (value), Qspace)));
- if ((EQ (location, Qleft_margin)
- || EQ (location, Qright_margin)
- || NILP (location))
- && valid_p
- && !display_replaced_before_p)
- {
- replaces_text_display_p = 1;
-
- /* Save current settings of IT so that we can restore them
- when we are finished with the glyph property value. */
- push_it (it);
+ if (valid_p && !display_replaced_before_p)
+ {
+ /* Save current settings of IT so that we can restore them
+ when we are finished with the glyph property value. */
+ push_it (it);
- if (NILP (location))
- it->area = TEXT_AREA;
- else if (EQ (location, Qleft_margin))
- it->area = LEFT_MARGIN_AREA;
- else
- it->area = RIGHT_MARGIN_AREA;
+ if (NILP (location))
+ it->area = TEXT_AREA;
+ else if (EQ (location, Qleft_margin))
+ it->area = LEFT_MARGIN_AREA;
+ else
+ it->area = RIGHT_MARGIN_AREA;
- if (STRINGP (value))
- {
- it->string = value;
- 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 = next_element_from_string;
- it->stop_charpos = 0;
- it->string_from_display_prop_p = 1;
- /* Say that we haven't consumed the characters with
- `display' property yet. The call to pop_it in
- set_iterator_to_next will clean this up. */
- *position = start_pos;
- }
- else if (CONSP (value) && EQ (XCAR (value), Qspace))
- {
- it->method = next_element_from_stretch;
- it->object = value;
- it->current.pos = it->position = start_pos;
- }
-#ifdef HAVE_WINDOW_SYSTEM
- else
- {
- it->what = IT_IMAGE;
- it->image_id = lookup_image (it->f, value);
- it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
- it->method = next_element_from_image;
-
- /* Say that we haven't consumed the characters with
- `display' property yet. The call to pop_it in
- set_iterator_to_next will clean this up. */
- *position = start_pos;
- }
-#endif /* HAVE_WINDOW_SYSTEM */
+ if (STRINGP (value))
+ {
+ it->string = value;
+ 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 = next_element_from_string;
+ it->stop_charpos = 0;
+ it->string_from_display_prop_p = 1;
+ /* Say that we haven't consumed the characters with
+ `display' property yet. The call to pop_it in
+ set_iterator_to_next will clean this up. */
+ *position = start_pos;
+ }
+ else if (CONSP (value) && EQ (XCAR (value), Qspace))
+ {
+ it->method = next_element_from_stretch;
+ it->object = value;
+ it->current.pos = it->position = start_pos;
}
+#ifdef HAVE_WINDOW_SYSTEM
else
- /* Invalid property or property not supported. Restore
- the position to what it was before. */
- *position = start_pos;
+ {
+ it->what = IT_IMAGE;
+ it->image_id = lookup_image (it->f, value);
+ it->position = start_pos;
+ it->object = NILP (object) ? it->w->buffer : object;
+ it->method = next_element_from_image;
+
+ /* Say that we haven't consumed the characters with
+ `display' property yet. The call to pop_it in
+ set_iterator_to_next will clean this up. */
+ *position = start_pos;
+ }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+ return 1;
}
- return replaces_text_display_p;
+ /* Invalid property or property not supported. Restore
+ POSITION to what it was before. */
+ *position = start_pos;
+ return 0;
}
-/* Check if PROP is a display sub-property value whose text should be
+/* Check if SPEC is a display specification value whose text should be
treated as intangible. */
static int
-single_display_prop_intangible_p (prop)
+single_display_spec_intangible_p (prop)
Lisp_Object prop;
{
/* Skip over `when FORM'. */
/* A list of sub-properties. */
while (CONSP (prop))
{
- if (single_display_prop_intangible_p (XCAR (prop)))
+ if (single_display_spec_intangible_p (XCAR (prop)))
return 1;
prop = XCDR (prop);
}
/* A vector of sub-properties. */
int i;
for (i = 0; i < ASIZE (prop); ++i)
- if (single_display_prop_intangible_p (AREF (prop, i)))
+ if (single_display_spec_intangible_p (AREF (prop, i)))
return 1;
}
else
- return single_display_prop_intangible_p (prop);
+ return single_display_spec_intangible_p (prop);
return 0;
}
/* Return 1 if PROP is a display sub-property value containing STRING. */
static int
-single_display_prop_string_p (prop, string)
+single_display_spec_string_p (prop, string)
Lisp_Object prop, string;
{
if (EQ (string, prop))
/* A list of sub-properties. */
while (CONSP (prop))
{
- if (single_display_prop_string_p (XCAR (prop), string))
+ if (single_display_spec_string_p (XCAR (prop), string))
return 1;
prop = XCDR (prop);
}
/* A vector of sub-properties. */
int i;
for (i = 0; i < ASIZE (prop); ++i)
- if (single_display_prop_string_p (AREF (prop, i), string))
+ if (single_display_spec_string_p (AREF (prop, i), string))
return 1;
}
else
- return single_display_prop_string_p (prop, string);
+ return single_display_spec_string_p (prop, string);
return 0;
}
/* If we have to display `...' for invisible text, set
the iterator up for that. */
if (display_ellipsis_p)
- setup_for_ellipsis (it);
+ setup_for_ellipsis (it, 0);
}
else
{
{
Lisp_Object prop;
- prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
+ /* Check the newline before point for invisibility. */
+ prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
Qinvisible, it->window);
if (TEXT_PROP_MEANS_INVISIBLE (prop))
visible_p = 0;
selective display. At the end, update IT's overlay information,
face information etc. */
-static void
+void
reseat_at_previous_visible_line_start (it)
struct it *it;
{
we hit the end of what we iterate over. Performance note: the
function pointer `method' used here turns out to be faster than
using a sequence of if-statements. */
- int success_p = (*it->method) (it);
+ int success_p;
+
+ get_next:
+ success_p = (*it->method) (it);
if (it->what == IT_CHARACTER)
{
it->dpvec = v->contents;
it->dpend = v->contents + v->size;
it->current.dpvec_index = 0;
+ it->saved_face_id = it->face_id;
it->method = next_element_from_display_vector;
- success_p = get_next_display_element (it);
}
else
{
set_iterator_to_next (it, 0);
- success_p = get_next_display_element (it);
}
+ goto get_next;
}
/* Translate control characters into `\003' or `^C' form.
translated to octal form. */
else if ((it->c < ' '
&& (it->area != TEXT_AREA
+ /* In mode line, treat \n like other crl chars. */
+ || (it->c != '\n'
+ && it->glyph_row && it->glyph_row->mode_line_p)
|| (it->c != '\n' && it->c != '\t')))
|| (it->multibyte_p
? ((it->c >= 127
&& it->len == 1)
- || !CHAR_PRINTABLE_P (it->c))
+ || !CHAR_PRINTABLE_P (it->c)
+ || it->c == 0x8ad
+ || it->c == 0x8a0)
: (it->c >= 127
- && it->c == unibyte_char_to_multibyte (it->c))))
+ && (!unibyte_display_via_language_environment
+ || it->c == unibyte_char_to_multibyte (it->c)))))
{
/* IT->c is a control character which must be displayed
either as '\003' or as `^C' where the '\\' and '^'
IT->ctl_chars with glyphs for what we have to
display. Then, set IT->dpvec to these glyphs. */
GLYPH g;
+ int ctl_len;
+ int face_id = escape_glyph_face;
+
+ /* Find the face id if `escape-glyph' unless we recently did. */
+ if (face_id < 0)
+ {
+ Lisp_Object tem = Fget (Qescape_glyph, Qface);
+ if (INTEGERP (tem))
+ face_id = XINT (tem);
+ else
+ face_id = 0;
+ /* If there's overflow, use 0 instead. */
+ if (FAST_GLYPH_FACE (FAST_MAKE_GLYPH (0, face_id)) != face_id)
+ face_id = 0;
+ escape_glyph_face = face_id;
+ }
if (it->c < 128 && it->ctl_arrow_p)
{
&& GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
g = XINT (DISP_CTRL_GLYPH (it->dp));
else
- g = FAST_MAKE_GLYPH ('^', 0);
+ g = FAST_MAKE_GLYPH ('^', face_id);
XSETINT (it->ctl_chars[0], g);
- g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
+ g = FAST_MAKE_GLYPH (it->c ^ 0100, face_id);
XSETINT (it->ctl_chars[1], g);
+ ctl_len = 2;
+ }
+ else if (it->c == 0x8a0 || it->c == 0x8ad)
+ {
+ /* Set IT->ctl_chars[0] to the glyph for `\\'. */
+ if (it->dp
+ && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
+ && GLYPH_CHAR_VALID_P (XINT (DISP_ESCAPE_GLYPH (it->dp))))
+ g = XINT (DISP_ESCAPE_GLYPH (it->dp));
+ else
+ g = FAST_MAKE_GLYPH ('\\', face_id);
+ XSETINT (it->ctl_chars[0], g);
- /* Set up IT->dpvec and return first character from it. */
- it->dpvec_char_len = it->len;
- it->dpvec = it->ctl_chars;
- it->dpend = it->dpvec + 2;
- it->current.dpvec_index = 0;
- it->method = next_element_from_display_vector;
- get_next_display_element (it);
+ g = FAST_MAKE_GLYPH (it->c == 0x8ad ? '-' : ' ', face_id);
+ XSETINT (it->ctl_chars[1], g);
+ ctl_len = 2;
}
else
{
&& GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
else
- escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
+ escape_glyph = FAST_MAKE_GLYPH ('\\', face_id);
if (SINGLE_BYTE_CHAR_P (it->c))
str[0] = it->c, len = 1;
XSETINT (it->ctl_chars[i * 4], escape_glyph);
/* Insert three more glyphs into IT->ctl_chars for
the octal display of the character. */
- g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
+ g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0',
+ face_id);
XSETINT (it->ctl_chars[i * 4 + 1], g);
- g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
+ g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0',
+ face_id);
XSETINT (it->ctl_chars[i * 4 + 2], g);
- g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
+ g = FAST_MAKE_GLYPH ((str[i] & 7) + '0',
+ face_id);
XSETINT (it->ctl_chars[i * 4 + 3], g);
}
-
- /* Set up IT->dpvec and return the first character
- from it. */
- it->dpvec_char_len = it->len;
- it->dpvec = it->ctl_chars;
- it->dpend = it->dpvec + len * 4;
- it->current.dpvec_index = 0;
- it->method = next_element_from_display_vector;
- get_next_display_element (it);
+ ctl_len = len * 4;
}
+
+ /* Set up IT->dpvec and return first character from it. */
+ it->dpvec_char_len = it->len;
+ it->dpvec = it->ctl_chars;
+ it->dpend = it->dpvec + ctl_len;
+ it->current.dpvec_index = 0;
+ it->saved_face_id = it->face_id;
+ it->method = next_element_from_display_vector;
+ goto get_next;
}
}
it->dpvec = NULL;
it->current.dpvec_index = -1;
+ /* Recheck faces after display vector */
+ it->stop_charpos = 0;
+
/* Skip over characters which were displayed via IT->dpvec. */
if (it->dpvec_char_len < 0)
reseat_at_next_visible_line_start (it, 1);
&& IT_STRING_CHARPOS (*it) >= 0));
}
-
/* Load IT's display element fields with information about the next
display element which comes from a display table entry or from the
result of translating a control character to one of the forms `^C'
- or `\003'. IT->dpvec holds the glyphs to return as characters. */
+ or `\003'.
+
+ IT->dpvec holds the glyphs to return as characters.
+ IT->saved_face_id holds the face id before the display vector--
+ it is restored into IT->face_idin set_iterator_to_next. */
static int
next_element_from_display_vector (it)
/* Precondition. */
xassert (it->dpvec && it->current.dpvec_index >= 0);
- /* Remember the current face id in case glyphs specify faces.
- IT's face is restored in set_iterator_to_next. */
- it->saved_face_id = it->face_id;
-
if (INTEGERP (*it->dpvec)
&& GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
{
struct it *it;
{
if (it->selective_display_ellipsis_p)
- {
- if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
- {
- /* Use the display table definition for `...'. Invalid glyphs
- will be handled by the method returning elements from dpvec. */
- struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
- it->dpvec_char_len = it->len;
- it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
- it->current.dpvec_index = 0;
- it->method = next_element_from_display_vector;
- }
- else
- {
- /* Use default `...' which is stored in default_invis_vector. */
- it->dpvec_char_len = it->len;
- it->dpvec = default_invis_vector;
- it->dpend = default_invis_vector + 3;
- it->current.dpvec_index = 0;
- it->method = next_element_from_display_vector;
- }
- }
+ setup_for_ellipsis (it, it->len);
else
{
/* The face at the current position may be different from the
{
int nlines, h;
struct it it2, it3;
- int start_pos = IT_CHARPOS (*it);
+ int start_pos;
+ move_further_back:
xassert (dy >= 0);
+ start_pos = IT_CHARPOS (*it);
+
/* Estimate how many newlines we must move back. */
nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
a line height of 13 pixels each, recentering with point
on the bottom line will try to move -39/2 = 19 pixels
backward. Try to avoid moving into the first line. */
- && it->current_y - target_y > line_height / 3 * 2
+ && it->current_y - target_y > line_height * 2 / 3
&& IT_CHARPOS (*it) > BEGV)
{
TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
target_y - it->current_y));
- move_it_vertically (it, target_y - it->current_y);
- xassert (IT_CHARPOS (*it) >= BEGV);
+ dy = it->current_y - target_y;
+ goto move_further_back;
}
else if (target_y >= it->current_y + line_height
&& IT_CHARPOS (*it) < ZV)
{
if (dy <= 0)
move_it_vertically_backward (it, -dy);
- else if (dy > 0)
+ else
{
TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
move_it_to (it, ZV, -1, it->current_y + dy, -1,
/* DVPOS == 0 means move to the start of the screen line. */
move_it_vertically_backward (it, 0);
xassert (it->current_x == 0 && it->hpos == 0);
+ /* Let next call to line_bottom_y calculate real line height */
+ last_height = 0;
}
else if (dvpos > 0)
move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
bcopy (SDATA (msg), buffer, len);
message_dolog (buffer, len - 1, 1, 0);
- SAFE_FREE (len);
+ SAFE_FREE ();
UNGCPRO;
}
}
return 0;
}
-
+\f
/* Display an echo area message M with a specified length of NBYTES
bytes. The string may include null characters. If M is 0, clear
struct gcpro gcpro1;
GCPRO1 (m);
+ clear_message (1,1);
/* First flush out any partial line written with print. */
message_log_maybe_newline ();
height = it.current_y + last_height;
else
height = it.current_y + it.max_ascent + it.max_descent;
- height -= it.extra_line_spacing;
+ height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
height = (height + unit - 1) / unit;
}
/* Copy at most PRECISION chars from STR. */
nbytes = strlen (str);
- n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
+ n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
while (nbytes--)
store_frame_title_char (*str++);
{
struct buffer *prev = current_buffer;
int count = SPECPDL_INDEX ();
- Lisp_Object old_tool_bar;
+ Lisp_Object new_tool_bar;
+ int new_n_tool_bar;
struct gcpro gcpro1;
/* Set current_buffer to the buffer of the selected
specbind (Qoverriding_local_map, Qnil);
}
- old_tool_bar = f->tool_bar_items;
- GCPRO1 (old_tool_bar);
+ GCPRO1 (new_tool_bar);
/* Build desired tool-bar items from keymaps. */
- BLOCK_INPUT;
- f->tool_bar_items
- = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
- UNBLOCK_INPUT;
+ new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
+ &new_n_tool_bar);
/* Redisplay the tool-bar if we changed it. */
- if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
- w->update_mode_line = Qt;
+ if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
+ {
+ /* Redisplay that happens asynchronously due to an expose event
+ may access f->tool_bar_items. Make sure we update both
+ variables within BLOCK_INPUT so no such event interrupts. */
+ BLOCK_INPUT;
+ f->tool_bar_items = new_tool_bar;
+ f->n_tool_bar_items = new_n_tool_bar;
+ w->update_mode_line = Qt;
+ UNBLOCK_INPUT;
+ }
UNGCPRO;
{
row->height = row->phys_height = it->last_visible_y - row->y;
row->ascent = row->phys_ascent = 0;
+ row->extra_line_spacing = 0;
}
row->full_width_p = 1;
}
-/* Return overlay arrow string at row, or nil. */
+/* Return overlay arrow string to display at row.
+ Return t if display as bitmap in left fringe.
+ Return nil if no overlay arrow. */
static Lisp_Object
-overlay_arrow_at_row (f, row, pbitmap)
- struct frame *f;
+overlay_arrow_at_row (it, row, pbitmap)
+ struct it *it;
struct glyph_row *row;
int *pbitmap;
{
&& (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
{
val = overlay_arrow_string_or_property (var, pbitmap);
- if (FRAME_WINDOW_P (f))
+ if (FRAME_WINDOW_P (it->f)
+ && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
return Qt;
- else if (STRINGP (val))
+ if (STRINGP (val))
return val;
break;
}
This is useful in situations where you need to redisplay but no
user action has occurred, making it inappropriate for the message
area to be cleared. See tracking_off and
- wait_reading_process_input for examples of these situations.
+ wait_reading_process_output for examples of these situations.
FROM_WHERE is an integer saying from where this function was
called. This is useful for debugging. */
}
else
redisplay_internal (1);
+
+ if (rif != NULL && rif->flush_display_optional)
+ rif->flush_display_optional (NULL);
}
{
struct glyph *glyph = row->glyphs[TEXT_AREA];
struct glyph *end = glyph + row->used[TEXT_AREA];
+ struct glyph *cursor = NULL;
/* The first glyph that starts a sequence of glyphs from string. */
struct glyph *string_start;
/* The X coordinate of string_start. */
/* The last known character position before string_start. */
int string_before_pos;
int x = row->x;
+ int cursor_x = x;
+ int cursor_from_overlay_pos = 0;
int pt_old = PT - delta;
/* Skip over glyphs not having an object at the start of the row.
string_start = NULL;
x += glyph->pixel_width;
++glyph;
+ if (cursor_from_overlay_pos
+ && last_pos > cursor_from_overlay_pos)
+ {
+ cursor_from_overlay_pos = 0;
+ cursor = 0;
+ }
}
else
{
string_start = glyph;
string_start_x = x;
/* Skip all glyphs from string. */
- SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
+ do
+ {
+ int pos;
+ if ((cursor == NULL || glyph > cursor)
+ && !NILP (Fget_char_property (make_number ((glyph)->charpos),
+ Qcursor, (glyph)->object))
+ && (pos = string_buffer_position (w, glyph->object,
+ string_before_pos),
+ (pos == 0 /* From overlay */
+ || pos == pt_old)))
+ {
+ /* Estimate overlay buffer position from the buffer
+ positions of the glyphs before and after the overlay.
+ Add 1 to last_pos so that if point corresponds to the
+ glyph right after the overlay, we still use a 'cursor'
+ property found in that overlay. */
+ cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
+ cursor = glyph;
+ cursor_x = x;
+ }
+ x += glyph->pixel_width;
+ ++glyph;
+ }
+ while (glyph < end && STRINGP (glyph->object));
}
}
- if (string_start
- && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
+ if (cursor != NULL)
+ {
+ glyph = cursor;
+ x = cursor_x;
+ }
+ else if (string_start
+ && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
{
/* We may have skipped over point because the previous glyphs
are from string. As there's no easy way to know the
struct glyph_row *row;
int window_height;
+ if (!make_cursor_line_fully_visible_p)
+ return 1;
+
/* It's not always possible to find the cursor, e.g, when a window
is full of overlay strings. Don't do anything in that case. */
if (w->cursor.vpos < 0)
row = MATRIX_ROW (matrix, w->cursor.vpos);
/* If the cursor row is not partially visible, there's nothing to do. */
- if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
+ if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
return 1;
/* If the row the cursor is in is taller than the window's height,
{
start_display (&it, w, scroll_margin_pos);
if (this_scroll_margin)
- move_it_vertically (&it, - this_scroll_margin);
+ move_it_vertically_backward (&it, this_scroll_margin);
if (extra_scroll_margin_lines)
move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
scroll_margin_pos = it.current.pos;
start_display (&it, w, startp);
if (scroll_conservatively)
- amount_to_scroll =
- max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
+ amount_to_scroll
+ = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
else if (scroll_step || temp_scroll_step)
amount_to_scroll = scroll_max;
else
if (amount_to_scroll <= 0)
return SCROLLING_FAILED;
- move_it_vertically (&it, - amount_to_scroll);
+ move_it_vertically_backward (&it, amount_to_scroll);
startp = it.current.pos;
}
}
else if (PT < XFASTINT (w->last_point))
{
/* Cursor has to be moved backward. Note that PT >=
- CHARPOS (startp) because of the outer
- if-statement. */
+ CHARPOS (startp) because of the outer if-statement. */
while (!row->mode_line_p
&& (MATRIX_ROW_START_CHARPOS (row) > PT
|| (MATRIX_ROW_START_CHARPOS (row) == PT
/* if PT is not in the glyph row, give up. */
rc = CURSOR_MOVEMENT_MUST_SCROLL;
}
- else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
+ else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
+ && make_cursor_line_fully_visible_p)
{
if (PT == MATRIX_ROW_END_CHARPOS (row)
&& !row->ends_at_zv_p
*w->desired_matrix->method = 0;
#endif
+ /* Force this to be looked up again for each redisp of each window. */
+ escape_glyph_face = -1;
+
specbind (Qinhibit_point_motion_hooks, Qt);
reconsider_clip_changes (w, buffer);
buffer. */
|| !NILP (Vwindow_scroll_functions)
|| MINI_WINDOW_P (w)
- || !(used_current_matrix_p =
- try_window_reusing_current_matrix (w)))
+ || !(used_current_matrix_p
+ = try_window_reusing_current_matrix (w)))
{
IF_DEBUG (debug_method_add (w, "1"));
try_window (window, startp);
if (it.current_y <= 0)
{
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
- move_it_vertically (&it, 0);
+ move_it_vertically_backward (&it, 0);
xassert (IT_CHARPOS (it) <= PT);
it.current_y = 0;
}
|| !NILP (Vwindow_scroll_functions)
|| !just_this_one_p
|| MINI_WINDOW_P (w)
- || !(used_current_matrix_p =
- try_window_reusing_current_matrix (w)))
+ || !(used_current_matrix_p
+ = try_window_reusing_current_matrix (w)))
try_window (window, startp);
/* If new fonts have been loaded (due to fontsets), give up. We
}
#ifdef HAVE_WINDOW_SYSTEM
- if (update_window_fringes (w, 0)
+ if (FRAME_WINDOW_P (f)
+ && update_window_fringes (w, 0)
&& !just_this_one_p
&& (used_current_matrix_p || overlay_arrow_seen)
&& !w->pseudo_window_p)
{
update_begin (f);
BLOCK_INPUT;
- draw_window_fringes (w);
+ if (draw_window_fringes (w, 1))
+ x_draw_vertical_border (w);
UNBLOCK_INPUT;
update_end (f);
}
/* Give up if old or new display is scrolled vertically. We could
make this function handle this, but right now it doesn't. */
start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
- if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
+ if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
return 0;
/* The variable new_start now holds the new window start. The old
last_text_row = last_reused_text_row = NULL;
while (it.current_y < it.last_visible_y
- && IT_CHARPOS (it) < CHARPOS (start)
&& !fonts_changed_p)
- if (display_line (&it))
- last_text_row = it.glyph_row - 1;
+ {
+ /* If we have reached into the characters in the START row,
+ that means the line boundaries have changed. So we
+ can't start copying with the row START. Maybe it will
+ work to start copying with the following row. */
+ while (IT_CHARPOS (it) > CHARPOS (start))
+ {
+ /* Advance to the next row as the "start". */
+ start_row++;
+ start = start_row->start.pos;
+ /* If there are no more rows to try, or just one, give up. */
+ if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
+ || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
+ || CHARPOS (start) == ZV)
+ {
+ clear_glyph_matrix (w->desired_matrix);
+ return 0;
+ }
+
+ start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
+ }
+ /* If we have reached alignment,
+ we can copy the rest of the rows. */
+ if (IT_CHARPOS (it) == CHARPOS (start))
+ break;
+
+ if (display_line (&it))
+ last_text_row = it.glyph_row - 1;
+ }
/* A value of current_y < last_visible_y means that we stopped
at the previous window start, which in turn means that we
if (it.current_y < it.last_visible_y)
{
/* IT.vpos always starts from 0; it counts text lines. */
- nrows_scrolled = it.vpos;
+ nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
/* Find PT if not already found in the lines displayed. */
if (w->cursor.vpos < 0)
{
- int dy = it.current_y - first_row_y;
+ int dy = it.current_y - start_row->y;
row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
row = row_containing_pos (w, PT, row, NULL, dy);
scroll_run_hook will clear the cursor, and use the
current matrix to get the height of the row the cursor is
in. */
- run.current_y = first_row_y;
+ run.current_y = start_row->y;
run.desired_y = it.current_y;
run.height = it.last_visible_y - it.current_y;
&& CHARPOS (start) > BEGV)
/* Old redisplay didn't take scroll margin into account at the bottom,
but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
- || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
+ || (w->cursor.y + (make_cursor_line_fully_visible_p
+ ? cursor_height + this_scroll_margin
+ : 1)) > it.last_visible_y)
{
w->cursor.vpos = -1;
clear_glyph_matrix (w->desired_matrix);
Building Desired Matrix Rows
***********************************************************************/
-/* Return a temporary glyph row holding the glyphs of an overlay
- arrow. Only used for non-window-redisplay windows. */
+/* Return a temporary glyph row holding the glyphs of an overlay arrow.
+ Used for non-window-redisplay windows, and for windows w/o left fringe. */
static struct glyph_row *
get_overlay_arrow_glyph_row (w, overlay_arrow_string)
row->height = it->max_ascent + it->max_descent;
row->phys_ascent = it->max_phys_ascent;
row->phys_height = it->max_phys_ascent + it->max_phys_descent;
+ row->extra_line_spacing = it->max_extra_line_spacing;
}
/* Compute the width of this line. */
row->pixel_width -= it->truncation_pixel_width;
row->ascent = row->phys_ascent = 0;
row->height = row->phys_height = row->visible_height = 1;
+ row->extra_line_spacing = 0;
}
/* Compute a hash code for this row. */
&& glyph->u.ch == ' '))
&& trailing_whitespace_p (glyph->charpos))
{
- int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
+ int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
+ if (face_id < 0)
+ return;
while (glyph >= start
&& BUFFERP (glyph->object)
hscrolled. This may stop at an x-position < IT->first_visible_x
if the first glyph is partially visible or if we hit a line end. */
if (it->current_x < it->first_visible_x)
- move_it_in_display_line_to (it, ZV, it->first_visible_x,
- MOVE_TO_POS | MOVE_TO_X);
+ {
+ move_it_in_display_line_to (it, ZV, it->first_visible_x,
+ MOVE_TO_POS | MOVE_TO_X);
+ }
/* Get the initial row height. This is either the height of the
text hscrolled, if there is any, or zero. */
row->height = it->max_ascent + it->max_descent;
row->phys_ascent = it->max_phys_ascent;
row->phys_height = it->max_phys_ascent + it->max_phys_descent;
+ row->extra_line_spacing = it->max_extra_line_spacing;
/* Loop generating characters. The loop is left with IT on the next
character to display. */
row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
row->phys_height = max (row->phys_height,
it->max_phys_ascent + it->max_phys_descent);
+ row->extra_line_spacing = max (row->extra_line_spacing,
+ it->max_extra_line_spacing);
set_iterator_to_next (it, 1);
continue;
}
row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
row->phys_height = max (row->phys_height,
it->max_phys_ascent + it->max_phys_descent);
+ row->extra_line_spacing = max (row->extra_line_spacing,
+ it->max_extra_line_spacing);
if (it->current_x - it->pixel_width < it->first_visible_x)
row->x = x - it->first_visible_x;
}
row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
row->phys_height = max (row->phys_height,
it->max_phys_ascent + it->max_phys_descent);
+ row->extra_line_spacing = max (row->extra_line_spacing,
+ it->max_extra_line_spacing);
/* End of this display line if row is continued. */
if (row->continued_p || row->ends_at_zv_p)
{
if (!get_next_display_element (it))
{
-#ifdef HAVE_WINDOW_SYSTEM
it->continuation_lines_width = 0;
row->ends_at_zv_p = 1;
row->exact_window_width_line_p = 1;
break;
-#endif /* HAVE_WINDOW_SYSTEM */
}
if (ITERATOR_AT_END_OF_LINE_P (it))
{
better to let it be displayed like cursors under X. */
if (! overlay_arrow_seen
&& (overlay_arrow_string
- = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
+ = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
!NILP (overlay_arrow_string)))
{
/* Overlay arrow in window redisplay is a fringe bitmap. */
- if (!FRAME_WINDOW_P (it->f))
+ if (STRINGP (overlay_arrow_string))
{
struct glyph_row *arrow_row
= get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
}
}
-
+ else
+ {
+ it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
+ row->overlay_arrow_p = 1;
+ }
overlay_arrow_seen = 1;
- it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
- row->overlay_arrow_p = 1;
}
/* Compute pixel dimensions of this line. */
Lisp_Object oprops, aelt;
oprops = Ftext_properties_at (make_number (0), elt);
+ /* If the starting string's properties are not what
+ we want, translate the string. Also, if the string
+ is risky, do that anyway. */
+
if (NILP (Fequal (props, oprops)) || risky)
{
/* If the starting string has properties,
if (this - 1 != last)
{
+ int nchars, nbytes;
+
/* Output to end of string or up to '%'. Field width
is length of string. Don't output more than
PRECISION allows us. */
--this;
- prec = chars_in_text (last, this - last);
- if (precision > 0 && prec > precision - n)
- prec = precision - n;
+ prec = c_string_width (last, this - last, precision - n,
+ &nchars, &nbytes);
if (frame_title_ptr)
n += store_frame_title (last, 0, prec);
{
int bytepos = last - lisp_string;
int charpos = string_byte_to_char (elt, bytepos);
+ int endpos = (precision <= 0
+ ? string_byte_to_char (elt,
+ this - lisp_string)
+ : charpos + nchars);
+
n += store_mode_line_string (NULL,
Fsubstring (elt, make_number (charpos),
- make_number (charpos + prec)),
+ make_number (endpos)),
0, 0, 0, Qnil);
}
else
The mode_line_string_face face property is always added to the string.
*/
-static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
+static int
+store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
char *string;
Lisp_Object lisp_string;
int copy_string;
props = mode_line_string_face_prop;
else if (!NILP (mode_line_string_face))
{
- Lisp_Object face = Fplist_get (props, Qface);
+ Lisp_Object face = Fsafe_plist_get (props, Qface);
props = Fcopy_sequence (props);
if (NILP (face))
face = mode_line_string_face;
Lisp_Object face;
if (NILP (props))
props = Ftext_properties_at (make_number (0), lisp_string);
- face = Fplist_get (props, Qface);
+ face = Fsafe_plist_get (props, Qface);
if (NILP (face))
face = mode_line_string_face;
else
DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
- 0, 3, 0,
+ 0, 4, 0,
doc: /* Return the mode-line of selected window as a string.
First optional arg FORMAT specifies a different format string (see
`mode-line-format' for details) to use. If FORMAT is t, return
the buffer's header-line. Second optional arg WINDOW specifies a
different window to use as the context for the formatting.
-If third optional arg NO-PROPS is non-nil, string is not propertized. */)
- (format, window, no_props)
- Lisp_Object format, window, no_props;
+If third optional arg NO-PROPS is non-nil, string is not propertized.
+Fourth optional arg BUFFER specifies which buffer to use. */)
+ (format, window, no_props, buffer)
+ Lisp_Object format, window, no_props, buffer;
{
struct it it;
int len;
window = selected_window;
CHECK_WINDOW (window);
w = XWINDOW (window);
- CHECK_BUFFER (w->buffer);
- if (XBUFFER (w->buffer) != current_buffer)
+ if (NILP (buffer))
+ buffer = w->buffer;
+
+ CHECK_BUFFER (buffer);
+
+ if (XBUFFER (buffer) != current_buffer)
{
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (w->buffer));
+ set_buffer_internal_1 (XBUFFER (buffer));
}
if (NILP (format) || EQ (format, Qt))
{
- face_id = NILP (format)
- ? CURRENT_MODE_LINE_FACE_ID (w) :
- HEADER_LINE_FACE_ID;
- format = NILP (format)
- ? current_buffer->mode_line_format
- : current_buffer->header_line_format;
+ face_id = (NILP (format)
+ ? CURRENT_MODE_LINE_FACE_ID (w)
+ : HEADER_LINE_FACE_ID);
+ format = (NILP (format)
+ ? current_buffer->mode_line_format
+ : current_buffer->header_line_format);
}
init_iterator (&it, w, -1, -1, NULL, face_id);
if (NILP (no_props))
{
- mode_line_string_face =
- (face_id == MODE_LINE_FACE_ID ? Qmode_line :
- face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
- face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
+ mode_line_string_face
+ = (face_id == MODE_LINE_FACE_ID ? Qmode_line
+ : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
+ : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
- mode_line_string_face_prop =
- NILP (mode_line_string_face) ? Qnil :
- Fcons (Qface, Fcons (mode_line_string_face, Qnil));
+ mode_line_string_face_prop
+ = (NILP (mode_line_string_face) ? Qnil
+ : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
/* We need a dummy last element in mode_line_string_list to
indicate we are building the propertized mode-line string.
Using mode_line_string_face_prop here GC protects it. */
- mode_line_string_list =
- Fcons (mode_line_string_face_prop, Qnil);
+ mode_line_string_list
+ = Fcons (mode_line_string_face_prop, Qnil);
frame_title_ptr = NULL;
}
else
{
tenths = remainder / 100;
if (50 <= remainder % 100)
- if (tenths < 9)
- tenths++;
- else
- {
- quotient++;
- if (quotient == 10)
- tenths = -1;
- else
- tenths = 0;
- }
+ {
+ if (tenths < 9)
+ tenths++;
+ else
+ {
+ quotient++;
+ if (quotient == 10)
+ tenths = -1;
+ else
+ tenths = 0;
+ }
+ }
}
else
if (500 <= remainder)
- if (quotient < 999)
- quotient++;
- else
- {
- quotient = 1;
- exponent++;
- tenths = 0;
- }
+ {
+ if (quotient < 999)
+ quotient++;
+ else
+ {
+ quotient = 1;
+ exponent++;
+ tenths = 0;
+ }
+ }
}
/* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
generated by character C. PRECISION >= 0 means don't return a
string longer than that value. FIELD_WIDTH > 0 means pad the
string returned with spaces to that value. Return 1 in *MULTIBYTE
- if the result is multibyte text. */
+ if the result is multibyte text.
+
+ Note we operate on the current buffer for most purposes,
+ the exception being w->base_line_pos. */
static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
Lisp_Object obj;
struct frame *f = XFRAME (WINDOW_FRAME (w));
char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = current_buffer;
obj = Qnil;
*multibyte = 0;
case 's':
/* status of process */
- obj = Fget_buffer_process (w->buffer);
+ obj = Fget_buffer_process (Fcurrent_buffer ());
if (NILP (obj))
return "no process";
#ifdef subprocesses
row->height = it->max_ascent + it->max_descent;
row->phys_ascent = it->max_phys_ascent;
row->phys_height = it->max_phys_ascent + it->max_phys_descent;
+ row->extra_line_spacing = it->max_extra_line_spacing;
/* This condition is for the case that we are called with current_x
past last_visible_x. */
row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
row->phys_height = max (row->phys_height,
it->max_phys_ascent + it->max_phys_descent);
+ row->extra_line_spacing = max (row->extra_line_spacing,
+ it->max_extra_line_spacing);
x += glyph->pixel_width;
++i;
}
s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
/* Display the internal border below the tool-bar window. */
- if (s->w == XWINDOW (s->f->tool_bar_window))
+ if (WINDOWP (s->f->tool_bar_window)
+ && s->w == XWINDOW (s->f->tool_bar_window))
s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
s->ybase = s->y + row->ascent;
return x_reached;
}
+/* Expand row matrix if too narrow. Don't expand if area
+ is not present. */
+
+#define IT_EXPAND_MATRIX_WIDTH(it, area) \
+ { \
+ if (!fonts_changed_p \
+ && (it->glyph_row->glyphs[area] \
+ < it->glyph_row->glyphs[area + 1])) \
+ { \
+ it->w->ncols_scale_factor++; \
+ fonts_changed_p = 1; \
+ } \
+ }
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
glyph->font_type = FONT_TYPE_UNKNOWN;
++it->glyph_row->used[area];
}
- else if (!fonts_changed_p)
- {
- it->w->ncols_scale_factor++;
- fonts_changed_p = 1;
- }
+ else
+ IT_EXPAND_MATRIX_WIDTH (it, area);
}
/* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
glyph->font_type = FONT_TYPE_UNKNOWN;
++it->glyph_row->used[area];
}
- else if (!fonts_changed_p)
- {
- it->w->ncols_scale_factor++;
- fonts_changed_p = 1;
- }
+ else
+ IT_EXPAND_MATRIX_WIDTH (it, area);
}
{
struct image *img;
struct face *face;
- int face_ascent, glyph_ascent;
+ int glyph_ascent;
struct glyph_slice slice;
xassert (it->what == IT_IMAGE);
#if 0 /* this breaks image tiling */
/* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
- face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
+ int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
if (face_ascent > it->ascent)
it->ascent = it->phys_ascent = face_ascent;
#endif
glyph->font_type = FONT_TYPE_UNKNOWN;
++it->glyph_row->used[area];
}
- else if (!fonts_changed_p)
- {
- it->w->ncols_scale_factor++;
- fonts_changed_p = 1;
- }
+ else
+ IT_EXPAND_MATRIX_WIDTH (it, area);
}
}
glyph->font_type = FONT_TYPE_UNKNOWN;
++it->glyph_row->used[area];
}
- else if (!fonts_changed_p)
- {
- it->w->ncols_scale_factor++;
- fonts_changed_p = 1;
- }
+ else
+ IT_EXPAND_MATRIX_WIDTH (it, area);
}
plist = XCDR (it->object);
/* Compute the width of the stretch. */
- if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
+ if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
&& calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
{
/* Absolute width `:width WIDTH' specified and valid. */
zero_width_ok_p = 1;
width = (int)tem;
}
- else if (prop = Fplist_get (plist, QCrelative_width),
+ else if (prop = Fsafe_plist_get (plist, QCrelative_width),
NUMVAL (prop) > 0)
{
/* Relative width `:relative-width FACTOR' specified and valid.
x_produce_glyphs (&it2);
width = NUMVAL (prop) * it2.pixel_width;
}
- else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
+ else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
&& calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
{
if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
width = 1;
/* Compute height. */
- if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
+ if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
&& calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
{
height = (int)tem;
zero_height_ok_p = 1;
}
- else if (prop = Fplist_get (plist, QCrelative_height),
+ else if (prop = Fsafe_plist_get (plist, QCrelative_height),
NUMVAL (prop) > 0)
height = FONT_HEIGHT (font) * NUMVAL (prop);
else
/* Compute percentage of height used for ascent. If
`:ascent ASCENT' is present and valid, use that. Otherwise,
derive the ascent from the font in use. */
- if (prop = Fplist_get (plist, QCascent),
+ if (prop = Fsafe_plist_get (plist, QCascent),
NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
ascent = height * NUMVAL (prop) / 100.0;
else if (!NILP (prop)
if (STRINGP (it->object))
position = make_number (IT_STRING_CHARPOS (*it));
- else
+ else if (BUFFERP (it->object))
position = make_number (IT_CHARPOS (*it));
+ else
+ return Qnil;
val = Fget_char_property (position, prop, it->object);
struct face *face;
struct font_info *font_info;
- face_id = lookup_named_face (it->f, face_name, ' ');
+ face_id = lookup_named_face (it->f, face_name, ' ', 0);
if (face_id < 0)
return make_number (-1);
it->current_x += it->pixel_width;
if (extra_line_spacing > 0)
- it->descent += extra_line_spacing;
+ {
+ it->descent += extra_line_spacing;
+ if (extra_line_spacing > it->max_extra_line_spacing)
+ it->max_extra_line_spacing = extra_line_spacing;
+ }
it->max_ascent = max (it->max_ascent, it->ascent);
it->max_descent = max (it->max_descent, it->descent);
if (!cursor_row->enabled_p)
goto mark_cursor_off;
+ /* If line spacing is > 0, old cursor may only be partially visible in
+ window after split-window. So adjust visible height. */
+ cursor_row->visible_height = min (cursor_row->visible_height,
+ window_text_bottom_y (w) - cursor_row->y);
+
/* If row is completely invisible, don't attempt to delete a cursor which
isn't there. This can happen if cursor is at top of a window, and
we switch to a buffer with a header line in that window. */
{
int x, y;
int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+ int width;
cursor_glyph = get_phys_cursor_glyph (w);
if (cursor_glyph == NULL)
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
+ width = min (cursor_glyph->pixel_width,
+ window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
- rif->clear_frame_area (f, x, y,
- cursor_glyph->pixel_width, cursor_row->visible_height);
+ rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
}
/* Erase the cursor by redrawing the character underneath it. */
int past_end = 0;
first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ if (charpos < MATRIX_ROW_START_CHARPOS (first))
+ {
+ *x = first->x;
+ *y = first->y;
+ *hpos = 0;
+ *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
+ return 1;
+ }
+
row = row_containing_pos (w, charpos, first, NULL, 0);
if (row == NULL)
{
- if (charpos < MATRIX_ROW_START_CHARPOS (first))
- {
- *x = *y = *hpos = *vpos = 0;
- return 1;
- }
- else
- {
- row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
- past_end = 1;
- }
+ row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ past_end = 1;
}
*x = row->x;
Cursor cursor;
Lisp_Object pointer;
{
+ /* Do not change cursor shape while dragging mouse. */
+ if (!NILP (do_mouse_tracking))
+ return;
+
if (!NILP (pointer))
{
if (EQ (pointer, Qarrow))
if (IMAGEP (object))
{
Lisp_Object image_map, hotspot;
- if ((image_map = Fplist_get (XCDR (object), QCmap),
+ if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map, dx, dy),
CONSP (hotspot))
/* Could check AREA_ID to see if we enter/leave this hot-spot.
If so, we could look for mouse-enter, mouse-leave
properties in PLIST (and do something...). */
- if ((plist = XCDR (hotspot), CONSP (plist)))
+ hotspot = XCDR (hotspot);
+ if (CONSP (hotspot)
+ && (plist = XCAR (hotspot), CONSP (plist)))
{
- pointer = Fplist_get (plist, Qpointer);
+ pointer = Fsafe_plist_get (plist, Qpointer);
if (NILP (pointer))
pointer = Qhand;
- help = Fplist_get (plist, Qhelp_echo);
+ help = Fsafe_plist_get (plist, Qhelp_echo);
if (!NILP (help))
{
help_echo_string = help;
}
}
if (NILP (pointer))
- pointer = Fplist_get (XCDR (object), QCpointer);
+ pointer = Fsafe_plist_get (XCDR (object), QCpointer);
}
}
/* If we're on a string with `help-echo' text property, arrange
for the help to be displayed. This is done by setting the
global variable help_echo_string to the help string. */
- help = Fget_text_property (pos, Qhelp_echo, string);
- if (!NILP (help))
+ if (NILP (help))
{
- help_echo_string = help;
- XSETWINDOW (help_echo_window, w);
- help_echo_object = string;
- help_echo_pos = charpos;
+ help = Fget_text_property (pos, Qhelp_echo, string);
+ if (!NILP (help))
+ {
+ help_echo_string = help;
+ XSETWINDOW (help_echo_window, w);
+ help_echo_object = string;
+ help_echo_pos = charpos;
+ }
}
if (NILP (pointer))
/* Which window is that in? */
window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
- /* If we were displaying active text in another window, clear that. */
- if (! EQ (window, dpyinfo->mouse_face_window))
+ /* If we were displaying active text in another window, clear that.
+ Also clear if we move out of text area in same window. */
+ if (! EQ (window, dpyinfo->mouse_face_window)
+ || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
clear_mouse_face (dpyinfo);
/* Not on a window -> return. */
if (part == ON_VERTICAL_BORDER)
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
- else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
+ else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
+ || part == ON_SCROLL_BAR)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
else
cursor = FRAME_X_OUTPUT (f)->text_cursor;
if (img != NULL && IMAGEP (img->spec))
{
Lisp_Object image_map, hotspot;
- if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
+ if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
!NILP (image_map))
&& (hotspot = find_hot_spot (image_map,
glyph->slice.x + dx,
/* Could check AREA_ID to see if we enter/leave this hot-spot.
If so, we could look for mouse-enter, mouse-leave
properties in PLIST (and do something...). */
- if ((plist = XCDR (hotspot), CONSP (plist)))
+ hotspot = XCDR (hotspot);
+ if (CONSP (hotspot)
+ && (plist = XCAR (hotspot), CONSP (plist)))
{
- pointer = Fplist_get (plist, Qpointer);
+ pointer = Fsafe_plist_get (plist, Qpointer);
if (NILP (pointer))
pointer = Qhand;
- help_echo_string = Fplist_get (plist, Qhelp_echo);
+ help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
if (!NILP (help_echo_string))
{
help_echo_window = window;
}
}
if (NILP (pointer))
- pointer = Fplist_get (XCDR (img->spec), QCpointer);
+ pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
}
}
do it for frames with vertical scroll bars because either the
right scroll bar of a window, or the left scroll bar of its
neighbor will suffice as a border. */
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
+ return;
+
if (!WINDOW_RIGHTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
{
staticpro (&Qfontification_functions);
Qtrailing_whitespace = intern ("trailing-whitespace");
staticpro (&Qtrailing_whitespace);
+ Qescape_glyph = intern ("escape-glyph");
+ staticpro (&Qescape_glyph);
Qimage = intern ("image");
staticpro (&Qimage);
QCmap = intern (":map");
doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
auto_raise_tool_bar_buttons_p = 1;
+ DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
+ doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
+ make_cursor_line_fully_visible_p = 1;
+
DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
doc: /* *Margin around tool-bar buttons in pixels.
If an integer, use that for both horizontal and vertical margins.