diff options
Diffstat (limited to 'Src/Zle')
-rw-r--r-- | Src/Zle/comp1.c | 3 | ||||
-rw-r--r-- | Src/Zle/iwidgets.list | 1 | ||||
-rw-r--r-- | Src/Zle/zle_hist.c | 318 | ||||
-rw-r--r-- | Src/Zle/zle_keymap.c | 2 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 42 | ||||
-rw-r--r-- | Src/Zle/zle_move.c | 15 | ||||
-rw-r--r-- | Src/Zle/zle_thingy.c | 17 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 63 | ||||
-rw-r--r-- | Src/Zle/zle_utils.c | 12 |
9 files changed, 265 insertions, 208 deletions
diff --git a/Src/Zle/comp1.c b/Src/Zle/comp1.c index c51aad297..f32e5f5c0 100644 --- a/Src/Zle/comp1.c +++ b/Src/Zle/comp1.c @@ -47,7 +47,7 @@ Cmlist cmatcher; void (*makecompparamsptr) _((void)); /**/ -void (*comp_setunsetptr) _((int, int)); +void (*comp_setunsetptr) _((unsigned int, unsigned int)); /* pointers to functions required by compctl and defined by zle */ @@ -147,6 +147,7 @@ createcompctltable(void) compctltab->hash = hasher; compctltab->emptytable = emptyhashtable; compctltab->filltable = NULL; + compctltab->cmpnodes = strcmp; compctltab->addnode = addhashnode; compctltab->getnode = gethashnode2; compctltab->getnode2 = gethashnode2; diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 61ad0e24a..e0c93bd03 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -91,6 +91,7 @@ "send-break", sendbreak, 0 "set-mark-command", setmarkcommand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "spell-word", spellword, 0 +"set-local-history", setlocalhistory, 0 "transpose-chars", transposechars, 0 "transpose-words", transposewords, 0 "undefined-key", undefinedkey, 0 diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c index 0064d4ef0..d2b9a3233 100644 --- a/Src/Zle/zle_hist.c +++ b/Src/Zle/zle_hist.c @@ -47,27 +47,16 @@ int lastcol; /**/ int histline; -/* the last line in the history (the current one), metafied */ - -/**/ -char *curhistline; +#define ZLETEXT(X) ((X)->zle_text ? (X)->zle_text : (X)->text) /**/ void remember_edits(void) { - if (histline == curhist) { - zsfree(curhistline); - curhistline = metafy((char *) line, ll, META_DUP); - } - else { - Histent ent = gethistent(histline); - - if (metadiffer(ent->zle_text ? ent->zle_text : ent->text, - (char *) line, ll)) { - zsfree(ent->zle_text); - ent->zle_text = metafy((char *) line, ll, META_DUP); - } + Histent ent = quietgethist(histline); + if (metadiffer(ZLETEXT(ent), (char *) line, ll)) { + zsfree(ent->zle_text); + ent->zle_text = metafy((char *) line, ll, META_DUP); } } @@ -75,11 +64,11 @@ remember_edits(void) void forget_edits(void) { - int i; + Histent he; - for (i = 0; i < histentct; i++) { - zsfree(histentarr[i].zle_text); - histentarr[i].zle_text = NULL; + for (he = hist_ring; he; he = up_histent(he)) { + zsfree(he->zle_text); + he->zle_text = NULL; } } @@ -87,16 +76,12 @@ forget_edits(void) void uphistory(void) { - if (zmult < 0) { - zmult = -zmult; - downhistory(); - zmult = -zmult; - } else if(!zle_goto_hist(histline - zmult) && isset(HISTBEEP)) + if (!zle_goto_hist(histline, -zmult) && isset(HISTBEEP)) feep(); } /**/ -int +static int upline(void) { int n = zmult; @@ -159,7 +144,6 @@ viuplineorhistory(void) vifirstnonblank(); } - /**/ void uplineorsearch(void) @@ -181,7 +165,7 @@ uplineorsearch(void) } /**/ -int +static int downline(void) { int n = zmult; @@ -268,26 +252,22 @@ downlineorsearch(void) void acceptlineanddownhistory(void) { - char *s; + Histent he; - if (!(s = zle_get_event(histline + 1))) { + if (!(he = movehistent(quietgethist(histline), 1, HIST_FOREIGN))) { feep(); return; } - pushnode(bufstack, ztrdup(s)); + pushnode(bufstack, ztrdup(ZLETEXT(he))); done = 1; - stackhist = histline + 1; + stackhist = he->histnum; } /**/ void downhistory(void) { - if (zmult < 0) { - zmult = -zmult; - uphistory(); - zmult = -zmult; - } else if(!zle_goto_hist(histline + zmult) && isset(HISTBEEP)) + if (!zle_goto_hist(histline, zmult) && isset(HISTBEEP)) feep(); } @@ -298,7 +278,7 @@ static char *srch_str; void historysearchbackward(void) { - int hl = histline; + Histent he; int n = zmult; char *s; @@ -308,7 +288,7 @@ historysearchbackward(void) zmult = n; return; } - if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0 + if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0 || memcmp(srch_str, line, histpos) != 0) { zfree(srch_str, histpos); for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; @@ -317,28 +297,29 @@ historysearchbackward(void) srch_str = zalloc(histpos); memcpy(srch_str, line, histpos); } - for (;;) { - hl--; - if (!(s = zle_get_event(hl))) { - feep(); - return; - } + he = quietgethist(histline); + while ((he = movehistent(he, -1, hist_skip_flags))) { + if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) + continue; + s = ZLETEXT(he); if (metadiffer(s, srch_str, histpos) < 0 && metadiffer(s, srch_str, ll)) { - if (--n <= 0) - break; + if (--n <= 0) { + zle_setline(he); + srch_hl = histline; + srch_cs = cs; + return; + } } } - zle_goto_hist(hl); - srch_hl = hl; - srch_cs = cs; + feep(); } /**/ void historysearchforward(void) { - int hl = histline; + Histent he; int n = zmult; char *s; @@ -348,7 +329,7 @@ historysearchforward(void) zmult = n; return; } - if (hl == curhist || hl != srch_hl || cs != srch_cs || mark != 0 + if (histline == curhist || histline != srch_hl || cs != srch_cs || mark != 0 || memcmp(srch_str, line, histpos) != 0) { zfree(srch_str, histpos); for (histpos = 0; histpos < ll && !iblank(line[histpos]); histpos++) ; @@ -357,20 +338,22 @@ historysearchforward(void) srch_str = zalloc(histpos); memcpy(srch_str, line, histpos); } - for (;;) { - hl++; - if (!(s = zle_get_event(hl))) { - feep(); - return; + he = quietgethist(histline); + while ((he = movehistent(he, 1, hist_skip_flags))) { + if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) + continue; + s = ZLETEXT(he); + if (metadiffer(s, srch_str, histpos) < (he->histnum == curhist) && + metadiffer(s, srch_str, ll)) { + if (--n <= 0) { + zle_setline(he); + srch_hl = histline; + srch_cs = cs; + return; + } } - if (metadiffer(s, srch_str, histpos) < (hl == curhist) && - metadiffer(s, srch_str, ll)) - if (--n <= 0) - break; } - zle_goto_hist(hl); - srch_hl = hl; - srch_cs = cs; + feep(); } /**/ @@ -387,7 +370,7 @@ beginningofbufferorhistory(void) void beginningofhistory(void) { - if (!zle_goto_hist(firsthist()) && isset(HISTBEEP)) + if (!zle_goto_hist(firsthist(), 0) && isset(HISTBEEP)) feep(); } @@ -405,7 +388,7 @@ endofbufferorhistory(void) void endofhistory(void) { - zle_goto_hist(curhist); + zle_goto_hist(curhist, 0); } /**/ @@ -419,7 +402,7 @@ insertlastword(void) /* multiple calls will now search back through the history, pem */ static char *lastinsert; static int lasthist, lastpos; - int evhist = curhist - 1, save; + int evhist = addhistnum(curhist, -1, HIST_FOREIGN), save; if (lastinsert) { int lastlen = ztrlen(lastinsert); @@ -428,7 +411,7 @@ insertlastword(void) if (lastpos <= pos && lastlen == pos - lastpos && memcmp(lastinsert, (char *)&line[lastpos], lastlen) == 0) { - evhist = --lasthist; + evhist = addhistnum(lasthist, -1, HIST_FOREIGN); cs = lastpos; foredel(pos - cs); } @@ -464,41 +447,37 @@ insertlastword(void) } /**/ -char * -qgetevent(int ev) +void +zle_setline(Histent he) { - return ((ev == curhist) ? curhistline : quietgetevent(ev)); + remember_edits(); + mkundoent(); + histline = he->histnum; + setline(ZLETEXT(he)); + setlastline(); + clearlist = 1; } /**/ -char * -zle_get_event(int ev) +void +setlocalhistory(void) { - Histent ent; - - if (ev == curhist) - return curhistline; - if (! (ent = quietgethist(ev))) - return NULL; - if (ent->zle_text) - return ent->zle_text; - return ent->text; + if (zmod.flags & MOD_MULT) { + hist_skip_flags = zmult? HIST_FOREIGN : 0; + } + else { + hist_skip_flags ^= HIST_FOREIGN; + } } /**/ -static int -zle_goto_hist(int ev) +int +zle_goto_hist(int ev, int n) { - char *t; - - remember_edits(); - if(!(t = zle_get_event(ev))) + Histent he = movehistent(quietgethist(ev), n, hist_skip_flags); + if (!he) return 0; - mkundoent(); - histline = ev; - setline(t); - setlastline(); - clearlist = 1; + zle_setline(he); return 1; } @@ -603,6 +582,7 @@ static struct isrch_spot { static int max_spot = 0; +/**/ #ifdef MODULE /**/ @@ -612,6 +592,7 @@ free_isrch_spots(void) zfree(isrch_spots, max_spot * sizeof(*isrch_spots)); } +/**/ #endif /* MODULE */ /**/ @@ -665,13 +646,15 @@ doisearch(int dir) char *okeymap = curkeymapname; static char *previous_search = NULL; static int previous_search_len = 0; + Histent he; clearlist = 1; strcpy(ibuf, ISEARCH_PROMPT); memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3); remember_edits(); - s = zle_get_event(hl); + he = quietgethist(hl); + s = ZLETEXT(he); selectkeymap("main", 1); pos = metalen(s, cs); for (;;) { @@ -705,15 +688,14 @@ doisearch(int dir) if (!skip_line && ((sbuf[0] == '^') ? (t = metadiffer(s, sbuf + 1, sbptr - 1) < sens ? s : NULL) : (t = hstrnstr(s, pos, sbuf, sbptr, dir, sens)))) { - zle_goto_hist(hl); + zle_setline(he); pos = t - s; cs = ztrsub(t, s) + (dir == 1? sbptr - (sbuf[0]=='^') : 0); nomatch = 0; statusline = ibuf + NORM_PROMPT_POS; break; } - hl += dir; - if (!(s = zle_get_event(hl))) { + if (!(he = movehistent(he, dir, hist_skip_flags))) { if (sbptr == (int)isrch_spots[top_spot-1].len && (isrch_spots[top_spot-1].flags & ISS_FAILING)) top_spot--; @@ -723,13 +705,17 @@ doisearch(int dir) feep(); nomatch = 1; } - s = last_line; + he = quietgethist(hl); + s = ZLETEXT(he); skip_line = 0; statusline = ibuf; break; } + hl = he->histnum; + s = ZLETEXT(he); pos = dir == 1? 0 : strlen(s); - skip_line = !strcmp(last_line, s); + skip_line = isset(HISTFINDNODUPS)? !!(he->flags & HIST_DUP) + : !strcmp(last_line, s); } } else { top_spot = 0; @@ -743,8 +729,9 @@ doisearch(int dir) if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) { int i; get_isrch_spot(0, &hl, &pos, &i, &sbptr, &dir, &nomatch); - s = zle_get_event(hl); - zle_goto_hist(hl); + he = quietgethist(hl); + zle_setline(he); + s = ZLETEXT(he); cs = i; break; } @@ -769,10 +756,11 @@ doisearch(int dir) statusline = ibuf; skip_pos = 1; } - s = zle_get_event(hl); + he = quietgethist(hl); + s = ZLETEXT(he); if (nomatch || !sbptr || (sbptr == 1 && sbuf[0] == '^')) { int i = cs; - zle_goto_hist(hl); + zle_setline(he); cs = i; } memcpy(ibuf + NORM_PROMPT_POS, (dir == 1) ? "fwd" : "bck", 3); @@ -874,42 +862,35 @@ doisearch(int dir) void acceptandinfernexthistory(void) { - int t0; - char *s; + Histent he; done = 1; - for (t0 = histline - 2;; t0--) { - if (!(s = qgetevent(t0))) + for (he = movehistent(quietgethist(histline), -2, HIST_FOREIGN); + he; he = movehistent(he, -1, HIST_FOREIGN)) { + if (!metadiffer(ZLETEXT(he), (char *) line, ll)) { + he = movehistent(he, 1, HIST_FOREIGN); + pushnode(bufstack, ztrdup(ZLETEXT(he))); + stackhist = he->histnum; return; - if (!metadiffer(s, (char *) line, ll)) - break; + } } - if (!(s = qgetevent(t0 + 1))) - return; - pushnode(bufstack, ztrdup(s)); - stackhist = t0 + 1; } /**/ void infernexthistory(void) { - int t0; - char *s; + Histent he; - for (t0 = histline - 2;; t0--) { - if (!(s = qgetevent(t0))) { - feep(); + for (he = movehistent(quietgethist(histline), -2, HIST_FOREIGN); + he; he = movehistent(he, -1, HIST_FOREIGN)) { + if (!metadiffer(ZLETEXT(he), (char *) line, ll)) { + he = movehistent(he, 1, HIST_FOREIGN); + zle_setline(he); return; } - if (! metadiffer(s, (char *) line, ll)) - break; } - if (!(s = qgetevent(t0 + 1))) { - feep(); - return; - } - zle_goto_hist(t0 + 1); + feep(); } /**/ @@ -925,7 +906,7 @@ vifetchhistory(void) return; } } - if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist) && + if (!zle_goto_hist((zmod.flags & MOD_MULT) ? zmult : curhist, 0) && isset(HISTBEEP)) feep(); } @@ -1041,7 +1022,8 @@ vihistorysearchbackward(void) void virepeatsearch(void) { - int hl = histline, t0; + Histent he; + int t0; int n = zmult; char *s; @@ -1054,23 +1036,21 @@ virepeatsearch(void) visrchsense = -visrchsense; } t0 = strlen(visrchstr); - for (;;) { - hl += visrchsense; - if (!(s = zle_get_event(hl))) { - feep(); - return; - } - if (!metadiffer(s, (char *) line, ll)) - continue; - if (*visrchstr == '^') { - if (strncmp(s, visrchstr + 1, t0 - 1) != 0) - continue; - } else if (!hstrnstr(s, 0, visrchstr, t0, 1, 1)) + he = quietgethist(histline); + while ((he = movehistent(he, visrchsense, hist_skip_flags))) { + if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) continue; - if (--n <= 0) - break; + s = ZLETEXT(he); + if (metadiffer(s, (char *) line, ll) + && (*visrchstr == '^'? strncmp(s, visrchstr + 1, t0 - 1) == 0 + : hstrnstr(s, 0, visrchstr, t0, 1, 1) != 0)) { + if (--n <= 0) { + zle_setline(he); + return; + } + } } - zle_goto_hist(hl); + feep(); } /**/ @@ -1090,8 +1070,8 @@ virevrepeatsearch(void) void historybeginningsearchbackward(void) { + Histent he; int cpos = cs; /* save cursor position */ - int hl = histline; int n = zmult; char *s; @@ -1101,20 +1081,21 @@ historybeginningsearchbackward(void) zmult = n; return; } - for (;;) { - hl--; - if (!(s = zle_get_event(hl))) { - feep(); - return; - } + he = quietgethist(histline); + while ((he = movehistent(he, -1, hist_skip_flags))) { + if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) + continue; + s = ZLETEXT(he); if (metadiffer(s, (char *)line, cs) < 0 && - metadiffer(s, (char *)line, ll)) - if (--n <= 0) - break; + metadiffer(s, (char *)line, ll)) { + if (--n <= 0) { + zle_setline(he); + cs = cpos; + return; + } + } } - - zle_goto_hist(hl); - cs = cpos; + feep(); } /* Extra function added by A.R. Iano-Fletcher. */ @@ -1124,8 +1105,8 @@ historybeginningsearchbackward(void) void historybeginningsearchforward(void) { + Histent he; int cpos = cs; /* save cursor position */ - int hl = histline; int n = zmult; char *s; @@ -1135,18 +1116,19 @@ historybeginningsearchforward(void) zmult = n; return; } - for (;;) { - hl++; - if (!(s = zle_get_event(hl))) { - feep(); - return; + he = quietgethist(histline); + while ((he = movehistent(he, 1, hist_skip_flags))) { + if (isset(HISTFINDNODUPS) && he->flags & HIST_DUP) + continue; + s = ZLETEXT(he); + if (metadiffer(s, (char *)line, cs) < (he->histnum == curhist) && + metadiffer(s, (char *)line, ll)) { + if (--n <= 0) { + zle_setline(he); + cs = cpos; + return; + } } - if (metadiffer(s, (char *)line, cs) < (hl == curhist) && - metadiffer(s, (char *)line, ll)) - if (--n <= 0) - break; } - - zle_goto_hist(hl); - cs = cpos; + feep(); } diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 1baa3a845..7504ed809 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -130,6 +130,7 @@ createkeymapnamtab(void) keymapnamtab->hash = hasher; keymapnamtab->emptytable = emptyhashtable; keymapnamtab->filltable = NULL; + keymapnamtab->cmpnodes = strcmp; keymapnamtab->addnode = addhashnode; keymapnamtab->getnode = gethashnode2; keymapnamtab->getnode2 = gethashnode2; @@ -172,6 +173,7 @@ newkeytab(char *kmname) ht->hash = hasher; ht->emptytable = emptyhashtable; ht->filltable = NULL; + ht->cmpnodes = strcmp; ht->addnode = addhashnode; ht->getnode = gethashnode2; ht->getnode2 = gethashnode2; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index a5da84b66..dfb437308 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -111,6 +111,10 @@ int prefixflag; /**/ int feepflag; +#ifdef FIONREAD +static int delayzsetterm; +#endif + /* set up terminal */ /**/ @@ -119,12 +123,30 @@ zsetterm(void) { struct ttyinfo ti; -#if defined(CLOBBERS_TYPEAHEAD) && defined(FIONREAD) +#if defined(FIONREAD) int val; ioctl(SHTTY, FIONREAD, (char *)&val); - if (val) + if (val) { + /* + * Problems can occur on some systems when switching from + * canonical to non-canonical input. The former is usually + * set while running programmes, but the latter is necessary + * for zle. If there is input in canonical mode, then we + * need to read it without setting up the terminal. Furthermore, + * while that input gets processed there may be more input + * being typed (i.e. further typeahead). This means that + * we can't set up the terminal for zle *at all* until + * we are sure there is no more typeahead to come. So + * if there is typeahead, we set the flag delayzsetterm. + * Then getkey() performs another FIONREAD call; if that is + * 0, we have finally used up all the typeahead, and it is + * safe to alter the terminal, which we do at that point. + */ + delayzsetterm = 1; return; + } else + delayzsetterm = 0; #endif /* sanitize the tty */ @@ -298,7 +320,19 @@ getkey(int keytmout) if (kungetct) ret = STOUC(kungetbuf[--kungetct]); else { - if (keytmout) { +#ifdef FIONREAD + if (delayzsetterm) { + int val; + ioctl(SHTTY, FIONREAD, (char *)&val); + if (!val) + zsetterm(); + } +#endif + if (keytmout +#ifdef FIONREAD + && ! delayzsetterm +#endif + ) { if (keytimeout > 500) exp100ths = 500; else if (keytimeout > 0) @@ -461,7 +495,6 @@ zleread(char *lp, char *rp, int flags) undoing = 1; line = (unsigned char *)zalloc((linesz = 256) + 2); virangeflag = lastcmd = done = cs = ll = mark = 0; - curhistline = NULL; vichgflag = 0; viinsbegin = 0; statusline = NULL; @@ -542,7 +575,6 @@ zleread(char *lp, char *rp, int flags) zleactive = no_restore_tty = 0; alarm(0); } LASTALLOC; - zsfree(curhistline); freeundo(); if (eofsent) { free(line); diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index d6e9c4b7d..7169f5700 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -476,17 +476,10 @@ vigotomark(void) feep(); return; } - if (curhist != vimarkline[ch]) { - char *s; - - remember_edits(); - if (!(s = qgetevent(vimarkline[ch]))) { - vimarkline[ch] = 0; - feep(); - return; - } - histline = vimarkline[ch]; - setline(s); + if (curhist != vimarkline[ch] && !zle_goto_hist(vimarkline[ch], 0)) { + vimarkline[ch] = 0; + feep(); + return; } cs = vimarkcs[ch]; if (cs > ll) diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c index b879669ac..dbf982899 100644 --- a/Src/Zle/zle_thingy.c +++ b/Src/Zle/zle_thingy.c @@ -64,6 +64,7 @@ createthingytab(void) thingytab->hash = hasher; thingytab->emptytable = emptythingytab; thingytab->filltable = NULL; + thingytab->cmpnodes = strcmp; thingytab->addnode = addhashnode; thingytab->getnode = gethashnode; thingytab->getnode2 = gethashnode2; @@ -356,7 +357,7 @@ bin_zle(char *name, char **args, char *ops, int func) /* check number of arguments */ for(n = 0; args[n]; n++) ; - if(!op->o && n != 1) { + if(!op->o && n != 1 && n != 2) { zerrnam(name, "wrong number of arguments", NULL, 0); return 1; } @@ -515,17 +516,31 @@ static int bin_zle_call(char *name, char **args, char *ops, char func) { Thingy t; + struct modifier modsave; if(!zleactive || incompctlfunc || incompfunc) { zerrnam(name, "widgets can only be called when ZLE is active", NULL, 0); return 1; } + if (args[1]) { + modsave = zmod; + if (isdigit(*args[1])) { + zmod.mult = atoi(args[1]); + zmod.flags |= MOD_MULT; + } + else { + zmod.mult = 1; + zmod.flags &= ~MOD_MULT; + } + } t = rthingy(args[0]); PERMALLOC { execzlefunc(t); } LASTALLOC; unrefthingy(t); + if (args[1]) + zmod = modsave; return 0; } diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c index 8db571d0b..bc6cff8b6 100644 --- a/Src/Zle/zle_tricky.c +++ b/Src/Zle/zle_tricky.c @@ -578,6 +578,10 @@ static char *varname; static int insubscr; +/* Parameter pointer for completing keys of an assoc array. */ + +static Param keypm; + /* 1 if we are completing in a quoted string (or inside `...`) */ /**/ @@ -1364,9 +1368,15 @@ get_comp_string(void) zsfree(varname); varname = ztrdup(tt); *s = sav; - if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb) - s = NULL, inwhat = IN_MATH, insubscr = 1; - else if (*s == '=' && cs > wb + (s - tt)) { + if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt + cs - wb) { + s = NULL; + inwhat = IN_MATH; + if ((keypm = (Param) paramtab->getnode(paramtab, varname)) && + (keypm->flags & PM_HASHED)) + insubscr = 2; + else + insubscr = 1; + } else if (*s == '=' && cs > wb + (s - tt)) { s++; wb += s - tt; t0 = STRING; @@ -1424,11 +1434,15 @@ get_comp_string(void) zsfree(varname); varname = ztrdup(nb); *ne = sav; + if ((keypm = (Param) paramtab->getnode(paramtab, + varname)) && + (keypm->flags & PM_HASHED)) + insubscr = 2; } } } if (inwhat == IN_MATH) { - if (compfunc) { + if (compfunc || insubscr == 2) { int lev; char *p; @@ -1472,7 +1486,11 @@ get_comp_string(void) zsfree(varname); varname = ztrdup((char *) line + i + 1); line[wb - 1] = sav; - insubscr = 1; + if ((keypm = (Param) paramtab->getnode(paramtab, varname)) && + (keypm->flags & PM_HASHED)) + insubscr = 2; + else + insubscr = 1; } } /* This variable will hold the current word in quoted form. */ @@ -3524,7 +3542,7 @@ int addmatches(Cadata dat, char **argv) { char *s, *ms, *lipre = NULL, *lisuf = NULL, *lpre = NULL, *lsuf = NULL; - char **aign = NULL, **dparr; + char **aign = NULL, **dparr = NULL; int lpl, lsl, pl, sl, bpl, bsl, llpl = 0, llsl = 0, nm = mnum; int oisalt = 0, isalt, isexact, doadd; Cline lc = NULL; @@ -4360,7 +4378,7 @@ callcompfunc(char *s, char *fn) PERMALLOC { q = compwords = (char **) - zalloc((clwnum - aadd + 1) * sizeof(char *)); + zalloc((clwnum + 1) * sizeof(char *)); for (p = clwords + aadd; *p; p++, q++) { tmp = dupstring(*p); untokenize(tmp); @@ -4829,13 +4847,22 @@ makecomplistglobal(char *os, int incmd, int lst, int flags) char *s; ccont = CC_CCCONT; + cc_dummy.suffix = NULL; if (linwhat == IN_ENV) { /* Default completion for parameter values. */ cc = &cc_default; + keypm = NULL; } else if (linwhat == IN_MATH) { - /* Parameter names inside mathematical expression. */ - cc_dummy.mask = CC_PARAMS; + if (insubscr == 2) { + /* Inside subscript of assoc array, complete keys. */ + cc_dummy.mask = 0; + cc_dummy.suffix = "]"; + } else { + /* Other math environment, complete paramete names. */ + keypm = NULL; + cc_dummy.mask = CC_PARAMS; + } cc = &cc_dummy; cc_dummy.refc = 10000; } else if (linwhat == IN_COND) { @@ -4851,13 +4878,16 @@ makecomplistglobal(char *os, int incmd, int lst, int flags) (CC_FILES | CC_PARAMS); cc = &cc_dummy; cc_dummy.refc = 10000; - } else if (linredir) + keypm = NULL; + } else if (linredir) { /* In redirections use default completion. */ cc = &cc_default; - else + keypm = NULL; + } else { /* Otherwise get the matches for the command. */ + keypm = NULL; return makecomplistcmd(os, incmd, flags); - + } if (cc) { /* First, use the -T compctl. */ if (!(flags & CFN_FIRST)) { @@ -5917,7 +5947,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) Comp compc = NULL; char *e, *h, hpatsav; Histent he; - int i = curhist - 1, n = cc->hnum; + int i = addhistnum(curhist,-1,HIST_FOREIGN), n = cc->hnum; /* Parse the pattern, if it isn't the null string. */ if (*(cc->hpat)) { @@ -5971,7 +6001,12 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd) if ((t = cc->mask & (CC_ALREG | CC_ALGLOB))) /* Add the two types of aliases. */ dumphashtable(aliastab, t | (cc->mask & (CC_DISCMDS|CC_EXCMDS))); - + if (keypm && cc == &cc_dummy) { + /* Add the keys of the parameter in keypm. */ + scanhashtable(keypm->gets.hfn(keypm), 0, 0, PM_UNSET, addhnmatch, 0); + keypm = NULL; + cc_dummy.suffix = NULL; + } if (!errflag && cc->ylist) { /* generate the user-defined display list: if anything fails, * * we silently allow the normal completion list to be used. */ diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index 4cdb3c52d..8524fd21e 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -572,10 +572,8 @@ undo(void) static void unapplychange(struct change *ch) { - if(ch->hist != histline) { - remember_edits(); - setline(zle_get_event(histline = ch->hist)); - } + if(ch->hist != histline) + zle_setline(quietgethist(ch->hist)); cs = ch->off; if(ch->ins) foredel(ztrlen(ch->ins)); @@ -613,10 +611,8 @@ redo(void) static void applychange(struct change *ch) { - if(ch->hist != histline) { - remember_edits(); - setline(zle_get_event(histline = ch->hist)); - } + if(ch->hist != histline) + zle_setline(quietgethist(ch->hist)); cs = ch->off; if(ch->del) foredel(ztrlen(ch->del)); |