mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-30 17:50:58 +01:00
25744: dynamic named directories and further doshfunc() simplification
This commit is contained in:
parent
84584ea58b
commit
b2d08a2155
13 changed files with 204 additions and 24 deletions
10
ChangeLog
10
ChangeLog
|
|
@ -1,3 +1,13 @@
|
||||||
|
2008-09-26 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
|
* 25744: Doc/Zsh/expn.yo, Src/exec.c, Src/math.c, Src/signals.c,
|
||||||
|
Src/subst.c, Src/utils.c, Src/Modules/zftp.c, Src/Zle/compcore.c,
|
||||||
|
Src/Zle/compctl.c, Src/Zle/zle_main.c, Src/Zle/zle_misc.c,
|
||||||
|
Test/D01prompt.ztst: Add dynamic named directories using
|
||||||
|
~[<stuff>] which calls zsh_directory_name n <stuff> and
|
||||||
|
reverse call to look up names. Also further simplify doshfunc()
|
||||||
|
interface to use flags directly from the Shfunc structure.
|
||||||
|
|
||||||
2008-09-25 Peter Stephenson <pws@csr.com>
|
2008-09-25 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
* 25684: Src/prompt.c: make %x and %I consistent with
|
* 25684: Src/prompt.c: make %x and %I consistent with
|
||||||
|
|
|
||||||
|
|
@ -1308,8 +1308,73 @@ The tt(PUSHD_MINUS)
|
||||||
option exchanges the effects of `tt(~PLUS())' and `tt(~-)' where they are
|
option exchanges the effects of `tt(~PLUS())' and `tt(~-)' where they are
|
||||||
followed by a number.
|
followed by a number.
|
||||||
|
|
||||||
cindex(directories, named)
|
subsect(Dynamic named directories)
|
||||||
cindex(named directories)
|
cindex(directories, named, dynamic)
|
||||||
|
cindex(named directories, dynamicic)
|
||||||
|
cindex(dynamic named directories)
|
||||||
|
|
||||||
|
The feature described here is only available if the shell function
|
||||||
|
tt(zsh_directory_name) exists.
|
||||||
|
|
||||||
|
A `tt(~)' followed by a string var(namstr) in unquoted square brackets is
|
||||||
|
treated specially as a dynamic directory name. Note that the first
|
||||||
|
unquoted closing square bracket always terminates var(namstr). The shell
|
||||||
|
function is passed two arguments: the string tt(n) (for name) and
|
||||||
|
var(namstr). It should either set the array tt(reply) to a single element
|
||||||
|
which is the directory corresponding to the name and return status zero
|
||||||
|
(executing an assignment as the last statement is usually sufficient), or
|
||||||
|
it should return status non-zero. In the former case the element of reply
|
||||||
|
is used as the directory; in the latter case the substitution is deemed to
|
||||||
|
have failed and tt(NOMATCH) handling is applied if the option is set.
|
||||||
|
|
||||||
|
The function tt(zsh_directory_name) is also used to see if a directory can
|
||||||
|
be turned into a name, for example when printing the directory stack or
|
||||||
|
when expanding tt(%~) in prompts. In this case the function is passed two
|
||||||
|
arguments: the string tt(d) (for directory) and the candidate for dynamic
|
||||||
|
naming. The function should either return non-zero status, if the
|
||||||
|
directory cannot be named by the function, or it should set the array reply
|
||||||
|
to consist of two elements: the first is the dynamic name for the directory
|
||||||
|
(as would appear within `tt(~[)var(...)tt(])'), and the second is the
|
||||||
|
prefix length of the directory to be replaced. For example, if the trial
|
||||||
|
directory is tt(/home/myname/src/zsh) and the dynamic name for
|
||||||
|
tt(/home/myname/src) (which has 16 characters) is tt(s), then the function
|
||||||
|
sets
|
||||||
|
|
||||||
|
example(reply=(s 16))
|
||||||
|
|
||||||
|
The directory name so returned is compared with possible static names for
|
||||||
|
parts of the directory path, as described below; it is used if the prefix
|
||||||
|
length matched (16 in the example) is longer than that matched by any
|
||||||
|
static name.
|
||||||
|
|
||||||
|
As a working example, here is a function that expands any dynamic names
|
||||||
|
beginning with the string tt(p:) to directories below
|
||||||
|
tt(/home/pws/perforce). In this simple case a static name for the
|
||||||
|
directory would be just as effective.
|
||||||
|
|
||||||
|
example(zsh_directory_name() {
|
||||||
|
emulate -L zsh
|
||||||
|
setopt extendedglob
|
||||||
|
local -a match mbegin mend
|
||||||
|
if [[ $1 = d ]]; then
|
||||||
|
if [[ $2 = (#b)(/home/pws/perforce/)([^/]##)* ]]; then
|
||||||
|
typeset -ga reply
|
||||||
|
reply=(p:$match[2] $(( ${#match[1]} + ${#match[2]} )) )
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
[[ $2 != (#b)p:(?*) ]] && return 1
|
||||||
|
typeset -ga reply
|
||||||
|
reply=(/home/pws/perforce/$match[1])
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
subsect(Static named directories)
|
||||||
|
cindex(directories, named, static)
|
||||||
|
cindex(named directories, static)
|
||||||
|
cindex(static named directories)
|
||||||
A `tt(~)' followed by anything not already covered is looked up as a
|
A `tt(~)' followed by anything not already covered is looked up as a
|
||||||
named directory, and replaced by the value of that named directory if found.
|
named directory, and replaced by the value of that named directory if found.
|
||||||
Named directories are typically home directories for users on the system.
|
Named directories are typically home directories for users on the system.
|
||||||
|
|
@ -1329,6 +1394,8 @@ with ties broken in favour of using a named directory,
|
||||||
except when the directory is tt(/) itself. The parameters tt($PWD) and
|
except when the directory is tt(/) itself. The parameters tt($PWD) and
|
||||||
tt($OLDPWD) are never abbreviated in this fashion.
|
tt($OLDPWD) are never abbreviated in this fashion.
|
||||||
|
|
||||||
|
subsect(`=' expansion)
|
||||||
|
|
||||||
If a word begins with an unquoted `tt(=)'
|
If a word begins with an unquoted `tt(=)'
|
||||||
and the tt(EQUALS) option is set,
|
and the tt(EQUALS) option is set,
|
||||||
the remainder of the word is taken as the
|
the remainder of the word is taken as the
|
||||||
|
|
@ -1336,6 +1403,8 @@ name of a command. If a command
|
||||||
exists by that name, the word is replaced
|
exists by that name, the word is replaced
|
||||||
by the full pathname of the command.
|
by the full pathname of the command.
|
||||||
|
|
||||||
|
subsect(Notes)
|
||||||
|
|
||||||
Filename expansion is performed on the right hand side of a parameter
|
Filename expansion is performed on the right hand side of a parameter
|
||||||
assignment, including those appearing after commands of the
|
assignment, including those appearing after commands of the
|
||||||
tt(typeset) family. In this case, the right hand side will be treated
|
tt(typeset) family. In this case, the right hand side will be treated
|
||||||
|
|
@ -1349,6 +1418,7 @@ If the option tt(MAGIC_EQUAL_SUBST) is set, any unquoted shell
|
||||||
argument in the form `var(identifier)tt(=)var(expression)' becomes eligible
|
argument in the form `var(identifier)tt(=)var(expression)' becomes eligible
|
||||||
for file expansion as described in the previous paragraph. Quoting the
|
for file expansion as described in the previous paragraph. Quoting the
|
||||||
first `tt(=)' also inhibits this.
|
first `tt(=)' also inhibits this.
|
||||||
|
|
||||||
texinode(Filename Generation)()(Filename Expansion)(Expansion)
|
texinode(Filename Generation)()(Filename Expansion)(Expansion)
|
||||||
sect(Filename Generation)
|
sect(Filename Generation)
|
||||||
cindex(filename generation)
|
cindex(filename generation)
|
||||||
|
|
|
||||||
|
|
@ -1480,7 +1480,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc(shfunc, NULL, 0, 1);
|
doshfunc(shfunc, NULL, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
/* Now add in the bit of the file we've got/sent already */
|
/* Now add in the bit of the file we've got/sent already */
|
||||||
sofar = last_sofar = startat;
|
sofar = last_sofar = startat;
|
||||||
|
|
@ -1613,7 +1613,7 @@ zfsenddata(char *name, int recv, int progress, off_t startat)
|
||||||
|
|
||||||
zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER);
|
zfsetparam("ZFTP_COUNT", &sofar, ZFPM_READONLY|ZFPM_INTEGER);
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc(shfunc, NULL, 0, 1);
|
doshfunc(shfunc, NULL, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
last_sofar = sofar;
|
last_sofar = sofar;
|
||||||
}
|
}
|
||||||
|
|
@ -2395,7 +2395,7 @@ zfgetcwd(void)
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc(shfunc, NULL, 0, 1);
|
doshfunc(shfunc, NULL, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -2615,7 +2615,7 @@ zftp_getput(char *name, char **args, int flags)
|
||||||
zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"),
|
zfsetparam("ZFTP_TRANSFER", ztrdup(recv ? "GF" : "PF"),
|
||||||
ZFPM_READONLY);
|
ZFPM_READONLY);
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc(shfunc, NULL, 0, 1);
|
doshfunc(shfunc, NULL, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
if (rest) {
|
if (rest) {
|
||||||
|
|
@ -2770,7 +2770,7 @@ zfclose(int leaveparams)
|
||||||
int osc = sfcontext;
|
int osc = sfcontext;
|
||||||
|
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
doshfunc(shfunc, NULL, 0, 1);
|
doshfunc(shfunc, NULL, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -814,7 +814,7 @@ callcompfunc(char *s, char *fn)
|
||||||
while (*p)
|
while (*p)
|
||||||
addlinknode(largs, dupstring(*p++));
|
addlinknode(largs, dupstring(*p++));
|
||||||
}
|
}
|
||||||
doshfunc(shfunc, largs, 0, 0);
|
doshfunc(shfunc, largs, 0);
|
||||||
cfret = lastval;
|
cfret = lastval;
|
||||||
lastval = olv;
|
lastval = olv;
|
||||||
} OLDHEAPS;
|
} OLDHEAPS;
|
||||||
|
|
|
||||||
|
|
@ -3664,7 +3664,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
incompctlfunc = 1;
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
/* Call the function. */
|
/* Call the function. */
|
||||||
doshfunc(shfunc, args, 0, 1);
|
doshfunc(shfunc, args, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
incompctlfunc = 0;
|
incompctlfunc = 0;
|
||||||
/* And get the result from the reply parameter. */
|
/* And get the result from the reply parameter. */
|
||||||
|
|
@ -3839,7 +3839,7 @@ makecomplistflags(Compctl cc, char *s, int incmd, int compadd)
|
||||||
if (incompfunc != 1)
|
if (incompfunc != 1)
|
||||||
incompctlfunc = 1;
|
incompctlfunc = 1;
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
doshfunc(shfunc, args, 0, 1);
|
doshfunc(shfunc, args, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
incompctlfunc = 0;
|
incompctlfunc = 0;
|
||||||
uv = "reply";
|
uv = "reply";
|
||||||
|
|
|
||||||
|
|
@ -1330,7 +1330,7 @@ execzlefunc(Thingy func, char **args, int set_bindk)
|
||||||
makezleparams(0);
|
makezleparams(0);
|
||||||
sfcontext = SFC_WIDGET;
|
sfcontext = SFC_WIDGET;
|
||||||
opts[XTRACE] = 0;
|
opts[XTRACE] = 0;
|
||||||
ret = doshfunc(shf, largs, shf->node.flags, 1);
|
ret = doshfunc(shf, largs, 1);
|
||||||
opts[XTRACE] = oxt;
|
opts[XTRACE] = oxt;
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
endparamscope();
|
endparamscope();
|
||||||
|
|
|
||||||
|
|
@ -1384,7 +1384,7 @@ iremovesuffix(ZLE_INT_T c, int keep)
|
||||||
startparamscope();
|
startparamscope();
|
||||||
makezleparams(0);
|
makezleparams(0);
|
||||||
sfcontext = SFC_COMPLETE;
|
sfcontext = SFC_COMPLETE;
|
||||||
doshfunc(shfunc, args, 0, 1);
|
doshfunc(shfunc, args, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
endparamscope();
|
endparamscope();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -518,7 +518,7 @@ commandnotfound(char *arg0, LinkList args)
|
||||||
return 127;
|
return 127;
|
||||||
|
|
||||||
pushnode(args, arg0);
|
pushnode(args, arg0);
|
||||||
return doshfunc(shf, args, shf->node.flags, 1);
|
return doshfunc(shf, args, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* execute an external command */
|
/* execute an external command */
|
||||||
|
|
@ -4064,7 +4064,7 @@ execshfunc(Shfunc shf, LinkList args)
|
||||||
cmdsp = 0;
|
cmdsp = 0;
|
||||||
if ((osfc = sfcontext) == SFC_NONE)
|
if ((osfc = sfcontext) == SFC_NONE)
|
||||||
sfcontext = SFC_DIRECT;
|
sfcontext = SFC_DIRECT;
|
||||||
doshfunc(shf, args, shf->node.flags, 0);
|
doshfunc(shf, args, 0);
|
||||||
sfcontext = osfc;
|
sfcontext = osfc;
|
||||||
free(cmdstack);
|
free(cmdstack);
|
||||||
cmdstack = ocs;
|
cmdstack = ocs;
|
||||||
|
|
@ -4191,8 +4191,6 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
* in which the first element is the function name (even if
|
* in which the first element is the function name (even if
|
||||||
* FUNCTIONARGZERO is set as this is handled inside this function).
|
* FUNCTIONARGZERO is set as this is handled inside this function).
|
||||||
*
|
*
|
||||||
* flags are a set of the PM_ flags associated with the function.
|
|
||||||
*
|
|
||||||
* If noreturnval is nonzero, then reset the current return
|
* If noreturnval is nonzero, then reset the current return
|
||||||
* value (lastval) to its value before the shell function
|
* value (lastval) to its value before the shell function
|
||||||
* was executed. However, in any case return the status value
|
* was executed. However, in any case return the status value
|
||||||
|
|
@ -4202,13 +4200,14 @@ loadautofn(Shfunc shf, int fksh, int autol)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export int
|
mod_export int
|
||||||
doshfunc(Shfunc shfunc, LinkList doshargs, int flags, int noreturnval)
|
doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
|
||||||
{
|
{
|
||||||
char **tab, **x, *oargv0;
|
char **tab, **x, *oargv0;
|
||||||
int oldzoptind, oldlastval, oldoptcind, oldnumpipestats, ret;
|
int oldzoptind, oldlastval, oldoptcind, oldnumpipestats, ret;
|
||||||
int *oldpipestats = NULL;
|
int *oldpipestats = NULL;
|
||||||
char saveopts[OPT_SIZE], *oldscriptname = scriptname;
|
char saveopts[OPT_SIZE], *oldscriptname = scriptname;
|
||||||
char *name = shfunc->node.nam;
|
char *name = shfunc->node.nam;
|
||||||
|
int flags = shfunc->node.flags;
|
||||||
char *fname = dupstring(name);
|
char *fname = dupstring(name);
|
||||||
int obreaks, saveemulation ;
|
int obreaks, saveemulation ;
|
||||||
Eprog prog;
|
Eprog prog;
|
||||||
|
|
|
||||||
|
|
@ -872,7 +872,7 @@ callmathfunc(char *o)
|
||||||
if (!shfunc)
|
if (!shfunc)
|
||||||
zerr("no such function: %s", shfnam);
|
zerr("no such function: %s", shfnam);
|
||||||
else {
|
else {
|
||||||
doshfunc(shfunc, l, 0, 1);
|
doshfunc(shfunc, l, 1);
|
||||||
return lastmathval;
|
return lastmathval;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1160,7 +1160,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
|
||||||
trapisfunc = isfunc = 1;
|
trapisfunc = isfunc = 1;
|
||||||
|
|
||||||
sfcontext = SFC_SIGNAL;
|
sfcontext = SFC_SIGNAL;
|
||||||
doshfunc((Shfunc)sigfn, args, 0, 1);
|
doshfunc((Shfunc)sigfn, args, 1);
|
||||||
sfcontext = osc;
|
sfcontext = osc;
|
||||||
freelinklist(args, (FreeFunc) NULL);
|
freelinklist(args, (FreeFunc) NULL);
|
||||||
zsfree(name);
|
zsfree(name);
|
||||||
|
|
|
||||||
19
Src/subst.c
19
Src/subst.c
|
|
@ -528,7 +528,8 @@ filesubstr(char **namptr, int assign)
|
||||||
char *str = *namptr;
|
char *str = *namptr;
|
||||||
|
|
||||||
if (*str == Tilde && str[1] != '=' && str[1] != Equals) {
|
if (*str == Tilde && str[1] != '=' && str[1] != Equals) {
|
||||||
char *ptr;
|
Shfunc dirfunc;
|
||||||
|
char *ptr, *tmp, *res;
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
val = zstrtol(str + 1, &ptr, 10);
|
val = zstrtol(str + 1, &ptr, 10);
|
||||||
|
|
@ -539,9 +540,23 @@ filesubstr(char **namptr, int assign)
|
||||||
*namptr = dyncat(pwd, str + 2);
|
*namptr = dyncat(pwd, str + 2);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (str[1] == '-' && isend(str[2])) { /* ~- */
|
} else if (str[1] == '-' && isend(str[2])) { /* ~- */
|
||||||
char *tmp;
|
|
||||||
*namptr = dyncat((tmp = oldpwd) ? tmp : pwd, str + 2);
|
*namptr = dyncat((tmp = oldpwd) ? tmp : pwd, str + 2);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (str[1] == Inbrack &&
|
||||||
|
(dirfunc = getshfunc("zsh_directory_name")) &&
|
||||||
|
(ptr = strchr(str+2, Outbrack))) {
|
||||||
|
char **arr;
|
||||||
|
untokenize(tmp = dupstrpfx(str+2, ptr - (str+2)));
|
||||||
|
remnulargs(tmp);
|
||||||
|
arr = subst_string_by_func(dirfunc, "n", tmp);
|
||||||
|
res = arr ? *arr : NULL;
|
||||||
|
if (res) {
|
||||||
|
*namptr = dyncat(res, ptr+1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (isset(NOMATCH))
|
||||||
|
zerr("no directory expansion: ~[%s]", tmp);
|
||||||
|
return 0;
|
||||||
} else if (!inblank(str[1]) && isend(*ptr) &&
|
} else if (!inblank(str[1]) && isend(*ptr) &&
|
||||||
(!idigit(str[1]) || (ptr - str < 4))) {
|
(!idigit(str[1]) || (ptr - str < 4))) {
|
||||||
char *ds;
|
char *ds;
|
||||||
|
|
|
||||||
49
Src/utils.c
49
Src/utils.c
|
|
@ -826,6 +826,7 @@ finddir(char *s)
|
||||||
{
|
{
|
||||||
static struct nameddir homenode = { {NULL, "", 0}, NULL, 0 };
|
static struct nameddir homenode = { {NULL, "", 0}, NULL, 0 };
|
||||||
static int ffsz;
|
static int ffsz;
|
||||||
|
Shfunc func = getshfunc("zsh_directory_name");
|
||||||
|
|
||||||
/* Invalidate directory cache if argument is NULL. This is called *
|
/* Invalidate directory cache if argument is NULL. This is called *
|
||||||
* whenever a node is added to or removed from the hash table, and *
|
* whenever a node is added to or removed from the hash table, and *
|
||||||
|
|
@ -841,7 +842,8 @@ finddir(char *s)
|
||||||
return finddir_last = NULL;
|
return finddir_last = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(s, finddir_full) && *finddir_full)
|
/* It's not safe to use the cache while we have function transformations.*/
|
||||||
|
if(!func && !strcmp(s, finddir_full) && *finddir_full)
|
||||||
return finddir_last;
|
return finddir_last;
|
||||||
|
|
||||||
if ((int)strlen(s) >= ffsz) {
|
if ((int)strlen(s) >= ffsz) {
|
||||||
|
|
@ -853,6 +855,21 @@ finddir(char *s)
|
||||||
finddir_last=NULL;
|
finddir_last=NULL;
|
||||||
finddir_scan(&homenode.node, 0);
|
finddir_scan(&homenode.node, 0);
|
||||||
scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 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 = tricat("[", 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;
|
return finddir_last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1146,7 +1163,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval)
|
||||||
sfcontext = SFC_HOOK;
|
sfcontext = SFC_HOOK;
|
||||||
|
|
||||||
if ((shfunc = getshfunc(name))) {
|
if ((shfunc = getshfunc(name))) {
|
||||||
ret = doshfunc(shfunc, lnklst, 0, 1);
|
ret = doshfunc(shfunc, lnklst, 1);
|
||||||
stat = 0;
|
stat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1162,7 +1179,7 @@ callhookfunc(char *name, LinkList lnklst, int arrayp, int *retval)
|
||||||
if ((arrptr = getaparam(arrnam))) {
|
if ((arrptr = getaparam(arrnam))) {
|
||||||
for (; *arrptr; arrptr++) {
|
for (; *arrptr; arrptr++) {
|
||||||
if ((shfunc = getshfunc(*arrptr))) {
|
if ((shfunc = getshfunc(*arrptr))) {
|
||||||
int newret = doshfunc(shfunc, lnklst, 0, 1);
|
int newret = doshfunc(shfunc, lnklst, 1);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = newret;
|
ret = newret;
|
||||||
stat = 0;
|
stat = 0;
|
||||||
|
|
@ -2901,6 +2918,32 @@ getshfunc(char *nam)
|
||||||
return (Shfunc) shfunctab->getnode(shfunctab, nam);
|
return (Shfunc) shfunctab->getnode(shfunctab, nam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the function func to substitute string orig by setting
|
||||||
|
* the parameter reply.
|
||||||
|
* Return the array from reply, or NULL if the function returned
|
||||||
|
* non-zero status.
|
||||||
|
* The returned value comes directly from the parameter and
|
||||||
|
* so should be used before there is any chance of that
|
||||||
|
* being changed or unset.
|
||||||
|
* If arg1 is not NULL, it is used as an initial argument to
|
||||||
|
* the function, with the original string as the second argument.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**/
|
||||||
|
char **
|
||||||
|
subst_string_by_func(Shfunc func, char *arg1, char *orig)
|
||||||
|
{
|
||||||
|
LinkList l = newlinklist();
|
||||||
|
addlinknode(l, func->node.nam);
|
||||||
|
if (arg1)
|
||||||
|
addlinknode(l, arg1);
|
||||||
|
addlinknode(l, orig);
|
||||||
|
if (doshfunc(func, l, 1))
|
||||||
|
return NULL;
|
||||||
|
return getaparam("reply");
|
||||||
|
}
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
mod_export char **
|
mod_export char **
|
||||||
mkarray(char *s)
|
mkarray(char *s)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
%prep
|
%prep
|
||||||
|
|
||||||
|
mkdir prompt.tmp
|
||||||
|
cd prompt.tmp
|
||||||
mydir=$PWD
|
mydir=$PWD
|
||||||
SHLVL=2
|
SHLVL=2
|
||||||
setopt extendedglob
|
setopt extendedglob
|
||||||
|
|
@ -104,3 +106,44 @@
|
||||||
print "Years do not agree in $date2, $date3"
|
print "Years do not agree in $date2, $date3"
|
||||||
fi
|
fi
|
||||||
0:Dates produced by prompt escapes
|
0:Dates produced by prompt escapes
|
||||||
|
|
||||||
|
mkdir foo
|
||||||
|
mkdir foo/bar
|
||||||
|
mkdir foo/bar/rod
|
||||||
|
(zsh_directory_name() {
|
||||||
|
emulate -L zsh
|
||||||
|
setopt extendedglob
|
||||||
|
local -a match mbegin mend
|
||||||
|
if [[ $1 = d ]]; then
|
||||||
|
if [[ $2 = (#b)(*bar)/rod ]]; then
|
||||||
|
reply=(barmy ${#match[1]})
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ $2 = barmy ]]; then
|
||||||
|
reply=($mydir/foo/bar)
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
# success
|
||||||
|
print ~[barmy]/anything
|
||||||
|
cd foo/bar/rod
|
||||||
|
print -P %~
|
||||||
|
# failure
|
||||||
|
setopt nonomatch
|
||||||
|
print ~[scuzzy]/rubbish
|
||||||
|
cd ../..
|
||||||
|
print -P %~
|
||||||
|
# catastrophic failure
|
||||||
|
unsetopt nonomatch
|
||||||
|
print ~[scuzzy]/rubbish
|
||||||
|
)
|
||||||
|
1q:Dynamic named directories
|
||||||
|
>$mydir/foo/bar/anything
|
||||||
|
>~[barmy]/rod
|
||||||
|
>~[scuzzy]/rubbish
|
||||||
|
>~mydir/foo
|
||||||
|
?(eval):33: no directory expansion: ~[scuzzy]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue