Subject: Re: [PATCH] add-zle-hook-widget
From: Bart Schaefer <[email-masked]>
To: [email-masked]
Date: Fri, 1 Jul 2016 13:11:58 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

Delayed response.

On Jun 21,  1:41am, Daniel Shahaf wrote:
} Subject: Re: [PATCH] add-zle-hook-widget
}
} Bart Schaefer wrote on Thu, Jun 16, 2016 at 22:20:55 -0700:
} > I think this is better than the situation with add-zsh-hook where
} > somebody has to be sure ALL the add-* calls are made in exactly the
} > right sequence ... or else has to know the implementation and muck
} > with it directly.
} 
} Agreed, although there _is_ something to be said for the "or else"
} alternative: it is a thin/KISS solution, "here's the explicit order
} hooks will be called in, have a field day".

You can't have it both ways -- either the implementation must be
documented, which you objected to, or it has to be possible to do
what's needed without knowing.

} Perhaps we should ditch indexing and use topological sorting [tsort(1)
} is in POSIX] instead: then we can let registrants specify "before:" and
} "after:" clauses

I don't think we want to get into the business of storing a partial
orderting and attempting to resolve it to a total one.  For one thing,
more information arrives every time add-zsh-hook is called.  Redo the
whole tsort each time?

} so B could do "add-zsh-hook zle-line-init B_hook before:A_hook"

How does that differ from:

} Having (B) unhook/rehook (A)'s hook sounds like a recipe for
} hard-to-diagnose bugs.

??  It's just the internals heuristically doing the unhook/re-hook at
B's behest, instead of B doing it explicitly.

Still, there might be something.  Just thinking aloud:

Firstly, I chose the syntax "index:name" to allow multiple items to be
added at once, but add-zsh-hook doesn't work that way so there's no
longer any reason for add-zle-hook-widget to work that way.  So let's
make the syntax be
	add-zle-hook-widget HOOK WIDGETNAME [INDEX]
instead of embedding the index in the widgetname.

(This might be tricky/confusing given that the widget list would still
need to be stored with each index attached.)

Secondly, the index could be symbolic as you suggest; perhaps first,
last, "before:otherwidget" and "after:otherwidget".  The difference
from a topological sort would be that before/after apply immediately,
so if there is no "otherwidget" present yet, they mean nothing.  You
still have to call add-zle-hook-widget in some kind of sequence, but
you don't have to know what index was assigned to otherwidget.  Also,
"otherwidget" should be a pattern.

Thirdly, allow multiple symbolic indices, to cover "before:X after:Y".
Try them until one fails, ignoring any that are meaningless.  If all
succeed, add the hook, else report error?

One other thought -- it probably doesn't work to have a single sequence
point for e.g. whether buffer modification happens.

} I'm not sure whether this is simpler or more complicated than indices.

Well, it sounds a lot more complicated to me, but it depends on whether
you mean complicated for the user to figure out beforehand what index to
use, or complicated for the shell to manage and the user to understand
afterward why a particular order of execution was chosen.

As tsort(1) itself says:
> Note that for a given partial ordering, generally there is no unique
> total ordering.

That means the widgets might start running in different order after a
new hook is added, for no reason the user is able to plainly see.  I like
the notion that a known total ordering can be imposed without having to
express increasingly detailed partial orders for each new addition.