I'm trying to write a completion function for a command that requires that its argument be an absolute path. (No, I don't know why.) I thought it would be nice to allow typing a relative path, but completion would expand it to an absolute path — that way, if I forget the requirement for an absolute path, completion will fix it for me. For example, if my working directory is home and I have a file "foo" and I type fo<TAB>, it would complete to /usr/me/foo instead of just foo like _files would do.

Problem is, I have no idea how to do this. I've been through all the flags on _files and compadd, and nothing sounds relevant. _canonical_paths sounds close, but I can't get it to do anything. Once the argument is an absolute path, _files works just fine; it's that initial step that's the issue. Suggestions?

1 Answer 1


The following function prepends $PWD/ to any relative path before passing it to _files, which is the normal completion function for files.

_absolute_files () {
  local expansion=$PREFIX$SUFFIX; expansion=${(e)expansion}
  if [[ "${expansion%%/#}" != "${expansion:a}" ]]; then
  _files "$@";

This works in many common cases, including recognizing paths starting with ~/ and such as absolute, and with paths expressed using a variable. I haven't thought about all possible interactions with expansion (e.g. of wildcards) and with embedding.

You must log in to answer this question.

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