I personally discovered this with the distributed `git` completer and a
`hash -d c=~/.config`, but the phenomenon is both general & long-lived.
I saw it also in zsh-4.1 and even zsh-2.6 although the latter required
some massaging of the test case. zsh-2.5.0.3 did not fail this way,
though that is old enough that it may not matter and I'm aware that
the specific delta from 2.5 to 2.6 was rather gigantic with src/->Src/
and much other churn over 30 years ago.
This is pretty close to a minimal reproducer which should work for
anyone interested in attacking the problem:
#!/bin/zsh -i
setopt autonamedirs # -i necessary, but..
hash -d nm=/a/path #..No $HOME||global rc
[[ ${nameddirs[nm]} == /a/path ]] || {
echo "did not insert"; exit 1
}
function test_local_nm {
local nm="/b/path"
}
test_local_nm # Call the function
[[ ${nameddirs[nm]} == /a/path ]] || {
echo "did not retain"; exit 2
}
Presumably this is unintended. It looks kind of bad for the usual idea
of `local`. It's also possible that I am not the first to report it as
locals are often short as are `hash -d` abbreviations. So, there is
substantial namespace pressure. I'm not sure if the bug should be
classified as with local and scoping or as with namedirs, but I am 95%
sure it is a "bug". It seems to be a 3-way interaction between `zsh -i`,
local, and autonamedirs. I didn't see anything with a quick search for
auto_*name_*dirs anyway.
I haven't really tried to single-step in a debugger or study the way
local & global namespaces interact to devise a fix here. I thought
it made sense to first get consensus this is a bug.