unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#62606: [PATCH] function to align mode-line elements to right
@ 2023-04-01 22:27 hugo
  2023-04-02  5:47 ` Eli Zaretskii
                   ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: hugo @ 2023-04-01 22:27 UTC (permalink / raw)
  To: 62606

[-- Attachment #1: Type: text/plain, Size: 668 bytes --]

I wanted to be able to right-align some elements of the mode-line. I
used `tab-bar-format-align-right' as a base and modified it to work with
the mode-line.

The functin aligns to the right /fringe/ rather than the margin because
some modes (e.g. [visual-fill-column-mode]) mess around the margin size,
but the right-align should be unaffected by this.

Patch attached. I want to know that the code is good before I do NEWS
and docs etc. Obviously it would be useful to document this in info
(elisp) Mode Line Variables and maybe in the `mode-line-format'
docstring.

Blue skies,

Hugo


[visual-fill-column-mode]
<https://codeberg.org/joostkremers/visual-fill-column>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-right-align-in-mode-line.patch --]
[-- Type: text/x-diff; name=0001-Support-right-align-in-mode-line.patch, Size: 2418 bytes --]

From 194ead37193a134040ac3f907199cbae2057efbb Mon Sep 17 00:00:00 2001
From: Hugo Heagren <hugo@heagren.com>
Date: Sat, 1 Apr 2023 22:27:25 +0100
Subject: [PATCH] Support right-align in mode-line

* lisp/bindings.el (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.
(mode-line-format-right-align):  New variable.  Convenience definition
for including right alignment in `mode-line-format'.
---
 lisp/bindings.el | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/lisp/bindings.el b/lisp/bindings.el
index 34aa8399a96..95a063fbbaf 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -304,6 +304,35 @@ mode-line-process
 ;;;###autoload
 (put 'mode-line-process 'risky-local-variable t)
 
