Problem
.zi-unload resolves the Zsh Plugin Standard unload hook using the plugin's
literal repository name:
|
(( ${+functions[${plugin}_plugin_unload]} )) && ${plugin}_plugin_unload |
(( ${+functions[${plugin}_plugin_unload]} )) && ${plugin}_plugin_unload
$plugin comes from .zi-any-to-user-plugin and is used verbatim, so
zi unload z-shell/zsh-eza looks for zsh-eza_plugin_unload.
The organization's own analyzer derives the shell-visible prefix by replacing
hyphens with underscores (zsh-lint v1.2.0,
internal/projectconfig/config.go, ShellPrefix), so plugin/function-namespace
rejects that name:
zsh-eza.plugin.zsh:37:3: [plugin/function-namespace] Function name "zsh-eza_plugin_unload"
must use public prefix "zsh_eza_" or private prefix "_zsh_eza_"
A plugin whose name contains a hyphen can therefore satisfy ADR-0020 or be
unloadable by Zi, but not both.
Reproduction
$ zsh -fc 'plugin=zsh-eza; zsh_eza_plugin_unload() { :; }
(( ${+functions[${plugin}_plugin_unload]} )) || print "MISS: ${plugin}_plugin_unload not found"'
MISS: zsh-eza_plugin_unload not found
Impact
Renaming to satisfy the analyzer makes unload a silent no-op: no error, and
under zi light there is no per-plugin tracking to fall back on, so nothing is
undone. This affects every hyphenated plugin and annex in the organization,
including zsh-eza, zsh-fancy-completions, and all z-a-* annexes.
This is distinct from #113, which concerns ownership across repeated loads of
the same plugin, and from #108, which concerned add-zsh-hook array ownership.
Both assume the unload function is reached at all.
Two ways to resolve it
Either side can move, and the choice belongs to the maintainers rather than to
the plugin repositories.
-
zsh-lint exempts the unload name. Accept
<identifier>_plugin_unload in plugin/function-namespace, since the
standard derives that one name from the project identifier itself. One rule
change, no manager churn.
-
Zi accepts both forms at the dispatch. Prefer the literal name for
compatibility:
local ___unload
for ___unload in "${plugin}_plugin_unload" "${plugin//[^A-Za-z0-9]/_}_plugin_unload"; do
(( ${+functions[$___unload]} )) && { $___unload; break; }
done
Acceptance criteria
zi unload reaches the unload function for a plugin whose name contains a
hyphen, whichever naming form the plugin declares.
- Behavior is unchanged for a plugin that declares only the literal-name form.
- A test covers a hyphenated plugin ID with each naming form.
- The chosen resolution is recorded so plugin repositories can drop the
suppression comments they carry today.
Current workaround
z-shell/zsh-eza and z-shell/z-a-meta-plugins keep the hyphenated name and
suppress the advisory plugin/function-namespace hint with a reason. The hint
is severity Hint and does not gate CI.
References
Problem
.zi-unloadresolves the Zsh Plugin Standard unload hook using the plugin'sliteral repository name:
zi/lib/zsh/autoload.zsh
Line 908 in 38c63c2
$plugincomes from.zi-any-to-user-pluginand is used verbatim, sozi unload z-shell/zsh-ezalooks forzsh-eza_plugin_unload.The organization's own analyzer derives the shell-visible prefix by replacing
hyphens with underscores (
zsh-lintv1.2.0,internal/projectconfig/config.go,ShellPrefix), soplugin/function-namespacerejects that name:
A plugin whose name contains a hyphen can therefore satisfy ADR-0020 or be
unloadable by Zi, but not both.
Reproduction
Impact
Renaming to satisfy the analyzer makes unload a silent no-op: no error, and
under
zi lightthere is no per-plugin tracking to fall back on, so nothing isundone. This affects every hyphenated plugin and annex in the organization,
including
zsh-eza,zsh-fancy-completions, and allz-a-*annexes.This is distinct from #113, which concerns ownership across repeated loads of
the same plugin, and from #108, which concerned
add-zsh-hookarray ownership.Both assume the unload function is reached at all.
Two ways to resolve it
Either side can move, and the choice belongs to the maintainers rather than to
the plugin repositories.
zsh-lintexempts the unload name. Accept<identifier>_plugin_unloadinplugin/function-namespace, since thestandard derives that one name from the project identifier itself. One rule
change, no manager churn.
Zi accepts both forms at the dispatch. Prefer the literal name for
compatibility:
Acceptance criteria
zi unloadreaches the unload function for a plugin whose name contains ahyphen, whichever naming form the plugin declares.
suppression comments they carry today.
Current workaround
z-shell/zsh-ezaandz-shell/z-a-meta-pluginskeep the hyphenated name andsuppress the advisory
plugin/function-namespacehint with a reason. The hintis severity Hint and does not gate CI.
References