]> git.eshelyaron.com Git - emacs.git/commitdiff
Introduce new variable mode-line-compact
authorLars Ingebrigtsen <larsi@gnus.org>
Tue, 29 Dec 2020 03:53:03 +0000 (04:53 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 29 Dec 2020 03:53:03 +0000 (04:53 +0100)
* 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.

doc/lispref/modes.texi
etc/NEWS
src/xdisp.c

index 675aeec8a5ff92c9d17d3fc353b009cabf9bd88d..40edc90a6af53aefbc5a772d885f2464b4c16272 100644 (file)
@@ -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
index 6348c1d8eefb0713d95c8f6f1f7b4db0f52825a2..a5247a9aea8f57bf2e61f4ef75aca1fccbfd75eb 100644 (file)
--- 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
index b5adee51055aabb528fd463a276860957195d1e9..6606e49e4289719fff47367f571cf48cdfe71f18 100644 (file)
@@ -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