+(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 modeline.
+
+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
+`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 (window-system)
+		    `(space :align-to (- right-fringe (,rest-width)))
+		  `(space :align-to (,(- (window-pixel-width) 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
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-04-01 22:27 bug#62606: [PATCH] function to align mode-line elements to right hugo
@ 2023-04-02  5:47 ` Eli Zaretskii
  2023-05-06 14:14   ` hugo
  2023-04-02 16:19 ` Juri Linkov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-04-02  5:47 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> Date: Sat, 01 Apr 2023 23:27:31 +0100
> From: hugo@heagren.com
> 
> I wanted to be able to right-align some elements of the mode-line. I
> used `tab-bar-format-align-right' as a base and modified it to work with
> the mode-line.

Thanks.

What would be the situations where the user could want this alignment?

One possible issue with right alignment is that when the total size of
the mode-line text changes (e.g., the mode lighter changes), the
leftmost part of it will move horizontally, something that could be
unpleasant and even annoying.

Also, what happens if the mode-line text is longer than the window
width.  What are user expectations in that case, and does :align-to
meet those expectations?

> The functin aligns to the right /fringe/ rather than the margin because
> some modes (e.g. [visual-fill-column-mode]) mess around the margin size,
> but the right-align should be unaffected by this.

This detail should not be hard-coded, IMO.  It should be up to the
calling Lisp program (or maybe even user option) whether the alignment
is to the right margin or to the window edge.

Also, did you test this when the fringe is inside the margins and the
margins have non-zero width?

> +  (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)))

The call to string-pixel-width will significantly slow down redisplay
of the mode line.  I wonder whether this feature should be implemented
in C instead, to avoid the slowdown.  On the C level, we always know
the actual width of the mode-line text, and can right-align it by
prepending a stretch glyph of a suitable width.

> +    (propertize " " 'display
> +		;; The `right' spec doesn't work on TTY frames
> +		;; when windows are split horizontally (bug#59620)
> +		(if (window-system)
                ^^^^^^^^^^^^^^^^^^^
This should use display-graphic-p, not window-system.

Did you test this in a session which has both GUI and TTY frames?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-04-01 22:27 bug#62606: [PATCH] function to align mode-line elements to right hugo
  2023-04-02  5:47 ` Eli Zaretskii
@ 2023-04-02 16:19 ` Juri Linkov
  2023-06-09 16:03 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
       [not found] ` <handler.62606.D62606.168862894016990.notifdone@debbugs.gnu.org>
  3 siblings, 0 replies; 24+ messages in thread
From: Juri Linkov @ 2023-04-02 16:19 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> I wanted to be able to right-align some elements of the mode-line. I
> used `tab-bar-format-align-right' as a base and modified it to work with
> the mode-line.
>
> The functin aligns to the right /fringe/ rather than the margin because
> some modes (e.g. [visual-fill-column-mode]) mess around the margin size,
> but the right-align should be unaffected by this.

Does this mean that currently `tab-bar-format-align-right'
doesn't work with `visual-fill-column-mode'?  Ok, I tried it out,
and see no problems.

> Patch attached. I want to know that the code is good before I do NEWS
> and docs etc. Obviously it would be useful to document this in info
> (elisp) Mode Line Variables and maybe in the `mode-line-format'
> docstring.

Thanks, everything works nicely when I tried your patch,
but one change was needed:

> +  (let* ((rest (cdr (memq 'mode-line-format-right-align
> +			  mode-line-format)))
> +	 (rest-str (format-mode-line rest))

Here `format-mode-line' returns an empty string when
`mode-line-format-right-align' was added in the middle
of `mode-line-format'.  For a strange reason, it expects
that `mode-line-format' should start with a string.
So everything is fine after replacing in your patch

   	 (rest-str (format-mode-line rest))
with
	 (rest-str (format-mode-line (append '("") rest)))





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-04-02  5:47 ` Eli Zaretskii
@ 2023-05-06 14:14   ` hugo
  2023-05-06 14:39     ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: hugo @ 2023-05-06 14:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 62606

[-- Attachment #1: Type: text/plain, Size: 3936 bytes --]

Thanks for the feedback. A new patch is attached.

> From: 	Eli Zaretskii
> Date: 	Sun, 02 Apr 2023 08:47:40 +0300

> What would be the situations where the user could want this alignment?

It's merely an aesthetic thing -- I just like having some of my
information right-aligned. I think the motivation for the tab bar
right-align function is similar?

> One possible issue with right alignment is that when the total size of
> the mode-line text changes (e.g., the mode lighter changes), the
> leftmost part of it will move horizontally, something that could be
> unpleasant and even annoying.

This doesn't happen with my proposed setup (though I agree it would be
annoying if it did!). The user includes the symbol
`mode-line-format-right-align' in their mode line format. This is a
variable which holds a mode-line construct `(:eval
(mode-line-format-right-align))'. So whenever the mode-line is reloaded
(and therefore, whenever the length could change), the space used to pad
the right-aligned part to the right is recalculated. The only situation
where this could go wrong would be if the length of the left part of the
mode-line changed /during/ the process of reloading the mode-line, which
seems unlikely to happen.

> Also, what happens if the mode-line text is longer than the window
> width.  What are user expectations in that case, and does :align-to
> meet those expectations?

Then the text overflows to the right. The behaviour with my patch is the
same as without: the text furthest to the right is not visible. The way
the patch is written would mean that the padding used to align text to
the right would be nil (i.e. a zero-width) string, but this is not
really relevant because it won't be visible (because it will be off the
right-hand edge of the screen).

> > The functin aligns to the right /fringe/ rather than the margin because
> > some modes (e.g. [visual-fill-column-mode]) mess around the margin size,
> > but the right-align should be unaffected by this.
> This detail should not be hard-coded, IMO.

On reflection, I think you're right.

> It should be up to the calling Lisp program (or maybe even user
> option) whether the alignment is to the right margin or to the window
> edge.

I found this easier to implement as a user option -- I've added
`mode-line-right-align-edge' to the patch.

> Also, did you test this when the fringe is inside the margins and the
> margins have non-zero width?

Yes. It does exactly what you expect (i.e. if
`mode-line-right-align-edge' is set to `right-fringe' then align
to the fringe, it set to `right-margin' etc.). Setting
`mode-line-right-align-edge' to `window' aligns to the right of
the window even in these circumstances.

> The call to string-pixel-width will significantly slow down redisplay
> of the mode line.

Yes, unfortunately.

> I wonder whether this feature should be implemented in C instead, to
> avoid the slowdown.

This would be great, but I definitely don't have the skills to do it.
Unless someone else does this, perhaps we could include my lisp
implementation for now, document the slowness (in the docstring),
and put a C implementation on the wishlist/TODO?

> This should use display-graphic-p, not window-system.

Fixed.

> Did you test this in a session which has both GUI and TTY frames?

Yes, it behaves correctly (i.e. right-aligns in both, even when the
same buffer is simultaneously displayed in both).

> From: 	Juri Linkov
> Date: 	Sun, 02 Apr 2023 19:19:01 +0300

> Here `format-mode-line' returns an empty string when
> `mode-line-format-right-align' was added in the middle of
> `mode-line-format'. For a strange reason, it expects that
> `mode-line-format' should start with a string. So everything is fine
> after replacing in your patch

Thanks for pointing this out. I've fixed it in the new patch (though my
fix uses a back-quote construction, but the effect is the same).

Hope the new version is better. Thoughts?

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-right-align-in-mode-line.patch --]
[-- Type: text/x-diff; name=0001-Support-right-align-in-mode-line.patch, Size: 4513 bytes --]

From 770e2a0617c650755f1be3de15ffbe13a9664a53 Mon Sep 17 00:00:00 2001
From: Hugo Heagren <hugo@heagren.com>
Date: Sat, 1 Apr 2023 22:27:25 +0100
Subject: [PATCH] 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'.
---
 lisp/bindings.el | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/lisp/bindings.el b/lisp/bindings.el
index 34aa8399a96..7ba9f325061 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -304,6 +304,70 @@ mode-line-process
 ;;;###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.
+
+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
+- right: synonym for right-margin (supported because this is how the
+  display property understands this, see info node `(elisp)Specified
+  Space'.)"
+  :type '(choice (const right)
+                 (const right-margin)
+                 (const right-fringe)
+                 (const window))
+  :group 'mode-line)
+
+(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
+                                           ((or 'right '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
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-05-06 14:14   ` hugo
@ 2023-05-06 14:39     ` Eli Zaretskii
  2023-06-05 20:45       ` hugo
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-05-06 14:39 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> Date: Sat, 06 May 2023 15:14:24 +0100
> From: hugo@heagren.com
> Cc: 62606@debbugs.gnu.org
> 
> > One possible issue with right alignment is that when the total size of
> > the mode-line text changes (e.g., the mode lighter changes), the
> > leftmost part of it will move horizontally, something that could be
> > unpleasant and even annoying.
> 
> This doesn't happen with my proposed setup (though I agree it would be
> annoying if it did!). The user includes the symbol
> `mode-line-format-right-align' in their mode line format. This is a
> variable which holds a mode-line construct `(:eval
> (mode-line-format-right-align))'. So whenever the mode-line is reloaded
> (and therefore, whenever the length could change), the space used to pad
> the right-aligned part to the right is recalculated.

That recalculation is what I alluded to: the space will be different
depending on the size of the mode-line text.

> > Also, what happens if the mode-line text is longer than the window
> > width.  What are user expectations in that case, and does :align-to
> > meet those expectations?
> 
> Then the text overflows to the right.

I'm not sure everyone will agree with your expectations.

> > This should use display-graphic-p, not window-system.
> 
> Fixed.
> 
> > Did you test this in a session which has both GUI and TTY frames?
> 
> Yes, it behaves correctly (i.e. right-aligns in both, even when the
> same buffer is simultaneously displayed in both).

And if then you delete all the GUI frames and only the TTY frames
remain?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-05-06 14:39     ` Eli Zaretskii
@ 2023-06-05 20:45       ` hugo
  2023-06-06 11:24         ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: hugo @ 2023-06-05 20:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 62606

On 2023-05-06 15:39, Eli Zaretskii wrote:
> > > One possible issue with right alignment is that when the total size of
> > > the mode-line text changes (e.g., the mode lighter changes), the
> > > leftmost part of it will move horizontally, something that could be
> > > unpleasant and even annoying.
> >
> > This doesn't happen with my proposed setup (though I agree it would be
> > annoying if it did!). The user includes the symbol
> > `mode-line-format-right-align' in their mode line format. This is a
> > variable which holds a mode-line construct `(:> eval
> > (mode-line-format-right-align))'. So whenever the mode-line is reloaded
> > (and therefore, whenever the length could change), the space used to pad
> > the right-aligned part to the right is recalculated.
> 
> That recalculation is what I alluded to: the space will be different
> depending on the size of the mode-line text.

I confess I am very confused. Let's say we have a modeline like this,
with parts L (left-aligned), M (middle - displays as empty space) and R
(right-aligned):

|--L--|-------M-------|-R-|
Foo bar                 X

If L gets longer then:
- M will get shorter
- R will stay the same

So we get:
|--L-----|----M-------|-R-|
Foo barrrr              X

Is this what you're worried about? If so, I don't think it's much of a
cause for concern. I modelled my function on
`tab-bar-format-align-right', which works in a very similar way. It also
strikes me that something like this happens anyway already: if we have a
mode-line with just a left-aligned lighter, and the lighter gets longer 
(or
shorter), then the space between the end of the lighter and the edge of
the screen (i.e. M+R) gets smaller (or bigger). Isn't this to be 
expected?

If this isn't the effect you're worried about, could you explain in more
detail?

> > > Also, what happens if the mode-line text is longer than the window
> > > width. What are user expectations in that case, and does :align-to
> > > meet those expectations?
> >
> > Then the text overflows to the right.
> 
> I'm not sure everyone will agree with your expectations.

The only alternative I can think of is that the right-aligned part stay
visible, and the other text overflows 'behind' it. Personally I don't
think this would make much sense, but I can see that some people might
prefer it. I suppose the best thing to do would be to add an option to
control the behaviour, but I've had a look at the code and I have no
idea how to implement the other version---the current behaviour is what
happens by default and it just seemed right to me.

> > > This should use display-graphic-p, not window-system.
> >
> > Fixed.
> >
> > > Did you test this in a session which has both GUI and TTY frames?
> >
> > Yes, it behaves correctly (i.e. right-aligns in both, even when the
> > same buffer is simultaneously displayed in both).
> 
> And if then you delete all the GUI frames and only the TTY frames
> remain?

Same effect -- the right-aligned part is still right-aligned in the 
remaining
TTY frames.

Hope that helps.

Hugo





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-05 20:45       ` hugo
@ 2023-06-06 11:24         ` Eli Zaretskii
  2023-06-09 12:47           ` hugo
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-06 11:24 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> Date: Mon, 05 Jun 2023 21:45:17 +0100
> From: hugo@heagren.com
> Cc: 62606@debbugs.gnu.org
> 
> On 2023-05-06 15:39, Eli Zaretskii wrote:
> > > > One possible issue with right alignment is that when the total size of
> > > > the mode-line text changes (e.g., the mode lighter changes), the
> > > > leftmost part of it will move horizontally, something that could be
> > > > unpleasant and even annoying.
> > >
> > > This doesn't happen with my proposed setup (though I agree it would be
> > > annoying if it did!). The user includes the symbol
> > > `mode-line-format-right-align' in their mode line format. This is a
> > > variable which holds a mode-line construct `(:> eval
> > > (mode-line-format-right-align))'. So whenever the mode-line is reloaded
> > > (and therefore, whenever the length could change), the space used to pad
> > > the right-aligned part to the right is recalculated.
> > 
> > That recalculation is what I alluded to: the space will be different
> > depending on the size of the mode-line text.
> 
> I confess I am very confused. Let's say we have a modeline like this,
> with parts L (left-aligned), M (middle - displays as empty space) and R
> (right-aligned):
> 
> |--L--|-------M-------|-R-|
> Foo bar                 X
> 
> If L gets longer then:
> - M will get shorter
> - R will stay the same
> 
> So we get:
> |--L-----|----M-------|-R-|
> Foo barrrr              X
> 
> Is this what you're worried about? If so, I don't think it's much of a
> cause for concern.

