Subject: Re: zle hook conventions (was Re: bracket-paste-magic ...)
From: Bart Schaefer <[email-masked]>
To: Zsh hackers list <[email-masked]>
Date: Fri, 3 Jun 2016 15:51:54 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Jun 3,  8:40pm, Daniel Shahaf wrote:
}
} I think it is possible for a plugin to hook into zle without interfering
} with other plugins' hooks, without assuming anything about those other
} plugins.  z-sy-h's hooking code attempts to achieve that

Yes, but (a) it's convoluted (b) it doesn't solve the ordering problem
[whichever plugin is sourced last gets its wrapper outermost] (c) it
is fragile in cases such as reloading a plugin [load A, load B, then
load A again, and now you have A() { B() { A() { ... } } } wrapping].

Plus, I thought the whole point of this conversation was to consider
ways to avoid having to do that kind of thing, because most plugins
are a lot more naive than z-sy-h.

} I think you're saying: if one plugin uses add-zle-hook-widget(), then
} other plugins can coexist with that plugin by also using
} add-zle-hook-widget().

Again yes, but also: if no plugin uses add-zle-hook-widget because it
requires zsh-5.X for some X >=3 and those plugins want to keep working
in zsh-4+, then we might as well never have introduced the feature.
If we're taking the position that the feature is useful, we should
design it in such a way that plugin writers want to adopt it.

} I'm a bit wary of imposing dependencies on other plugins.  Might there
} be a valid reason for those fourth-party plugins to prefer not to use
} add-zle-hook-widget?

You seem to be arguing in circles here.  This is back to supporting the
position of throwing up our hands and doing nothing because we can't
(or shouldn't) make everyone do the same thing.

Plugins that don't want to use the convention are in no different boat
than they always were:  They either must be clever like z-sy-h, or they
simply break (or cause breakage) by being naive, and it's then up to
the user who's installing them to work it out (which was my original
point about paying attention to ~/.zshrc when updating a plugin).

} > Usage would be e.g. (inventing a function for example purposes):
} > 
} >     add-zle-hook-widget zle-line-pre-redraw 30:z-sy-h-redraw
} 
} This appears to be a straightforward registrar API.

Intentionally comparable to add-zsh-hook.
 
} I would suggest making this idempotent by uniquifying the list of hooks
} (in order to support 'source ~/.zshrc').

Cf. "crudely sketched", but it in fact does so, the extant_hooks local
is declared with -U, so when assigned it will discard duplicates.

} With my plugin author perspective, if I were to add a dependency on this
} function, I'd want it to be easily available for users to install.
} Where would add-zle-hook-widget's implementation live?  In Functions/ in
} the zsh tree, or as a third-party project?

I'd presume that if the convention were agreed upon, we'd ship it with
the "standard" set of autoloadable functions alongside (or even packed
with, in some way) add-zsh-hook.

} > 	zstyle -g extant_hooks "$hook" widgets
} > 	extant_hooks+=("$@")
} > 	zstyle -- "$hook" widgets "${extant_hooks[@]}"
} 
} Why use zstyle's instead of declaring a global array and appending to it?

Mostly to be able to use the widget names directly without having to
remove hyphens or convert to underscores.  Partly, to avoid polluting
the parameter namespace further.  Also to demonstrate that zstyle is
not just a quaint side-effect of the completion system.

-- 
Barton E. Schaefer