if (XINT (w->hscroll) != hscroll)
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
- w->hscroll = w->min_hscroll = make_number (hscroll);
+ w->hscroll = make_number (hscroll);
return ncol;
}
This is updated by redisplay, when it runs to completion.\n\
Simply changing the buffer text or setting `window-start'\n\
does not update this value.\n\
-If UP-TO-DATE is non-nil, compute the up-to-date position\n\
+If UPDATE is non-nil, compute the up-to-date position\n\
if it isn't already recorded.")
(window, update)
Lisp_Object window, update;
cope with variable-height lines. */
start_display (&it, w, startp);
move_it_vertically (&it, window_box_height (w));
+ move_it_past_eol (&it);
value = make_number (IT_CHARPOS (it));
}
else
Qnil, look at just the selected frame;
Qvisible, look at visible frames;
a frame, just look at windows on that frame.
- If MINI is non-zero, perform the operation on minibuffer windows too.
-*/
+ If MINI is non-zero, perform the operation on minibuffer windows too. */
enum window_loop
{
{
struct window *w;
int startpos;
- int top;
+ int top, new_top;
if (NILP (window))
window = selected_window;
else
CHECK_LIVE_WINDOW (window, 0);
-
w = XWINDOW (window);
startpos = marker_position (w->start);
on the frame. But don't try to do this if the window start is
outside the visible portion (as might happen when the display is
not current, due to typeahead). */
- if (startpos >= BUF_BEGV (XBUFFER (w->buffer))
+ new_top = XFASTINT (w->top) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
+ if (new_top != top
+ && startpos >= BUF_BEGV (XBUFFER (w->buffer))
&& startpos <= BUF_ZV (XBUFFER (w->buffer)))
{
struct position pos;
pos = *vmotion (startpos, -top, w);
set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+ w->window_end_valid = Qnil;
w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
|| FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
: Qnil);
/* Maybe delete WINDOW if it's too small. */
if (!nodelete_p && !NILP (w->parent))
{
- int min_size;
-
if (!MINI_WINDOW_P (w) && !NILP (w->too_small_ok))
min_size = width_p ? MIN_SAFE_WINDOW_WIDTH : MIN_SAFE_WINDOW_HEIGHT;
else
{
if (it.current_y + it.max_ascent + it.max_descent
> it.last_visible_y)
- /* The last line was only partially visible, make it fully
- visible. */
- w->vscroll = (it.last_visible_y
- - it.current_y + it.max_ascent + it.max_descent);
+ {
+ /* The last line was only partially visible, make it fully
+ visible. */
+ w->vscroll = (it.last_visible_y
+ - it.current_y + it.max_ascent + it.max_descent);
+ adjust_glyphs (it.f);
+ }
else if (noerror)
return;
else
(arg)
register Lisp_Object arg;
{
-
+ Lisp_Object result;
+ int hscroll;
+ struct window *w = XWINDOW (selected_window);
+
if (NILP (arg))
- XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+ XSETFASTINT (arg, window_internal_width (w) - 2);
else
arg = Fprefix_numeric_value (arg);
- return
- Fset_window_hscroll (selected_window,
- make_number (XINT (XWINDOW (selected_window)->hscroll)
- + XINT (arg)));
+ hscroll = XINT (w->hscroll) + XINT (arg);
+ result = Fset_window_hscroll (selected_window, make_number (hscroll));
+
+ if (!NILP (Finteractive_p ()))
+ w->min_hscroll = w->hscroll;
+
+ return result;
}
DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 1, "P",
(arg)
register Lisp_Object arg;
{
+ Lisp_Object result;
+ int hscroll;
+ struct window *w = XWINDOW (selected_window);
+
if (NILP (arg))
- XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+ XSETFASTINT (arg, window_internal_width (w) - 2);
else
arg = Fprefix_numeric_value (arg);
- return
- Fset_window_hscroll (selected_window,
- make_number (XINT (XWINDOW (selected_window)->hscroll)
- - XINT (arg)));
-}
-
-DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
- "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
-The desired position of point is always relative to the current window.\n\
-Just C-u as prefix means put point in the center of the window.\n\
-If ARG is omitted or nil, erases the entire frame and then\n\
-redraws with point in the center of the current window.")
- (arg)
- register Lisp_Object arg;
-{
- register struct window *w = XWINDOW (selected_window);
- register int ht = window_internal_height (w);
- struct position pos;
- struct buffer *buf = XBUFFER (w->buffer);
- struct buffer *obuf = current_buffer;
-
- if (NILP (arg))
- {
- extern int frame_garbaged;
- int i;
-
- /* Invalidate pixel data calculated for all compositions. */
- for (i = 0; i < n_compositions; i++)
- composition_table[i]->font = NULL;
-
- Fredraw_frame (w->frame);
- SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
- XSETFASTINT (arg, ht / 2);
- }
- else if (CONSP (arg)) /* Just C-u. */
- {
- XSETFASTINT (arg, ht / 2);
- }
- else
- {
- arg = Fprefix_numeric_value (arg);
- CHECK_NUMBER (arg, 0);
- }
-
- if (XINT (arg) < 0)
- XSETINT (arg, XINT (arg) + ht);
-
- set_buffer_internal (buf);
- pos = *vmotion (PT, - XINT (arg), w);
-
- set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
- w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
- || FETCH_BYTE (pos.bytepos - 1) == '\n')
- ? Qt : Qnil);
- w->force_start = Qt;
- set_buffer_internal (obuf);
+ hscroll = XINT (w->hscroll) - XINT (arg);
+ result = Fset_window_hscroll (selected_window, make_number (hscroll));
+
+ if (!NILP (Finteractive_p ()))
+ w->min_hscroll = w->hscroll;
- return Qnil;
+ return result;
}
-
/* Value is the number of lines actually displayed in window W,
as opposed to its height. */
}
+DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
+ "Center point in window and redisplay frame.\n\
+With prefix argument ARG, recenter putting point on screen line ARG\n\
+relative to the current window. If ARG is negative, it counts up from the\n\
+bottom of the window. (ARG should be less than the height of the window.)\n\
+\n\
+If ARG is omitted or nil, erase the entire frame and then\n\
+redraw with point in the center of the current window.\n\
+Just C-u as prefix means put point in the center of the window\n\
+and redisplay normally--don't erase and redraw the frame.")
+ (arg)
+ register Lisp_Object arg;
+{
+ struct window *w = XWINDOW (selected_window);
+ struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *obuf = current_buffer;
+ int center_p = 0;
+ int charpos, bytepos;
+
+ if (NILP (arg))
+ {
+ int i;
+
+ /* Invalidate pixel data calculated for all compositions. */
+ for (i = 0; i < n_compositions; i++)
+ composition_table[i]->font = NULL;
+
+ Fredraw_frame (w->frame);
+ SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w)));
+ center_p = 1;
+ }
+ else if (CONSP (arg)) /* Just C-u. */
+ center_p = 1;
+ else
+ {
+ arg = Fprefix_numeric_value (arg);
+ CHECK_NUMBER (arg, 0);
+ }
+
+ set_buffer_internal (buf);
+
+ /* Handle centering on a gfaphical frame specially. Such frames can
+ have variable-height lines and centering point on the basis of
+ line counts would lead to strange effects. */
+ if (center_p && FRAME_WINDOW_P (XFRAME (w->frame)))
+ {
+ struct it it;
+ struct text_pos pt;
+
+ SET_TEXT_POS (pt, PT, PT_BYTE);
+ start_display (&it, w, pt);
+ move_it_vertically (&it, - it.last_visible_y / 2);
+ charpos = IT_CHARPOS (it);
+ bytepos = IT_BYTEPOS (it);
+ }
+ else
+ {
+ struct position pos;
+
+ if (center_p)
+ {
+ int ht = displayed_window_lines (w);
+ arg = make_number (ht / 2);
+ }
+ else if (XINT (arg) < 0)
+ {
+ int ht = displayed_window_lines (w);
+ XSETINT (arg, XINT (arg) + ht);
+ }
+
+ pos = *vmotion (PT, - XINT (arg), w);
+ charpos = pos.bufpos;
+ bytepos = pos.bytepos;
+ }
+
+ /* Set the new window start. */
+ set_marker_both (w->start, w->buffer, charpos, bytepos);
+ w->window_end_valid = Qnil;
+ w->force_start = Qt;
+ if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
+ w->start_at_line_beg = Qt;
+ else
+ w->start_at_line_beg = Qnil;
+
+ set_buffer_internal (obuf);
+ return Qnil;
+}
+
+
DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
0, 1, 0,
"Return the height in lines of the text display area of WINDOW.\n\