No, I was talking about the case where the R part becomes longer.

> I modelled my function on
> `tab-bar-format-align-right', which works in a very similar way.

IMNSHO, that mopdel is not the ideal one.

> It also
> strikes me that something like this happens anyway already: if we have a
> mode-line with just a left-aligned lighter, and the lighter gets longer 
> (or
> shorter), then the space between the end of the lighter and the edge of
> the screen (i.e. M+R) gets smaller (or bigger). Isn't this to be 
> expected?

Yes.  But with left alignment the beginning of the text never moves,
only the end.  With right alignment, the beginning moves.  It's
jarring, IMO.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-06 11:24         ` Eli Zaretskii
@ 2023-06-09 12:47           ` hugo
  2023-06-09 13:13             ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: hugo @ 2023-06-09 12:47 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 62606

On 2023-06-06 12:24, Eli Zaretskii wrote:
> No, I was talking about the case where the R part becomes longer.

I see now. So you're worried about the difference between these two:

|L|-------M-----|--R--|
  X              Foo Bar

|L|-------M---|---R---|
  X            Foo Barrr

And how `Foo' moves left in the second case. I understand.

>> I modelled my function on
>> `tab-bar-format-align-right', which works in a very similar way.
> 
> IMNSHO, that mopdel is not the ideal one.

I'm not sure what you mean? If you're talking about what the function
/does/, isn't this just a matter of preference? You might not like using
it, but I /do/ like it. I wanted a function which does exactly what that
function does, but for the modeline. I find the way it displays
information perfectly natural. Clearly enough other people also do that
the tab-bar equivalent was worth building and using. If you're talking
about the internals, could you explain a bit more?

> Yes.  But with left alignment the beginning of the text never moves,
> only the end.  With right alignment, the beginning moves.  It's
> jarring, IMO.

Right, I see. But that's only true of the text as a whole isn't it?
Consider a modeline with two constructs, FOO and BAR: '(FOO " " BAR).
Both are left aligned. Say FOO prints "foo" and BAR prints "bar", so we
have:

foo bar

If FOO now prints something longer (e.g. "foooooooo", the beginning of 
the
BAR part will move, thus:

foo bar
     ----->
foooooooo bar

So with left aligned text, sometimes the beginning (of some piece of
information) moves as well). This happens for real if FOO is something
like the buffer name -- BAR will move whenever we switch to a buffer
with a name of a different length. I think if people who want
left-aligned text can put up with this, then people who want
right-aligned text will probably put up with the equivalent problem.

In fact, it was precisely /because/ of this kind of situation, that I
originally wanted to right-align some of my information, so that it
/wouldn't/ move when elements to the left of it changed length. By
right-aligning, I can completely control the space between them.

Overall, I can see that this isn't a feature you like, and probably not
one you would use either, but it's similar enough (in function and in
problems) to other stuff already in Emacs that it seems pretty
reasonable to me.

best,

Hugo





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-09 12:47           ` hugo
@ 2023-06-09 13:13             ` Eli Zaretskii
       [not found]               ` <f60acc21a937b413f6528264f233ebfe@heagren.com>
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-09 13:13 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> Date: Fri, 09 Jun 2023 13:47:55 +0100
> From: hugo@heagren.com
> Cc: 62606@debbugs.gnu.org
> 
> On 2023-06-06 12:24, Eli Zaretskii wrote:
> >> I modelled my function on
> >> `tab-bar-format-align-right', which works in a very similar way.
> > 
> > IMNSHO, that mopdel is not the ideal one.
> 
> I'm not sure what you mean? If you're talking about what the function
> /does/, isn't this just a matter of preference? You might not like using
> it, but I /do/ like it. I wanted a function which does exactly what that
> function does, but for the modeline. I find the way it displays
> information perfectly natural. Clearly enough other people also do that
> the tab-bar equivalent was worth building and using. If you're talking
> about the internals, could you explain a bit more?

Put mildly, the implementation is IMO very complicated, and hard to
follow and maintain/develop.

> > Yes.  But with left alignment the beginning of the text never moves,
> > only the end.  With right alignment, the beginning moves.  It's
> > jarring, IMO.
> 
> Right, I see. But that's only true of the text as a whole isn't it?
> Consider a modeline with two constructs, FOO and BAR: '(FOO " " BAR).
> Both are left aligned. Say FOO prints "foo" and BAR prints "bar", so we
> have:
> 
> foo bar
> 
> If FOO now prints something longer (e.g. "foooooooo", the beginning of 
> the
> BAR part will move, thus:
> 
> foo bar
>      ----->
> foooooooo bar
> 
> So with left aligned text, sometimes the beginning (of some piece of
> information) moves as well). This happens for real if FOO is something
> like the buffer name -- BAR will move whenever we switch to a buffer
> with a name of a different length. I think if people who want
> left-aligned text can put up with this, then people who want
> right-aligned text will probably put up with the equivalent problem.

Yes, but with the current mode-line structure, we take care to prevent
that by leaving enough padding for the extra text to have space,
before it starts shifting what's after it.  With right-alignment,
that's harder to accomplish.

> In fact, it was precisely /because/ of this kind of situation, that I
> originally wanted to right-align some of my information, so that it
> /wouldn't/ move when elements to the left of it changed length. By
> right-aligning, I can completely control the space between them.

You can accomplish that by padding, even without right-alignment, I
think.

> Overall, I can see that this isn't a feature you like, and probably not
> one you would use either, but it's similar enough (in function and in
> problems) to other stuff already in Emacs

Sadly.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
       [not found]               ` <f60acc21a937b413f6528264f233ebfe@heagren.com>
