[Top][All Lists]

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

Re: Framework extending window functions for Follow Mode (etc.).

From: Alan Mackenzie
Subject: Re: Framework extending window functions for Follow Mode (etc.).
Date: Sun, 8 Nov 2015 19:57:49 +0000
User-agent: Mutt/1.5.23 (2014-03-12)

Hello, Martin.

On Sun, Nov 08, 2015 at 07:10:51PM +0100, martin rudalics wrote:
>  > Well, it's now been renamed `set-window-start-group-function', but
>  > basically, yes.  The caller would call `set-window-start' without having
>  > to know whether FM is active or not.

>  >> If so, then how comes that this argument is called "GROUP"?

>  > The idea is that a general package, like isearch, can call

>  >      (set-window-start win ws nil 'group)

>  > and this will do the Right Thing regardless of whether Follow Mode (or
>  > whatever) is active or not.  GROUP non-nil just says "work on the whole
>  > group of windows if there is one".

> So the idea is that ‘follow-mode’ sets `set-window-start-group-function'
> to say ‘follow-mode-set-window-start’ which is then called whenever
> ‘isearch-mode’ calls ‘set-window-start’.  Since you don't do this on a
> per window basis, ‘follow-mode-set-window-start' can be also called for
> windows that are not managed by ‘follow-mode’ ....

No.  `set-window-start-group-function' is buffer local.  The state of
being managed by Follow Mode is also a buffer local thing - in any given
Emacs session, either all windows displaying foo.el or none of them have
Follow Mode active.  If they are in different frames, FM manages them as
disjoint groups.

> .... probably in the hope that ‘follow-mode-set-window-start’
> temporarily binds ‘set-window-start-group-function’ to nil around a
> nested call to ‘set-window-start’.

The recursive call to `set-window-start' has its GROUP parameter nil.
There is no need for such temporary binding.

> It strikes me as a bad idea that ‘follow-mode-set-window-start’ has to
> take care of windows that are not in ‘follow-mode’.

It doesn't, because of the buffer localness of `s-w-s-g-f', combined with
the all-or-nothingness of Follow Mode on a buffer.

> And you preclude the simultaneous use of a second mode operating on a
> disjoint group of windows maybe even on another frame - there's only one
> global ‘set-window-start-group-function’ variable.  Your approach
> doesn't scale.

If the disjoint group is displaying a different buffer, there is no
problem, the xx-group-function's all being buffer local.  If it's the
same buffer - well, it sounds like rather a hypothetical case to me.  It
would involve the set-window-start-group-function having to chose which
of the two schemes it would use, depending on some flag, frame parameter,
or what have you.  Nothing would be precluded.

>  >> An argument with such a name should be non-nil only in calls by
>  >> ‘follow-mode’ or other packages that know that WINDOW is part of some
>  >> "group".

>  > Absolutely the reverse.  See above.  Actually, most calls from Follow
>  > Mode, which will be about rearranging the individual windows, will be
>  > called with GROUP set to nil.

> Obviously so.  I consider this a drawback.

If things were to be implemented with a window parameters as you suggest,
this would add a lot to the complexity of Follow Mode, since each call to
one of the window primitives would have to be surrounded by code
nullifying a window parameter.  Adding GROUP optional arguments is, by
comparison, trivial and non-intrusive.  I've done it.

>  >> ‘isearch-mode’ has no idea whether WINDOW is part of a group and should
>  >> not have to.

>  > By my proposal, it wouldn't have to.  But it would have to be aware of
>  > the possibility.

> By my proposal it wouldn't even have to be aware of the possibility.

It would have to be.  For a hypothetical example, say there's some minor
mode which keeps something or other in a buffer at least n lines away
from a window boundary.  Its maintainer would need to decide whether that
just means n lines from the top/bottom of the entire FM group, or from
the "internal" boundaries too.

>  >> OTOH somebody might want ‘set-window-start’ to behave specially even
>  >> when WINDOW is not part of a group.

>  > This sounds a bit hypothetical.  Do you have an example of the sort of
>  > thing this might be?

> I can easily devise one: Suppose I want text-mode windows to always
> start at the beginning of a paragraph and prog-mode windows at the
> beginning of a defun provided it is within easy reach, say at most three
> lines, from the position proposed by ‘set-window-start’.  Do we really
> want to tell people that in such case they should use an argument called

How would you program that now, without the GROUP facility?  That's how
you'd still do it with GROUP in existence.  To use the
xx-group-function's for this sort of thing would be an abuse of them.

