Function: format-mode-line
format-mode-line is a function defined in xdisp.c.
Signature
(format-mode-line FORMAT &optional FACE WINDOW BUFFER)
Documentation
Return a string formatted according to mode-line format specification.
First arg FORMAT specifies the mode line format (see mode-line-format
for details) to use.
By default, the format is evaluated for the currently selected window.
Optional second arg FACE specifies the face property to put on all
characters for which no face is specified. The value nil means the
default face. The value t means whatever face the window's mode line
currently uses (either mode-line or mode-line-inactive,
depending on whether the window is the selected window or not).
An integer value means the value string has no text
properties.
Optional third and fourth args WINDOW and BUFFER specify the window and buffer to use as the context for the formatting (defaults are the selected window and the WINDOW's buffer).
Probably introduced at or before Emacs version 22.1.
Source Code
// Defined in /usr/src/emacs/src/xdisp.c
{
struct it it;
int len;
struct window *w;
struct buffer *old_buffer = NULL;
int face_id;
bool no_props = FIXNUMP (face);
specpdl_ref count = SPECPDL_INDEX ();
Lisp_Object str;
int string_start = 0;
w = decode_any_window (window);
XSETWINDOW (window, w);
if (NILP (buffer))
buffer = w->contents;
CHECK_BUFFER (buffer);
if (!BUFFER_LIVE_P (XBUFFER (buffer)))
error ("Attempt to format a mode line for a dead buffer");
/* Make formatting the modeline a non-op when noninteractive, otherwise
there will be problems later caused by a partially initialized frame. */
if (NILP (format) || noninteractive)
return empty_unibyte_string;
if (no_props)
face = Qnil;
face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
: EQ (face, Qt) ? (EQ (window, selected_window)
? MODE_LINE_ACTIVE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
: EQ (face, Qmode_line_active) ? MODE_LINE_ACTIVE_FACE_ID
: EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
: EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
: EQ (face, Qtab_line) ? TAB_LINE_FACE_ID
: EQ (face, Qtab_bar) ? TAB_BAR_FACE_ID
: EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
: DEFAULT_FACE_ID;
old_buffer = current_buffer;
/* Save things including mode_line_proptrans_alist,
and set that to nil so that we don't alter the outer value. */
record_unwind_protect (unwind_format_mode_line,
format_mode_line_unwind_data
(XFRAME (WINDOW_FRAME (w)),
old_buffer, selected_window, true));
mode_line_proptrans_alist = Qnil;
Fselect_window (window, Qt);
set_buffer_internal_1 (XBUFFER (buffer));
init_iterator (&it, w, -1, -1, NULL, face_id);
/* Make sure `base_line_number` is fresh in case we encounter a `%l`. */
if (current_buffer == XBUFFER ((w)->contents)
&& !BASE_LINE_NUMBER_VALID_P (w))
w->base_line_number = 0;
if (no_props)
{
mode_line_target = MODE_LINE_NOPROP;
mode_line_string_face_prop = Qnil;
mode_line_string_list = Qnil;
string_start = MODE_LINE_NOPROP_LEN (0);
}
else
{
mode_line_target = MODE_LINE_STRING;
mode_line_string_list = Qnil;
mode_line_string_face = face;
mode_line_string_face_prop
= NILP (face) ? Qnil : list2 (Qface, face);
}
push_kboard (FRAME_KBOARD (it.f));
display_mode_element (&it, 0, 0, 0, format, Qnil, false);
pop_kboard ();
if (no_props)
{
len = MODE_LINE_NOPROP_LEN (string_start);
str = make_string (mode_line_noprop_buf + string_start, len);
}
else
{
mode_line_string_list = Fnreverse (mode_line_string_list);
str = Fmapconcat (Qidentity, mode_line_string_list,
empty_unibyte_string);
}
return unbind_to (count, str);
}