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

Initial path completion option



Here's the second completion option it would be quite nice to have in
order to smooth compatibility with tcsh: again, the new code is pretty
minimal --- in fact, all but a couple of lines are just bookkeeping.
tcsh allows you to specify an initial path, below which all completion
will implicitly take place.  This is particularly nice, for example,
when completing mail folders.  (Not having a tcsh feature always
rankles a bit, too.)

Now `-W /path/prefix' (-W stands for `with directory', that's not so
bad as some of the letters) applies to the options -f, -/, -c and -g
and is implicitly put in front.  For example,

compctl -x 's[+]' -W ~/Mail -/ -- folders

properly handles mail folders: +zsh, +zsh/bugs, +zsh/bugs/fixed
etc. etc. would all be completable using the built-in mechanism for
following paths.  Currently, you have to do something like

compctl -x 's[+]' -g '~/Mail/*(:t)' -- folders

or write a function if you want subdirectories handled at all.  In
either case, you can't use the path-following facilities.

I suppose ideally you should be able to specify a list of directories
to -W, but I don't think the world (or the code) is ready for that
yet.  You can always use + if you want, though you don't get a list
then.  (A more generally solution is a version of + which adds
together all possibilities straight away, say ++, but now I'm
probably dreaming.)

*** Doc/Zsh/compctl.yo.withd	Mon Sep 15 18:09:28 1997
--- Doc/Zsh/compctl.yo	Tue Sep 16 16:52:49 1997
***************
*** 103,108 ****
--- 103,109 ----
    [ tt(-s) var(subststring) ])
  list([ tt(-K) var(function) ] [ tt(-H) var(num pattern) ])
  list([ tt(-Q) ] [ tt(-P) var(prefix) ] [ tt(-S) var(suffix) ])
+ liat([ tt(-W) var(file-prefix) ]
  list([ tt(-q) ] [ tt(-X) var(explanation) ])
  list([ tt(-l) var(cmd) ] [ tt(-U) ])
  endlist()
***************
*** 309,314 ****
--- 310,325 ----
  the completed string.  In the case of menu completion the suffix is
  inserted immediately, but it is still possible to cycle through the
  list of completions by repeatedly hitting the same key.
+ )
+ item(tt(-W) var(file-prefix))(
+ With directory var(file-prefix):  for command, file, directory and
+ globbing completion (options tt(-c), tt(-f), tt(-/), tt(-g)), the file
+ prefix is implicitly added in front of the completion.  For example,
+ 
+ nofill(tt(compctl -/ -W ~/Mail maildirs))
+ 
+ completes any subdirectories to any depth beneath the directory
+ tt(~/Mail), although that prefix does not appear on the command line.
  )
  item(tt(-q))(
  If used with a suffix as specified by the previous option, this
*** Src/Zle/comp.h.withd	Mon Sep 15 16:35:45 1997
--- Src/Zle/comp.h	Tue Sep 16 15:56:41 1997
***************
*** 104,109 ****
--- 104,110 ----
      char *explain;		/* for -X (explanation)                    */
      char *prefix, *suffix;	/* for -P and -S (prefix, suffix)          */
      char *subcmd;		/* for -l (command name to use)            */
+     char *withd;		/* for -w (with directory                  */
      char *hpat;			/* for -H (history pattern)                */
      int hnum;			/* for -H (number of events to search)     */
      Compctl ext;		/* for -x (first of the compctls after -x) */
*** Src/Zle/compctl.c.withd	Mon Sep 15 18:30:40 1997
--- Src/Zle/compctl.c	Tue Sep 16 16:27:08 1997
***************
*** 280,285 ****
--- 280,298 ----
  		    *argv = "" - 1;
  		}
  		break;
+ 	    case 'W':
+ 		if ((*argv)[1]) {
+ 		    cct.withd = (*argv) + 1;
+ 		    *argv = "" - 1;
+ 		} else if (!argv[1]) {
+ 		    zwarnnam(name, "command string expected after -%c", NULL,
+ 			    **argv);
+ 		    return 1;
+ 		} else {
+ 		    cct.withd = *++argv;
+ 		    *argv = "" - 1;
+ 		}
+ 		break;
  	    case 'H':
  		if ((*argv)[1])
  		    cct.hnum = atoi((*argv) + 1);
***************
*** 715,720 ****
--- 728,734 ----
      zsfree(cc->prefix);
      zsfree(cc->suffix);
      zsfree(cc->subcmd);
