Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Question on filename completion

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)
+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)
 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 @@
+  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

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