Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Question on filename completion
- X-seq: zsh-users 12858
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: "Zsh Users" <zsh-users@xxxxxxxxxx>
- Subject: Re: Question on filename completion
- Date: Sun, 18 May 2008 21:24:22 +0100
- In-reply-to: <080518120311.ZM4212@xxxxxxxxxxxxxxxxxxxxxx>
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- References: <d53cb3110805181023p1e823d8drb196db9e52f79b33@xxxxxxxxxxxxxx> <080518120311.ZM4212@xxxxxxxxxxxxxxxxxxxxxx>
On Sun, 18 May 2008 12:03:11 -0700
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> On May 18, 10:53pm, Gowtham M wrote:
> }
> } When I hit tab at
> } zsh> ls /some/path/to/something/761/xyz/_ # Tab is hit when cursor is at _
> }
> } zsh spends a lot of time in stat64()ing all the directories from
> } /some/path/to/something/0 to /some/path/to/something/9999
> }
> } I do not understand why this is required to complete the filename
> } after /some/path/to/something/761/xyz
>
> This is _path_files at work. Try typing
>
> zsh> ls /s/p/t/s<TAB>
>
> and you'll find that it gets competed to
>
> zsh> ls /some/path/to/something/
>
> On any given completion attempt, _path_files doesn't know whether any
> path component might be only part of a directory name which, if it were
> completed, would lead to additional matches among the sub-directories,
> etc. So it re-scans the whole hierarchy.
Right. However, I've always been uncomfortable that this is
unconditional. 99.9% of the time I find that if the directory path as
I've given it exists already, it's the path I want, and looking for more
is just slowing things down, sometimes unbearably (as for remote paths
in Cygwin).
Here's the accept-exact-dirs style to remedy that. There could very
well be glitches with the style set, but it appears to be usable
already, and I will try it out myself since I've been vaguely wanting it
for a long time. As you can see from the patch it's highly unlikely to
cause problems if not set.
Index: Doc/Zsh/compsys.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v
retrieving revision 1.209
diff -u -r1.209 compsys.yo
--- Doc/Zsh/compsys.yo 16 May 2008 11:49:21 -0000 1.209
+++ Doc/Zsh/compsys.yo 18 May 2008 20:13:50 -0000
@@ -1098,6 +1098,20 @@
`continue', _expand will add the expansion as a match and the completion
system will also be allowed to continue.
)
+kindex(accept-exact-dirs, completion style)
+item(tt(accept-exact-dirs))(
+This is used by filename completion. Unlike tt(accept-exact) it is
+a boolean. By default, filename completion examines all components
+of a path to see if there are completions of that component, even if
+the component matches an existing directory. For example, when
+completion after tt(/usr/bin/), the function examines possible
+completions to tt(/usr).
+
+When this style is true, any prefix of a path that matches an existing
+directory is accepted without any attempt to complete it further.
+Hence, in the given example, the path tt(/usr/bin/) is accepted
+immediately and completion tried in that directory.
+)
kindex(add-space, completion style)
item(tt(add-space))(
This style is used by the tt(_expand) completer. If it is true (the
Index: Completion/Unix/Type/_path_files
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v
retrieving revision 1.27
diff -u -r1.27 _path_files
--- Completion/Unix/Type/_path_files 23 Feb 2008 00:10:24 -0000 1.27
+++ Completion/Unix/Type/_path_files 18 May 2008 20:13:51 -0000
@@ -318,6 +318,29 @@
skipped=
cpre=
+
+ if zstyle -t ":completion:${curcontext}:paths" accept-exact-dirs &&
+ [[ $pre = (#b)(*)/([^/]#) ]]; then
+ # We've been told that we can accept an exact directory
+ # prefix immediately. Try this with the longest path prefix
+ # first: this saves stats in the simple case and may get around
+ # automount behaviour if early components don't yet exist.
+ tmp1=$match[1]
+ tpre=$match[2]
+ while true; do
+ if [[ -d $donepath$tmp1 ]]; then
+ donepath=$donepath$tmp1/
+ pre=$tpre
+ break
+ elif [[ $tmp1 = (#b)(*)/([^/]#) ]]; then
+ tmp1=$match[1]
+ tpre=$match[2]/$tpre
+ else
+ break
+ fi
+ done
+ fi
+
tpre="$pre"
tsuf="$suf"
testpath="$donepath"
--
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author