about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2002-06-20 16:39:47 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2002-06-20 16:39:47 +0000
commit19817c34d18fc850cff54971b98bc9aa1809d1b8 (patch)
treea75c94d1136124745fbcfad958a8a8d943d741ed
parent61f9940d67117e0ab2dd9b3cba04eee6773f83a5 (diff)
downloadzsh-19817c34d18fc850cff54971b98bc9aa1809d1b8.tar.gz
zsh-19817c34d18fc850cff54971b98bc9aa1809d1b8.tar.xz
zsh-19817c34d18fc850cff54971b98bc9aa1809d1b8.zip
17334: TYPESET_SILENT shell option and typeset -p option
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/builtins.yo34
-rw-r--r--Doc/Zsh/options.yo9
-rw-r--r--Src/builtin.c59
-rw-r--r--Src/options.c1
-rw-r--r--Src/params.c98
-rw-r--r--Src/zsh.h2
7 files changed, 146 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 38672efd7..37a25bcd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-06-20  Peter Stephenson  <pws@csr.com>
+
+	* 17334: Src/builtin.c, Src/options.c, Src/params.c, Src/zsh.h,
+	Doc/Zsh/builtins.yo, Doc/Zsh/options.yo: add TYPESET_SILENT
+	shell option and `typeset -p' option.
+
 2002-06-17  Peter Stephenson  <pws@csr.com>
 
 	* unposted: Config/version.mk, Completion/Unix/Command/.distfile,
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index db7a65a2d..f46887144 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -424,7 +424,7 @@ Bring each specified var(job) in turn to the foreground.
 If no var(job) is specified, resume the current job.
 )
 findex(float)
-item(tt(float) [ {tt(PLUS())|tt(-)}tt(EFghlrtux) ] [ var(name)[tt(=)var(value)] ... ])(
+item(tt(float) [ {tt(PLUS())|tt(-)}tt(EFghlprtux) ] [ var(name)[tt(=)var(value)] ... ])(
 Equivalent to tt(typeset -E), except that options irrelevant to floating
 point numbers are not permitted.
 )
@@ -525,7 +525,7 @@ the form of a call to hash.
 )
 alias(history)(fc -l)
 findex(integer)
-item(tt(integer) [ {tt(PLUS())|tt(-)}tt(ghilrtux) ] [ var(name)[tt(=)var(value)] ... ])(
+item(tt(integer) [ {tt(PLUS())|tt(-)}tt(ghilprtux) ] [ var(name)[tt(=)var(value)] ... ])(
 Equivalent to tt(typeset -i), except that options irrelevant to
 integers are not permitted.
 )
@@ -624,7 +624,7 @@ sitem([var(mm)tt(:)]var(ss))(minutes and seconds)
 endsitem()
 )
 findex(local)
-item(tt(local) [ {tt(PLUS())|tt(-)}tt(AEFLRUZahilrtux) [var(n)]] [ var(name)[tt(=)var(value)] ] ...)(
+item(tt(local) [ {tt(PLUS())|tt(-)}tt(AEFLRUZahilprtux) [var(n)]] [ var(name)[tt(=)var(value)] ] ...)(
 Same as tt(typeset), except that the options tt(-g), and
 tt(-f) are not permitted.  In this case the tt(-x) option does not force
 the use of tt(-g), i.e. exported variables will be local to functions.
@@ -1076,7 +1076,7 @@ Equivalent to tt(whence -v).
 findex(typeset)
 cindex(parameters, setting)
 cindex(parameters, declaring)
-xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFLRUZafghilrtuxm) [var(n)]] [ \
+xitem(tt(typeset) [ {tt(PLUS())|tt(-)}tt(AEFLRUZafghilprtuxm) [var(n)]] [ \
 var(name)[tt(=)var(value)] ... ])
 item(tt(typeset) -T [ {tt(PLUS()|tt(-))}tt(LRUZrux) ] \
   var(SCALAR)[tt(=)var(value)] var(array))(
@@ -1095,11 +1095,18 @@ For each var(name)tt(=)var(value) assignment, the parameter
 var(name) is set to var(value).  Note that arrays currently cannot be
 assigned in tt(typeset) expressions, only scalars and integers.
 
-For each remaining var(name) that refers to a parameter that is set, the
-name and value of the parameter are printed in the form of an assignment.
-Nothing is printed for newly-created parameters, or when any attribute
-flags listed below are given along with the var(name).  Using `tt(PLUS())'
-instead of minus to introduce an attribute turns it off.
+If the shell option tt(TYPESET_SILENT) is not set, for each remaining
+var(name) that refers to a parameter that is set, the name and value of the
+parameter are printed in the form of an assignment.  Nothing is printed for
+newly-created parameters, or when any attribute flags listed below are
+given along with the var(name).  Using `tt(PLUS())' instead of minus to
+introduce an attribute turns it off.
+
+If the tt(-p) option is given, parameters and values are printed in the
+form of a typeset comand and an assignment (which will be printed
+separately for arrays and associative arrays), regardless of other flags
+and options.  Note that the tt(-h) flag on parameters is respected; no
+value will be shown for these parameters.
 
 If the tt(-T) option is given, exactly two (or zero) var(name)
 arguments must be present.  They represent a scalar and an array (in
@@ -1133,10 +1140,11 @@ is the word `tt(PLUS())', then names are printed but values are not.
 
 If the tt(-m) flag is given the var(name) arguments are taken as patterns
 (which should be quoted).  With no attribute flags, all parameters (or
-functions with the tt(-f) flag) with matching names are printed.  Note that
-tt(-m) is ignored if no patterns are given.  If the tt(+g) flag is combined
-with tt(-m), a new local parameter is created for every matching parameter
-that is not already local.  Otherwise tt(-m) applies all other flags or
+functions with the tt(-f) flag) with matching names are printed (the shell
+option tt(TYPESET_SILENT) is not used in this case).  Note that tt(-m) is
+ignored if no patterns are given.  If the tt(+g) flag is combined with
+tt(-m), a new local parameter is created for every matching parameter that
+is not already local.  Otherwise tt(-m) applies all other flags or
 assignments to the existing parameters.  Except when assignments are made
 with var(name)tt(=)var(value), using tt(+m) forces the matching parameters
 to be printed, even inside a function.
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index af07b7f5f..27f6b7e91 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -1161,6 +1161,15 @@ item(tt(TRANSIENT_RPROMPT))(
 Remove any right prompt from display when accepting a command
 line.  This may be useful with terminals with other cut/paste methods.
 )
