emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a66f0d3: Introduce new variable mode-line-compact


From: Lars Ingebrigtsen
Subject: master a66f0d3: Introduce new variable mode-line-compact
Date: Mon, 28 Dec 2020 22:55:10 -0500 (EST)

branch: master
commit a66f0d3bd3486b7253f482b7169b0de2d0d49c79
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    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.
---
 doc/lispref/modes.texi |  9 +++++++++
 etc/NEWS               |  6 ++++++
 src/xdisp.c            | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 675aeec..40edc90 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 6348c1d..a5247a9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1615,6 +1615,12 @@ the column number format (when 'column-number-mode' is 
on), and
 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
 patches to the Emacs issue tracker.
diff --git a/src/xdisp.c b/src/xdisp.c
index b5adee5..6606e49 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]