of the top or bottom of the window. */
int scroll_margin;
+/* Number of characters of overlap to show,
+ when scrolling a one-line window such as a minibuffer. */
+static int minibuffer_scroll_overlap;
+
/* Nonzero if try_window_id has made blank lines at window bottom
since the last redisplay that paused */
static int blank_end_of_window;
struct buffer *oldbuf;
int oldpoint, oldbegv, oldzv;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
+ int point_at_end = 0;
+ int zv_at_end = 0;
oldbuf = current_buffer;
Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
BEGV = BEG;
ZV = Z;
if (oldpoint == Z)
- oldpoint += len + nlflag;
+ point_at_end = 1;
if (oldzv == Z)
- oldzv += len + nlflag;
+ zv_at_end = 1;
TEMP_SET_PT (Z);
- if (len)
+
+ /* Insert the string--maybe converting multibyte to single byte
+ or vice versa, so that all the text fits the buffer. */
+ if (! NILP (oldbuf->enable_multibyte_characters)
+ && NILP (current_buffer->enable_multibyte_characters))
+ {
+ int c, i = 0, nbytes;
+ /* Convert a multibyte string to single-byte
+ for the *Message* buffer. */
+ while (i < len)
+ {
+ c = STRING_CHAR (m + i, len - i);
+ i += XFASTINT (Fchar_bytes (make_number (c)));
+ /* Truncate the character to its last byte--we can only hope
+ the user is happy with the character he gets,
+ since if it isn't right, there is no way to do it right. */
+ c &= 0xff;
+ insert_char (c);
+ }
+ }
+ else if (NILP (oldbuf->enable_multibyte_characters)
+ && ! NILP (current_buffer->enable_multibyte_characters))
+ {
+ int c, i = 0;
+ /* Convert a single-byte string to multibyte
+ for the *Message* buffer. */
+ while (i < len)
+ {
+ c = m[i++];
+ /* Convert non-ascii chars as if for self-insert. */
+ if (c >= 0200 && c <= 0377)
+ c += nonascii_insert_offset;
+ insert_char (c);
+ }
+ }
+ else if (len)
insert_1 (m, len, 1, 0);
+
if (nlflag)
{
int this_bol, prev_bol, dup;
}
}
BEGV = oldbegv;
- ZV = oldzv;
- TEMP_SET_PT (oldpoint);
+ if (zv_at_end)
+ ZV = Z;
+ else
+ ZV = oldzv;
+ if (point_at_end)
+ TEMP_SET_PT (Z);
+ else
+ TEMP_SET_PT (oldpoint);
set_buffer_internal (oldbuf);
windows_or_buffers_changed = old_windows_or_buffers_changed;
message_log_need_newline = !nlflag;
{
int len;
#ifdef NO_ARG_ARRAY
- EMACS_INT a[3];
- a[0] = a1;
- a[1] = a2;
- a[2] = a3;
+ char *a[3];
+ a[0] = (char *) a1;
+ a[1] = (char *) a2;
+ a[2] = (char *) a3;
len = doprnt (FRAME_MESSAGE_BUF (f),
FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
area to be cleared. See tracking_off and
wait_reading_process_input for examples of these situations. */
+void
redisplay_preserve_echo_area ()
{
if (echo_area_glyphs == 0 && previous_echo_glyphs != 0)
w->base_line_number = Qnil;
pos = *vmotion (PT, - (height / 2), w);
+
+ /* The minibuffer is often just one line. Ordinary scrolling
+ gives little overlap and looks bad. So show 20 chars before point. */
+ if (height == 1
+ && (pos.bufpos >= PT - minibuffer_scroll_overlap
+ /* If we scrolled less than 1/2 line forward, we will
+ get too much overlap, so change to the usual amount. */
+ || pos.bufpos < startp + width / 2)
+ && PT > BEGV + minibuffer_scroll_overlap
+ /* If we scrolled to an actual line boundary,
+ that's different; don't ignore line boundaries. */
+ && FETCH_CHAR (pos.bufpos - 1) != '\n')
+ pos.bufpos = PT - minibuffer_scroll_overlap;
+
/* Set startp here explicitly in case that helps avoid an infinite loop
in case the window-scroll-functions functions get errors. */
Fset_marker (w->start, make_number (pos.bufpos), Qnil);
&& !WINDOW_FULL_WIDTH_P (w))
|| !NILP (current_buffer->truncate_lines));
- /* 1 if we should highlight the region. */
+ /* 1 if this buffer has a region to highlight. */
int highlight_region
= (!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active)
- && (XWINDOW (current_buffer->last_selected_window) == w
- || highlight_nonselected_windows));
+ && XMARKER (current_buffer->mark)->buffer != 0);
int region_beg, region_end;
int selective = (INTEGERP (current_buffer->selective_display)
if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
/* Show where to highlight the region. */
- if (highlight_region && XMARKER (current_buffer->mark)->buffer != 0
+ if (highlight_region
/* Maybe highlight only in selected window. */
&& (highlight_nonselected_windows
- || w == XWINDOW (selected_window)))
+ || w == XWINDOW (selected_window)
+ || (MINI_WINDOW_P (XWINDOW (selected_window))
+ && w == XWINDOW (Vminibuf_scroll_window))))
{
region_beg = marker_position (current_buffer->mark);
if (PT < region_beg)
Vwindow_size_change_functions = Qnil;
DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
- "List of Functions to call before redisplaying a window with scrolling.\n\
+ "List of functions to call before redisplaying a window with scrolling.\n\
Each function is called with two arguments, the window\n\
and its new display-start position. Note that the value of `window-end'\n\
is not valid when these functions are called.");
Vwindow_scroll_functions = Qnil;
+
+ DEFVAR_INT ("minibuffer-scroll-overlap", &minibuffer_scroll_overlap,
+ "*Number of characters of overlap when scrolling a one-line window.\n\
+This commonly affects the minibuffer window, hence the name of the variable.");
+ minibuffer_scroll_overlap = 20;
}
/* initialize the window system */