1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-01-16 10:01:16 +01:00

35386: expand tabs where useful in builtins outputing function.

Also add to zed -f.

Option is -x <numm>.
This commit is contained in:
Peter Stephenson 2015-06-05 11:21:22 +01:00
parent 4804a7c5ff
commit 2abba7243a
10 changed files with 243 additions and 51 deletions

View file

@ -1,3 +1,11 @@
2015-06-05 Peter Stephenson <p.stephenson@samsung.com>
* 35386: Doc/Zsh/builtins.yo, Doc/Zsh/contrib.yo,
Functions/Misc/zed, Src/builtin.c, Src/hashtable.c,
Src/pattern.c, Src/text.c, Src/utils.c, Src/zsh.h:
expand tabs for function output in functions, whence, where,
which and also zed -f using -x num option.
2015-06-03 Oliver Kiddle <opk@zsh.org>
* 35360 (replacing 35357): configure.ac, Src/Modules/zpty.c:

View file

@ -791,11 +791,18 @@ Equivalent to tt(typeset -E), except that options irrelevant to floating
point numbers are not permitted.
)
findex(functions)
xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UkmtTuz) ] [ var(name) ... ])
xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UkmtTuz) ] [ tt(-x) var(num) ] [ var(name) ... ])
xitem(tt(functions -M) var(mathfn) [ var(min) [ var(max) [ var(shellfn) ] ] ])
xitem(tt(functions -M) [ tt(-m) var(pattern) ... ])
item(tt(functions +M) [ tt(-m) ] var(mathfn) ... )(
Equivalent to tt(typeset -f), with the exception of the tt(-M) option.
Equivalent to tt(typeset -f), with the exception of the tt(-x) and
tt(-M) options.
The tt(-x) option indicates that any functions output will have
each leading tab for indentation, added by the shell to show syntactic
structure, expanded to the given number var(num) of spaces. var(num)
can also be 0 to suppress all indentation.
Use of the tt(-M) option may not be combined with any of the options
handled by tt(typeset -f).
@ -1927,6 +1934,9 @@ function is first referenced; see noderef(Functions). The tt(-k) and
tt(-z) flags make the function be loaded using ksh-style or zsh-style
autoloading respectively. If neither is given, the setting of the
tt(KSH_AUTOLOAD) option determines how the function is loaded.
Note that the builtin tt(functions) provides the same basic capabilities
as tt(typeset -f) but gives access to a few extra options.
)
item(tt(-h))(
Hide: only useful for special parameters (those marked `<S>' in the table in
@ -2180,7 +2190,7 @@ the user is potentially interested in both, so this problem is intrinsic
to process IDs.
)
findex(whence)
item(tt(whence) [ tt(-vcwfpamsS) ] var(name) ...)(
item(tt(whence) [ tt(-vcwfpamsS) ] [ tt(-x) var(num) ] var(name) ...)(
For each var(name), indicate how it would be interpreted if used as a
command name.
@ -2233,14 +2243,19 @@ As tt(-s), but if the pathname had to be resolved by following
multiple symlinks, the intermediate steps are printed, too. The
symlink resolved at each step might be anywhere in the path.
)
item(tt(-x) var(num))(
Expand tabs when outputting shell functions using the tt(-c) option.
This has the same effect as the tt(-x) option to the tt(functions)
builtin.
)
enditem()
)
findex(where)
item(tt(where) [ tt(-wpmsS) ] var(name) ...)(
item(tt(where) [ tt(-wpmsS) ] [ tt(-x) var(num) ] var(name) ...)(
Equivalent to tt(whence -ca).
)
findex(which)
item(tt(which) [ tt(-wpamsS) ] var(name) ...)(
item(tt(which) [ tt(-wpamsS) ] [ tt(-x) var(num) ] var(name) ...)(
Equivalent to tt(whence -c).
)
findex(zcompile)

View file

@ -3561,7 +3561,7 @@ set to the ANSI terminal escapes that turn off all attributes and turn on
bold intensity, respectively.
)
findex(fned)
item(tt(fned) var(name))(
item(tt(fned) [ tt(-x) var(num) ] var(name))(
Same as tt(zed -f). This function does not appear in the zsh
distribution, but can be created by linking tt(zed) to the name tt(fned)
in some directory in your tt(fpath).
@ -3749,7 +3749,7 @@ the difference in function between tt(zargs) and tt(xargs)) or run
tt(zargs) with the tt(-)tt(-help) option.
)
findex(zed)
xitem(tt(zed) [ tt(-f) ] var(name))
xitem(tt(zed) [ tt(-f) [ tt(-x) var(num) ] var(name))
item(tt(zed -b))(
This function uses the ZLE editor to edit a file or function.
@ -3758,7 +3758,10 @@ If the tt(-f) option is given, the name is taken to be that of
a function; if the function is marked for autoloading, tt(zed) searches
for it in the tt(fpath) and loads it. Note that functions edited this way
are installed into the current shell, but em(not) written back to the
autoload file.
autoload file. In this case the tt(-x) option specifies that leading
tabs indenting the function according to syntax should be converted into
the given number of spaces; `tt(-x 2)' is consistent with the layout
of functions distributed with the shell.
Without tt(-f), var(name) is the path name of the file to edit, which need
not exist; it is created on write, if necessary.

View file

@ -9,8 +9,9 @@
local var opt zed_file_name
# We do not want timeout while we are editing a file
integer TMOUT=0 okargs=1 fun bind
local -a expand
while getopts "fb" opt; do
while getopts "fbx:" opt; do
case $opt in
(f)
fun=1
@ -19,6 +20,14 @@ while getopts "fb" opt; do
(b)
bind=1
;;
(x)
if [[ $OPTARG != <-> ]]; then
print -r "Integer expected after -x: $OPTARG" >&2
return 1
fi
expand=(-x $OPTARG)
;;
esac
done
shift $(( OPTIND - 1 ))
@ -29,8 +38,8 @@ shift $(( OPTIND - 1 ))
if (( $# != okargs )); then
echo 'Usage:
zed filename
zed -f function
zed -b'
zed -f [ -x N ] function
zed -b' >&2
return 1
fi
@ -71,7 +80,7 @@ fi
setopt localoptions nobanghist
if ((fun)) then
var="$(functions $1)"
var="$(functions $expand $1)"
# If function is undefined but autoloadable, load it
if [[ $var = *\#\ undefined* ]] then
var="$(autoload +X $1; functions $1)"

View file

@ -72,7 +72,7 @@ static struct builtin builtins[] =
BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W", NULL),
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMtTuUz", NULL),
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMtTuUx:z", NULL),
BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "Ldfmrv", NULL),
@ -128,9 +128,9 @@ static struct builtin builtins[] =
BUILTIN("unset", BINF_PSPECIAL, bin_unset, 1, -1, 0, "fmv", NULL),
BUILTIN("unsetopt", 0, bin_setopt, 0, -1, BIN_UNSETOPT, NULL, NULL),
BUILTIN("wait", 0, bin_fg, 0, -1, BIN_WAIT, NULL, NULL),
BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsSw", NULL),
BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsSw", "ca"),
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsSw", "c"),
BUILTIN("whence", 0, bin_whence, 0, -1, 0, "acmpvfsSwx:", NULL),
BUILTIN("where", 0, bin_whence, 0, -1, 0, "pmsSwx:", "ca"),
BUILTIN("which", 0, bin_whence, 0, -1, 0, "ampsSwx:", "c"),
BUILTIN("zmodload", 0, bin_zmodload, 0, -1, 0, "AFRILP:abcfdilmpue", NULL),
BUILTIN("zcompile", 0, bin_zcompile, 0, -1, 0, "tUMRcmzka", NULL),
};
@ -2749,7 +2749,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
Patprog pprog;
Shfunc shf;
int i, returnval = 0;
int on = 0, off = 0, pflags = 0, roff;
int on = 0, off = 0, pflags = 0, roff, expand = 0;
/* Do we have any flags defined? */
if (OPT_PLUS(ops,'u'))
@ -2785,11 +2785,23 @@ bin_functions(char *name, char **argv, Options ops, int func)
}
if ((off & PM_UNDEFINED) || (OPT_ISSET(ops,'k') && OPT_ISSET(ops,'z')) ||
(OPT_ISSET(ops,'x') && !OPT_HASARG(ops,'x')) ||
(OPT_MINUS(ops,'X') && (OPT_ISSET(ops,'m') || *argv || !scriptname))) {
zwarnnam(name, "invalid option(s)");
return 1;
}
if (OPT_ISSET(ops,'x')) {
char *eptr;
expand = (int)zstrtol(OPT_ARG(ops,'x'), &eptr, 10);
if (*eptr) {
zwarnnam(name, "number expected after -x");
return 1;
}
if (expand == 0) /* no indentation at all */
expand = -1;
}
if (OPT_PLUS(ops,'f') || roff || OPT_ISSET(ops,'+'))
pflags |= PRINT_NAMEONLY;
@ -2948,8 +2960,8 @@ bin_functions(char *name, char **argv, Options ops, int func)
} else {
if (OPT_ISSET(ops,'U') && !OPT_ISSET(ops,'u'))
on &= ~PM_UNDEFINED;
scanhashtable(shfunctab, 1, on|off, DISABLED, shfunctab->printnode,
pflags);
scanshfunc(1, on|off, DISABLED, shfunctab->printnode,
pflags, expand);
}
unqueue_signals();
return ret;
@ -2965,8 +2977,8 @@ bin_functions(char *name, char **argv, Options ops, int func)
/* with no options, just print all functions matching the glob pattern */
queue_signals();
if (!(on|off) && !OPT_ISSET(ops,'X')) {
scanmatchtable(shfunctab, pprog, 1, 0, DISABLED,
shfunctab->printnode, pflags);
scanmatchshfunc(pprog, 1, 0, DISABLED,
shfunctab->printnode, pflags, expand);
} else {
/* apply the options to all functions matching the glob pattern */
for (i = 0; i < shfunctab->hsize; i++) {
@ -3008,7 +3020,7 @@ bin_functions(char *name, char **argv, Options ops, int func)
returnval = 1;
} else
/* no flags, so just print */
shfunctab->printnode(&shf->node, pflags);
printshfuncexpand(&shf->node, pflags, expand);
} else if (on & PM_UNDEFINED) {
int signum = -1, ok = 1;
@ -3222,6 +3234,7 @@ bin_whence(char *nam, char **argv, Options ops, int func)
int aliasflags;
int csh, all, v, wd;
int informed = 0;
int expand = 0;
char *cnam, **allmatched = 0;
/* Check some option information */
@ -3230,6 +3243,17 @@ bin_whence(char *nam, char **argv, Options ops, int func)
all = OPT_ISSET(ops,'a');
wd = OPT_ISSET(ops,'w');
if (OPT_ISSET(ops,'x')) {
char *eptr;
expand = (int)zstrtol(OPT_ARG(ops,'x'), &eptr, 10);
if (*eptr) {
zwarnnam(nam, "number expected after -x");
return 1;
}
if (expand == 0) /* no indentation at all */
expand = -1;
}
if (OPT_ISSET(ops,'w'))
printflags |= PRINT_WHENCE_WORD;
else if (OPT_ISSET(ops,'c'))
@ -3286,8 +3310,8 @@ bin_whence(char *nam, char **argv, Options ops, int func)
/* and shell functions... */
informed +=
scanmatchtable(shfunctab, pprog, 1, 0, DISABLED,
shfunctab->printnode, printflags);
scanmatchshfunc(pprog, 1, 0, DISABLED,
shfunctab->printnode, printflags, expand);
/* and builtins. */
informed +=
@ -3342,7 +3366,7 @@ bin_whence(char *nam, char **argv, Options ops, int func)
}
/* Look for shell function */
if ((hn = shfunctab->getnode(shfunctab, *argv))) {
shfunctab->printnode(hn, printflags);
printshfuncexpand(hn, printflags, expand);
informed = 1;
if (!all)
continue;

View file

@ -937,13 +937,17 @@ printshfuncnode(HashNode hn, int printflags)
quotedzputs(f->node.nam, stdout);
if (f->funcdef || f->node.flags & PM_UNDEFINED) {
printf(" () {\n\t");
if (f->node.flags & PM_UNDEFINED)
printf("%c undefined\n\t", hashchar);
else
printf(" () {\n");
zoutputtab(stdout);
if (f->node.flags & PM_UNDEFINED) {
printf("%c undefined\n", hashchar);
zoutputtab(stdout);
} else
t = getpermtext(f->funcdef, NULL, 1);
if (f->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL))
printf("%c traced\n\t", hashchar);
if (f->node.flags & (PM_TAGGED|PM_TAGGED_LOCAL)) {
printf("%c traced\n", hashchar);
zoutputtab(stdout);
}
if (!t) {
char *fopt = "UtTkz";
int flgs[] = {
@ -959,11 +963,12 @@ printshfuncnode(HashNode hn, int printflags)
zputs(t, stdout);
zsfree(t);
if (f->funcdef->flags & EF_RUN) {
printf("\n\t");
printf("\n");
zoutputtab(stdout);
quotedzputs(f->node.nam, stdout);
printf(" \"$@\"");
}
}
}
printf("\n}");
} else {
printf(" () { }");
@ -979,6 +984,59 @@ printshfuncnode(HashNode hn, int printflags)
putchar('\n');
}
/*
* Wrap scanmatchtable for shell functions with optional
* expansion of leading tabs.
* expand = 0 is standard: use hard tabs.
* expand > 0 uses that many spaces.
* expand < 0 uses no identation.
*
* Note this function and the following two are called with
* interrupts queued, so saving and restoring text_expand_tabs
* is safe.
*/
/**/
mod_export int
scanmatchshfunc(Patprog pprog, int sorted, int flags1, int flags2,
ScanFunc scanfunc, int scanflags, int expand)
{
int ret, save_expand;
save_expand = text_expand_tabs;
text_expand_tabs = expand;
ret = scanmatchtable(shfunctab, pprog, sorted, flags1, flags2,
scanfunc, scanflags);
text_expand_tabs = save_expand;
return ret;
}
/* Wrap scanhashtable to expand tabs for shell functions */
/**/
mod_export int
scanshfunc(int sorted, int flags1, int flags2,
ScanFunc scanfunc, int scanflags, int expand)
{
return scanmatchshfunc(NULL, sorted, flags1, flags2,
scanfunc, scanflags, expand);
}
/* Wrap shfunctab->printnode to expand tabs */
/**/
mod_export void
printshfuncexpand(HashNode hn, int printflags, int expand)
{
int save_expand;
save_expand = text_expand_tabs;
text_expand_tabs = expand;
shfunctab->printnode(hn, printflags);
text_expand_tabs = save_expand;
}
/**************************************/
/* Reserved Word Hash Table Functions */
/**************************************/

View file

@ -2202,20 +2202,15 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalen,
if ((patglobflags & GF_MATCHREF) &&
!(patflags & PAT_FILE)) {
char *str = ztrduppfx(patinstart, patinlen);
char *ptr = patinstart;
int mlen = 0;
int mlen;
/*
* Count the characters. We're not using CHARSUB()
* because the string is still metafied. We're
* not using mb_metastrlen() because that expects
* the string to be null terminated.
* because the string is still metafied.
*/
MB_METACHARINIT();
while (ptr < patinstart + patinlen) {
mlen++;
ptr += MB_METACHARLEN(ptr);
}
mlen = MB_METASTRLEN2END(patinstart, 0,
patinstart + patinlen);
setsparam("MATCH", str);
setiparam("MBEGIN",

View file

@ -30,6 +30,16 @@
#include "zsh.mdh"
#include "text.pro"
/*
* If non-zero, expand syntactically significant leading tabs in text
* to this number of spaces.
*
* If negative, don't output leading whitespace at all.
*/
/**/
int text_expand_tabs;
static char *tptr, *tbuf, *tlim, *tpending;
static int tsiz, tindent, tnewlins, tjob;
@ -156,8 +166,16 @@ taddnl(int no_semicolon)
if (tnewlins) {
tdopending();
taddchr('\n');
for (t0 = 0; t0 != tindent; t0++)
taddchr('\t');
for (t0 = 0; t0 != tindent; t0++) {
if (text_expand_tabs >= 0) {
if (text_expand_tabs) {
int t1;
for (t1 = 0; t1 < text_expand_tabs; t1++)
taddchr(' ');
} else
taddchr('\t');
}
}
} else if (no_semicolon) {
taddstr(" ");
} else {
@ -165,6 +183,30 @@ taddnl(int no_semicolon)
}
}
/*
* Output a tab that may be expanded as part of a leading set.
* Note this is not part of the text framework; it's for
* code that needs to output its own tabs that are to be
* consistent with those from getpermtext().
*
* Note these tabs are only expected to be useful at the
* start of the line, so we make no attempt to count columns.
*/
/**/
void
zoutputtab(FILE *outf)
{
if (text_expand_tabs < 0)
return;
if (text_expand_tabs) {
int i;
for (i = 0; i < text_expand_tabs; i++)
fputc(' ', outf);
} else
fputc('\t', outf);
}
/* get a permanent textual representation of n */
/**/

View file

@ -4471,9 +4471,10 @@ ztrlen(char const *s)
for (l = 0; *s; l++) {
if (*s++ == Meta) {
#ifdef DEBUG
if (! *s)
if (! *s) {
fprintf(stderr, "BUG: unexpected end of string in ztrlen()\n");
else
break;
} else
#endif
s++;
}
@ -4481,6 +4482,35 @@ ztrlen(char const *s)
return l;
}
#ifndef MULTIBYTE_SUPPORT
/*
* ztrlen() but with explicit end point for non-null-terminated
* segments. eptr may not be NULL.
*/
/**/
mod_export int
ztrlenend(char const *s, char const *eptr)
{
int l;
for (l = 0; s < eptr; l++) {
if (*s++ == Meta) {
#ifdef DEBUG
if (! *s) {
fprintf(stderr,
"BUG: unexpected end of string in ztrlenend()\n");
break;
} else
#endif
s++;
}
}
return l;
}
#endif /* MULTIBYTE_SUPPORT */
/* Subtract two pointers in a metafied string. */
/**/
@ -4879,11 +4909,16 @@ mb_metacharlenconv(const char *s, wint_t *wcp)
* If width is 1, return total character width rather than number.
* If width is greater than 1, return 1 if character has non-zero width,
* else 0.
*
* Ends if either *ptr is '\0', the normal case (eptr may be NULL for
* this), or ptr is eptr (i.e. *eptr is where the null would be if null
* terminated) for strings not delimited by nulls --- note these are
* still metafied.
*/
/**/
mod_export int
mb_metastrlen(char *ptr, int width)
mb_metastrlenend(char *ptr, int width, char *eptr)
{
char inchar, *laststart;
size_t ret;
@ -4898,7 +4933,7 @@ mb_metastrlen(char *ptr, int width)
num = num_in_char = 0;
memset(&mb_shiftstate, 0, sizeof(mb_shiftstate));
while (*ptr) {
while (*ptr && !(eptr && ptr >= eptr)) {
if (*ptr == Meta)
inchar = *++ptr ^ 32;
else

View file

@ -2926,9 +2926,11 @@ enum {
typedef wint_t convchar_t;
#define MB_METACHARLENCONV(str, cp) mb_metacharlenconv((str), (cp))
#define MB_METACHARLEN(str) mb_metacharlenconv(str, NULL)
#define MB_METASTRLEN(str) mb_metastrlen(str, 0)
#define MB_METASTRWIDTH(str) mb_metastrlen(str, 1)
#define MB_METASTRLEN2(str, widthp) mb_metastrlen(str, widthp)
#define MB_METASTRLEN(str) mb_metastrlenend(str, 0, NULL)
#define MB_METASTRWIDTH(str) mb_metastrlenend(str, 1, NULL)
#define MB_METASTRLEN2(str, widthp) mb_metastrlenend(str, widthp, NULL)
#define MB_METASTRLEN2END(str, widthp, eptr) \
mb_metastrlenend(str, widthp, eptr)
/*
* We replace broken implementations with one that uses Unicode
@ -3011,6 +3013,7 @@ typedef int convchar_t;
#define MB_METASTRLEN(str) ztrlen(str)
#define MB_METASTRWIDTH(str) ztrlen(str)
#define MB_METASTRLEN2(str, widthp) ztrlen(str)
#define MB_METASTRLEN2END(str, widthp, eptr) ztrlenend(str, eptr)
#define WCWIDTH_WINT(c) (1)