+     zsfree(cc->withd);
      zsfree(cc->hpat);
      
      /* and copy over the new stuff, (permanently) allocating
***************
*** 729,734 ****
--- 743,749 ----
      cc->prefix = ztrdup(cct->prefix);
      cc->suffix = ztrdup(cct->suffix);
      cc->subcmd = ztrdup(cct->subcmd);
+     cc->withd = ztrdup(cct->withd);
      cc->hpat = ztrdup(cct->hpat);
      cc->hnum = cct->hnum;
  
***************
*** 847,852 ****
--- 862,868 ----
      printif(cc->glob, 'g');
      printif(cc->str, 's');
      printif(cc->subcmd, 'l');
+     printif(cc->withd, 'W');
      if (cc->hpat) {
  	printf(" -H %d ", cc->hnum);
  	quotedzputs(cc->hpat, stdout);
*** Src/Zle/zle_tricky.c.withd	Mon Sep 15 17:27:39 1997
--- Src/Zle/zle_tricky.c	Tue Sep 16 16:53:46 1997
***************
*** 2606,2612 ****
  	    } else {
  		/* No pattern matching. */
  		addwhat = CC_FILES;
! 		prpre = ztrdup(ppre);
  
  		if (sf2)
  		    /* We are in the path, so add only directories. */
--- 2606,2615 ----
  	    } else {
  		/* No pattern matching. */
  		addwhat = CC_FILES;
! 		if (cc->withd) {
! 		    prpre = tricat(cc->withd, "/", ppre);
! 		} else
! 		    prpre = ztrdup(ppre);
  
  		if (sf2)
  		    /* We are in the path, so add only directories. */
***************
*** 2617,2623 ****
  			gen_matches_files(0, 0, 1);
  		    else if (cc->mask & CC_COMMPATH) {
  			/* Completion of command paths. */
! 			if (sf1)
  			    /* There is a path prefix, so add *
  			     * directories and executables.   */
  			    gen_matches_files(1, 1, 0);
--- 2620,2626 ----
  			gen_matches_files(0, 0, 1);
  		    else if (cc->mask & CC_COMMPATH) {
  			/* Completion of command paths. */
! 			if (sf1 || cc->withd)
  			    /* There is a path prefix, so add *
  			     * directories and executables.   */
  			    gen_matches_files(1, 1, 0);
***************
*** 2678,2690 ****
  			    if (*g == '~')
  				*g = Tilde;
  			    remnulargs(g);
! 			    if (*g == Equals || *g == Tilde) {
  				/* The pattern has a `~' or `=' at the  *
  				 * beginning, so we expand this and use *
  				 * the result.                          */
  				filesub(&g, 0);
  				addlinknode(l, dupstring(g));
! 			    } else if (*g == '/')
  				/* The pattern is a full path (starting *
  				 * with '/'), so add it unchanged.      */
  				addlinknode(l, dupstring(g));
--- 2681,2693 ----
  			    if (*g == '~')
  				*g = Tilde;
  			    remnulargs(g);
! 			    if ((*g == Equals || *g == Tilde) && !cc->withd) {
  				/* The pattern has a `~' or `=' at the  *
  				 * beginning, so we expand this and use *
  				 * the result.                          */
  				filesub(&g, 0);
  				addlinknode(l, dupstring(g));
! 			    } else if (*g == '/' && !cc->withd)
  				/* The pattern is a full path (starting *
  				 * with '/'), so add it unchanged.      */
  				addlinknode(l, dupstring(g));
***************
*** 2705,2716 ****
  				    if (itok(*p2))
  					break;
  				if (!*p2) {
! 				    if (*g == Equals || *g == Tilde ||
! 					*g == '/') {
  					/* IF the pattern started with `~',  *
  					 * `=', or `/', add the result only, *
! 					 * if it realy matches what we have  *
! 					 * on the line.                      */
  					while ((p2 = (char *)ugetnode(l)))
  					    if (strpfx(prpre, p2))
  						addmatch(p2 + pl, NULL);
--- 2708,2721 ----
  				    if (itok(*p2))
  					break;
  				if (!*p2) {
! 				    if ((*g == Equals || *g == Tilde ||
! 					*g == '/') || cc->withd) {
  					/* IF the pattern started with `~',  *
  					 * `=', or `/', add the result only, *
! 					 * if it really matches what we have *
! 					 * on the line.                      *
! 					 * Do this if an initial directory   *
! 					 * was specified, too.               */
  					while ((p2 = (char *)ugetnode(l)))
  					    if (strpfx(prpre, p2))
  						addmatch(p2 + pl, NULL);

-- 
Peter Stephenson <pws@xxxxxx>       Tel: +49 33762 77366
WWW:  http://www.ifh.de/~pws/       Fax: +49 33762 77413
Deutsches Elektronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen
DESY-IfH, Platanenallee 6, 15738 Zeuthen, Germany.



Messages sorted by: Reverse Date, Date, Thread, Author