about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-11-23 11:48:03 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-11-23 11:48:03 +0000
commit003d10889614f87e3fee6c1689a8abdaaf3efacb (patch)
tree83c00d1f41483123e1625bde5eb9560ffa18aa4c
parent8115ef8458fd8dcc39f178c1edfd624ca439eef2 (diff)
downloadzsh-003d10889614f87e3fee6c1689a8abdaaf3efacb.tar.gz
zsh-003d10889614f87e3fee6c1689a8abdaaf3efacb.tar.xz
zsh-003d10889614f87e3fee6c1689a8abdaaf3efacb.zip
manual/8746
-rw-r--r--Completion/Base/_arguments43
-rw-r--r--Doc/Zsh/compsys.yo4
-rw-r--r--Src/Zle/computil.c103
3 files changed, 93 insertions, 57 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index fa72f323d..0a3ffc021 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -190,8 +190,8 @@ if comparguments -i "$autod" "$@"; then
     _tags options
   fi
 
-  while _tags; do
-    while true; do
+  while true; do
+    while _tags; do
       if [[ -n "$matched" ]] || _requested arguments; then
         _description expl "$descr"
 
@@ -286,30 +286,31 @@ if comparguments -i "$autod" "$@"; then
             equal -QqS= -M "$match"
         fi
       fi
-      if [[ -n "$opts" && -z "$aret$matched" &&
-            nm -eq compstate[nmatches] ]]; then
+    done
+    if [[ -n "$opts" && -z "$aret$matched" &&
+          nm -eq compstate[nmatches] ]]; then
 
-        prefix="${PREFIX#*\=}"
-        suffix="$SUFFIX"
-        PREFIX="${PREFIX%%\=*}"
-        SUFFIX=''
-        compadd -M "$match" -D equal - "${(@)equal%%:*}"
+      prefix="${PREFIX#*\=}"
+      suffix="$SUFFIX"
+      PREFIX="${PREFIX%%\=*}"
+      SUFFIX=''
+      compadd -M "$match" -D equal - "${(@)equal%%:*}"
 
