about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/comp.h26
-rw-r--r--Src/Zle/complete.c30
-rw-r--r--Src/Zle/compresult.c124
3 files changed, 143 insertions, 37 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index b18947064..22029d511 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -345,27 +345,31 @@ typedef void (*CLPrintFunc)(Cmgroup, Cmatch *, int, int, int, int,
 #define CP_UNAMBIG     (1 << CPN_UNAMBIG)
 #define CPN_UNAMBIGC   14
 #define CP_UNAMBIGC    (1 << CPN_UNAMBIGC)
-#define CPN_LISTMAX    15
+#define CPN_UNAMBIGP   15
+#define CP_UNAMBIGP    (1 << CPN_UNAMBIGP)
+#define CPN_INSERTP    16
+#define CP_INSERTP     (1 << CPN_INSERTP)
+#define CPN_LISTMAX    17
 #define CP_LISTMAX     (1 << CPN_LISTMAX)
-#define CPN_LASTPROMPT 16
+#define CPN_LASTPROMPT 18
 #define CP_LASTPROMPT  (1 << CPN_LASTPROMPT)
-#define CPN_TOEND      17
+#define CPN_TOEND      19
 #define CP_TOEND       (1 << CPN_TOEND)
-#define CPN_OLDLIST    18
+#define CPN_OLDLIST    20
 #define CP_OLDLIST     (1 << CPN_OLDLIST)
-#define CPN_OLDINS     19
+#define CPN_OLDINS     21
 #define CP_OLDINS      (1 << CPN_OLDINS)
-#define CPN_VARED      20
+#define CPN_VARED      22
 #define CP_VARED       (1 << CPN_VARED)
-#define CPN_LISTLINES  21
+#define CPN_LISTLINES  23
 #define CP_LISTLINES   (1 << CPN_LISTLINES)
-#define CPN_QUOTES     22
+#define CPN_QUOTES     24
 #define CP_QUOTES      (1 << CPN_QUOTES)
-#define CPN_IGNORED    23
+#define CPN_IGNORED    25
 #define CP_IGNORED     (1 << CPN_IGNORED)
 
-#define CP_KEYPARAMS   24
-#define CP_ALLKEYS     ((unsigned int) 0xffffff)
+#define CP_KEYPARAMS   26
+#define CP_ALLKEYS     ((unsigned int) 0x3ffffff)
 
 /* Hooks. */
 
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index df9faed7a..5c166291e 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -956,6 +956,10 @@ static struct compparam compkparams[] = {
     { "unambiguous", PM_SCALAR | PM_READONLY, NULL, NULL, VAL(get_unambig) },
     { "unambiguous_cursor", PM_INTEGER | PM_READONLY, NULL, NULL,
       VAL(get_unambig_curs) },
+    { "unambiguous_positions", PM_SCALAR | PM_READONLY, NULL, NULL,
+      VAL(get_unambig_pos) },
+    { "insert_positions", PM_SCALAR | PM_READONLY, NULL, NULL,
+      VAL(get_insert_pos) },
     { "list_max", PM_INTEGER, VAL(complistmax), NULL, NULL },
     { "last_prompt", PM_SCALAR, VAL(complastprompt), NULL, NULL },
     { "to_end", PM_SCALAR, VAL(comptoend), NULL, NULL },
@@ -1103,7 +1107,7 @@ get_complist(Param pm)
 static char *
 get_unambig(Param pm)
 {
-    return unambig_data(NULL);
+    return unambig_data(NULL, NULL, NULL);
 }
 
 /**/
@@ -1112,12 +1116,34 @@ get_unambig_curs(Param pm)
 {
     int c;
 
-    unambig_data(&c);
+    unambig_data(&c, NULL, NULL);
 
     return c;
 }
 
 /**/
+static char *
+get_unambig_pos(Param pm)
+{
+    char *p;
+
+    unambig_data(NULL, &p, NULL);
+
+    return p;
+}
+
+/**/
+static char *
+get_insert_pos(Param pm)
+{
+    char *p;
+
+    unambig_data(NULL, NULL, &p);
+
+    return p;
+}
+
+/**/
 static void
 compunsetfn(Param pm, int exp)
 {
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 287e1509f..061c2a6fd 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -154,18 +154,20 @@ cut_cline(Cline l)
     return l;
 }
 
-/* This builds the unambiguous string. If ins is non-zero, it is
- * immediatly inserted in the line. Otherwise csp is used to return
- * the relative cursor position in the string returned. */
+/* This builds the unambiguous string. If ins is one, it is immediately
+ * inserted into the line. Otherwise csp is used to return the relative
+ * cursor position in the string returned and posl contains all 
+ * positions with missing or ambiguous characters. If ins is two, csp
+ * and posl contain real command line positions (including braces). */
 
 /**/
 static char *
-cline_str(Cline l, int ins, int *csp)
+cline_str(Cline l, int ins, int *csp, LinkList posl)
 {
     Cline s;
     int ocs = cs, ncs, pcs, scs;
     int pm, pmax, pmm, pma, sm, smax, smm, sma, d, dm, mid;
-    int i, j, li = 0, cbr;
+    int i, j, li = 0, cbr, padd = (ins ? wb - ocs : -ocs);
     Brinfo brp, brs;
 
     l = cut_cline(l);
@@ -222,6 +224,8 @@ cline_str(Cline l, int ins, int *csp)
 
 		if ((s->flags & CLF_DIFF) && (!dm || (s->flags & CLF_MATCHED))) {
 		    d = cs; dm = s->flags & CLF_MATCHED;
+		    if (posl)
+			addlinknode(posl, (void *) ((long) (cs + padd)));
 		}
 		li += s->llen;
 	    }
@@ -242,12 +246,15 @@ cline_str(Cline l, int ins, int *csp)
 	}
 	/* Remember the position if this is the first prefix with
 	 * missing characters. */
-	if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF) &&
-	    (((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
-	      (!pmm || (l->flags & CLF_MATCHED))) ||
-	     ((l->flags & CLF_MATCHED) && !pmm))) {
-	    pm = cs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
-	    pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
+	if ((l->flags & CLF_MISS) && !(l->flags & CLF_SUF)) {
+	    if (posl && l->min != l->max)
+		addlinknode(posl, (void *) ((long) (cs + padd)));
+	    if (((pmax < (l->max - l->min) || (pma && l->max != l->min)) &&
+		 (!pmm || (l->flags & CLF_MATCHED))) ||
+		((l->flags & CLF_MATCHED) && !pmm)) {
+		pm = cs; pmax = l->max - l->min; pmm = l->flags & CLF_MATCHED;
+		pma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
+	    }
 	}
 	if (ins) {
 	    int ocs, bl;
@@ -291,12 +298,15 @@ cline_str(Cline l, int ins, int *csp)
 	if (l->flags & CLF_MISS) {
 	    if (l->flags & CLF_MID)
 		mid = cs;
-	    else if ((l->flags & CLF_SUF) && 
-		     (((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
-		       (!smm || (l->flags & CLF_MATCHED))) ||
-		      ((l->flags & CLF_MATCHED) && !smm))) {
-		sm = cs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
-		sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
+	    else if (l->flags & CLF_SUF) {
+		if (posl && l->min != l->max)
+		    addlinknode(posl, (void *) ((long) (cs + padd)));
+		if (((smax < (l->min - l->max) || (sma && l->max != l->min)) &&
+		     (!smm || (l->flags & CLF_MATCHED))) ||
+		    ((l->flags & CLF_MATCHED) && !smm)) {
+		    sm = cs; smax = l->min - l->max; smm = l->flags & CLF_MATCHED;
+		    sma = ((l->prefix || l->suffix) && l->min == cline_sublen(l));
+		}
 	    }
 	}
 	if (ins) {
@@ -389,10 +399,14 @@ cline_str(Cline l, int ins, int *csp)
 	    cs += i;
 	    if (j >= 0 && (!dm || (js->flags & CLF_MATCHED))) {
 		d = cs - j; dm = js->flags & CLF_MATCHED;
+		if (posl)
+		    addlinknode(posl, (void *) ((long) (cs - j + padd)));
 	    }
 	}
 	l = l->next;
     }
+    if (posl)
+	addlinknode(posl, (void *) ((long) (cs + padd)));
     if (ins) {
 	int ocs = cs;
 
@@ -411,6 +425,17 @@ cline_str(Cline l, int ins, int *csp)
 	    sm += cs - ocs;
 	if (d >= ocs)
 	    d += cs - ocs;
+
+	if (posl) {
+	    LinkNode node;
+	    long p;
+
+	    for (node = firstnode(posl); node; incnode(node)) {
+		p = (long) getdata(node);
+		if (p >= ocs)
+		    setdata(node, (void *) (p + cs - ocs));
+	    }
+	}
     }
     /* This calculates the new cursor position. If we had a mid cline
      * with missing characters, we take this, otherwise if we have a
@@ -420,7 +445,7 @@ cline_str(Cline l, int ins, int *csp)
 	   (cbr >= 0 ? cbr :
 	    (pm >= 0 ? pm : (sm >= 0 ? sm : (d >= 0 ? d : cs)))));
 
-    if (!ins) {
+    if (ins != 1) {
 	/* We always inserted the string in the line. If that was not
 	 * requested, we copy it and remove from the line. */
 	char *r = zalloc((i = cs - ocs) + 1);
@@ -430,7 +455,8 @@ cline_str(Cline l, int ins, int *csp)
 	cs = ocs;
 	foredel(i);
 
-	*csp = ncs - ocs;
+	if (csp)
+	    *csp = ncs - ocs;
 
 	return r;
     }
@@ -440,31 +466,81 @@ cline_str(Cline l, int ins, int *csp)
     return NULL;
 }
 
+/* Small utility function turning a list of positions into a colon
+ * separated string. */
+
+static char *
+build_pos_string(LinkList list)
+{
+    LinkNode node;
+    int l;
+    char buf[40], *s;
+
+    for (node = firstnode(list), l = 0; node; incnode(node)) {
+	sprintf(buf, "%ld", (long) getdata(node));
+	setdata(node, dupstring(buf));
+	l += 1 + strlen(buf);
+    }
+    s = (char *) zalloc(l * sizeof(char));
+    *s = 0;
+    for (node = firstnode(list); node;) {
+	strcat(s, (char *) getdata(node));
+	incnode(node);
+	if (node)
+	    strcat(s, ":");
+    }
+    return s;
+}
+
 /* This is a utility function using the function above to allow access
  * to the unambiguous string and cursor position via compstate. */
 
 /**/
 char *
-unambig_data(int *cp)
+unambig_data(int *cp, char **pp, char **ip)
 {
-    static char *scache = NULL;
+    static char *scache = NULL, *pcache = NULL, *icache = NULL;
     static int ccache;
 
     if (mnum && ainfo) {
 	if (mnum != unambig_mnum) {
+	    LinkList list = newlinklist();
+
 	    zsfree(scache);
 	    scache = cline_str((ainfo->count ? ainfo->line : fainfo->line),
-			       0, &ccache);
+			       0, &ccache, list);
+	    zsfree(pcache);
+	    if (empty(list))
+		pcache = ztrdup("");
+	    else
+		pcache = build_pos_string(list);
+
+	    zsfree(icache);
+
+	    list = newlinklist();
+	    zsfree(cline_str((ainfo->count ? ainfo->line : fainfo->line),
+			     2, NULL, list));
+	    if (empty(list))
+		icache = ztrdup("");
+	    else
+		icache = build_pos_string(list);
 	}
     } else if (mnum != unambig_mnum || !ainfo || !scache) {
 	zsfree(scache);
 	scache = ztrdup("");
+	zsfree(pcache);
+	pcache = ztrdup("");
+	zsfree(icache);
+	icache = ztrdup("");
 	ccache = 0;
     }
     unambig_mnum = mnum;
     if (cp)
 	*cp = ccache + 1;
-
+    if (pp)
+	*pp = pcache;
+    if (ip)
+	*ip = icache;
     return scache;
 }
 
@@ -665,7 +741,7 @@ do_ambiguous(void)
 	foredel(we - wb);
 
 	/* Now get the unambiguous string and insert it into the line. */
-	cline_str(ainfo->line, 1, NULL);
+	cline_str(ainfo->line, 1, NULL, NULL);
 
 	/* Sometimes the different match specs used may result in a cline
 	 * that gives an empty string. If that happened, we re-insert the