zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@csr.com>
To: zsh-workers@sunsite.dk
Subject: Re: Bug#519535: history expansion: modifier completion missing
Date: Tue, 17 Mar 2009 12:09:44 +0000	[thread overview]
Message-ID: <20090317120944.18d6805b@news01> (raw)
In-Reply-To: <20090317110003.6c676a4d@news01>

On Tue, 17 Mar 2009 11:00:03 +0000
Peter Stephenson <pws@csr.com> wrote:
> I've a mind to leave a and A as they were, note that they don't care if the
> file doesn't exist (which is also entirely consistent with h, t, etc.), and
> add c to do the following.  You could then stack :c:A if you really wanted.

I certainly like this better.  You can now do stuff like

% print ${${:-cat}:c:h}
/bin

although since

% print ${${:-=cat}:h}
/bin

also works it's possibly not much of a gain; however, here you don't need to
force an additional level of expansion on parameters; however however,

% foo=cat
% print ${${:-=$foo}:h}
/bin

also works, too.  One other quirk that makes it less useful (which
surprised me enough before I realised it was indeed the way globbing has
always worked that I've mentioned it specially) is that

% print cat(:c)

doesn't work, because the glob qualifiers turn on globbing, which finds
that the file "cat" doesn't exist and rejects it at that point.  Maybe we
need an alternative syntax for this case.

Index: Doc/Zsh/expn.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/expn.yo,v
retrieving revision 1.103
diff -u -r1.103 expn.yo
--- Doc/Zsh/expn.yo	15 Mar 2009 01:17:06 -0000	1.103
+++ Doc/Zsh/expn.yo	17 Mar 2009 12:05:05 -0000
@@ -219,12 +219,21 @@
 item(tt(a))(
 Turn a file name into an absolute path:  prepends the current directory,
 if necessary, and resolves any use of `tt(..)' and `tt(.)' in the path.
+Note that the transformation takes place even if the file or any
+intervening directories do not exist.
 )
 item(tt(A))(
 As `tt(a)', but also resolve use of symbolic links where possible.
 Note that resolution of `tt(..)' occurs em(before) resolution of symbolic
 links.
 )
+item(tt(c))(
+Resolve a command name into an absolute path by searching the command
+path given by the tt(PATH) variable.  This does not work for commands
+containing directory parts.  Note also that this does not usually work as
+a glob qualifier unless a file of the same name is found in the
+current directory.
+)
 item(tt(e))(
 Remove all but the extension.
 )
Index: Src/hist.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/hist.c,v
retrieving revision 1.90
diff -u -r1.90 hist.c
--- Src/hist.c	15 Mar 2009 01:17:06 -0000	1.90
+++ Src/hist.c	17 Mar 2009 12:05:05 -0000
@@ -638,6 +638,13 @@
 		    return -1;
 		}
 		break;
+	    case 'c':
+		if (!(sline = equalsubstr(sline, 0, 0))) {
+		    herrflush();
+		    zerr("modifier failed: c");
+		    return -1;
+		}
+		break;
 	    case 'h':
 		if (!remtpath(&sline)) {
 		    herrflush();
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.96
diff -u -r1.96 subst.c
--- Src/subst.c	15 Mar 2009 01:17:06 -0000	1.96
+++ Src/subst.c	17 Mar 2009 12:05:05 -0000
@@ -539,12 +539,43 @@
     }
 }
 
+#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
+#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') )
+
+/*
+ * do =foo substitution, or equivalent.
+ * on entry, str should point to the "foo".
+ * if assign, this is in an assignment
+ * if nomatch, report hard error on failure.
+ * if successful, returns the expansion, else NULL.
+ */
+
+/**/
+char *
+equalsubstr(char *str, int assign, int nomatch)
+{
+    char *pp, *cnam, *cmdstr, *ret;
+
+    for (pp = str; !isend2(*pp); pp++)
+	;
+    cmdstr = dupstrpfx(str, pp-str);
+    untokenize(cmdstr);
+    remnulargs(cmdstr);
+    if (!(cnam = findcmd(cmdstr, 1))) {
+	if (nomatch)
+	    zerr("%s not found", cmdstr);
+	return NULL;
+    }
+    ret = dupstring(cnam);
+    if (*pp)
+	ret = dyncat(ret, pp);
+    return ret;
+}
+
 /**/
 mod_export int
 filesubstr(char **namptr, int assign)
 {
-#define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
-#define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') )
     char *str = *namptr;
 
     if (*str == Tilde && str[1] != '=' && str[1] != Equals) {
@@ -606,27 +637,17 @@
 	    return 1;
 	}
     } else if (*str == Equals && isset(EQUALS) && str[1]) {   /* =foo */
-	char *pp, *cnam, *cmdstr, *str1 = str+1;
-
-	for (pp = str1; !isend2(*pp); pp++)
-	    ;
-	cmdstr = dupstrpfx(str1, pp-str1);
-	untokenize(cmdstr);
-	remnulargs(cmdstr);
-	if (!(cnam = findcmd(cmdstr, 1))) {
-	    if (isset(NOMATCH))
-		zerr("%s not found", cmdstr);
-	    return 0;
+	char *expn = equalsubstr(str+1, assign, isset(NOMATCH));
+	if (expn) {
+	    *namptr = expn;
+	    return 1;
 	}
-	*namptr = dupstring(cnam);
-	if (*pp)
-	    *namptr = dyncat(*namptr, pp);
-	return 1;
     }
     return 0;
+}
+
 #undef isend
 #undef isend2
-}
 
 /**/
 static char *
@@ -3201,6 +3222,7 @@
 	    switch (**ptr) {
             case 'a':
             case 'A':
+	    case 'c':
 	    case 'h':
 	    case 'r':
 	    case 'e':
@@ -3345,6 +3367,13 @@
 		    case 'A':
 			chrealpath(&copy);
 			break;
+		    case 'c':
+		    {
+			char *copy2 = equalsubstr(copy, 0, 0);
+			if (copy2)
+			    copy = copy2;
+			break;
+		    }
 		    case 'h':
 			remtpath(&copy);
 			break;
@@ -3410,6 +3439,13 @@
 		case 'A':
 		    chrealpath(str);
 		    break;
+		case 'c':
+		{
+		    char *copy2 = equalsubstr(*str, 0, 0);
+		    if (copy2)
+			*str = copy2;
+		    break;
+		}
 		case 'h':
 		    remtpath(str);
 		    break;

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


  reply	other threads:[~2009-03-17 12:10 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20090313105555.GA19025@piper.oerlikon.madduck.net>
2009-03-15  6:22 ` Clint Adams
2009-03-16 18:18   ` Peter Stephenson
2009-03-17  2:44     ` Bart Schaefer
2009-03-17  9:57       ` Peter Stephenson
2009-03-17 11:00         ` Peter Stephenson
2009-03-17 12:09           ` Peter Stephenson [this message]
2009-03-17 17:36         ` Bart Schaefer
2009-03-17 18:46         ` Modifiers, command position, and so forth (Re: Bug#519535: history expansion: modifier completion missing) Bart Schaefer
2009-03-18 19:36           ` Peter Stephenson
2009-03-19  0:34             ` Bart Schaefer
2009-03-19 14:34             ` Peter Stephenson
2009-03-19 15:28     ` Bug#519535: history expansion: modifier completion missing Mikael Magnusson
2009-03-19 16:09       ` Peter Stephenson
2009-03-19 16:18         ` Mikael Magnusson
2009-03-19 16:18       ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090317120944.18d6805b@news01 \
    --to=pws@csr.com \
    --cc=zsh-workers@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).