+pindex(TYPESET_SILENT)
+item(tt(TYPESET_SILENT))(
+If this is unset, executing any of the `tt(typeset)' family of
+commands with no options and a list of parameters that have no values
+to be assigned but already exist will display the value of the parameter.
+If the option is set, they will only be shown when parameters are selected
+with the `tt(-m)' option.  The option `tt(-p)' is available whether or not
+the option is set.
+)
 pindex(UNSET)
 cindex(parameters, substituting unset)
 cindex(unset parameters, substituting)
diff --git a/Src/builtin.c b/Src/builtin.c
index 60971b9e1..741ac2305 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -53,7 +53,7 @@ static struct builtin builtins[] =
     BUILTIN("cd", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
     BUILTIN("chdir", 0, bin_cd, 0, 2, BIN_CD, NULL, NULL),
     BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
-    BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilrtux", NULL),
+    BUILTIN("declare", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilprtux", NULL),
     BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmr", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
@@ -62,11 +62,11 @@ static struct builtin builtins[] =
     BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmr", NULL),
     BUILTIN("eval", BINF_PSPECIAL, bin_eval, 0, -1, BIN_EVAL, NULL, NULL),
     BUILTIN("exit", BINF_PSPECIAL, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
-    BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "EFHLRTUZafhilrtu", "xg"),
+    BUILTIN("export", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, BIN_EXPORT, "EFHLRTUZafhilprtu", "xg"),
     BUILTIN("false", 0, bin_false, 0, -1, 0, NULL, NULL),
     BUILTIN("fc", BINF_FCOPTS, bin_fc, 0, -1, BIN_FC, "nlreIRWAdDfEim", NULL),
     BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
-    BUILTIN("float", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "EFHghlrtux", "E"),
+    BUILTIN("float", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "EFHghlprtux", "E"),
     BUILTIN("functions", BINF_TYPEOPTS, bin_functions, 0, -1, 0, "mtuU", NULL),
     BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
     BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
@@ -77,11 +77,11 @@ static struct builtin builtins[] =
 #endif
 
     BUILTIN("history", 0, bin_fc, 0, -1, BIN_FC, "nrdDfEim", "l"),
-    BUILTIN("integer", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghilrtux", "i"),
+    BUILTIN("integer", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "Hghilprtux", "i"),
     BUILTIN("jobs", 0, bin_fg, 0, -1, BIN_JOBS, "dlpZrs", NULL),
     BUILTIN("kill", 0, bin_kill, 0, -1, 0, NULL, NULL),
     BUILTIN("let", 0, bin_let, 1, -1, 0, NULL, NULL),
-    BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZahilrtux", NULL),
+    BUILTIN("local", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZahilprtux", NULL),
     BUILTIN("log", 0, bin_log, 0, 0, 0, NULL, NULL),
     BUILTIN("logout", 0, bin_break, 0, 1, BIN_LOGOUT, NULL, NULL),
 
@@ -101,7 +101,7 @@ static struct builtin builtins[] =
     BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
     BUILTIN("r", BINF_R, bin_fc, 0, -1, BIN_FC, "nrl", NULL),
     BUILTIN("read", 0, bin_read, 0, -1, 0, "ceklnpqrtzuAE0123456789", NULL),
-    BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghiltux", "r"),
+    BUILTIN("readonly", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilptux", "r"),
     BUILTIN("rehash", 0, bin_hash, 0, 0, 0, "df", "r"),
     BUILTIN("return", BINF_PSPECIAL, bin_break, 0, 1, BIN_RETURN, NULL, NULL),
     BUILTIN("set", BINF_PSPECIAL, bin_set, 0, -1, 0, NULL, NULL),
@@ -115,7 +115,7 @@ static struct builtin builtins[] =
     BUILTIN("trap", BINF_PSPECIAL, bin_trap, 0, -1, 0, NULL, NULL),
     BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL),
     BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsw", "v"),
-    BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilrtuxm", NULL),
+    BUILTIN("typeset", BINF_TYPEOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AEFHLRTUZafghilprtuxm", NULL),
     BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL),
     BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "m", "a"),
     BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"),
@@ -1607,7 +1607,8 @@ getasg(char *s)
 /**/
 Param
 typeset_single(char *cname, char *pname, Param pm, int func,
-	       int on, int off, int roff, char *value, Param altpm)
+	       int on, int off, int roff, char *value, Param altpm,
+	       char *ops)
 {
     int usepm, tc, keeplocal = 0, newspecial = 0;
     char *subscript;
@@ -1688,7 +1689,10 @@ typeset_single(char *cname, char *pname, Param pm, int func,
     if (usepm) {
 	on &= ~PM_LOCAL;
 	if (!on && !roff && !value) {
-	    paramtab->printnode((HashNode)pm, PRINT_INCLUDEVALUE);
+	    if (ops['p'])
+		paramtab->printnode((HashNode)pm, PRINT_TYPESET);
+	    else if (unset(TYPESETSILENT) && !ops['m'])
+		paramtab->printnode((HashNode)pm, PRINT_INCLUDEVALUE);
 	    return pm;
 	}
 	if ((pm->flags & PM_RESTRICTED) && isset(RESTRICTED)) {
@@ -1733,6 +1737,8 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 	    return NULL;
 	}
 	pm->flags |= (on & PM_READONLY);
+	if (ops['p'])
+	    paramtab->printnode((HashNode)pm, PRINT_TYPESET);
 	return pm;
     }
 
@@ -1921,6 +1927,9 @@ typeset_single(char *cname, char *pname, Param pm, int func,
 	return NULL;
     }
 
+    if (ops['p'])
+	paramtab->printnode((HashNode)pm, PRINT_TYPESET);
+
     return pm;
 }
 
@@ -1985,11 +1994,15 @@ bin_typeset(char *name, char **argv, char *ops, int func)
     queue_signals();
 
     /* Given no arguments, list whatever the options specify. */
+    if (ops['p'])
+	printflags |= PRINT_TYPESET;
     if (!*argv) {
-	if (!(on|roff))
-	    printflags |= PRINT_TYPE;
-	if (roff || ops['+'])
-	    printflags |= PRINT_NAMEONLY;
+	if (!ops['p']) {
+	    if (!(on|roff))
+		printflags |= PRINT_TYPE;
+	    if (roff || ops['+'])
+		printflags |= PRINT_NAMEONLY;
+	}
 	scanhashtable(paramtab, 1, on|roff, 0, paramtab->printnode, printflags);
 	unqueue_signals();
 	return 0;
@@ -2055,7 +2068,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
 				 (Param)paramtab->getnode(paramtab,
 							  asg->name),
 				 func, (on | PM_ARRAY) & ~PM_EXPORTED,
-				 off, roff, asg->value, NULL))) {
+				 off, roff, asg->value, NULL, ops))) {
 	    unqueue_signals();
 	    return 1;
 	}
@@ -2066,7 +2079,8 @@ bin_typeset(char *name, char **argv, char *ops, int func)
 	if (!(pm=typeset_single(name, asg0.name,
 				(Param)paramtab->getnode(paramtab,
 							 asg0.name),
-				func, on, off, roff, asg0.value, apm))) {
+				func, on, off, roff, asg0.value, apm,
+				ops))) {
 	    if (oldval)
 		zsfree(oldval);
 	    unsetparam_pm(apm, 1, 1);
@@ -2089,10 +2103,12 @@ bin_typeset(char *name, char **argv, char *ops, int func)
 
     /* With the -m option, treat arguments as glob patterns */
     if (ops['m']) {
-	if (!(on|roff))
-	    printflags |= PRINT_TYPE;
-	if (!on)
-	    printflags |= PRINT_NAMEONLY;
+	if (!ops['p']) {
+	    if (!(on|roff))
+		printflags |= PRINT_TYPE;
+	    if (!on)
+		printflags |= PRINT_NAMEONLY;
+	}
 
 	while ((asg = getasg(*argv++))) {
 	    LinkList pmlist = newlinklist();
@@ -2131,7 +2147,7 @@ bin_typeset(char *name, char **argv, char *ops, int func)
 	    for (pmnode = firstnode(pmlist); pmnode; incnode(pmnode)) {
 		pm = (Param) getdata(pmnode);
 		if (!typeset_single(name, pm->nam, pm, func, on, off, roff,
-				    asg->value, NULL))
+				    asg->value, NULL, ops))
 		    returnval = 1;
 	    }
 	}
@@ -2145,7 +2161,8 @@ bin_typeset(char *name, char **argv, char *ops, int func)
 			    (Param) (paramtab == realparamtab ?
 				     gethashnode2(paramtab, asg->name) :
 				     paramtab->getnode(paramtab, asg->name)),
-			    func, on, off, roff, asg->value, NULL))
+			    func, on, off, roff, asg->value, NULL,
+			    ops))
 	    returnval = 1;
     }
     unqueue_signals();
diff --git a/Src/options.c b/Src/options.c
index fe0b8da30..7555440f6 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -200,6 +200,7 @@ static struct optname optns[] = {
 {NULL, "singlelinezle",	      OPT_KSH,			 SINGLELINEZLE},
 {NULL, "sunkeyboardhack",     0,			 SUNKEYBOARDHACK},
 {NULL, "transientrprompt",    0,			 TRANSIENTRPROMPT},
+{NULL, "typesetsilent",	      OPT_EMULATE|OPT_BOURNE,	 TYPESETSILENT},
 {NULL, "unset",		      OPT_EMULATE|OPT_BSHELL,	 UNSET},
 {NULL, "verbose",	      0,			 VERBOSE},
 {NULL, "xtrace",	      0,			 XTRACE},
diff --git a/Src/params.c b/Src/params.c
index 2e8351af7..4d7fcdc4e 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3486,6 +3486,36 @@ freeparamnode(HashNode hn)
 
 /* Print a parameter */
 
+enum paramtypes_flags {
+    PMTF_USE_CT		= (1<<0),
+    PMTF_TEST_LEVEL	= (1<<1)
+};
+
+struct paramtypes {
+    int binflag;	/* The relevant PM_FLAG(S) */
+    const char *string;	/* String for verbose output */
+    int typeflag;	/* Flag for typeset -? */
+    int flags;		/* The enum above */
+};
+
+static const struct paramtypes pmtypes[] = {
+    { PM_AUTOLOAD, "undefined", 0, 0},
+    { PM_INTEGER, "integer", 'i', PMTF_USE_CT},
+    { PM_EFLOAT, "float", 'E', 0},
+    { PM_FFLOAT, "float", 'F', 0},
+    { PM_ARRAY, "array", 'a', 0},
+    { PM_HASHED, "association", 'A', 0},
+    { 0, "local", 0, PMTF_TEST_LEVEL},
+    { PM_LEFT, "left justified", 'L', PMTF_USE_CT},
+    { PM_RIGHT_B, "right justified", 'R', PMTF_USE_CT},
+    { PM_RIGHT_Z, "zero filled", 'Z', PMTF_USE_CT},
+    { PM_LOWER, "lowercase", 'l', 0},
+    { PM_UPPER, "uppercase", 'u', 0},
+    { PM_READONLY, "readonly", 'r', 0},
+    { PM_TAGGED, "tagged", 't', 0},
+    { PM_EXPORTED, "exported", 'x', 0}
+};
+
 /**/
 mod_export void
 printparamnode(HashNode hn, int printflags)
@@ -3496,36 +3526,43 @@ printparamnode(HashNode hn, int printflags)
     if (p->flags & PM_UNSET)
 	return;
 
+    if (printflags & PRINT_TYPESET)
+	printf("typeset ");
+
     /* Print the attributes of the parameter */
-    if (printflags & PRINT_TYPE) {
-	if (p->flags & PM_AUTOLOAD)
-	    printf("undefined ");
-	if (p->flags & PM_INTEGER)
-	    printf("integer ");
-	if (p->flags & (PM_EFLOAT|PM_FFLOAT))
-	    printf("float ");
-	else if (p->flags & PM_ARRAY)
-	    printf("array ");
-	else if (p->flags & PM_HASHED)
-	    printf("association ");
-	if (p->level)
-	    printf("local ");
-	if (p->flags & PM_LEFT)
-	    printf("left justified %d ", p->ct);
-	if (p->flags & PM_RIGHT_B)
-	    printf("right justified %d ", p->ct);
-	if (p->flags & PM_RIGHT_Z)
-	    printf("zero filled %d ", p->ct);
-	if (p->flags & PM_LOWER)
-	    printf("lowercase ");
-	if (p->flags & PM_UPPER)
-	    printf("uppercase ");
-	if (p->flags & PM_READONLY)
-	    printf("readonly ");
-	if (p->flags & PM_TAGGED)
-	    printf("tagged ");
-	if (p->flags & PM_EXPORTED)
-	    printf("exported ");
+    if (printflags & (PRINT_TYPE|PRINT_TYPESET)) {
+	int doneminus = 0, i;
+	const struct paramtypes *pmptr;
+
+	for (pmptr = pmtypes, i = 0; i < sizeof(pmtypes)/sizeof(*pmptr);
+	     i++, pmptr++) {
+	    int doprint = 0;
+	    if (pmptr->flags & PMTF_TEST_LEVEL) {
+		if (p->level)
+		    doprint = 1;
+	    } else if (p->flags & pmptr->binflag)
+		doprint = 1;
+
+	    if (doprint) {
+		if (printflags & PRINT_TYPESET) {
+		    if (pmptr->typeflag) {
+			if (!doneminus) {
+			    putchar('-');
+			    doneminus = 1;
+			}
+			putchar(pmptr->typeflag);
+		    }
+		} else {
+		    printf("%s ", pmptr->string);
+		}
+		if ((pmptr->flags & PMTF_USE_CT) && p->ct) {
+		    printf("%d ", p->ct);
+		    doneminus = 0;
+		}
+	    }
+	}
+	if (doneminus)
+	    putchar(' ');
     }
 
     if ((printflags & PRINT_NAMEONLY) ||
@@ -3543,6 +3580,9 @@ printparamnode(HashNode hn, int printflags)
     }
     if (printflags & PRINT_KV_PAIR)
 	putchar(' ');
+    else if ((printflags & PRINT_TYPESET) &&
+	     (PM_TYPE(p->flags) == PM_ARRAY || PM_TYPE(p->flags) == PM_HASHED))
+	printf("\n%s=", p->nam);
     else
 	putchar('=');
 
diff --git a/Src/zsh.h b/Src/zsh.h
index 15b4c404a..504fd1396 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1244,6 +1244,7 @@ struct nameddir {
 #define PRINT_LIST		(1<<2)
 #define PRINT_KV_PAIR		(1<<3)
 #define PRINT_INCLUDEVALUE	(1<<4)
+#define PRINT_TYPESET		(1<<5)
 
 /* flags for printing for the whence builtin */
 #define PRINT_WHENCE_CSH	(1<<5)
@@ -1465,6 +1466,7 @@ enum {
     SINGLELINEZLE,
     SUNKEYBOARDHACK,
     TRANSIENTRPROMPT,
+    TYPESETSILENT,
     UNSET,
     VERBOSE,
     XTRACE,