Note: Please don't respond about this being a XY situation. I am trying to understand how a globbing pattern works, not trying to achieve a specific result. Am also not interested in other ways to achieve this with zstyle, etc.
Recently I was in a situation where I wanted to complete only symbolic links from a specific directory as a function's argument. A pattern like *(@)
works as an argument to -g
of _files
as long as the directory has at least one symbolic link. If there are no symbolic links in the directory, the completion filter fails as it now completes regular files (non symbolic links)... So I went through the documentation, and it seemed adding N
(NULL GLOB) qualifier is the answer. I changed the pattern to *(@N)
, but that still returns regular files when there are no symbolic links. Surprisingly, adding a negation in front of N (pattern *(@^N)
) makes it work correctly under all cases. But am a little unsure if this is because I hit a zsh bug (and this pattern will stop working in future) or if this pattern really makes sense and is worth relying on.
It would be great if someone would be able to confirm that the pattern below works not because its a zsh bug, and what it means. Here's a test file foocomp.zsh
:
function foo {
echo "foo called with $1"
}
function _foo {
_files -g '*(@^N)' -W $PWD/foodir/
}
function bar {
echo "bar called with $1"
}
function _bar {
_files -g '*(@N)' -W $PWD/foodir/
}
compdef _foo foo
compdef _bar bar
Steps:
- Save
foocomp.zsh
file to some directory - mkdir foodir && cd foodir
- touch hello && ln -s hello world && cd ..
- source
foocomp.zsh
- Type foo or bar and press tab, it should only complete world.
- Delete symbolic link world
- Type foo and press tab again, it would not complete anything (which is desired behavior)
- Type bar and press tab again, it will complete hello.