emacs-diffs
[Top][All Lists]
Advanced

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

master c296bcc6c42 1/2: Support right-align in mode-line


From: Eli Zaretskii
Subject: master c296bcc6c42 1/2: Support right-align in mode-line
Date: Thu, 6 Jul 2023 03:34:02 -0400 (EDT)

branch: master
commit c296bcc6c42ebb0fbc5078a137bbf6b501b8a44f
Author: Hugo Heagren <hugo@heagren.com>
Commit: Eli Zaretskii <eliz@gnu.org>

    Support right-align in mode-line
    
    * lisp/bindings.el (mode-line-right-align-edge):  New custom
    variable, controls where `mode-line-format-right-align' should
    align to.
    (mode-line-format-right-align):  New function.  If the symbol
    `mode-line-format-right-align' appears in `mode-line-format',
    then return return a padding string which aligns everything
    after that symbol to the right.  Padding width is altered with
    the display property and depends on the value of
    `mode-line-right-align-edge'.
    (mode-line-format-right-align):  New variable.  Convenience
    definition for including right alignment in `mode-line-format'.
    * doc/lispref/modes.texi (Mode Line Variables):  Document new
    alignment functionality and user option.  (Bug#62606)
---
 doc/lispref/modes.texi | 10 ++++++++
 etc/NEWS               |  6 +++++
 lisp/bindings.el       | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 8ca0afe1bca..b4f69e79155 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -2275,6 +2275,16 @@ current buffer is remote.
 
 @defvar mode-line-client
 This variable is used to identify @code{emacsclient} frames.
+@end defvar
+
+@defvar mode-line-format-right-align
+Anything following this symbol in @code{mode-line-format} will be
+right-aligned.
+@end defvar
+
+@defvar mode-line-right-align-edge
+This variable controls exactly @code{mode-line-format-right-align}
+aligns content to.
 @end defvar
 
   The following three variables are used in @code{mode-line-modes}:
diff --git a/etc/NEWS b/etc/NEWS
index e36e77fa97f..50fd1382866 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -92,6 +92,12 @@ plus, minus, check-mark, start, etc.
 The 'tool-bar-position' frame parameter can be set to 'bottom' on all
 window systems other than Nextstep.
 
+** Modeline elements can now be right-aligned
+Anything following the symbol 'mode-line-format-right-align' in
+'mode-line-format' will be right-aligned. Exactly where it is
+right-aligned to is controlled by the new user option
+'mode-line-right-align-edge'.
+
 
 * Editing Changes in Emacs 30.1
 
diff --git a/lisp/bindings.el b/lisp/bindings.el
index c77b64c05da..f1a75b080be 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -304,6 +304,70 @@ Normally nil in most modes, since there is no process to 
display.")
 ;;;###autoload
 (put 'mode-line-process 'risky-local-variable t)
 
+(defcustom mode-line-right-align-edge 'window
+  "Where function `mode-line-format-right-align' should align to.
+Internally, that function uses `:align-to' in a display property,
+so aligns to the left edge of the given area.  See info node
+`(elisp)Pixel Specification'.
+
+Must be set to a symbol.  Acceptable values are:
+- `window': align to extreme right of window, regardless of margins
+  or fringes
+- `right-fringe': align to right-fringe
+- `right-margin': align to right-margin"
+  :type '(choice (const right-margin)
+                 (const right-fringe)
+                 (const window))
+  :group 'mode-line
+  :version "30.1")
+
+(defun mode--line-format-right-align ()
+  "Right-align all following mode-line constructs.
+
+When the symbol `mode-line-format-right-align' appears in
+`mode-line-format', return a string of one space, with a display
+property to make it appear long enough to align anything after
+that symbol to the right of the rendered mode line.  Exactly how
+far to the right is controlled by `mode-line-right-align-edge'.
+
+It is important that the symbol `mode-line-format-right-align' be
+included in `mode-line-format' (and not another similar construct
+such as `(:eval (mode-line-format-right-align)').  This is because
+the symbol `mode-line-format-right-align' is processed by
+`format-mode-line' as a variable."
+  (let* ((rest (cdr (memq 'mode-line-format-right-align
+                         mode-line-format)))
+        (rest-str (format-mode-line `("" ,@rest)))
+        (rest-width (string-pixel-width rest-str)))
+    (propertize " " 'display
+               ;; The `right' spec doesn't work on TTY frames
+               ;; when windows are split horizontally (bug#59620)
+               (if (and (display-graphic-p)
+                         (not (eq mode-line-right-align-edge 'window)))
+                   `(space :align-to (- ,mode-line-right-align-edge
+                                         (,rest-width)))
+                 `(space :align-to (,(- (window-pixel-width)
+                                         (window-scroll-bar-width)
+                                         (window-right-divider-width)
+                                         (* (or (cdr (window-margins)) 1)
+                                            (frame-char-width))
+                                         ;; Manually account for value of
+                                         ;; `mode-line-right-align-edge' even
+                                         ;; when display is non-graphical
+                                         (pcase mode-line-right-align-edge
+                                           ('right-margin
+                                            (or (cdr (window-margins)) 0))
+                                           ('right-fringe
+                                            ;; what here?
+                                            (or (cadr (window-fringes)) 0))
+                                           (_ 0))
+                                         rest-width)))))))
+
+(defvar mode-line-format-right-align '(:eval (mode--line-format-right-align))
+  "Mode line construct to right align all following constructs.")
+;;;###autoload
+(put 'mode-line-format-right-align 'risky-local-variable t)
+
 (defun bindings--define-key (map key item)
   "Define KEY in keymap MAP according to ITEM from a menu.
 This is like `define-key', but it takes the definition from the



reply via email to

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