From: Lars Ingebrigtsen Date: Tue, 29 Dec 2020 03:53:03 +0000 (+0100) Subject: Introduce new variable mode-line-compact X-Git-Tag: emacs-28.0.90~4516 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a66f0d3bd3486b7253f482b7169b0de2d0d49c79;p=emacs.git Introduce new variable mode-line-compact * doc/lispref/modes.texi (Mode Line Basics): Document it (bug#34476). * src/xdisp.c (display_mode_line): Use it. (syms_of_xdisp): New variable mode-line-compact. --- diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 675aeec8a5f..40edc90a6af 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1930,6 +1930,15 @@ This function also forces an update of the menu bar and frame title. color using the face @code{mode-line}. Other windows' mode lines appear in the face @code{mode-line-inactive} instead. @xref{Faces}. +@vindex mode-line-compact + Some modes put a lot of data in the mode line, pushing elements at +the end of the mode line off to the right. Emacs can ``compress'' the +mode line if the @code{mode-line-compact} variable is non-@code{nil} +by turning stretches of spaces into a single space. If this variable +is @code{long}, this is only done when the mode line is wider than the +currently selected window. This variable can be buffer-local to only +compress mode-lines in certain buffers. + @node Mode Line Data @subsection The Data Structure of the Mode Line @cindex mode line construct diff --git a/etc/NEWS b/etc/NEWS index 6348c1d8eef..a5247a9aea8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1614,6 +1614,12 @@ the column number format (when 'column-number-mode' is on), and 'mode-line-position-column-line-format' is the combined format (when both modes are on). ++++ +*** New user option 'mode-line-compact'. +If non-nil, repeating spaces are compressed into a single space. If +'long', this is only done when the mode line is longer than the +current window width (in characters). + +++ *** New command 'submit-emacs-patch'. This works like 'report-emacs-bug', but is more geared towards sending diff --git a/src/xdisp.c b/src/xdisp.c index b5adee51055..6606e49e428 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -25451,14 +25451,49 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) format_mode_line_unwind_data (NULL, NULL, Qnil, false)); - mode_line_target = MODE_LINE_DISPLAY; - /* Temporarily make frame's keyboard the current kboard so that kboard-local variables in the mode_line_format will get the right values. */ push_kboard (FRAME_KBOARD (it.f)); record_unwind_save_match_data (); - display_mode_element (&it, 0, 0, 0, format, Qnil, false); + + if (NILP (Vmode_line_compact)) + { + mode_line_target = MODE_LINE_DISPLAY; + display_mode_element (&it, 0, 0, 0, format, Qnil, false); + } + else + { + Lisp_Object mode_string = Fformat_mode_line (format, Qnil, Qnil, Qnil); + if (EQ (Vmode_line_compact, Qlong) + && window_body_width (XWINDOW (selected_window), FALSE) >= + SCHARS (mode_string)) + { + display_string (SSDATA (mode_string), Qnil, Qnil, 0, 0, &it, 0, 0, 0, + STRING_MULTIBYTE (mode_string)); + } + else + { + char *string = xmalloc (SBYTES (mode_string) + 1), + *ostring = SSDATA (mode_string); + char *s = string, prev = 0; + + /* Copy over the data from the mode line string, but ignore + repeating spaces. This should be safe even for multibyte + strings, since this is UTF-8. */ + for (int i = 0; i < SBYTES (mode_string); i++) + { + char c = ostring[i]; + if (!(c == ' ' && prev == ' ')) + prev = *s++ = c; + } + *s = 0; + + display_string (string, Qnil, Qnil, 0, 0, &it, 0, 0, 0, + STRING_MULTIBYTE (mode_string)); + xfree (string); + } + } pop_kboard (); unbind_to (count, Qnil); @@ -34805,6 +34840,14 @@ wide as that tab on the display. */); The face used for trailing whitespace is `trailing-whitespace'. */); Vshow_trailing_whitespace = Qnil; + DEFVAR_LISP ("mode-line-compact", Vmode_line_compact, + doc: /* Non-nil means that mode lines should be compact. +This means that repeating spaces will be replaced with a single space. +If this variable is `long', only mode lines that are wider than the +currently selected window are compressed. */); + Vmode_line_compact = Qnil; + DEFSYM (Qlong, "long"); + DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display, doc: /* Control highlighting of non-ASCII space and hyphen chars. If the value is t, Emacs highlights non-ASCII chars which have the