On May 3, 2021, at 3:50 AM, martin rudalics <rudalics@gmx.at> wrote:

>> Sure, but the event gives you the window, and through it the buffer of
>> that window, so I see no particular reason to make the window
>> selected.
>
>
> A given buffer may appear in multiple windows, which likely will have
> different “window-start” and “window-end”.  So you have to find the
> line position in the buffer relevant for that particular window.  Also
> tying me to this is the fact that the format-mode-line method
> obviously uses windows, not buffers.

I'm still missing you.  Both `window-start' and `window-point' have a
WINDOW argument.  So running `get-buffer-window-list' for the buffer you
want to manage and calling the former for each window you get that way
should all do what you want.

Since I’m working on the mode line, I am managing windows, not buffers. Mode line :eval forms handle this issue for you automatically, by quietly selecting the appropriate window (even inactive ones).  So nothing is needed there.  Only on modeline _mouse events_ do I need to target a specific window (the one mentioned in the event).  

For calculating the line number in a window which may or may not be selected, (format-mode-line "%l” 0 win) has a window argument, but it does *not* have a position argument.  It takes its position from (as far as I can tell) the window-point of its window argument.  So I need to move window-point and immediately restore it if I want to use format-mode-line.  If the window were selected, a simple save-excursion would be enough.  But I cannot first select the window or I get “mode line flashing".  I need a mythical `save-excursion-in-window', if you will.

But perhaps I am missing you?  If you think there’s a simpler approach that permits the format-mode-line line number workaround without set-window-point, could you share some pseudo-code?

I recognize I could avoid this issue if an optimization like Stefan’s nlinum caching would work well enough, in which case I can drop the use of format-mode-line, and avoid moving window-point at all.  The cost is an after-change-function always running, which some people might object to (me included).   And now simply 

If line-number-at-pos were more performant, and not dependent on position within the buffer, I could avoid both of these things (format-mode-line and an after-change-function).  Quick overview of timing per line-num calc on /usr/dict/words (236k lines) @ (point-max):

line-number-at-pos: 21ms
set-window-point, (string-to-number (format-line-mode %l), restore window-point: 2ms

And please keep in mind: Calling `select-window' in an :eval form within
`mode-line-format' means asking for trouble.  Calling `set-window-start'
and `set-window-point' anywhere within `mode-line-format' or a hook like
`window-scroll-functions' or `window-state-change-functions' means
asking for more trouble.  All these serve to react to changes in the
window configuration but should never change that configuration itself.

I’m not using select-window at all now.  On set-window-point, see above; I admit it’s not clear to me why setting and restoring window-point is any worse than a save-excursion.  

But I will certainly need set-window-start for handling mouse-based events on the mode line (click/drag/scroll).  Perhaps I didn’t make it clear that set-window-start will only be called in mouse-based event callbacks on the mode line; apologies if so.  If even this is problematic in your view, could you clarify the sort of “trouble” it would cause?  Other mouse events in the mode-line call things like ‘previous-buffer, so it’s not clear to me why set-window-start would lead to any special issues when driven by mouse events.