I am new to writing zsh completions. How can I ignore symbolic links from showing in completion returned by _files -W /path/to/folder/?

1 Answer 1


A test directory is populated:

% cd && mkdir foo && cd foo
% touch file1 file2
% mkdir dir1
% ln -s file1 link1
% ln -s dir1 link2

and with the not-symlink glob qualifiers ^ @ the symlinks may be ignored.

% print *
dir1 file1 file2 link1 link2
% print *(^@)
dir1 file1 file2

A completion then can use the -g flag to _path_files which _files uses, many ZSH completion functions and builtins have to be chased down such indirections:

-g pattern Specifies that only files matching the pattern should be completed.

So perhaps:

#compdef foo
_arguments "1:file:_files -W ~/foo -g '*(^@)'" && return 0

However, this completes on symlinks that point to directories:

% foo <<MASHTABKEY>>
dir1/   file1   file2   link2@

% ln -s /etc/passwd
% ln -s /etc
% foo <<MASHTABKEY>>
dir1/   etc@    file1   file2   link2@

If symlinks that point to directories are a problem, a different line of attack is to complete on all files in the ~/foo directory

#compdef foo
_arguments '1:file:_files -W ~/foo' && return 0

and to then specify an all-files completion style for foo:

% zstyle ':completion:*:*:foo:*:*' file-patterns '*(^@):all-files'
% foo <<MASHTABKEY>>
dir/ file1 file2
  • I did some testing, and your second method is more accurate... It works even if the directory only has symbolic links, and no regular files. In that case the first method still shows symbolic links in completion, which is undesirable. Second method with zstyle ':completion:*:*:foo:*:*' file-patterns '*(^@):all-files' works under all cases.
    – codepoet
    Commented Sep 8, 2022 at 23:50
  • I just asked a corollary/follow up question here: unix.stackexchange.com/q/717679/456507
    – codepoet
    Commented Sep 18, 2022 at 2:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .