Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I can't find any 'detailed enough' documentation about zstyle, and I'm surprised that no one faced this problem before:

here is what I get with tab completion:

source l<TAB>
l2ping*                  lefty*                   libwmf-fontmap*          locate*                  lpq.cups

this is certainly/obviously the executable files of my $PATH. However, I would like to use source with a local file, but I can't understand how to change it.

Basically, the command file is completed as I expect, so I'd like to tell zstyle to use the same rules.

I guess that I could adapt :completion:*:killall:* 'ps -u $USER -o cmd h', to do the job, but this would be quite ugly and I'm looking for a zstyle-builtin option.

I thought that I could adapt something like ':completion:*:cd:*' ignore-parents parent pwd to source, but the completion result never changes ...

for information:

$ zsh --version
zsh 4.3.17 (x86_64-redhat-linux-gnu)
$ zstyle
        :completion::complete:* /home/kevin/.oh-my-zsh/cache/
        :completion:*:*:*:*:processes 'ps -u kevin -o pid,user,comm -w -w'
        :completion:*:killall:* 'ps -u $USER -o cmd h'
        :completion:*:hosts crx672 idrouille koguis localhost kevin localhost.localdomain localhost ::1 kevin localhost6.localdomain6 localhost6 kevin localhost
        :completion:*:*:*:users adm amanda apache avahi beaglidx bin cacti canna clamav daemon dbus distcache dovecot fax ftp games gdm gkrellmd gopher hacluster haldaemon halt hsqldb ident junkbust ldap lp mail mailman mailnull mldonkey mysql nagios named netdump news nfsnobody nobody nscd ntp nut nx openvpn operator pcap postfix postgres privoxy pulse pvm quagga radvd rpc rpcuser rpm shutdown squid sshd sync uucp vcsa xfs
        :completion:*:functions '_*'
        :completion:*:*:kill:*:processes '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01'
        :completion:* ''
        :completion:*:*:*:*:* select
        * show
        :completion:*:cd:* local-directories directory-stack path-directories
(eval)  :url-quote-magic 'zmodload -i zsh/parameter;
     reply=( noglob
         ${(k)galiases[(R)(* |)(noglob|urlglobber|globurl) *]:-}
         ${(k)aliases[(R)(* |)(noglob|urlglobber|globurl) *]:-} )'
        :urlglobber ftp file
        :url-quote-magic:* '*?[]^(|)~#{}='
        :urlglobber http https ftp
(eval)  :url-quote-magic:* 'reply=(";&<>${histchars[1]}")'
        :completion::complete:* 1
        :completion:*:*:git:* 'flow:description for foo'
share|improve this question
The standard, POSIX-compliant behavior of ., for which source is a synonym in shells that have it, specifies that $PATH shall be searched for files that do not contain slash. If you want to restrict the search and completion to local files, a simple way is to type ./ first. This is probably cleaner than messing up the shell completion. – jw013 Apr 24 '12 at 10:01
it makes sense ... but I'm used to my bash habits, and I'd like to get the same behavior with zsh :) – Kevin Apr 24 '12 at 10:13
I haven't had enough coffee yet. So you would like the zsh shell builtin source to complete the same way as when you auto-complete a binary? – uther Apr 24 '12 at 12:49
yes, indeed (I thought it was specific to file, but it's actually the default behavior for binaries) – Kevin Apr 24 '12 at 13:27
I've done a lot of reading on this and I'm confused. @jw013 is right that . will search $PATH first if the file does not contain a slash, but according to the zsh manual, source is the same as . except that the current directory is always searched and is always searched first, before directories in $PATH. So my understanding is source l<TAB> should match the local file in the directory first. However, it's not behaving that way for me either. Perhaps an advanced zsh user such as @Gilles has some insight. – uther Apr 24 '12 at 18:40

1 Answer 1

up vote 4 down vote accepted

As of zsh 4.3.10, source is completed by _source which doesn't look up any zstyle. It might be possible to set a style used by _files, but that would be hackish, even by zsh standards.

I suggest that you rewrite the _source function to your liking, it's not very long. Something like:

_my_source () {
  if [[ CURRENT -ge 3 ]]; then
    compset -n 2
  elif [[ $service = . ]]; then
      _files -W path
compdef _my_source source
share|improve this answer
thanks, it's more complicated than expected, but working perfectly! – Kevin Apr 25 '12 at 7:33
@Gilles Well done! – uther Apr 25 '12 at 11:09

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.