/* Nonzero means print newline to message log before next message. */
-int message_log_need_newline;
+static int message_log_need_newline;
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
/* Like mode-line-format, but for the titlebar on an iconified frame. */
Lisp_Object Vicon_title_format;
+/* List of functions to call when a window's size changes. These
+ functions get one arg, a frame on which one or more windows' sizes
+ have changed. */
+static Lisp_Object Vwindow_size_change_functions;
+
/* Values of those variables at last redisplay. */
static Lisp_Object last_arrow_position, last_arrow_string;
/* If cursor motion alone moves point off frame,
Try scrolling this many lines up or down if that will bring it back. */
-int scroll_step;
+static int scroll_step;
/* Nonzero if try_window_id has made blank lines at window bottom
since the last redisplay that paused */
static int cursor_vpos;
static int cursor_hpos;
-int debug_end_pos;
+static int debug_end_pos;
/* Nonzero means display mode line highlighted */
int mode_line_inverse_video;
+static int message_log_check_duplicate ();
static void echo_area_display ();
void mark_window_display_accurate ();
static void redisplay_windows ();
int line_number_displayed;
/* Maximum buffer size for which to display line numbers. */
-int line_number_display_limit;
+static int line_number_display_limit;
/* Number of lines to keep in the message log buffer.
t means infinite. nil means don't log at all. */
Lisp_Object Vmessage_log_max;
\f
+void
+message_log_maybe_newline ()
+{
+ if (message_log_need_newline)
+ message_dolog ("", 0, 1);
+}
+
+
/* Add a string to the message log, optionally terminated with a newline.
This function calls low-level routines in order to bypass text property
hooks, etc. which might not be safe to run. */
int oldpoint, oldbegv, oldzv;
oldbuf = current_buffer;
- Fset_buffer (Fget_buffer_create (build_string (" *Messages*")));
+ Fset_buffer (Fget_buffer_create (build_string ("*Messages*")));
+ current_buffer->undo_list = Qt;
oldpoint = PT;
oldbegv = BEGV;
oldzv = ZV;
if (len)
insert_1 (m, len, 1, 0);
if (nlflag)
- insert_1 ("\n", 1, 1, 0);
- if (NATNUMP (Vmessage_log_max))
{
- int pos = scan_buffer ('\n', PT, 0,
- -XFASTINT (Vmessage_log_max) - 1, 0, 1);
- oldpoint -= min (pos, oldpoint) - BEG;
- oldbegv -= min (pos, oldbegv) - BEG;
- oldzv -= min (pos, oldzv) - BEG;
- del_range_1 (BEG, pos, 0);
+ int this_bol, prev_bol, dup;
+ insert_1 ("\n", 1, 1, 0);
+
+ this_bol = scan_buffer ('\n', Z, 0, -2, 0, 0);
+ if (this_bol > BEG)
+ {
+ prev_bol = scan_buffer ('\n', this_bol, 0, -2, 0, 0);
+ dup = message_log_check_duplicate (prev_bol, this_bol);
+ if (dup)
+ {
+ if (oldpoint > prev_bol)
+ oldpoint -= min (this_bol, oldpoint) - prev_bol;
+ if (oldbegv > prev_bol)
+ oldbegv -= min (this_bol, oldbegv) - prev_bol;
+ if (oldzv > prev_bol)
+ oldzv -= min (this_bol, oldzv) - prev_bol;
+ del_range_1 (prev_bol, this_bol, 0);
+ if (dup > 1)
+ {
+ char dupstr[40];
+ int duplen;
+
+ /* If you change this format, don't forget to also
+ change message_log_check_duplicate. */
+ sprintf (dupstr, " [%d times]", dup);
+ duplen = strlen (dupstr);
+ TEMP_SET_PT (Z-1);
+ if (oldpoint == Z)
+ oldpoint += duplen;
+ if (oldzv == Z)
+ oldzv += duplen;
+ insert_1 (dupstr, duplen, 1, 0);
+ }
+ }
+ }
+
+ if (NATNUMP (Vmessage_log_max))
+ {
+ int pos = scan_buffer ('\n', Z, 0,
+ -XFASTINT (Vmessage_log_max) - 1, 0, 0);
+ oldpoint -= min (pos, oldpoint) - BEG;
+ oldbegv -= min (pos, oldbegv) - BEG;
+ oldzv -= min (pos, oldzv) - BEG;
+ del_range_1 (BEG, pos, 0);
+ }
}
BEGV = oldbegv;
ZV = oldzv;
TEMP_SET_PT (oldpoint);
set_buffer_internal (oldbuf);
+ message_log_need_newline = !nlflag;
}
}
+/* We are at the end of the buffer after just having inserted a newline.
+ (Note: We depend on the fact we won't be crossing the gap.)
+ Check to see if the most recent message looks a lot like the previous one.
+ 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 (prev_bol, this_bol)
+ int prev_bol, this_bol;
+{
+ int i;
+ int len = Z - 1 - this_bol;
+ int seen_dots = 0;
+ unsigned char *p1 = BUF_CHAR_ADDRESS (current_buffer, prev_bol);
+ unsigned char *p2 = BUF_CHAR_ADDRESS (current_buffer, this_bol);
+
+ for (i = 0; i < len; i++)
+ {
+ if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.'
+ && p1[i] != '\n')
+ seen_dots = 1;
+ if (p1[i] != p2[i])
+ return seen_dots;
+ }
+ p1 += len;
+ if (*p1 == '\n')
+ return 2;
+ if (*p1++ == ' ' && *p1++ == '[')
+ {
+ int n = 0;
+ while (*p1 >= '0' && *p1 <= '9')
+ n = n * 10 + *p1++ - '0';
+ if (strncmp (p1, " times]\n", 8) == 0)
+ return n+1;
+ }
+ return 0;
+}
+
/* Display an echo area message M with a specified length of LEN chars.
The string may include null characters. If m is 0, clear out any
existing message, and let the minibuffer text show through.
int len;
{
/* First flush out any partial line written with print. */
- if (message_log_need_newline)
- message_dolog ("", 0, 1);
- message_log_need_newline = 0;
+ message_log_maybe_newline ();
if (m)
message_dolog (m, len, 1);
message2_nolog (m, len);
}
}
+/* The non-logging version of that function. */
+void
+message_nolog (m, a1, a2, a3)
+ char *m;
+ EMACS_INT a1, a2, a3;
+{
+ Lisp_Object old_log_max;
+ old_log_max = Vmessage_log_max;
+ Vmessage_log_max = Qnil;
+ message (m, a1, a2, a3);
+ Vmessage_log_max = old_log_max;
+}
+
void
update_echo_area ()
{
0, 0, 0, 0, FRAME_WIDTH (f));
/* If desired cursor location is on this line, put it at end of text */
+ if (cursor_in_echo_area)
+ FRAME_CURSOR_Y (f) = vpos;
if (FRAME_CURSOR_Y (f) == vpos)
FRAME_CURSOR_X (f) = FRAME_DESIRED_GLYPHS (f)->used[vpos];
#endif
\f
/* Prepare for redisplay by updating menu-bar item lists when appropriate.
- This can't be done in `redisplay' itself because it can call eval. */
+ This can call eval. */
void
prepare_menu_bars ()
{
register struct window *w = XWINDOW (selected_window);
int all_windows;
+ struct gcpro gcpro1, gcpro2;
- if (noninteractive)
- return;
-
- /* Set the visible flags for all frames.
- Do this before checking for resized or garbaged frames; they want
- to know if their frames are visible.
- See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
- {
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
- }
-
- /* Notice any pending interrupt request to change frame size. */
- do_pending_window_change ();
+ all_windows = (update_mode_lines || buffer_shared > 1
+ || clip_changed || windows_or_buffers_changed);
- if (frame_garbaged)
+ /* Update the menu bar item lists, if appropriate.
+ This has to be done before any actual redisplay
+ or generation of display lines. */
+ if (all_windows)
{
- redraw_garbaged_frames ();
- frame_garbaged = 0;
- }
+ Lisp_Object tail, frame;
- all_windows = (update_mode_lines || buffer_shared > 1
- || clip_changed || windows_or_buffers_changed);
+ FOR_EACH_FRAME (tail, frame)
+ {
+ /* If a window on this frame changed size,
+ report that to the user and clear the size-change flag. */
+ if (FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame)))
+ {
+ Lisp_Object functions;
+ /* Clear flag first in case we get error below. */
+ FRAME_WINDOW_SIZES_CHANGED (XFRAME (frame)) = 0;
+ functions = Vwindow_size_change_functions;
+ GCPRO2 (tail, functions);
+ while (CONSP (functions))
+ {
+ call1 (XCONS (functions)->car, frame);
+ functions = XCONS (functions)->cdr;
+ }
+ UNGCPRO;
+ }
+ GCPRO1 (tail);
+ update_menu_bar (XFRAME (frame));
+ UNGCPRO;
+ }
+ }
+ else
+ update_menu_bar (selected_frame);
+ /* Update all frame titles based on their buffer names, etc.
+ We do this after the menu bars so that the frame will first
+ create its menu bar using the name `emacs' if no other name
+ has yet been specified. */
#ifdef HAVE_X_WINDOWS
if (windows_or_buffers_changed)
{
x_consider_frame_title (frame);
}
#endif
-
- /* Update the menu bar item lists, if appropriate.
- This has to be done before any actual redisplay
- or generation of display lines. */
- if (all_windows)
- {
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- update_menu_bar (XFRAME (frame));
- }
- else
- update_menu_bar (selected_frame);
}
\f
/* Do a frame update, taking possible shortcuts into account.
int all_windows;
register int tlbufpos, tlendpos;
struct position pos;
- extern int input_pending;
if (noninteractive)
return;
Lisp_Object tail, frame;
FOR_EACH_FRAME (tail, frame)
- FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+ {
+ FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+
+ /* Clear out all the display lines in which we will generate the
+ glyphs to display. */
+ init_desired_glyphs (XFRAME (frame));
+ }
}
/* Notice any pending interrupt request to change frame size. */
frame_garbaged = 0;
}
+ prepare_menu_bars ();
+
if (clip_changed || windows_or_buffers_changed
|| (!NILP (w->column_number_displayed)
&& XFASTINT (w->column_number_displayed) != current_column ()))
int left = XFASTINT (w->left);
int *charstart_next_line
= FRAME_CURRENT_GLYPHS (XFRAME (WINDOW_FRAME (w)))->charstarts[this_line_vpos + 1];
- int i;
int adjust;
if (Z - tlendpos == ZV)
}
goto update;
}
- /* If highlighting the region, we can't just move the cursor. */
+ /* If highlighting the region, or if the cursor is in the echo area,
+ then we can't just move the cursor. */
else if (! (!NILP (Vtransient_mark_mode)
&& !NILP (current_buffer->mark_active))
- && NILP (w->region_showing))
+ && NILP (w->region_showing)
+ && !cursor_in_echo_area)
{
pos = *compute_motion (tlbufpos, 0,
XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
FOR_EACH_FRAME (tail, frame)
{
FRAME_PTR f = XFRAME (frame);
+ if (! FRAME_TERMCAP_P (f) || f == selected_frame)
+ {
- /* Mark all the scroll bars to be removed; we'll redeem the ones
- we want when we redisplay their windows. */
- if (condemn_scroll_bars_hook)
- (*condemn_scroll_bars_hook) (f);
+ /* Mark all the scroll bars to be removed; we'll redeem the ones
+ we want when we redisplay their windows. */
+ if (condemn_scroll_bars_hook)
+ (*condemn_scroll_bars_hook) (f);
- if (FRAME_VISIBLE_P (f))
- redisplay_windows (FRAME_ROOT_WINDOW (f));
+ if (FRAME_VISIBLE_P (f))
+ redisplay_windows (FRAME_ROOT_WINDOW (f));
- /* Any scroll bars which redisplay_windows should have nuked
- should now go away. */
- if (judge_scroll_bars_hook)
- (*judge_scroll_bars_hook) (f);
+ /* Any scroll bars which redisplay_windows should have nuked
+ should now go away. */
+ if (judge_scroll_bars_hook)
+ (*judge_scroll_bars_hook) (f);
+ }
}
}
else if (FRAME_VISIBLE_P (selected_frame))
continue;
f = XFRAME (XCONS (tail)->car);
- if (FRAME_VISIBLE_P (f))
+
+ if ((! FRAME_TERMCAP_P (f) || f == selected_frame)
+ && FRAME_VISIBLE_P (f))
{
pause |= update_frame (f, 0, 0);
if (!pause)
{
if (FRAME_VISIBLE_P (selected_frame))
pause = update_frame (selected_frame, 0, 0);
+ else
+ pause = 0;
/* We may have called echo_area_display at the top of this
function. If the echo area is on another frame, that may
struct position pos;
int opoint = PT;
int tem;
- int window_needs_modeline;
+ int update_mode_line;
if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */
abort ();
height = window_internal_height (w);
+ update_mode_line = (!NILP (w->update_mode_line) || update_mode_lines);
if (MINI_WINDOW_P (w))
{
}
}
- if (update_mode_lines)
- w->update_mode_line = Qt;
-
/* Otherwise set up data on this window; select its buffer and point value */
- set_buffer_temp (XBUFFER (w->buffer));
+ if (update_mode_line)
+ set_buffer_internal (XBUFFER (w->buffer));
+ else
+ set_buffer_temp (XBUFFER (w->buffer));
+
opoint = PT;
/* Count number of windows showing the selected buffer.
{
/* Forget any recorded base line for line number display. */
w->base_line_number = Qnil;
- w->update_mode_line = Qt;
+ /* Redisplay the mode line. Select the buffer properly for that. */
+ if (!update_mode_line)
+ {
+ set_buffer_temp (old);
+ set_buffer_internal (XBUFFER (w->buffer));
+ update_mode_line = 1;
+ w->update_mode_line = Qt;
+ }
w->force_start = Qnil;
XSETFASTINT (w->last_modified, 0);
if (startp < BEGV) startp = BEGV;
if (XFASTINT (w->last_modified) >= MODIFF
&& PT >= startp && !clip_changed
&& (just_this_one || XFASTINT (w->width) == FRAME_WIDTH (f))
+ /* If force-mode-line-update was called, really redisplay;
+ that's how redisplay is forced after e.g. changing
+ buffer-invisibility-spec. */
+ && NILP (w->update_mode_line)
/* Can't use this case if highlighting a region. */
&& !(!NILP (Vtransient_mark_mode) && !NILP (current_buffer->mark_active))
&& NILP (w->region_showing)
&& !EQ (window, minibuf_window))
{
pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0),
- PT, height + 1, 10000, width, hscroll,
+ PT, height, 0, width, hscroll,
pos_tab_offset (w, startp), w);
if (pos.vpos < height)
}
XSETFASTINT (w->last_modified, 0);
- w->update_mode_line = Qt;
+ /* Redisplay the mode line. Select the buffer properly for that. */
+ if (!update_mode_line)
+ {
+ set_buffer_temp (old);
+ set_buffer_internal (XBUFFER (w->buffer));
+ update_mode_line = 1;
+ w->update_mode_line = Qt;
+ }
/* Try to scroll by specified few lines */
goto scroll_fail;
}
- pos = *vmotion (startp, PT < startp ? - scroll_step : scroll_step,
+ pos = *vmotion (startp,
+ (PT < startp ? - scroll_step : scroll_step),
width, hscroll, window);
if (PT >= pos.bufpos)
= (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil;
done:
- if ((!NILP (w->update_mode_line)
+ if ((update_mode_line
/* If window not full width, must redo its mode line
if the window to its side is being redone */
|| (!just_this_one && width < FRAME_WIDTH (f) - 1)
}
/* When we reach a frame's selected window, redo the frame's menu bar. */
- if (!NILP (w->update_mode_line)
+ if (update_mode_line
#ifdef USE_X_TOOLKIT
&& FRAME_EXTERNAL_MENU_BAR (f)
#else
|| (w == XWINDOW (minibuf_window) && ! echo_area_glyphs))
{
whole = ZV - BEGV;
- start = startp - BEGV;
+ start = marker_position (w->start) - BEGV;
/* I don't think this is guaranteed to be right. For the
moment, we'll pretend it is. */
end = (Z - XINT (w->window_end_pos)) - BEGV;
}
BUF_PT (current_buffer) = opoint;
- set_buffer_temp (old);
+ if (update_mode_line)
+ set_buffer_internal (old);
+ else
+ set_buffer_temp (old);
BUF_PT (current_buffer) = lpoint;
}
\f
{
val = *display_text_line (w, pos, vpos, val.hpos, tab_offset);
tab_offset += width;
+ /* For the first line displayed, display_text_line
+ subtracts the prompt width from the tab offset.
+ But it does not affect the value of our variable tab_offset.
+ So we do the subtraction again,
+ for the sake of continuation lines of that first line. */
+ if (MINI_WINDOW_P (w) && vpos == XFASTINT (w->top))
+ tab_offset -= minibuf_prompt_width;
+
if (val.vpos) tab_offset = 0;
vpos++;
if (pos != val.bufpos)
- last_text_vpos
- /* Next line, unless prev line ended in end of buffer with no cr */
- = vpos - (val.vpos && (FETCH_CHAR (val.bufpos - 1) != '\n'
+ {
+ int invis = 0;
#ifdef USE_TEXT_PROPERTIES
- || ! NILP (Fget_char_property (val.bufpos-1,
- Qinvisible,
- window))
+ Lisp_Object invis_prop;
+ invis_prop = Fget_char_property (val.bufpos-1, Qinvisible, window);
+ invis = TEXT_PROP_MEANS_INVISIBLE (invis_prop);
#endif
- ));
+
+ last_text_vpos
+ /* Next line, unless prev line ended in end of buffer with no cr */
+ = vpos - (val.vpos
+ && (FETCH_CHAR (val.bufpos - 1) != '\n' || invis));
+ }
pos = val.bufpos;
}
/* Find position before which nothing is changed. */
bp = *compute_motion (start, 0, lmargin,
- min (ZV, beg_unchanged + BEG), height + 1, 0,
+ min (ZV, beg_unchanged + BEG), height, 0,
width, hscroll, pos_tab_offset (w, start), w);
if (bp.vpos >= height)
{
- if (PT < bp.bufpos && !bp.contin)
+ if (PT < bp.bufpos)
{
/* All changes are below the frame, and point is on the frame.
We don't need to change the frame at all.
width, hscroll, pos_tab_offset (w, start), w);
XSETFASTINT (w->window_end_vpos, height);
XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
- return 1;
+ goto findpoint;
}
return 0;
}
/* If point was not in a line that was displayed, find it */
if (cursor_vpos < 0)
{
+ findpoint:
val = *compute_motion (start, 0, lmargin, PT, 10000, 10000,
width, hscroll, pos_tab_offset (w, start), w);
/* Admit failure if point is off frame now */
struct position val;
int lastpos;
int invis;
+ int last_invis_skip = 0;
+ Lisp_Object last_invis_prop;
int hscroll = XINT (w->hscroll);
int truncate = (hscroll
|| (truncate_partial_width_windows
register struct Lisp_Vector *dp = window_display_table (w);
Lisp_Object default_invis_vector[3];
- /* Nonzero means display something where there are invisible lines.
- The precise value is the number of glyphs to display. */
+ /* Number of characters of ellipsis to display after an invisible line
+ if it calls for an ellipsis.
+ Note that this value can be nonzero regardless of whether
+ selective display is enabled--you must check that separately. */
int selective_rlen
- = (selective && dp && VECTORP (DISP_INVIS_VECTOR (dp))
+ = (dp && VECTORP (DISP_INVIS_VECTOR (dp))
? XVECTOR (DISP_INVIS_VECTOR (dp))->size
- : selective && !NILP (current_buffer->selective_display_ellipses)
- ? 3 : 0);
+ : !NILP (current_buffer->selective_display_ellipses) ? 3 : 0);
/* This is the sequence of Lisp objects to display
when there are invisible lines. */
Lisp_Object *invis_vector_contents
w->width > 10 ? w->width - 4 : -1)
- hpos);
hpos += minibuf_prompt_width;
+ taboffset -= minibuf_prompt_width;
}
else
minibuf_prompt_width = 0;
if (XFASTINT (limit) > pos + 50)
XSETFASTINT (limit, pos + 50);
endpos = Fnext_single_property_change (position, Qinvisible,
- Fcurrent_buffer (), limit);
+ Fcurrent_buffer (),
+ limit);
if (INTEGERP (endpos))
next_invisible = XINT (endpos);
else
next_invisible = end;
- if (! NILP (prop))
+ if (TEXT_PROP_MEANS_INVISIBLE (prop))
{
if (pos < PT && next_invisible >= PT)
{
cursor_hpos = p1 - leftmargin;
}
pos = next_invisible;
+ last_invis_skip = pos;
+ last_invis_prop = prop;
}
}
if (pos >= end)
p = &FETCH_CHAR (pos);
}
c = *p++;
- if (c >= 040 && c < 0177
- && (dp == 0 || !VECTORP (DISP_CHAR_VECTOR (dp, c))))
+ /* Let a display table override all standard display methods. */
+ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+ {
+ p1 = copy_part_of_rope (f, p1, leftmargin,
+ XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
+ XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
+ current_face);
+ }
+ else if (c >= 040 && c < 0177)
{
if (p1 >= leftmargin)
*p1 = MAKE_GLYPH (f, c, current_face);
else if (c == '\n')
{
invis = 0;
+ if (last_invis_skip == pos
+ && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop))
+ invis = 1;
while (pos + 1 < end
&& selective > 0
&& indented_beyond_p (pos + 1, selective))
#endif
break;
}
- else if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
- {
- p1 = copy_part_of_rope (f, p1, leftmargin,
- XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
- XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
- current_face);
- }
else if (c < 0200 && ctl_arrow)
{
if (p1 >= leftmargin)
cursor_hpos += XFASTINT (w->left);
if (w == XWINDOW (FRAME_SELECTED_WINDOW (f)))
{
- FRAME_CURSOR_Y (f) = cursor_vpos;
- FRAME_CURSOR_X (f) = cursor_hpos;
+ if (!(cursor_in_echo_area && FRAME_HAS_MINIBUF_P (f)
+ && EQ (FRAME_MINIBUF_WINDOW (f), minibuf_window)))
+ {
+ FRAME_CURSOR_Y (f) = cursor_vpos;
+ FRAME_CURSOR_X (f) = cursor_hpos;
+ }
if (w == XWINDOW (selected_window))
{
XSTRING (string)->data,
XSTRING (string)->size,
hpos, 0, 0, hpos, maxendcol);
- /* Put a gap of 3 spaces between items. */
+ /* Put a space between items. */
if (hpos < maxendcol)
{
- int hpos1 = hpos + 3;
+ int hpos1 = hpos + 1;
hpos = display_string (w, vpos, "", 0, hpos, 0, 0,
min (hpos1, maxendcol), maxendcol);
}
w->column_number_displayed = Qnil;
get_display_line (f, vpos, left);
+
+ /* Temporarily make frame F's kboard the current kboard
+ so that kboard-local variables in the mode_line_format
+ will get the right values. */
+ push_frame_kboard (f);
+
display_mode_element (w, vpos, left, 0, right, right,
current_buffer->mode_line_format);
+
+ pop_frame_kboard ();
+
FRAME_DESIRED_GLYPHS (f)->bufp[vpos] = 0;
/* Make the mode line inverse video if the entire line
|| XFASTINT (XWINDOW (w->parent)->width) == FRAME_WIDTH (f))
FRAME_DESIRED_GLYPHS (f)->highlight[vpos] = mode_line_inverse_video;
#ifdef HAVE_FACES
- else if (! FRAME_TERMCAP_P (f))
+ else if (! FRAME_TERMCAP_P (f) && mode_line_inverse_video)
{
/* For a partial width window, explicitly set face of each glyph. */
int i;
switch (c)
{
+ case '*':
+ if (!NILP (b->read_only))
+ return "%";
+ if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
+ return "*";
+ return "-";
+
+ case '+':
+ /* This differs from %* only for a modified read-only buffer. */
+ if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
+ return "*";
+ if (!NILP (b->read_only))
+ return "%";
+ return "-";
+
+ case '&':
+ /* This differs from %* in ignoring read-only-ness. */
+ if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
+ return "*";
+ return "-";
+
+ case '%':
+ return "%";
+
+ case '[':
+ {
+ int i;
+ char *p;
+
+ if (command_loop_level > 5)
+ return "[[[... ";
+ p = decode_mode_spec_buf;
+ for (i = 0; i < command_loop_level; i++)
+ *p++ = '[';
+ *p = 0;
+ return decode_mode_spec_buf;
+ }
+
+ case ']':
+ {
+ int i;
+ char *p;
+
+ if (command_loop_level > 5)
+ return " ...]]]";
+ p = decode_mode_spec_buf;
+ for (i = 0; i < command_loop_level; i++)
+ *p++ = ']';
+ *p = 0;
+ return decode_mode_spec_buf;
+ }
+
+ case '-':
+ {
+ register char *p;
+ register int i;
+
+ if (maxwidth < sizeof (lots_of_dashes))
+ return lots_of_dashes;
+ else
+ {
+ for (p = decode_mode_spec_buf, i = maxwidth; i > 0; i--)
+ *p++ = '-';
+ *p = '\0';
+ }
+ return decode_mode_spec_buf;
+ }
+
case 'b':
obj = b->name;
#if 0
#endif
break;
+ case 'c':
+ {
+ int col = current_column ();
+ XSETFASTINT (w->column_number_displayed, col);
+ sprintf (decode_mode_spec_buf, "%d", col);
+ return decode_mode_spec_buf;
+ }
+
+ case 'F':
+ /* %F displays the frame name. */
+ return (char *) XSTRING (selected_frame->name)->data;
+
case 'f':
obj = b->filename;
#if 0
#endif
break;
- case 'c':
- {
- int col = current_column ();
- XSETFASTINT (w->column_number_displayed, col);
- sprintf (decode_mode_spec_buf, "%d", col);
- return decode_mode_spec_buf;
- }
-
case 'l':
{
int startpos = marker_position (w->start);
return " Narrow";
break;
- case '*':
- if (!NILP (b->read_only))
- return "%";
- if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
- return "*";
- return "-";
-
- case '+':
- /* This differs from %* only for a modified read-only buffer. */
- if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
- return "*";
- if (!NILP (b->read_only))
- return "%";
- return "-";
-
- case '&':
- /* This differs from %* in ignoring read-only-ness. */
- if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
- return "*";
- return "-";
-
- case 's':
- /* status of process */
- obj = Fget_buffer_process (w->buffer);
- if (NILP (obj))
- return "no process";
-#ifdef subprocesses
- obj = Fsymbol_name (Fprocess_status (obj));
-#endif
- break;
-
- case 't': /* indicate TEXT or BINARY */
-#ifdef MODE_LINE_BINARY_TEXT
- return MODE_LINE_BINARY_TEXT (b);
-#else
- return "T";
-#endif
-
case 'p':
{
int pos = marker_position (w->start);
}
}
- case '%':
- return "%";
-
- case '[':
- {
- int i;
- char *p;
-
- if (command_loop_level > 5)
- return "[[[... ";
- p = decode_mode_spec_buf;
- for (i = 0; i < command_loop_level; i++)
- *p++ = '[';
- *p = 0;
- return decode_mode_spec_buf;
- }
-
- case ']':
- {
- int i;
- char *p;
-
- if (command_loop_level > 5)
- return " ...]]]";
- p = decode_mode_spec_buf;
- for (i = 0; i < command_loop_level; i++)
- *p++ = ']';
- *p = 0;
- return decode_mode_spec_buf;
- }
+ case 's':
+ /* status of process */
+ obj = Fget_buffer_process (w->buffer);
+ if (NILP (obj))
+ return "no process";
+#ifdef subprocesses
+ obj = Fsymbol_name (Fprocess_status (obj));
+#endif
+ break;
- case '-':
- {
- register char *p;
- register int i;
-
- if (maxwidth < sizeof (lots_of_dashes))
- return lots_of_dashes;
- else
- {
- for (p = decode_mode_spec_buf, i = maxwidth; i > 0; i--)
- *p++ = '-';
- *p = '\0';
- }
- return decode_mode_spec_buf;
- }
+ case 't': /* indicate TEXT or BINARY */
+#ifdef MODE_LINE_BINARY_TEXT
+ return MODE_LINE_BINARY_TEXT (b);
+#else
+ return "T";
+#endif
}
if (STRINGP (obj))
else if (c == 0)
break;
- if (c >= 040 && c < 0177
- && (dp == 0 || !VECTORP (DISP_CHAR_VECTOR (dp, c))))
+ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+ {
+ p1 = copy_part_of_rope (f, p1, start,
+ XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
+ XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
+ 0);
+ }
+ else if (c >= 040 && c < 0177)
{
if (p1 >= start)
*p1 = c;
}
while ((p1 - start + hscroll - (hscroll > 0)) % tab_width);
}
- else if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
- {
- p1 = copy_part_of_rope (f, p1, start,
- XVECTOR (DISP_CHAR_VECTOR (dp, c))->contents,
- XVECTOR (DISP_CHAR_VECTOR (dp, c))->size,
- 0);
- }
else if (c < 0200 && ! NILP (buffer_defaults.ctl_arrow))
{
if (p1 >= start)
}
}
\f
+/* This is like a combination of memq and assq.
+ Return 1 if PROPVAL appears as an element of LIST
+ or as the car of an element of LIST.
+ If PROPVAL is a list, compare each element against LIST
+ in that way, and return 1 if any element of PROPVAL is found in LIST.
+ Otherwise return 0.
+ This function cannot quit. */
+
+int
+invisible_p (propval, list)
+ register Lisp_Object propval;
+ Lisp_Object list;
+{
+ register Lisp_Object tail, proptail;
+ for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+ {
+ register Lisp_Object tem;
+ tem = XCONS (tail)->car;
+ if (EQ (propval, tem))
+ return 1;
+ if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
+ return 1;
+ }
+ if (CONSP (propval))
+ for (proptail = propval; CONSP (proptail);
+ proptail = XCONS (proptail)->cdr)
+ {
+ Lisp_Object propelt;
+ propelt = XCONS (proptail)->car;
+ for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+ {
+ register Lisp_Object tem;
+ tem = XCONS (tail)->car;
+ if (EQ (propelt, tem))
+ return 1;
+ if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Return 1 if PROPVAL appears as the car of an element of LIST
+ and the cdr of that element is non-nil.
+ If PROPVAL is a list, check each element of PROPVAL in that way,
+ and the first time some element is found,
+ return 1 if the cdr of that element is non-nil.
+ Otherwise return 0.
+ This function cannot quit. */
+
+int
+invisible_ellipsis_p (propval, list)
+ register Lisp_Object propval;
+ Lisp_Object list;
+{
+ register Lisp_Object tail, proptail;
+ for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+ {
+ register Lisp_Object tem;
+ tem = XCONS (tail)->car;
+ if (CONSP (tem) && EQ (propval, XCONS (tem)->car))
+ return ! NILP (XCONS (tem)->cdr);
+ }
+ if (CONSP (propval))
+ for (proptail = propval; CONSP (proptail);
+ proptail = XCONS (proptail)->cdr)
+ {
+ Lisp_Object propelt;
+ propelt = XCONS (proptail)->car;
+ for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
+ {
+ register Lisp_Object tem;
+ tem = XCONS (tail)->car;
+ if (CONSP (tem) && EQ (propelt, XCONS (tem)->car))
+ return ! NILP (XCONS (tem)->cdr);
+ }
+ }
+ return 0;
+}
+\f
void
syms_of_xdisp ()
{
If nil, disable message logging. If t, log messages but don't truncate\n\
the buffer when it becomes large.");
XSETFASTINT (Vmessage_log_max, 50);
+
+ DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
+ "Functions called before redisplay, if window sizes have changed.\n\
+The value should be a list of functions that take one argument.\n\
+Just before redisplay, for each frame, if any of its windows have changed\n\
+size since the last redisplay, or have been split or deleted,\n\
+all the functions in the list are called, with the frame as argument.");
+ Vwindow_size_change_functions = Qnil;
}
/* initialize the window system */