summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/comp.h2
-rw-r--r--Src/Zle/compcore.c52
-rw-r--r--Src/Zle/complete.c6
-rw-r--r--Src/params.c15
4 files changed, 64 insertions, 11 deletions
diff --git a/Src/Zle/comp.h b/Src/Zle/comp.h
index bd0401800..93e3c68eb 100644
--- a/Src/Zle/comp.h
+++ b/Src/Zle/comp.h
@@ -233,6 +233,8 @@ struct menuinfo {
#define CAF_MATCH 4
#define CAF_UNIQCON 8
#define CAF_UNIQALL 16
+#define CAF_ARRAYS 32
+#define CAF_KEYS 64
/* Data for compadd and addmatches() */
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 4c109ed4e..38cbe03a2 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -1538,6 +1538,17 @@ get_user_var(char *nam)
}
}
+static char **
+get_user_keys(char *nam)
+{
+ char **ret;
+
+ if ((ret = gethkparam(nam)))
+ return (incompfunc ? arrdup(ret) : ret);
+
+ return NULL;
+}
+
/* This is used by compadd to add a couple of matches. The arguments are
* the strings given via options. The last argument is the array with
* the matches. */
@@ -1549,8 +1560,9 @@ addmatches(Cadata dat, char **argv)
char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL;
char **aign = NULL, **dparr = NULL, *oaq = autoq, *oppre = dat->ppre;
char *oqp = qipre, *oqs = qisuf, qc, **disp = NULL, *ibuf = NULL;
+ char **arrays = NULL;
int lpl, lsl, pl, sl, bcp = 0, bcs = 0, bpadd = 0, bsadd = 0;
- int ppl = 0, psl = 0;
+ int ppl = 0, psl = 0, ilen = 0;
int llpl = 0, llsl = 0, nm = mnum, gflags = 0, ohp = haspattern;
int isexact, doadd, ois = instring, oib = inbackt;
Cline lc = NULL, pline = NULL, sline = NULL;
@@ -1855,16 +1867,18 @@ addmatches(Cadata dat, char **argv)
/* Walk through the matches given. */
obpl = bpl;
obsl = bsl;
- if (aign || pign) {
- int max = 0;
- char **ap = argv;
-
- ppl = (dat->ppre ? strlen(dat->ppre) : 0);
- while ((s = *ap++))
- if ((sl = strlen(s)) > max)
- max = sl;
- psl = (dat->psuf ? strlen(dat->psuf) : 0);
- ibuf = (char *) zhalloc(1 + ppl + max + psl);
+ if (dat->aflags & CAF_ARRAYS) {
+ arrays = argv;
+ argv = NULL;
+ while (*arrays && (!(argv = ((dat->aflags & CAF_KEYS) ?
+ get_user_keys(*arrays) :
+ get_user_var(*arrays))) || !*argv))
+ arrays++;
+ arrays++;
+ if (!argv) {
+ ms = NULL;
+ argv = &ms;
+ }
}
for (; (s = *argv); argv++) {
bpl = obpl;
@@ -1877,6 +1891,9 @@ addmatches(Cadata dat, char **argv)
if (aign || pign) {
int il = ppl + sl + psl, addit = 1;
+ if (il > ilen)
+ ibuf = (char *) zhalloc((ilen = il) + 1);
+
if (ppl)
memcpy(ibuf, dat->ppre, ppl);
strcpy(ibuf + ppl, s);
@@ -1953,6 +1970,19 @@ addmatches(Cadata dat, char **argv)
}
free_cline(lc);
}
+ if ((dat->aflags & CAF_ARRAYS) && !argv[1]) {
+ argv = NULL;
+ while (*arrays && (!(argv = ((dat->aflags & CAF_KEYS) ?
+ get_user_keys(*arrays) :
+ get_user_var(*arrays))) || !*argv))
+ arrays++;
+ arrays++;
+ if (!argv) {
+ ms = NULL;
+ argv = &ms;
+ }
+ argv--;
+ }
}
if (dat->apar)
set_list_array(dat->apar, aparl);
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 8c8950303..c87aac596 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -442,6 +442,12 @@ bin_compadd(char *name, char **argv, char *ops, int func)
case 'e':
dat.flags |= CMF_ISPAR;
break;
+ case 'a':
+ dat.aflags |= CAF_ARRAYS;
+ break;
+ case 'k':
+ dat.aflags |= CAF_ARRAYS|CAF_KEYS;
+ break;
case 'F':
sp = &(dat.ign);
e = "string expected after -%c";
diff --git a/Src/params.c b/Src/params.c
index 8c39ec2ac..aa20e79f4 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1741,6 +1741,21 @@ gethparam(char *s)
return NULL;
}
+/* Retrieve the keys of an assoc array parameter as an array */
+
+/**/
+mod_export char **
+gethkparam(char *s)
+{
+ struct value vbuf;
+ Value v;
+
+ if (!idigit(*s) && (v = getvalue(&vbuf, &s, 0)) &&
+ PM_TYPE(v->pm->flags) == PM_HASHED)
+ return paramvalarr(v->pm->gets.hfn(v->pm), SCANPM_WANTKEYS);
+ return NULL;
+}
+
/**/
mod_export Param
setsparam(char *s, char *val)