@ 2023-06-09 14:52                 ` Eli Zaretskii
  0 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-09 14:52 UTC (permalink / raw)
  To: hugo, Stefan Monnier, Lars Ingebrigtsen; +Cc: 62606

> Date: Fri, 09 Jun 2023 15:28:36 +0100
> From: hugo@heagren.com
> 
> On 2023-06-09 14:13, Eli Zaretskii wrote:
> > You can accomplish that by padding, even without right-alignment, I
> > think.
> 
> Yes you can. I just prefer how right-alignment looks. You can even think 
> of right-alignment as ane extreme case of padding, if
> 
> >> Overall, I can see that this isn't a feature you like, and probably 
> >> not
> >> one you would use either, but it's similar enough (in function and in
> >> problems) to other stuff already in Emacs
> > 
> > Sadly.
> 
> Since you don't agree with the general implementation or function of
> this patch, I don't think I'm going to be able to do anything to make it
> more acceptable for you.
> 
> I've fixed all the technical issues which have been pointed out (except
> the thing about calling `string-pixel-width', that's way beyond my
> skills atm). Clearly some people (whoever wrote and now uses
> `tab-bar-format-align-right') like features like this, so I think this
> is worth merging, in basically the state its in now. If you don't
> though, I'm happy to publish it as a separate package. What do you
> think?

Let's hear from others.  Stefan, Lars, any thoughts?  Does anyone else
have any comments about this proposed feature?

In any case, before we accept this, it must be documented and called
out in NEWS.  Also, the defcustom should have a :version tag.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-04-01 22:27 bug#62606: [PATCH] function to align mode-line elements to right hugo
  2023-04-02  5:47 ` Eli Zaretskii
  2023-04-02 16:19 ` Juri Linkov
@ 2023-06-09 16:03 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-06-09 16:17   ` Eli Zaretskii
  2023-06-19 19:06   ` bug#62606: [PATCH] function to align mode-line elements to right hugo
       [not found] ` <handler.62606.D62606.168862894016990.notifdone@debbugs.gnu.org>
  3 siblings, 2 replies; 24+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-09 16:03 UTC (permalink / raw)
  To: hugo; +Cc: 62606

> Let's hear from others.  Stefan, Lars, any thoughts?  Does anyone else
> have any comments about this proposed feature?

FWIW, my mode-lines always tend to overflow to the right, so I wouldn't
be able to use that functionality, but I have no doubt that it would be
welcome by several users, based on some of the mode-lines I've
seen elsewhere.

Also, the code is fairly simple and self-contained, so I don't see
a good reason not to include that.

Some comments about the code below:

> +(defcustom mode-line-right-align-edge 'window
> +  "Where function `mode-line-format-right-align' should align to.
> +
> +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
> +- right: synonym for right-margin (supported because this is how the
> +  display property understands this, see info node `(elisp)Specified
> +  Space'.)"

I think symbols like `right-fringe` should be enclosed in `...'
in docstrings.  Also, I see no reason to encourage the use of an alias,
so I'd drop either `right-margin` or `right` from the doc (especially
since it doesn't really come for free in the code).

As a user I'd wonder if "align to right-fringe" means to align to
the beginning (i.e. left side) or end (i.e. right side) of the
right fringe.

[ And now I wonder: can Emacs have R2L modelines?  If so, what should
  happen in those?  ]

> +(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."

AFAICT, this function is internal to the implementation of the
`mode-line-format-right-align` mode-line spec.  So maybe it should use
"--" in its name.

> +  (let* ((rest (cdr (memq 'mode-line-format-right-align
> +			  mode-line-format)))

This is the ugly part of the implementation: the
`mode-line-format-right-align` has to "find itself".
I wonder if/how we could get rid of this wrinkle.

Maybe instead of a `mode-line-format` of the form:

    (..LEFT.. mode-line-format-right-align ..RIGHT..)

an alternative is to use

    (..LEFT.. (:eval (mode-line-format-right-align ..RIGHT..)))

I wonder if it would work as well (I'm worried that it means that
`..RIGHT..` is not processed directly by the C code by goes through the
`format-mode-line` ELisp function to turn it into an ELisp string
first and that could affect the result).

It would have the advantage that it doesn't process `..RIGHT..` twice,
and it should also be usable in `header-line-format` and friends.

It's not great tho :-(


        Stefan






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-09 16:03 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-06-09 16:17   ` Eli Zaretskii
  2023-06-09 16:52     ` bug#62606: R2L modelines (was: bug#62606: [PATCH] function to align mode-line elements to right) Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-06-19 19:06   ` bug#62606: [PATCH] function to align mode-line elements to right hugo
  1 sibling, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-09 16:17 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: hugo, 62606

> Cc: 62606@debbugs.gnu.org
> Date: Fri, 09 Jun 2023 12:03:02 -0400
> From:  Stefan Monnier via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> 
> [ And now I wonder: can Emacs have R2L modelines?  If so, what should
>   happen in those?  ]

We don't support that.  From display_mode_line:

  /* FIXME: This should be controlled by a user option.  But
     supporting such an option is not trivial, since the mode line is
     made up of many separate strings.  */
  it.paragraph_embedding = L2R;

and a more complete rationale in redisplay_tool_bar:

  /* FIXME: This should be controlled by a user option.  But it
     doesn't make sense to have an R2L tool bar if the menu bar cannot
     be drawn also R2L, and making the menu bar R2L is tricky due
     toolkit-specific code that implements it.  If an R2L tool bar is
     ever supported, display_tool_bar_line should also be augmented to
     call unproduce_glyphs like display_line and display_string
     do.  */

Bottom line: Emacs doesn't support making the UI right-to-left.
IMNSHO in IME, supporting that would be a lot of work for very little
benefit.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: R2L modelines (was: bug#62606: [PATCH] function to align mode-line elements to right)
  2023-06-09 16:17   ` Eli Zaretskii
@ 2023-06-09 16:52     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 24+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-06-09 16:52 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hugo, 62606

>> [ And now I wonder: can Emacs have R2L modelines?  If so, what should
>>   happen in those?  ]
[...]
> Bottom line: Emacs doesn't support making the UI right-to-left.
> IMNSHO in IME, supporting that would be a lot of work for very little
> benefit.

Indeed, it seems to be of any real use, we'd first need to be able to
translate most of the elements (like mode names, menu titles, ...).

[ Sorry for this offtopic drift in the thread.  I'll stop here.  ]


        Stefan






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-09 16:03 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-06-09 16:17   ` Eli Zaretskii
@ 2023-06-19 19:06   ` hugo
  2023-06-24 12:05     ` Eli Zaretskii
  1 sibling, 1 reply; 24+ messages in thread
From: hugo @ 2023-06-19 19:06 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 62606

[-- Attachment #1: Type: text/plain, Size: 1774 bytes --]

On 2023-06-09 17:03, Stefan Monnier wrote:
> Also, the code is fairly simple and self-contained, so I don't see
> a good reason not to include that.

Thanks :)

> I think symbols like `right-fringe` should be enclosed in `...'
> in docstrings.

Fixed in new patch, attached.

> Also, I see no reason to encourage the use of an alias,
> so I'd drop either `right-margin` or `right` from the doc (especially
> since it doesn't really come for free in the code).

Fixed. Dropped `right', as it was the less descriptive version.

> As a user I'd wonder if "align to right-fringe" means to align to
> the beginning (i.e. left side) or end (i.e. right side) of the
> right fringe.

Documented (and included a link to relevant info node).

> AFAICT, this function is internal to the implementation of the
> `mode-line-format-right-align` mode-line spec.  So maybe it should use
> "--" in its name.

You're right -- Done.

> This is the ugly part of the implementation

Yes, I agree :(

> an alternative is to use
> 
>     (..LEFT.. (:eval (mode-line-format-right-align ..RIGHT..)))

I share your technical worries about this. I worry too that this might 
end
up being more confusing for users, because it invites such constructions
as:

(..LEFT.. (:eval (mode-line-format-right-align ..RIGHT..)) ..WHAT..)

Where the behaviour of ..WHAT.. is at best to be completely hidden, and
at worst undefined. If we use a single symbol, this can't happen.

I also think that, as a user, it's good to have consistent interfaces
for this sort of thing, and my proposed function is intended to work
just like `tab-bar-format-align-right', which is included as a symbol,
not a more complex construction.

> should also be usable in `header-line-format` and friends.

This would good though.

Hugo

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-right-align-in-mode-line.patch --]
[-- Type: text/x-diff; name=0001-Support-right-align-in-mode-line.patch, Size: 4483 bytes --]

From b9fb6399f38f250e9629e8350108ea934d4cfd97 Mon Sep 17 00:00:00 2001
From: Hugo Heagren <hugo@heagren.com>
Date: Sat, 1 Apr 2023 22:27:25 +0100
Subject: [PATCH] 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'.
---
 lisp/bindings.el | 63 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/lisp/bindings.el b/lisp/bindings.el
index 34aa8399a96..d6f12e64399 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -304,6 +304,69 @@ mode-line-process
 ;;;###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 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)
+
+(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
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-19 19:06   ` bug#62606: [PATCH] function to align mode-line elements to right hugo
@ 2023-06-24 12:05     ` Eli Zaretskii
  2023-06-26 10:06       ` hugo
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-24 12:05 UTC (permalink / raw)
  To: hugo; +Cc: monnier, 62606

> Cc: 62606@debbugs.gnu.org
> Date: Mon, 19 Jun 2023 20:06:58 +0100
> From: hugo@heagren.com
> 
> On 2023-06-09 17:03, Stefan Monnier wrote:
> > Also, the code is fairly simple and self-contained, so I don't see
> > a good reason not to include that.
> 
> Thanks :)
> 
> > I think symbols like `right-fringe` should be enclosed in `...'
> > in docstrings.
> 
> Fixed in new patch, attached.
> 
> > Also, I see no reason to encourage the use of an alias,
> > so I'd drop either `right-margin` or `right` from the doc (especially
> > since it doesn't really come for free in the code).
> 
> Fixed. Dropped `right', as it was the less descriptive version.
> 
> > As a user I'd wonder if "align to right-fringe" means to align to
> > the beginning (i.e. left side) or end (i.e. right side) of the
> > right fringe.
> 
> Documented (and included a link to relevant info node).
> 
> > AFAICT, this function is internal to the implementation of the
> > `mode-line-format-right-align` mode-line spec.  So maybe it should use
> > "--" in its name.
> 
> You're right -- Done.
> 
> > This is the ugly part of the implementation
> 
> Yes, I agree :(
> 
> > an alternative is to use
> > 
> >     (..LEFT.. (:eval (mode-line-format-right-align ..RIGHT..)))
> 
> I share your technical worries about this. I worry too that this might 
> end
> up being more confusing for users, because it invites such constructions
> as:
> 
> (..LEFT.. (:eval (mode-line-format-right-align ..RIGHT..)) ..WHAT..)
> 
> Where the behaviour of ..WHAT.. is at best to be completely hidden, and
> at worst undefined. If we use a single symbol, this can't happen.
> 
> I also think that, as a user, it's good to have consistent interfaces
> for this sort of thing, and my proposed function is intended to work
> just like `tab-bar-format-align-right', which is included as a symbol,
> not a more complex construction.
> 
> > should also be usable in `header-line-format` and friends.
> 
> This would good though.

Thanks.

This will need suitable additions to NEWS and the manual.

Also, we will need you to sign the copyright assignment paperwork, as
the size of the changes exceeds what we can accept without an
assignment.  Would you like to start your assignment paperwork rolling
at this time?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-24 12:05     ` Eli Zaretskii
@ 2023-06-26 10:06       ` hugo
  2023-06-26 11:55         ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: hugo @ 2023-06-26 10:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: monnier, 62606

> This will need suitable additions to NEWS and the manual.

Sure, I'll write a new patch as soon as I have time. Hopefully this 
week.

> Also, we will need you to sign the copyright assignment paperwork, as
> the size of the changes exceeds what we can accept without an
> assignment.  Would you like to start your assignment paperwork rolling
> at this time?

I'v already assinged copyright -- I've contributed to Emacs before.

Hugo





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-26 10:06       ` hugo
@ 2023-06-26 11:55         ` Eli Zaretskii
  2023-07-02 12:43           ` hugo
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2023-06-26 11:55 UTC (permalink / raw)
  To: hugo; +Cc: monnier, 62606

> Date: Mon, 26 Jun 2023 11:06:48 +0100
> From: hugo@heagren.com
> Cc: monnier@iro.umontreal.ca, 62606@debbugs.gnu.org
> 
> > This will need suitable additions to NEWS and the manual.
> 
> Sure, I'll write a new patch as soon as I have time. Hopefully this 
> week.

Thanks.

> > Also, we will need you to sign the copyright assignment paperwork, as
> > the size of the changes exceeds what we can accept without an
> > assignment.  Would you like to start your assignment paperwork rolling
> > at this time?
> 
> I'v already assinged copyright -- I've contributed to Emacs before.

Yes, I see it now, sorry.  (I didn't find it before because your name
appears in the list of assignment with a typo.  Should be fixed soon.)





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-06-26 11:55         ` Eli Zaretskii
@ 2023-07-02 12:43           ` hugo
  2023-07-06  7:35             ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: hugo @ 2023-07-02 12:43 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: monnier, 62606

[-- Attachment #1: Type: text/plain, Size: 759 bytes --]

> This will need suitable additions to NEWS

New patch attached with addition to NEWS (and a version tag for the
defcustom, which I forgot last time). I haven't marked the news item
with +++ or ---, wasn't sure whether I've done everything I need to yet.

> and the manual

I've added documentation to the 'Mode Line Variables' section of the
Elisp manual. This seemed to be where similar things were documented.
Updated my commit message to reflect this.

>> I'v already assinged copyright -- I've contributed to Emacs before.
> Yes, I see it now, sorry. (I didn't find it before because your name
> appears in the list of assignment with a typo. Should be fixed soon.)

Do I need to update my AUTHORs entry with this new change?

Hope that's all good.

Hugo

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-right-align-in-mode-line.patch --]
[-- Type: text/x-diff; name=0001-Support-right-align-in-mode-line.patch, Size: 5896 bytes --]

From ce5f8b86a56eb51f4c320a86de0c0444c9f052ce Mon Sep 17 00:00:00 2001
From: Hugo Heagren <hugo@heagren.com>
Date: Sat, 1 Apr 2023 22:27:25 +0100
Subject: [PATCH] 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.
---
 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 @@ Mode Line Variables
 
 @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 3061a147b26..352c69f1cb1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -87,6 +87,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'.
+
 \f
 * 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 @@ mode-line-process
 ;;;###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
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-07-02 12:43           ` hugo
@ 2023-07-06  7:35             ` Eli Zaretskii
  0 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2023-07-06  7:35 UTC (permalink / raw)
  To: hugo; +Cc: 62606-done, monnier

> Date: Sun, 02 Jul 2023 13:43:21 +0100
> From: hugo@heagren.com
> Cc: monnier@iro.umontreal.ca, 62606@debbugs.gnu.org
> 
> > This will need suitable additions to NEWS
> 
> New patch attached with addition to NEWS (and a version tag for the
> defcustom, which I forgot last time). I haven't marked the news item
> with +++ or ---, wasn't sure whether I've done everything I need to yet.
> 
> > and the manual
> 
> I've added documentation to the 'Mode Line Variables' section of the
> Elisp manual. This seemed to be where similar things were documented.
> Updated my commit message to reflect this.
> 
> >> I'v already assinged copyright -- I've contributed to Emacs before.
> > Yes, I see it now, sorry. (I didn't find it before because your name
> > appears in the list of assignment with a typo. Should be fixed soon.)
> 
> Do I need to update my AUTHORs entry with this new change?
> 
> Hope that's all good.

Thanks, installed on the master branch, and closing the bug.

In the future, please mention the bug number in the log message, when
that number becomes known to you (basically, if you post an updated
patch, the bug number should already be known).





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
       [not found] ` <handler.62606.D62606.168862894016990.notifdone@debbugs.gnu.org>
@ 2023-07-14 16:37   ` Juri Linkov
  2023-07-17 17:56     ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2023-07-14 16:37 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hugo, 62606

>> Hope that's all good.
>
> Thanks, installed on the master branch, and closing the bug.

I customized the mode-line to use variable-pitch fonts with

  (set-face-attribute 'mode-line nil :inherit '(variable-pitch))

that produces wrong right-alignment.  This problem was already fixed
in `tab-bar-format-align-right' by using `add-face-text-property'.
This patch does the same for the mode-line:

diff --git a/lisp/bindings.el b/lisp/bindings.el
index f1a75b080be..047492e82d4 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -338,7 +338,10 @@ mode--line-format-right-align
   (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)))
+	 (rest-width (progn
+                       (add-face-text-property
+                        0 (length rest-str) 'mode-line t rest-str)
+                       (string-pixel-width rest-str))))
     (propertize " " 'display
 		;; The `right' spec doesn't work on TTY frames
 		;; when windows are split horizontally (bug#59620)





^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2023-07-14 16:37   ` Juri Linkov
@ 2023-07-17 17:56     ` Juri Linkov
       [not found]       ` <CALDnm53v4O9cYcYwcqGpYVb4xVOw6t+FM1xX21k7HFxWyuiSaQ@mail.gmail.com>
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2023-07-17 17:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hugo, 62606

> I customized the mode-line to use variable-pitch fonts with
>
>   (set-face-attribute 'mode-line nil :inherit '(variable-pitch))
>
> that produces wrong right-alignment.  This problem was already fixed
> in `tab-bar-format-align-right' by using `add-face-text-property'.
> This patch does the same for the mode-line:

Now pushed to master.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
       [not found]             ` <835xznro5i.fsf@gnu.org>
@ 2024-01-21 10:20               ` João Távora
  2024-01-21 10:27                 ` Eli Zaretskii
  0 siblings, 1 reply; 24+ messages in thread
From: João Távora @ 2024-01-21 10:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hugo, 62606, juri

On Sun, Jan 21, 2024 at 10:12 AM Eli Zaretskii <eliz@gnu.org> wrote:

> Thanks, but I don't want to expose the tail of the mode-line to Lisp,
> let alone do it on every iteration through mode-line-format.

Why?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2024-01-21 10:20               ` João Távora
@ 2024-01-21 10:27                 ` Eli Zaretskii
  2024-01-21 10:39                   ` João Távora
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2024-01-21 10:27 UTC (permalink / raw)
  To: João Távora; +Cc: hugo, 62606, juri

> From: João Távora <joaotavora@gmail.com>
> Date: Sun, 21 Jan 2024 10:20:46 +0000
> Cc: juri@linkov.net, hugo@heagren.com, 62606@debbugs.gnu.org
> 
> On Sun, Jan 21, 2024 at 10:12 AM Eli Zaretskii <eliz@gnu.org> wrote:
> 
> > Thanks, but I don't want to expose the tail of the mode-line to Lisp,
> > let alone do it on every iteration through mode-line-format.
> 
> Why?

Because I have more than enough gray hair from debugging and fixing
problems related to this stuff, including the
mode-line-format-right-align itself and the issues it causes.  I was
(mildly) against installing this feature, for the same reason, and I
certainly won't agree to let this particular tail to wag the dog any
more than it already has.  It's bad enough to have a non-trivial
display feature that is not maintained by anyone; adding more features
to it is really too much.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#62606: [PATCH] function to align mode-line elements to right
  2024-01-21 10:27                 ` Eli Zaretskii
@ 2024-01-21 10:39                   ` João Távora
  0 siblings, 0 replies; 24+ messages in thread
From: João Távora @ 2024-01-21 10:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hugo, 62606, juri

On Sun, Jan 21, 2024 at 10:28 AM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: João Távora <joaotavora@gmail.com>
> > Date: Sun, 21 Jan 2024 10:20:46 +0000
> > Cc: juri@linkov.net, hugo@heagren.com, 62606@debbugs.gnu.org
> >
> > On Sun, Jan 21, 2024 at 10:12 AM Eli Zaretskii <eliz@gnu.org> wrote:
> >
> > > Thanks, but I don't want to expose the tail of the mode-line to Lisp,
> > > let alone do it on every iteration through mode-line-format.
> >
> > Why?
>
> Because I have more than enough gray hair from debugging and fixing
> problems related to this stuff, including the
> mode-line-format-right-align itself and the issues it causes.  I was
> (mildly) against installing this feature, for the same reason, and I
> certainly won't agree to let this particular tail to wag the dog any
> more than it already has.  It's bad enough to have a non-trivial
> display feature that is not maintained by anyone; adding more features
> to it is really too much.

Right.  But any technical arguments?

What's the difference between solving this in Lisp, which you
would accept, and solving this in C+Lisp?  It's a two line change
like a zillion others just one of the lines happens to be
a single assignment in C.

I can offer to maintain this feature, or the whole display_mode_element
& friends.  Any other grey-hair inducing outstanding bugs (apart from this
one I've found).

João





^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2024-01-21 10:39 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-01 22:27 bug#62606: [PATCH] function to align mode-line elements to right hugo
2023-04-02  5:47 ` Eli Zaretskii
2023-05-06 14:14   ` hugo
2023-05-06 14:39     ` Eli Zaretskii
2023-06-05 20:45       ` hugo
2023-06-06 11:24         ` Eli Zaretskii
2023-06-09 12:47           ` hugo
2023-06-09 13:13             ` Eli Zaretskii
     [not found]               ` <f60acc21a937b413f6528264f233ebfe@heagren.com>
2023-06-09 14:52                 ` Eli Zaretskii
2023-04-02 16:19 ` Juri Linkov
2023-06-09 16:03 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-06-09 16:17   ` Eli Zaretskii
2023-06-09 16:52     ` bug#62606: R2L modelines (was: bug#62606: [PATCH] function to align mode-line elements to right) Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-06-19 19:06   ` bug#62606: [PATCH] function to align mode-line elements to right hugo
2023-06-24 12:05     ` Eli Zaretskii
2023-06-26 10:06       ` hugo
2023-06-26 11:55         ` Eli Zaretskii
2023-07-02 12:43           ` hugo
2023-07-06  7:35             ` Eli Zaretskii
     [not found] ` <handler.62606.D62606.168862894016990.notifdone@debbugs.gnu.org>
2023-07-14 16:37   ` Juri Linkov
2023-07-17 17:56     ` Juri Linkov
     [not found]       ` <CALDnm53v4O9cYcYwcqGpYVb4xVOw6t+FM1xX21k7HFxWyuiSaQ@mail.gmail.com>
     [not found]         ` <83fryrs1l8.fsf@gnu.org>
     [not found]           ` <87edebjcku.fsf@gmail.com>
     [not found]             ` <835xznro5i.fsf@gnu.org>
2024-01-21 10:20               ` João Távora
2024-01-21 10:27                 ` Eli Zaretskii
2024-01-21 10:39                   ` João Távora

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).