static void mark_window_display_accurate_1 (struct window *, int);
static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
static int display_prop_string_p (Lisp_Object, Lisp_Object);
-static int cursor_row_p (struct window *, struct glyph_row *);
+static int cursor_row_p (struct glyph_row *);
static int redisplay_mode_lines (Lisp_Object, int);
static char *decode_mode_spec_coding (Lisp_Object, char *, int);
static void handle_stop (struct it *);
static void handle_stop_backwards (struct it *, EMACS_INT);
static int single_display_spec_intangible_p (Lisp_Object);
+static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
static void ensure_echo_area_buffers (void);
static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
static int trailing_whitespace_p (EMACS_INT);
-static int message_log_check_duplicate (EMACS_INT, EMACS_INT,
- EMACS_INT, EMACS_INT);
+static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
static void push_it (struct it *);
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
static void select_frame_for_redisplay (Lisp_Object);
-static void redisplay_internal (int);
+static void redisplay_internal (void);
static int echo_area_display (int);
static void redisplay_windows (Lisp_Object);
static void redisplay_window (Lisp_Object, int);
static int display_mode_line (struct window *, enum face_id, Lisp_Object);
static int display_mode_element (struct it *, int, int, int, Lisp_Object, Lisp_Object, int);
static int store_mode_line_string (const char *, Lisp_Object, int, int, int, Lisp_Object);
-static const char *decode_mode_spec (struct window *, int, int, int,
- Lisp_Object *);
+static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
static void display_menu_bar (struct window *);
-static int display_count_lines (EMACS_INT, EMACS_INT, EMACS_INT, int,
- EMACS_INT *);
+static int display_count_lines (EMACS_INT, EMACS_INT, int, EMACS_INT *);
static int display_string (const char *, Lisp_Object, Lisp_Object,
EMACS_INT, EMACS_INT, struct it *, int, int, int, int);
static void compute_line_metrics (struct it *);
line_height = last_height;
else if (IT_CHARPOS (*it) < ZV)
{
- move_it_by_lines (it, 1, 1);
+ move_it_by_lines (it, 1);
line_height = (it->max_ascent || it->max_descent
? it->max_ascent + it->max_descent
: last_height);
it2 = it;
if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
- move_it_by_lines (&it, 1, 0);
+ move_it_by_lines (&it, 1);
if (charpos < IT_CHARPOS (it)
|| (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
{
redisplay during the evaluation. */
Lisp_Object
-safe_call (int nargs, Lisp_Object *args)
+safe_call (size_t nargs, Lisp_Object *args)
{
Lisp_Object val;
{
int count = SPECPDL_INDEX ();
Lisp_Object val;
+ struct buffer *obuf = current_buffer;
+ int begv = BEGV, zv = ZV;
+ int old_clip_changed = current_buffer->clip_changed;
val = Vfontification_functions;
specbind (Qfontification_functions, Qnil);
unbind_to (count, Qnil);
+ /* Fontification functions routinely call `save-restriction'.
+ Normally, this tags clip_changed, which can confuse redisplay
+ (see discussion in Bug#6671). Since we don't perform any
+ special handling of fontification changes in the case where
+ `save-restriction' isn't called, there's no point doing so in
+ this case either. So, if the buffer's restrictions are
+ actually left unchanged, reset clip_changed. */
+ if (obuf == current_buffer)
+ {
+ if (begv == BEGV && zv == ZV)
+ current_buffer->clip_changed = old_clip_changed;
+ }
+ /* There isn't much we can reasonably do to protect against
+ misbehaving fontification, but here's a fig leaf. */
+ else if (!NILP (BVAR (obuf, name)))
+ set_buffer_internal_1 (obuf);
+
/* The fontification code may have added/removed text.
It could do even a lot worse, but let's at least protect against
the most obvious case where only the text past `pos' gets changed',
return 0;
}
-/* Look for STRING in overlays and text properties in W's buffer,
- between character positions FROM and TO (excluding TO).
+/* Look for STRING in overlays and text properties in the current
+ buffer, between character positions FROM and TO (excluding TO).
BACK_P non-zero means look back (in this case, TO is supposed to be
less than FROM).
Value is the first character position where STRING was found, or
zero if it wasn't found before hitting TO.
- W's buffer must be current.
-
This function may only use code that doesn't eval because it is
called asynchronously from note_mouse_highlight. */
static EMACS_INT
-string_buffer_position_lim (struct window *w, Lisp_Object string,
+string_buffer_position_lim (Lisp_Object string,
EMACS_INT from, EMACS_INT to, int back_p)
{
Lisp_Object limit, prop, pos;
return found ? XINT (pos) : 0;
}
-/* Determine which buffer position in W's buffer STRING comes from.
+/* Determine which buffer position in current buffer STRING comes from.
AROUND_CHARPOS is an approximate position where it could come from.
Value is the buffer position or 0 if it couldn't be determined.
- W's buffer must be current.
-
This function is necessary because we don't record buffer positions
in glyphs generated from strings (to keep struct glyph small).
This function may only use code that doesn't eval because it is
called asynchronously from note_mouse_highlight. */
-EMACS_INT
-string_buffer_position (struct window *w, Lisp_Object string, EMACS_INT around_charpos)
+static EMACS_INT
+string_buffer_position (Lisp_Object string, EMACS_INT around_charpos)
{
const int MAX_DISTANCE = 1000;
- EMACS_INT found = string_buffer_position_lim (w, string, around_charpos,
+ EMACS_INT found = string_buffer_position_lim (string, around_charpos,
around_charpos + MAX_DISTANCE,
0);
if (!found)
- found = string_buffer_position_lim (w, string, around_charpos,
+ found = string_buffer_position_lim (string, around_charpos,
around_charpos - MAX_DISTANCE, 1);
return found;
}
/* DY == 0 means move to the start of the screen line. The
value of nlines is > 0 if continuation lines were involved. */
if (nlines > 0)
- move_it_by_lines (it, nlines, 1);
+ move_it_by_lines (it, nlines);
}
else
{
{
do
{
- move_it_by_lines (it, 1, 1);
+ move_it_by_lines (it, 1);
}
while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
}
if (IT_CHARPOS (*it) == ZV
&& ZV > BEGV
&& FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
- move_it_by_lines (it, 0, 0);
+ move_it_by_lines (it, 0);
}
}
/* Move IT by a specified number DVPOS of screen lines down. DVPOS
negative means move up. DVPOS == 0 means move to the start of the
- screen line. NEED_Y_P non-zero means calculate IT->current_y. If
- NEED_Y_P is zero, IT->current_y will be left unchanged.
+ screen line.
- Further optimization ideas: If we would know that IT->f doesn't use
+ Optimization idea: If we would know that IT->f doesn't use
a face with proportional font, we could be faster for
truncate-lines nil. */
void
-move_it_by_lines (struct it *it, int dvpos, int need_y_p)
+move_it_by_lines (struct it *it, int dvpos)
{
/* The commented-out optimization uses vmotion on terminals. This
c = string_char_and_length (msg + i, &char_bytes);
work[0] = (ASCII_CHAR_P (c)
? c
- : multibyte_char_to_unibyte (c, Qnil));
+ : multibyte_char_to_unibyte (c));
insert_1_both (work, 1, 1, 1, 0, 0);
}
}
if (nlflag)
{
EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
- int dups;
+ unsigned long int dups;
insert_1 ("\n", 1, 1, 0, 0);
scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
prev_bol = PT;
prev_bol_byte = PT_BYTE;
- dups = message_log_check_duplicate (prev_bol, prev_bol_byte,
- this_bol, this_bol_byte);
+ dups = message_log_check_duplicate (prev_bol_byte,
+ this_bol_byte);
if (dups)
{
del_range_both (prev_bol, prev_bol_byte,
/* If you change this format, don't forget to also
change message_log_check_duplicate. */
- sprintf (dupstr, " [%d times]", dups);
+ sprintf (dupstr, " [%lu times]", dups);
duplen = strlen (dupstr);
TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
insert_1 (dupstr, duplen, 1, 0, 1);
Return 0 if different, 1 if the new one should just replace it, or a
value N > 1 if we should also append " [N times]". */
-static int
-message_log_check_duplicate (EMACS_INT prev_bol, EMACS_INT prev_bol_byte,
- EMACS_INT this_bol, EMACS_INT this_bol_byte)
+static unsigned long int
+message_log_check_duplicate (EMACS_INT prev_bol_byte, EMACS_INT this_bol_byte)
{
EMACS_INT i;
EMACS_INT len = Z_BYTE - 1 - this_bol_byte;
return 2;
if (*p1++ == ' ' && *p1++ == '[')
{
- int n = 0;
- while (*p1 >= '0' && *p1 <= '9')
- n = n * 10 + *p1++ - '0';
- if (strncmp ((char *) p1, " times]\n", 8) == 0)
+ char *pend;
+ unsigned long int n = strtoul ((char *) p1, &pend, 10);
+ if (strncmp (pend, " times]\n", 8) == 0)
return n+1;
}
return 0;
{
if (m)
{
- EMACS_INT len;
-
- len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
+ char *buf = FRAME_MESSAGE_BUF (f);
+ size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f);
+ int len = vsnprintf (buf, bufsize, m, ap);
+ if (len < 0)
+ len = 0;
+
+ /* Do any truncation at a character boundary. */
+ if (0 < bufsize && bufsize <= len)
+ for (len = bufsize - 1;
+ len && ! CHAR_HEAD_P (buf[len - 1]);
+ len--)
+ continue;
message2 (FRAME_MESSAGE_BUF (f), len, 0);
}
}
-/* The non-logging version of message. */
-
-void
-message_nolog (const char *m, ...)
-{
- Lisp_Object old_log_max;
- va_list ap;
- va_start (ap, m);
- old_log_max = Vmessage_log_max;
- Vmessage_log_max = Qnil;
- vmessage (m, ap);
- Vmessage_log_max = old_log_max;
- va_end (ap);
-}
-
-
/* Display the current message in the current mini-buffer. This is
only called from error handlers in process.c, and is not time
critical. */
{
++windows_or_buffers_changed;
++update_mode_lines;
- redisplay_internal (0);
+ redisplay_internal ();
}
}
}
c = string_char_and_length (msg + i, &n);
work[0] = (ASCII_CHAR_P (c)
? c
- : multibyte_char_to_unibyte (c, Qnil));
+ : multibyte_char_to_unibyte (c));
insert_1_both (work, 1, 1, 1, 0, 0);
}
}
int count = SPECPDL_INDEX ();
specbind (Qredisplay_dont_pause, Qt);
windows_or_buffers_changed = 1;
- redisplay_internal (0);
+ redisplay_internal ();
unbind_to (count, Qnil);
}
else if (FRAME_WINDOW_P (f) && n == 0)
void
redisplay (void)
{
- redisplay_internal (0);
+ redisplay_internal ();
}
polling_stopped_here = 0; } while (0)
-/* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
- response to any user action; therefore, we should preserve the echo
- area. (Actually, our caller does that job.) Perhaps in the future
- avoid recentering windows if it is not necessary; currently that
- causes some problems. */
+/* Perhaps in the future avoid recentering windows if it
+ is not necessary; currently that causes some problems. */
static void
-redisplay_internal (int preserve_echo_area)
+redisplay_internal (void)
{
struct window *w = XWINDOW (selected_window);
struct window *sw;
/* We have a previously displayed message, but no current
message. Redisplay the previous message. */
display_last_displayed_message_p = 1;
- redisplay_internal (1);
+ redisplay_internal ();
display_last_displayed_message_p = 0;
}
else
- redisplay_internal (1);
+ redisplay_internal ();
if (FRAME_RIF (SELECTED_FRAME ()) != NULL
&& FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
EMACS_INT tem;
str = glyph->object;
- tem = string_buffer_position_lim (w, str, pos, pos_after, 0);
+ tem = string_buffer_position_lim (str, pos, pos_after, 0);
if (tem == 0 /* from overlay */
|| pos <= tem)
{
SCROLLING_NEED_LARGER_MATRICES
};
+/* If scroll-conservatively is more than this, never recenter.
+
+ If you change this, don't forget to update the doc string of
+ `scroll-conservatively' and the Emacs manual. */
+#define SCROLL_LIMIT 100
+
static int
try_scrolling (Lisp_Object window, int just_this_one_p,
EMACS_INT arg_scroll_conservatively, EMACS_INT scroll_step,
int dy = 0, amount_to_scroll = 0, scroll_down_p = 0;
int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
Lisp_Object aggressive;
- int scroll_limit = INT_MAX / FRAME_LINE_HEIGHT (f);
+ /* We will never try scrolling more than this number of lines. */
+ int scroll_limit = SCROLL_LIMIT;
#if GLYPH_DEBUG
debug_method_add (w, "try_scrolling");
else
this_scroll_margin = 0;
- /* Force arg_scroll_conservatively to have a reasonable value, to avoid
- overflow while computing how much to scroll. Note that the user
- can supply scroll-conservatively equal to `most-positive-fixnum',
- which can be larger than INT_MAX. */
+ /* Force arg_scroll_conservatively to have a reasonable value, to
+ avoid scrolling too far away with slow move_it_* functions. Note
+ that the user can supply scroll-conservatively equal to
+ `most-positive-fixnum', which can be larger than INT_MAX. */
if (arg_scroll_conservatively > scroll_limit)
{
- arg_scroll_conservatively = scroll_limit;
- scroll_max = INT_MAX;
+ arg_scroll_conservatively = scroll_limit + 1;
+ scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f);
}
else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
/* Compute how much we should try to scroll maximally to bring
/* Compute how many pixels below window bottom to stop searching
for PT. This avoids costly search for PT that is far away if
the user limited scrolling by a small number of lines, but
- always finds PT if arg_scroll_conservatively is set to a large
+ always finds PT if scroll_conservatively is set to a large
number, such as most-positive-fixnum. */
int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f));
- int y_to_move =
- slack >= INT_MAX - it.last_visible_y
- ? INT_MAX
- : it.last_visible_y + slack;
+ int y_to_move = it.last_visible_y + slack;
/* Compute the distance from the scroll margin to PT or to
the scroll limit, whichever comes first. This should
amount_to_scroll = float_amount;
if (amount_to_scroll == 0 && float_amount > 0)
amount_to_scroll = 1;
+ /* Don't let point enter the scroll margin near top of
+ the window. */
+ if (amount_to_scroll > height - 2*this_scroll_margin + dy)
+ amount_to_scroll = height - 2*this_scroll_margin + dy;
}
}
return SCROLLING_FAILED;
start_display (&it, w, startp);
- if (scroll_max < INT_MAX)
+ if (arg_scroll_conservatively <= scroll_limit)
move_it_vertically (&it, amount_to_scroll);
else
{
/* Extra precision for users who set scroll-conservatively
- to most-positive-fixnum: make sure the amount we scroll
+ to a large number: make sure the amount we scroll
the window start is never less than amount_to_scroll,
which was computed as distance from window bottom to
point. This matters when lines at window top and lines
int start_y = line_bottom_y (&it1);
do {
- move_it_by_lines (&it, 1, 1);
+ move_it_by_lines (&it, 1);
it1 = it;
} while (line_bottom_y (&it1) - start_y < amount_to_scroll);
}
/* If STARTP is unchanged, move it down another screen line. */
if (CHARPOS (it.current.pos) == CHARPOS (startp))
- move_it_by_lines (&it, 1, 1);
+ move_it_by_lines (&it, 1);
startp = it.current.pos;
}
else
{
/* Point is in the scroll margin at the top of the window or
above what is displayed in the window. */
- int y0;
+ int y0, y_to_move;
/* Compute the vertical distance from PT to the scroll
- margin position. Give up if distance is greater than
- scroll_max. */
+ margin position. Move as far as scroll_max allows, or
+ one screenful, or 10 screen lines, whichever is largest.
+ Give up if distance is greater than scroll_max. */
SET_TEXT_POS (pos, PT, PT_BYTE);
start_display (&it, w, pos);
y0 = it.current_y;
+ y_to_move = max (it.last_visible_y,
+ max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)));
move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
- it.last_visible_y, -1,
+ y_to_move, -1,
MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
dy = it.current_y - y0;
if (dy > scroll_max)
start_display (&it, w, startp);
if (arg_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
amount_to_scroll = float_amount;
if (amount_to_scroll == 0 && float_amount > 0)
amount_to_scroll = 1;
+ amount_to_scroll -=
+ this_scroll_margin - dy - FRAME_LINE_HEIGHT (f);
+ /* Don't let point enter the scroll margin near
+ bottom of the window. */
+ if (amount_to_scroll > height - 2*this_scroll_margin + dy)
+ amount_to_scroll = height - 2*this_scroll_margin + dy;
}
}
{
min_distance = distance;
pos = it.current.pos;
- move_it_by_lines (&it, 1, 0);
+ move_it_by_lines (&it, 1);
}
/* Set the window start there. */
&& row < w->current_matrix->rows
+ w->current_matrix->nrows - 1
&& MATRIX_ROW_START_CHARPOS (row+1) == PT
- && !cursor_row_p (w, row))
+ && !cursor_row_p (row))
++row;
/* If within the scroll margin, scroll. Note that
skip forward over overlay strings. */
while (MATRIX_ROW_BOTTOM_Y (row) < last_y
&& MATRIX_ROW_END_CHARPOS (row) == PT
- && !cursor_row_p (w, row))
+ && !cursor_row_p (row))
++row;
/* If within the scroll margin, scroll. */
{
if (MATRIX_ROW_START_CHARPOS (row) <= PT
&& PT <= MATRIX_ROW_END_CHARPOS (row)
- && cursor_row_p (w, row))
+ && cursor_row_p (row))
rv |= set_cursor_from_row (w, row, w->current_matrix,
0, 0, 0, 0);
/* As soon as we've found the first suitable row
}
while (MATRIX_ROW_BOTTOM_Y (row) < last_y
&& MATRIX_ROW_START_CHARPOS (row) == PT
- && cursor_row_p (w, row));
+ && cursor_row_p (row));
}
}
}
|| temp_scroll_step
|| NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
|| NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
- && !current_buffer->clip_changed
&& CHARPOS (startp) >= BEGV
&& CHARPOS (startp) <= ZV)
{
}
}
- /* Finally, just choose place to start which centers point */
+ /* Finally, just choose a place to start which positions point
+ according to user preferences. */
recenter:
- if (centering_position < 0)
- centering_position = window_box_height (w) / 2;
#if GLYPH_DEBUG
debug_method_add (w, "recenter");
if (!buffer_unchanged_p)
w->base_line_number = Qnil;
- /* Move backward half the height of the window. */
+ /* Determine the window start relative to point. */
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
it.current_y = it.last_visible_y;
+ if (centering_position < 0)
+ {
+ int margin =
+ scroll_margin > 0
+ ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)
+ : 0;
+ EMACS_INT margin_pos = CHARPOS (startp);
+ int scrolling_up;
+ Lisp_Object aggressive;
+
+ /* If there is a scroll margin at the top of the window, find
+ its character position. */
+ if (margin)
+ {
+ struct it it1;
+
+ start_display (&it1, w, startp);
+ move_it_vertically (&it1, margin);
+ margin_pos = IT_CHARPOS (it1);
+ }
+ scrolling_up = PT > margin_pos;
+ aggressive =
+ scrolling_up
+ ? BVAR (current_buffer, scroll_up_aggressively)
+ : BVAR (current_buffer, scroll_down_aggressively);
+
+ if (!MINI_WINDOW_P (w)
+ && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
+ {
+ int pt_offset = 0;
+
+ /* Setting scroll-conservatively overrides
+ scroll-*-aggressively. */
+ if (!scroll_conservatively && NUMBERP (aggressive))
+ {
+ double float_amount = XFLOATINT (aggressive);
+
+ pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
+ if (pt_offset == 0 && float_amount > 0)
+ pt_offset = 1;
+ if (pt_offset)
+ margin -= 1;
+ }
+ /* Compute how much to move the window start backward from
+ point so that point will be displayed where the user
+ wants it. */
+ if (scrolling_up)
+ {
+ centering_position = it.last_visible_y;
+ if (pt_offset)
+ centering_position -= pt_offset;
+ centering_position -=
+ FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0));
+ /* Don't let point enter the scroll margin near top of
+ the window. */
+ if (centering_position < margin * FRAME_LINE_HEIGHT (f))
+ centering_position = margin * FRAME_LINE_HEIGHT (f);
+ }
+ else
+ centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset;
+ }
+ else
+ /* Set the window start half the height of the window backward
+ from point. */
+ centering_position = window_box_height (w) / 2;
+ }
move_it_vertically_backward (&it, centering_position);
+
xassert (IT_CHARPOS (it) >= BEGV);
/* The function move_it_vertically_backward may move over more
it.current_x = it.hpos = 0;
- /* Set startp here explicitly in case that helps avoid an infinite loop
- in case the window-scroll-functions functions get errors. */
+ /* Set the window start position here explicitly, to avoid an
+ infinite loop in case the functions in window-scroll-functions
+ get errors. */
set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
/* Run scroll hooks. */
&& PT >= Z - XFASTINT (w->window_end_pos))
{
clear_glyph_matrix (w->desired_matrix);
- move_it_by_lines (&it, 1, 0);
+ move_it_by_lines (&it, 1);
try_window (window, it.current.pos, 0);
}
else if (PT < IT_CHARPOS (it))
{
clear_glyph_matrix (w->desired_matrix);
- move_it_by_lines (&it, -1, 0);
+ move_it_by_lines (&it, -1);
try_window (window, it.current.pos, 0);
}
else
if (CHARPOS (new_start) <= CHARPOS (start))
{
- int first_row_y;
-
/* Don't use this method if the display starts with an ellipsis
displayed for invisible text. It's not easy to handle that case
below, and it's certainly not worth the effort since this is
text. Note that it.vpos == 0 if or if not there is a
header-line; it's not the same as the MATRIX_ROW_VPOS! */
start_display (&it, w, new_start);
- first_row_y = it.current_y;
w->cursor.vpos = -1;
last_text_row = last_reused_text_row = NULL;
DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
doc: /* Like `format', but print result to stderr.
usage: (trace-to-stderr STRING &rest OBJECTS) */)
- (int nargs, Lisp_Object *args)
+ (size_t nargs, Lisp_Object *args)
{
Lisp_Object s = Fformat (nargs, args);
fprintf (stderr, "%s", SDATA (s));
}
-/* Value is non-zero if glyph row ROW in window W should be
+/* Value is non-zero if glyph row ROW should be
used to hold the cursor. */
static int
-cursor_row_p (struct window *w, struct glyph_row *row)
+cursor_row_p (struct glyph_row *row)
{
int result = 1;
&& !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
&& PT >= MATRIX_ROW_START_CHARPOS (row)
&& PT <= MATRIX_ROW_END_CHARPOS (row)
- && cursor_row_p (it->w, row))
+ && cursor_row_p (row))
set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
/* Highlight trailing whitespace. */
charpos = (STRING_MULTIBYTE (elt)
? string_byte_to_char (elt, bytepos)
: bytepos);
- spec = decode_mode_spec (it->w, c, field, prec, &string);
+ spec = decode_mode_spec (it->w, c, field, &string);
multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
switch (mode_line_target)
static const char power_letter[] =
{
- 0, /* not used */
+ 0, /* no letter */
'k', /* kilo */
'M', /* mega */
'G', /* giga */
p = psuffix = buf + max (width, length);
/* Print EXPONENT. */
- if (exponent)
- *psuffix++ = power_letter[exponent];
+ *psuffix++ = power_letter[exponent];
*psuffix = '\0';
/* Print TENTHS. */
}
/* Return a string for the output of a mode line %-spec for window W,
- 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 a Lisp string in
+ generated by character C. FIELD_WIDTH > 0 means pad the string
+ returned with spaces to that value. Return a Lisp string in
*STRING if the resulting string is taken from that Lisp string.
Note we operate on the current buffer for most purposes,
static const char *
decode_mode_spec (struct window *w, register int c, int field_width,
- int precision, Lisp_Object *string)
+ Lisp_Object *string)
{
Lisp_Object obj;
struct frame *f = XFRAME (WINDOW_FRAME (w));
}
/* Count lines from base line to window start position. */
- nlines = display_count_lines (linepos, linepos_byte,
+ nlines = display_count_lines (linepos_byte,
startpos_byte,
startpos, &junk);
limit_byte = CHAR_TO_BYTE (limit);
}
- nlines = display_count_lines (startpos, startpos_byte,
+ nlines = display_count_lines (startpos_byte,
limit_byte,
- (height * 2 + 30),
&position);
}
/* Now count lines from the start pos to point. */
- nlines = display_count_lines (startpos, startpos_byte,
+ nlines = display_count_lines (startpos_byte,
PT_BYTE, PT, &junk);
/* Record that we did display the line number. */
}
-/* Count up to COUNT lines starting from START / START_BYTE.
+/* Count up to COUNT lines starting from START_BYTE.
But don't go beyond LIMIT_BYTE.
Return the number of lines thus found (always nonnegative).
Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
static int
-display_count_lines (EMACS_INT start, EMACS_INT start_byte,
+display_count_lines (EMACS_INT start_byte,
EMACS_INT limit_byte, int count,
EMACS_INT *byte_pos_ptr)
{
}
-/* Get face and two-byte form of character C in face FACE_ID on frame
- F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
- means we want to display multibyte text. DISPLAY_P non-zero means
+/* Get face and two-byte form of character C in face FACE_ID on frame F.
+ The encoding of C is returned in *CHAR2B. DISPLAY_P non-zero means
make sure that X resources for the face returned are allocated.
Value is a pointer to a realized face that is ready for display if
DISPLAY_P is non-zero. */
static INLINE struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
- XChar2b *char2b, int multibyte_p, int display_p)
+ XChar2b *char2b, int display_p)
{
struct face *face = FACE_FROM_ID (f, face_id);
-1, Qnil);
face = get_char_face_and_encoding (s->f, c, face_id,
- s->char2b + i, 1, 1);
+ s->char2b + i, 1);
if (face)
{
if (! s->face)
/* Fill glyph string S from a sequence of stretch glyphs.
- ROW is the glyph row in which the glyphs are found, AREA is the
- area within the row. START is the index of the first glyph to
- consider, END is the index of the last + 1.
+ START is the index of the first glyph to consider,
+ END is the index of the last + 1.
Value is the index of the first glyph not in S. */
static int
-fill_stretch_glyph_string (struct glyph_string *s, struct glyph_row *row,
- enum glyph_row_area area, int start, int end)
+fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
{
struct glyph *glyph, *last;
int voffset, face_id;
}
static struct font_metrics *
-get_per_char_metric (struct frame *f, struct font *font, XChar2b *char2b)
+get_per_char_metric (struct font *font, XChar2b *char2b)
{
static struct font_metrics metrics;
unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
struct font_metrics *pcm;
face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
- if (face->font && (pcm = get_per_char_metric (f, face->font, &char2b)))
+ if (face->font && (pcm = get_per_char_metric (face->font, &char2b)))
{
if (pcm->rbearing > pcm->width)
*right = pcm->rbearing - pcm->width;
{ \
s = (struct glyph_string *) alloca (sizeof *s); \
INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
- START = fill_stretch_glyph_string (s, row, area, START, END); \
+ START = fill_stretch_glyph_string (s, START, END); \
append_glyph_string (&HEAD, &TAIL, s); \
s->x = (X); \
} \
if (get_char_glyph_code (it->char_to_display, font, &char2b))
{
- pcm = get_per_char_metric (it->f, font, &char2b);
+ pcm = get_per_char_metric (font, &char2b);
if (pcm->width == 0
&& pcm->rbearing == 0 && pcm->lbearing == 0)
pcm = NULL;
if (! font_not_found_p)
{
get_char_face_and_encoding (it->f, c, it->face_id,
- &char2b, it->multibyte_p, 0);
- pcm = get_per_char_metric (it->f, font, &char2b);
+ &char2b, 0);
+ pcm = get_per_char_metric (font, &char2b);
}
/* Initialize the bounding box. */
int ch = COMPOSITION_GLYPH (cmp, i);
int face_id;
struct face *this_face;
- int this_boff;
if (ch == '\t')
ch = ' ';
pcm = NULL;
else
{
- this_boff = font->baseline_offset;
- if (font->vertical_centering)
- this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
get_char_face_and_encoding (it->f, ch, face_id,
- &char2b, it->multibyte_p, 0);
- pcm = get_per_char_metric (it->f, font, &char2b);
+ &char2b, 0);
+ pcm = get_per_char_metric (font, &char2b);
}
if (! pcm)
cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
END_CHARPOS, or if they come from an overlay. */
if (EQ (glyph->object, before_string))
{
- pos = string_buffer_position (w, before_string,
+ pos = string_buffer_position (before_string,
start_charpos);
/* If pos == 0, it means before_string came from an
overlay, not from a buffer position. */
}
else if (EQ (glyph->object, after_string))
{
- pos = string_buffer_position (w, after_string, end_charpos);
+ pos = string_buffer_position (after_string, end_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
END_CHARPOS, or if they come from an overlay. */
if (EQ (glyph->object, before_string))
{
- pos = string_buffer_position (w, before_string, start_charpos);
+ pos = string_buffer_position (before_string, start_charpos);
/* If pos == 0, it means before_string came from an
overlay, not from a buffer position. */
if (!pos || (pos >= start_charpos && pos < end_charpos))
}
else if (EQ (glyph->object, after_string))
{
- pos = string_buffer_position (w, after_string, end_charpos);
+ pos = string_buffer_position (after_string, end_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
END_CHARPOS, or if they come from an overlay. */
if (EQ (end->object, before_string))
{
- pos = string_buffer_position (w, before_string, start_charpos);
+ pos = string_buffer_position (before_string, start_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
else if (EQ (end->object, after_string))
{
- pos = string_buffer_position (w, after_string, end_charpos);
+ pos = string_buffer_position (after_string, end_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
END_CHARPOS, or if they come from an overlay. */
if (EQ (end->object, before_string))
{
- pos = string_buffer_position (w, before_string, start_charpos);
+ pos = string_buffer_position (before_string, start_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
else if (EQ (end->object, after_string))
{
- pos = string_buffer_position (w, after_string, end_charpos);
+ pos = string_buffer_position (after_string, end_charpos);
if (!pos || (pos >= start_charpos && pos < end_charpos))
break;
}
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
{
- Lisp_Object area_id, plist;
+ Lisp_Object plist;
- area_id = XCAR (hotspot);
- /* Could check AREA_ID to see if we enter/leave this hot-spot.
+ /* Could check XCAR (hotspot) 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...). */
hotspot = XCDR (hotspot);
CONSP (hotspot))
&& (hotspot = XCDR (hotspot), CONSP (hotspot)))
{
- Lisp_Object area_id, plist;
+ Lisp_Object plist;
- area_id = XCAR (hotspot);
- /* Could check AREA_ID to see if we enter/leave this hot-spot.
+ /* Could check XCAR (hotspot) 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...). */
hotspot = XCDR (hotspot);
check if the text under it has one. */
struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
- pos = string_buffer_position (w, object, start);
+ pos = string_buffer_position (object, start);
if (pos > 0)
{
mouse_face = get_char_property_and_overlay
struct glyph_row *r
= MATRIX_ROW (w->current_matrix, vpos);
EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
- EMACS_INT p = string_buffer_position (w, obj, start);
+ EMACS_INT p = string_buffer_position (obj, start);
if (p > 0)
{
help = Fget_char_property (make_number (p),
struct glyph_row *r
= MATRIX_ROW (w->current_matrix, vpos);
EMACS_INT start = MATRIX_ROW_START_CHARPOS (r);
- EMACS_INT p = string_buffer_position (w, obj, start);
+ EMACS_INT p = string_buffer_position (obj, start);
if (p > 0)
pointer = Fget_char_property (make_number (p),
Qpointer, w->buffer);
onto the screen again. If that cannot be done, then redisplay
recenters point as usual.
+If the value is greater than 100, redisplay will never recenter point,
+but will always scroll just enough text to bring point into view, even
+if you move far away.
+
A value of zero means always recenter point if it moves off screen. */);
scroll_conservatively = 0;