zsh-workers
 help / color / mirror / code / Atom feed
* why '_file -/' completes files if there is no directory?
@ 2013-07-25 14:09 Jun T.
  2013-08-08  6:56 ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jun T. @ 2013-07-25 14:09 UTC (permalink / raw)
  To: zsh-workers

With the following style:
zstyle ':completion:*:warnings' format 'No match for: %d

If there is no subdirectory in the current directory,
    zsh$ cd <TAB>
gives
    No match for: `local directory'
but
    zsh$ rmdir <TAB>
completes the normal files in the current directory.
Similar behavior for 'gcc -I<TAB>' etc.
Not a serious problem, but I prefer getting a warning than being
offered a useless list of normal files.

Are there any way to stop this behavior by using zstyle?
Obviously I can't use
zstyle ':completion:*' file-patterns '*(-/)'
so I tried
zstyle ':completion:*:directories' file-patterns '*(-/)'
but it didn't' work (it seems setting file-patterns for a specific
tag has no meaning). Setting file-patterns (or tag-order?) to each
context ':completion:*:gcc:option-I-1:*' etc. may work, but I don't
want to do that even if it works.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: why '_file -/' completes files if there is no directory?
  2013-07-25 14:09 why '_file -/' completes files if there is no directory? Jun T.
@ 2013-08-08  6:56 ` Bart Schaefer
  2013-08-08 16:34   ` Jun T.
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2013-08-08  6:56 UTC (permalink / raw)
  To: zsh-workers

This came in while I was on vacation, but I noticed it still has no
replies.

On Jul 25, 11:09pm, Jun T. wrote:
} Subject: why '_file -/' completes files if there is no directory?

The literal answer to this question is that _files always completes
anything in the filesystem.  The -g and -/ options don't mean that
matches will be restricted, just that they'll be grouped differently.

} With the following style:
} zstyle ':completion:*:warnings' format 'No match for: %d
} 
} If there is no subdirectory in the current directory,
}     zsh$ cd <TAB>
} gives
}     No match for: `local directory'
} but
}     zsh$ rmdir <TAB>
} completes the normal files in the current directory.

I suspect it was left that way because people who were used to the
older, less context-aware completion preferred the visual feedback of
having *something* completed.

} Not a serious problem, but I prefer getting a warning than being
} offered a useless list of normal files.
} 
} Are there any way to stop this behavior by using zstyle?

Yes, though it's not obvious.  More below.

} I tried
} zstyle ':completion:*:directories' file-patterns '*(-/)'
} but it didn't' work (it seems setting file-patterns for a specific
} tag has no meaning).

Right, the file-patterns style may be used to *define* the tags, so it
is evaluated before the tag part of the context is generated.

} Setting file-patterns (or tag-order?) to each
} context ':completion:*:gcc:option-I-1:*' etc. may work, but I don't
} want to do that even if it works.

Yes, tag-order is the "approved" mechanism.  However, zstyle provides
a convenient back-door for the cases where the approved method is not
general enough: the -e option calls "eval" on the style value at the
point where the style is looked up, which means you can examine the
current state of local variables, etc.  Here's your answer:

zstyle -e ':completion::*' file-patterns \
	'[[ $funcstack[1] = _files && $type = */* ]] && reply=("*(/)")'

This isn't ideal because it's fragile if _files is ever rewritten, but
those core completers are pretty stable at this point.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: why '_file -/' completes files if there is no directory?
  2013-08-08  6:56 ` Bart Schaefer
@ 2013-08-08 16:34   ` Jun T.
  2013-08-09  5:59     ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jun T. @ 2013-08-08 16:34 UTC (permalink / raw)
  To: zsh-workers


On 2013/08/08, at 15:56, Bart Schaefer <schaefer@brasslantern.com> wrote:
>  Here's your answer:
> 
> zstyle -e ':completion::*' file-patterns \
> 	'[[ $funcstack[1] = _files && $type = */* ]] && reply=("*(/)")'

Thanks!, this is exactly what I'm looking for.

Now 'rmdir <TAB>' gives a warning as I expect.
Interestingly, 'gcc -I<TAB>' gives nothing, i.e., not completes
normal files nor gives a warning.
This is not a problem for me (it's OK if I don't get a list of normal files),
but I'm just curious why no warning?
'gcc -I./<TAB>' does give a warning, though.

This happens only if the optspec given to _arguments has the form '*-I-'.
Either '-I-' or '*-I' gives a warning. 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: why '_file -/' completes files if there is no directory?
  2013-08-08 16:34   ` Jun T.
@ 2013-08-09  5:59     ` Bart Schaefer
  2013-08-09 13:27       ` Jun T.
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2013-08-09  5:59 UTC (permalink / raw)
  To: zsh-workers

On Aug 9,  1:34am, Jun T. wrote:
}
} Interestingly, 'gcc -I<TAB>' gives nothing, i.e., not completes
} normal files nor gives a warning.
} 'gcc -I./<TAB>' does give a warning, though.

This comes down to some oddness in _describe.  In the first case (no
warnings), "compdescribe -g csl2 _args _tmpm _tmpd" succeeds so a
compadd call is made, _ret=0 is assigned, and _describe returns 0
without reaching the end of the _tags loop.

In the second case, compdescribe fails so _describe falls out of the
_tags loop and returns 1.  You mention that:

} This happens only if the optspec given to _arguments has the form '*-I-'.

In this form, the string "-I" is provided to compadd as a possible
completion (because it is allowed to appear more than once on the
command line).  With the form -I- it is not, because it's allowed only
once; with *-I the code takes an entirely different path because a
separate word is being completed, and _describe is never called.

The result of all this is that with an optspec in the "*-I-" format,
the -I by itself is treated as successful but ambiguous completion,
rather than as a finished option string that needs its argument.  I
think this is probably a bug in comparguments -- it should be able to
tell from the single colon in "*-I-:header file ..." that -I can't
appear a second time without first filling in its mandatory argument
-- but like most of us I'm lost as to whether the problem is with
computil.c:ca_parse_line during "comparguments -i", or whether it's
actually a bug in cd_init or cd_get as part of compdescribe, or ...


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: why '_file -/' completes files if there is no directory?
  2013-08-09  5:59     ` Bart Schaefer
@ 2013-08-09 13:27       ` Jun T.
  0 siblings, 0 replies; 5+ messages in thread
From: Jun T. @ 2013-08-09 13:27 UTC (permalink / raw)
  To: zsh-workers

On 2013/08/09, at 14:59, Bart Schaefer <schaefer@brasslantern.com> wrote:
> The result of all this is that with an optspec in the "*-I-" format,
> the -I by itself is treated as successful but ambiguous completion,
> rather than as a finished option string that needs its argument.

Thanks for the analysis and explanation.
I feel I've understood at least something, but also feel that the mist
gets thicker and thicker as I go deeper into the completion system ...

Anyway, thank you again for your 'zstyle -e' trick.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-08-09 13:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-25 14:09 why '_file -/' completes files if there is no directory? Jun T.
2013-08-08  6:56 ` Bart Schaefer
2013-08-08 16:34   ` Jun T.
2013-08-09  5:59     ` Bart Schaefer
2013-08-09 13:27       ` Jun T.

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).