-        if [[ $#equal -eq 1 ]]; then
-	  PREFIX="$prefix"
-	  SUFFIX="$suffix"
-	  IPREFIX="${IPREFIX}${equal[1]%%:*}="
-	  matched=yes
+      if [[ $#equal -eq 1 ]]; then
+        PREFIX="$prefix"
+	SUFFIX="$suffix"
+	IPREFIX="${IPREFIX}${equal[1]%%:*}="
+	matched=yes
 
-	  comparguments -L "${equal[1]%%:*}" descr action subc
-	  curcontext="${oldcontext}:$subc"
+	comparguments -L "${equal[1]%%:*}" descr action subc
+	curcontext="${oldcontext}:$subc"
 
-	  continue
-        fi
+	_tags arguments
+
+	continue
       fi
-      break
-    done
-    [[ -n "$aret" || nm -ne compstate[nmatches] ]] && break
+    fi
+    break
   done
 
   [[ -z "$aret" || -z "$usecc" ]] && curcontext="$oldcontext"
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index b5a75007c..da8ed87d5 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -1985,8 +1985,8 @@ case the colon at the end of the var(message) is needed. The only case
 where it can be left is when neither a var(message), nor a var(action) 
 is given.
 
-To include a colon in the var(message) or the var(action), it has to
-be preceded by a backslash.
+To include a colon in the option name, the var(message) or the
+var(action), it has to be preceded by a backslash.
 
 During the evaluation or execution of the action the array `tt(line)'
 will be set to the command name and normal arguments from the command
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index cc20c8e6a..15db89bdf 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -50,12 +50,15 @@ static void
 cdisp_calc(Cdisp disp, char **args)
 {
     char *cp;
-    int i;
+    int i, nbc;
 
     for (; *args; args++) {
-	if ((cp = strchr(*args, ':')) && cp[1]) {
+	for (nbc = 0, cp = *args; *cp && *cp != ':'; cp++)
+	    if (*cp == '\\' && cp[1])
+		cp++, nbc++;
+	if (*cp == ':' && cp[1]) {
 	    disp->colon++;
-	    if ((i = cp - *args) > disp->pre)
+	    if ((i = cp - *args - nbc) > disp->pre)
 		disp->pre = i;
 	    if ((i = strlen(cp + 1)) > disp->suf)
 		disp->suf = i;
@@ -70,7 +73,7 @@ cdisp_build(Cdisp disp, char *sep, char **args)
 {
     int sl = strlen(sep), pre = disp->pre, suf;
     VARARR(char, buf, disp->pre + disp->suf + sl + 1);
-    char **ret, **rp, *cp;
+    char **ret, **rp, *cp, *copy, *cpp, oldc;
 
     ret = (char **) zalloc((arrlen(args) + 1) * sizeof(char *));
 
@@ -78,18 +81,21 @@ cdisp_build(Cdisp disp, char *sep, char **args)
     suf = pre + sl;
 
     for (rp = ret; *args; args++) {
-	if ((cp = strchr(*args, ':')) && cp[1]) {
+	copy = dupstring(*args);
+	for (cp = cpp = copy; *cp && *cp != ':'; cp++) {
+	    if (*cp == '\\' && cp[1])
+		cp++;
+	    *cpp++ = *cp;
+	}
+	oldc = *cpp;
+	*cpp = '\0';
+	if (((cpp == cp && oldc == ':') || *cp == ':') && cp[1]) {
 	    memset(buf, ' ', pre);
-	    memcpy(buf, *args, (cp - *args));
+	    memcpy(buf, copy, (cpp - copy));
 	    strcpy(buf + suf, cp + 1);
 	    *rp++ = ztrdup(buf);
-	} else {
-	    if (cp)
-		*cp = '\0';
-	    *rp++ = ztrdup(*args);
-	    if (cp)
-		*cp = ':';
-	}
+	} else
+	    *rp++ = ztrdup(copy);
     }
     *rp = NULL;
 
@@ -153,6 +159,7 @@ freecdsets(Cdset p)
 }
 
 /* Initialisation. Store and calculate the string and matches and so on. */
+
 static int
 cd_init(char *nam, char *sep, char **args, int disp)
 {
@@ -218,15 +225,21 @@ cd_get(char **params)
 
     if ((set = cd_state.sets)) {
 	char **sd, **sdp, **md, **mdp, **ss, **ssp, **ms, **msp;
-	char **p, **mp, *cp;
+	char **p, **mp, *cp, *copy, *cpp, oldc;
 	int dl = 1, sl = 1, sepl = strlen(cd_state.sep);
 	int pre = cd_state.disp.pre, suf = cd_state.disp.suf;
 	VARARR(char, buf, pre + suf + sepl + 1);
 
 	for (p = set->strs; *p; p++)
-	    if (cd_state.showd && (cp = strchr(*p, ':')) && cp[1])
-		dl++;
-	    else
+	    if (cd_state.showd) {
+		for (cp = *p; *cp && *cp != ':'; cp++)
+		    if (*cp == '\\' && cp[1])
+			cp++;
+		if (*cp == ':' && cp[1])
+		    dl++;
+		else
+		    sl++;
+	    } else
 		sl++;
 
 	sd = (char **) zalloc(dl * sizeof(char *));
@@ -243,32 +256,34 @@ cd_get(char **params)
 
 	for (sdp = sd, ssp = ss, mdp = md, msp = ms,
 		 p = set->strs, mp = set->matches; *p; p++) {
-	    if ((cp = strchr(*p, ':')) && cp[1] && cd_state.showd) {
+	    copy = dupstring(*p);
+	    for (cp = cpp = copy; *cp && *cp != ':'; cp++) {
+		if (*cp == '\\' && cp[1])
+		    cp++;
+		*cpp++ = *cp;
+	    }
+	    oldc = *cpp;
+	    *cpp = '\0';
+	    if (((cpp == cp && oldc == ':') || *cp == ':') && cp[1] &&
+		cd_state.showd) {
 		memset(buf, ' ', pre);
-		memcpy(buf, *p, (cp - *p));
+		memcpy(buf, copy, (cpp - copy));
 		strcpy(buf + suf, cp + 1);
 		*sdp++ = ztrdup(buf);
 		if (mp) {
 		    *mdp++ = ztrdup(*mp);
 		    if (*mp)
 			mp++;
-		} else {
-		    *cp = '\0';
-		    *mdp++ = ztrdup(*p);
-		    *cp = ':';
-		}
+		} else
+		    *mdp++ = ztrdup(copy);
 	    } else {
-		if (cp)
-		    *cp = '\0';
-		*ssp++ = ztrdup(*p);
+		*ssp++ = ztrdup(copy);
 		if (mp) {
 		    *msp++ = ztrdup(*mp);
 		    if (*mp)
 			mp++;
 		} else
-		    *msp++ = ztrdup(*p);
-		if (cp)
-		    *cp = ':';
+		    *msp++ = ztrdup(copy);
 	    }
 	}
 	*sdp = *ssp = *mdp = *msp = NULL;
@@ -473,6 +488,25 @@ rembslashcolon(char *s)
     return r;
 }
 
+/* Add backslashes before colons. */
+
+static char *
+bslashcolon(char *s)
+{
+    char *p, *r;
+
+    r = p = zhalloc((2 * strlen(s)) + 1);
+
+    while (*s) {
+	if (*s == ':')
+	    *p++ = '\\';
+	*p++ = *s++;
+    }
+    *p = '\0';
+
+    return r;
+}
+
 /* Parse an argument definition. */
 
 static Caarg
@@ -766,7 +800,7 @@ parse_cadef(char *nam, char **args)
 		optp = &((*optp)->next);
 
 		opt->next = NULL;
-		opt->name = ztrdup(name);
+		opt->name = ztrdup(rembslashcolon(name));
 		if (descr)
 		    opt->descr = ztrdup(descr);
 		else if (adpre && oargs && !oargs->next &&
@@ -1414,14 +1448,15 @@ bin_comparguments(char *nam, char **args, char *ops, int func)
 		    default:          l = equal;   break;
 		    }
 		    if (p->descr) {
-			int len = strlen(p->name) + strlen(p->descr) + 2;
+			char *n = bslashcolon(p->name);
+			int len = strlen(n) + strlen(p->descr) + 2;
 
 			str = (char *) zhalloc(len);
-			strcpy(str, p->name);
+			strcpy(str, n);
 			strcat(str, ":");
 			strcat(str, p->descr);
 		    } else
-			str = p->name;
+			str = bslashcolon(p->name);
 		    addlinknode(l, str);
 		}
 	    }