diff options
Diffstat (limited to 'Src/utils.c')
-rw-r--r-- | Src/utils.c | 140 |
1 files changed, 99 insertions, 41 deletions
diff --git a/Src/utils.c b/Src/utils.c index b64530bcc..066710e1e 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1,4 +1,3 @@ - /* * utils.c - miscellaneous utilities * @@ -891,7 +890,8 @@ finddir(char *s) { static struct nameddir homenode = { {NULL, "", 0}, NULL, 0 }; static int ffsz; - Shfunc func = getshfunc("zsh_directory_name"); + char **ares; + int len; /* Invalidate directory cache if argument is NULL. This is called * * whenever a node is added to or removed from the hash table, and * @@ -907,9 +907,16 @@ finddir(char *s) return finddir_last = NULL; } - /* It's not safe to use the cache while we have function transformations.*/ - if(!func && !strcmp(s, finddir_full) && *finddir_full) +#if 0 + /* + * It's not safe to use the cache while we have function + * transformations, and it's not clear it's worth the + * complexity of guessing here whether subst_string_by_hook + * is going to turn up the goods. + */ + if (!strcmp(s, finddir_full) && *finddir_full) return finddir_last; +#endif if ((int)strlen(s) >= ffsz) { free(finddir_full); @@ -921,18 +928,15 @@ finddir(char *s) finddir_scan(&homenode.node, 0); scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 0); - if (func) { - char **ares = subst_string_by_func(func, "d", finddir_full); - int len; - if (ares && arrlen(ares) >= 2 && - (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) { - /* better duplicate this string since it's come from REPLY */ - finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir)); - finddir_last->node.nam = zhtricat("[", dupstring(ares[0]), "]"); - finddir_last->dir = dupstrpfx(finddir_full, len); - finddir_last->diff = len - strlen(finddir_last->node.nam); - finddir_best = len; - } + ares = subst_string_by_hook("zsh_directory_name", "d", finddir_full); + if (ares && arrlen(ares) >= 2 && + (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) { + /* better duplicate this string since it's come from REPLY */ + finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir)); + finddir_last->node.nam = zhtricat("[", dupstring(ares[0]), "]"); + finddir_last->dir = dupstrpfx(finddir_full, len); + finddir_last->diff = len - strlen(finddir_last->node.nam); + finddir_best = len; } return finddir_last; @@ -1292,7 +1296,8 @@ preprompt(void) countprompt(str, &w, 0, -1); opts[PROMPTPERCENT] = percents; zputs(str, shout); - fprintf(shout, "%*s\r%*s\r", (int)columns - w - !hasxn, "", w, ""); + fprintf(shout, "%*s\r%*s\r", (int)zterm_columns - w - !hasxn, + "", w, ""); fflush(shout); free(str); } @@ -1554,49 +1559,49 @@ mod_export int winchanged; static int adjustlines(int signalled) { - int oldlines = lines; + int oldlines = zterm_lines; #ifdef TIOCGWINSZ - if (signalled || lines <= 0) - lines = shttyinfo.winsize.ws_row; + if (signalled || zterm_lines <= 0) + zterm_lines = shttyinfo.winsize.ws_row; else - shttyinfo.winsize.ws_row = lines; + shttyinfo.winsize.ws_row = zterm_lines; #endif /* TIOCGWINSZ */ - if (lines <= 0) { + if (zterm_lines <= 0) { DPUTS(signalled, "BUG: Impossible TIOCGWINSZ rows"); - lines = tclines > 0 ? tclines : 24; + zterm_lines = tclines > 0 ? tclines : 24; } - if (lines > 2) + if (zterm_lines > 2) termflags &= ~TERM_SHORT; else termflags |= TERM_SHORT; - return (lines != oldlines); + return (zterm_lines != oldlines); } static int adjustcolumns(int signalled) { - int oldcolumns = columns; + int oldcolumns = zterm_columns; #ifdef TIOCGWINSZ - if (signalled || columns <= 0) - columns = shttyinfo.winsize.ws_col; + if (signalled || zterm_columns <= 0) + zterm_columns = shttyinfo.winsize.ws_col; else - shttyinfo.winsize.ws_col = columns; + shttyinfo.winsize.ws_col = zterm_columns; #endif /* TIOCGWINSZ */ - if (columns <= 0) { + if (zterm_columns <= 0) { DPUTS(signalled, "BUG: Impossible TIOCGWINSZ cols"); - columns = tccolumns > 0 ? tccolumns : 80; + zterm_columns = tccolumns > 0 ? tccolumns : 80; } - if (columns > 2) + if (zterm_columns > 2) termflags &= ~TERM_NARROW; else termflags |= TERM_NARROW; - return (columns != oldcolumns); + return (zterm_columns != oldcolumns); } /* check the size of the window and adjust if necessary. * @@ -1630,8 +1635,8 @@ adjustwinsize(int from) ttycols = shttyinfo.winsize.ws_col; } else { /* Set to value from environment on failure */ - shttyinfo.winsize.ws_row = lines; - shttyinfo.winsize.ws_col = columns; + shttyinfo.winsize.ws_row = zterm_lines; + shttyinfo.winsize.ws_col = zterm_columns; resetzle = (from == 1); } #else @@ -1651,9 +1656,9 @@ adjustwinsize(int from) * but I'm concerned about what happens on race conditions; e.g., * * suppose the user resizes his xterm during `eval $(resize)'? */ if (adjustlines(from) && zgetenv("LINES")) - setiparam("LINES", lines); + setiparam("LINES", zterm_lines); if (adjustcolumns(from) && zgetenv("COLUMNS")) - setiparam("COLUMNS", columns); + setiparam("COLUMNS", zterm_columns); getwinsz = 1; break; case 2: @@ -2406,8 +2411,10 @@ getquery(char *valid_chars, int purge) } zbeep(); } - if (c >= 0) - write_loop(SHTTY, &c, 1); + if (c >= 0) { + char buf = (char)c; + write_loop(SHTTY, &buf, 1); + } if (nl) write_loop(SHTTY, "\n", 1); @@ -3211,7 +3218,7 @@ getshfunc(char *nam) char ** subst_string_by_func(Shfunc func, char *arg1, char *orig) { - int osc = sfcontext; + int osc = sfcontext, osm = stopmsg; LinkList l = newlinklist(); char **ret; @@ -3227,6 +3234,47 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig) ret = getaparam("reply"); sfcontext = osc; + stopmsg = osm; + return ret; +} + +/** + * Front end to subst_string_by_func to use hook-like logic. + * name can refer to a function, and name + "_hook" can refer + * to an array containing a list of functions. The functions + * are tried in order until one returns success. + */ +/**/ +char ** +subst_string_by_hook(char *name, char *arg1, char *orig) +{ + Shfunc func; + char **ret = NULL; + + if ((func = getshfunc(name))) { + ret = subst_string_by_func(func, arg1, orig); + } + + if (!ret) { + char **arrptr; + int namlen = strlen(name); + VARARR(char, arrnam, namlen + HOOK_SUFFIX_LEN); + memcpy(arrnam, name, namlen); + memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN); + + if ((arrptr = getaparam(arrnam))) { + /* Guard against internal modification of the array */ + arrptr = arrdup(arrptr); + for (; *arrptr; arrptr++) { + if ((func = getshfunc(*arrptr))) { + ret = subst_string_by_func(func, arg1, orig); + if (ret) + break; + } + } + } + } + return ret; } @@ -3637,6 +3685,8 @@ spname(char *oldname) thresh = (int)(p - spnameguess) / 4 + 1; if (thresh < 3) thresh = 3; + else if (thresh > 100) + thresh = 100; if ((thisdist = mindist(newname, spnameguess, spnamebest)) >= thresh) { /* The next test is always true, except for the first path * * component. We could initialize bestdist to some large * @@ -3667,16 +3717,22 @@ mindist(char *dir, char *mindistguess, char *mindistbest) int mindistd, nd; DIR *dd; char *fn; - char buf[PATH_MAX]; + char *buf; if (dir[0] == '\0') dir = "."; mindistd = 100; + + buf = zalloc(strlen(dir) + strlen(mindistguess) + 2); sprintf(buf, "%s/%s", dir, mindistguess); + if (access(unmeta(buf), F_OK) == 0) { strcpy(mindistbest, mindistguess); + free(buf); return 0; } + free(buf); + if (!(dd = opendir(unmeta(dir)))) return mindistd; while ((fn = zreaddir(dd, 0))) { @@ -5517,6 +5573,8 @@ getkeystring(char *s, int *len, int how, int *misc) } *t++ = zstrtol(s + (*s == 'x'), &s, (*s == 'x') ? 16 : 8); + if ((how & GETKEY_PRINTF_PERCENT) && t[-1] == '%') + *t++ = '%'; if (svchar) { u[3] = svchar; svchar = '\0'; |