Subject: Re: [PATCH] add-zle-hook-widget
From: Bart Schaefer <[email-masked]>
To: [email-masked]
Date: Thu, 16 Jun 2016 22:20:55 -0700
List-Id: Zsh Workers List <zsh-workers.zsh.org>

On Jun 15, 11:24pm, Daniel Shahaf wrote:
}
} Bart Schaefer wrote on Tue, Jun 14, 2016 at 11:10:54 -0700:
} > Mostly I made that decision because add-zsh-hook explicitly declares
} > that its values are arrays and displays their values with "typeset"
} > if the -L option is passed.
} 
} Then how about saying that registrations may only be added/removed
} through calls to add-z-h-w [-d], without documenting how its storage
} is implemented?

  > it seemed odd to expose this
  > detail in one case and hide it in the other.

} > The whole ordering thing depends on the cooperation of whoever declared
} > widgets A and B in the first place.  Declarer(A) could as easily make
} > capricious changes to his index as not provide it at all.
} 
} Let's not assume the author of (A) is malicious.

I'm not assuming malice, just inconsistency, or a well-meaning decision
that (A) should come after (B) even though declarer(B) thinks exactly
the opposite.

} The question is whether the API enables the problem to happen, and
} the answer is it does: permitting registrations that specify no index
} means plugins _will_ register without specifying an index.

I'm not convinced that's a problem; no index means "I don't care when
this runs, and it shouldn't matter."  If it turns out otherwise for
some other widget, then that other widget merely has to delete the
un-indexed widget and re-declare it with an index.

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.

} I strongly suspect that the releasing the current interface would be
} a mistake: with the current interface, the majority of registrants will
} specify no index, and then regitrants that _do_ wish to take advantage
} of the ordering facility won't be able to.

The choice of index numbers can't be made in a vaccuum, and maybe it
can't even be made by anyone other than the user editing his .zshrc.
In the previous example, declarer(B) has to be aware of widget (A)
and know what index it uses in order to choose another index that
comes after it; how does that differ from being aware of (A) and
therefore asserting new indices for both?  If (B) is NOT aware of (A)
then what difference could it make what index declarer(A) chose?

} So, what I think _will_ work is either of three options: drop indices
} altogether (restoring parity with add-zsh-hook); declare "no index" as
} equivalent to index == 42 (for some well-known value 42); make indices
} mandatory.  I don't have a preference among these three options.

These all degenerate to the same problem in the right circumstances;
e.g. what happens if (A) and (B) both have index 42 and then (C) wants
to run *between* them?

What you have convinced me is that in the absence of an explicit index
there's some value in retaining the order in which the add-* calls
were made, which the code as last pushed doesn't.

} > I'm strongly of the opinion that this is the WRONG way to manipulate a
} > non-special editor widget, and that the right way needs more help than
} > this kind of facility can provide, and that I'm not going to attempt
} > to explain all the details in this thread.
} 
} You do not have to agree with me, but it is common for whoever states
} a disagreeing opinion to give at least a brief glimpse of the technical
} considerations underlying their different assessment.

The gist is that these special widgets by definition do nothing unless
user-defined, so there's no distinction between replacing the widget
action and augmenting it.  Non-special widgets each have an intended
semantic, so there *is* that distinction, and *usually* it's desired
to augment rather than replace.  For special widgets it's reasonable
to simply enumerate a list of actions; for non-special that's not good
enough.

} I have a 'zle -N zle-line-init' in my zshrc.  The function gets
} redefined.

Yeah, I've concluded that for add-zsh-hook the hook widget name and the
implementation function name can't be the same.

} zle-keymap-select takes a non-empty argument list.  (and is one of the
} widgets handled by add-z-h-w)

Good point.

} > (I wonder why the widget is NOT parsed as an argument of the -N option,
} > now that I think about it.)
} 
} The -N option doesn't take an argument; the widget name is a positional
} argument.  (The optspec is "aAcCDfFgGIKlLmMNrRTUw" with no colon after
} the 'N'.)

Yes, I know that; rephrased:  "I wonder why the optspec for bin_zle chose
to place the widget name in a positional argument rather than make it an
argument to -N, given that there are no other valid options that can be
passed along with -N."

} % autoload -U +X add-zle-hook-widget 

Oh.  It doesn't work with +X, it only works with -X.  That's because the
file is designed to be "source"-able rather than "autoload +X"-able.
I'm not sure there's a way to make it safe for all three of autoload +X,
source, and kshautoload.