[ .... ]

>  > The problem I see with that is that when some code wants to set the
>  > window start of an individual window, it's going to have to do something
>  > like this:

>  >      (let ((save-ws-param (window-parameter win 'set-window-start)))
>  >        (set-window-parameter win 'window-start nil)
>  >        (set-window-start win ws)
>  >        (set-window-parameter win 'window-start save-ws-param))

>  > , which is rather clumsy.  In fact, the situation almost calls for a
>  > macro which would look something like:

>  >      (with-window-parameters-set win '((set-window-start . nil))
>  >        (set-window-start win ws))

>  > , but even this isn't very pretty.

> It would do

> (let ((ignore-window-parameters t))
>    (set-window-start win ws))

That's assuming that _all_ window parameters have to be ignored at once.
But even that pair of lines is over twice as bulky as simply writing

    (set-windows-start win ws)


I see a further problem with the window parameters approach.  When a
different buffer becomes displayed in such a window, the parameter would
stay set.  There is a fundamental mismatch here: Follow Modishness is
associated with a buffer (not a set of windows); window parameters are
fundamentally attached to windows.  This clash is bound to cause
awkwardnesses.  So, to cope with temporary buffer changes, one would have
to build whole complexes of mechanisms to temporarily delete the window
parameters, and so on.

[ .... ]

>  > But the criterion as to whether a `set-window-start' call wants to
>  > operate on an individual window or the group (if there is one) would be
>  > attached to the window rather than to the call.  I don't think this is
>  > right.

> Above I tried to explain why attaching the criterion to a call is
> insufficient.

It may or may not be sufficient, but it is necessary.  I'm trying to
imagine things if `set-window-start''s NOFORCE argument had instead been
implemented as a window parameter.  It would make programming windows
that bit more clumsy than it is at the moment.  I can't see at all where
the GROUP argument is any different.

>  > They cannot be.  They are packages which do their own window
>  > manipulation, and so will have to make up their minds whether a
>  > particular `window-start' or `pos-visiblie-in-window-p' refers to an
>  > individual window or to the group (if any).  This distinction is
>  > essentially encapsulated in the package.

> Which package?

Edebug, for example.  It gathers things like `window-start's, so that it
can rebuild a window layout when switching between modes.  Or something.
Here, these calls clearly call for GROUP to be nil.  If the window
parameter approach were chosen, edebug.el would need modifying.  As
would, potentially, lots of other packages.

>  > It is more convenient for a
>  > package to set an optional parameter to nil or non-nil than to have to
>  > "bind" a window parameter to nil.

> I suppose the package you care about is ‘follow-mode’.  As far as
> isearch and all other packages are concerned, it's obviously easier to
> neither set a window parameter nor an optional argument.

Yes, I care about Follow Mode.  And I care about Isearch, a great deal.
The two currently don't work together.  Something like an optional
argument or a window parameter is absolutely needed to make them work

>  > Distorting your meaning for a paragraph: Under my proposal, there is no
>  > urgent need to update any package which uses `set-window-start' and
>  > friends.  If it currently fails to work well with FM, it will continue to
>  > work just the same until somebody amends it.  Your proposal is more
>  > radical: we'd have to check each of the 124 uses of
>  > `pos-visible-in-window-p' to make sure they actually should work on
>  > entire window groups.  I would guess most of them will, but some won't.
>  > It would, of course, also affect external code.

> ‘follow-mode-set-window-start’ would have to take care of that.

It can't do, any more than `set-window-start' could take care of an
implicit NOFORCE parameter.

> If you really care about this have ‘follow-mode-set-window-start’ check
> a variable like ‘isearch-mode’ to make sure that it affects isearch
> calls only.

I take it that's a bit of sarcasm?

>  >>   > Also, were Follow Mode to be superseded at any time, then the 
> interface
>  >>   > I'm proposing would not need adapting to FM's successor.

>  >> The interface you propose already needs adapting up to 132 libraries to
>  >> FM.

>  > No.  There is no need, see above, even though it would be beneficial.
>  > With your proposal, we'd need to check a lot of code.

> If we changed up to 132 arguments in calls of ‘set-window-start’ and
> decided that ‘follow-mode’ is obsolete we'd have up to 132 calls to
> change back.

Not at all.  The interface would remain unchanged, only the setting of
`set-window-start-group-function' would need to change.

> martin

Alan Mackenzie (Nuremberg, Germany).

reply via email to

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