zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: emulate -l to list options that would change
@ 2015-10-31 20:40 Peter Stephenson
  2015-11-01  0:03 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Stephenson @ 2015-10-31 20:40 UTC (permalink / raw)
  To: Zsh hackers list

For a long time I've felt a bit unclean about the fact that the easiest
way to find out what changes in an emulation is to look at the source.
It's there in the documentation, but not in an easily queriable way (and
certainly not an automatable one).

This fixes it so that "emulate -l [-LR] <mode>" tells you what options would
change if you executed "emulate [-LR] <mode>".  This is incompatible with
additional options (including a -c argument).

Arguably "emulate -l" should be an error, but it seems natural enough it does
the same as "emulate".

diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 85d1742..d13c7b4 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -477,7 +477,7 @@ cindex(compatibility, csh)
 cindex(sh, compatibility)
 cindex(ksh, compatibility)
 cindex(csh, compatibility)
-item(tt(emulate) [ tt(-LR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ var(flags) ... ] ])(
+item(tt(emulate) [ tt(-lLR) ] [ {tt(zsh)|tt(sh)|tt(ksh)|tt(csh)} [ var(flags) ... ] ])(
 Without any argument print current emulation mode.
 
 With single argument set up zsh options to emulate the specified shell
@@ -518,6 +518,14 @@ function, if any; normally these options are turned off in all emulation
 modes except tt(ksh). The tt(-L) switch is mutually exclusive with the
 use of tt(-c) in var(flags).
 
+If there is a single argument and the tt(-l) switch is given, the
+options that would be set or unset (the latter indicated with the prefix
+`tt(no)') are listed.  tt(-l) can be combined with tt(-L) or tt(-R) and
+the list will be modified in the appropriate way.  Note the list does
+not depend on the current setting of options, i.e. it includes all
+options that may in principle change, not just those that would actually
+change.
+
 The var(flags) may be any of the invocation-time flags described in
 ifnzman(noderef(Invocation))\
 ifzman(the section INVOCATION in zmanref(zsh)),
diff --git a/Src/builtin.c b/Src/builtin.c
index 8045bc8..0be20a5 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -58,7 +58,7 @@ static struct builtin builtins[] =
     BUILTIN("disable", 0, bin_enable, 0, -1, BIN_DISABLE, "afmprs", NULL),
     BUILTIN("disown", 0, bin_fg, 0, -1, BIN_DISOWN, NULL, NULL),
     BUILTIN("echo", BINF_SKIPINVALID, bin_print, 0, -1, BIN_ECHO, "neE", "-"),
-    BUILTIN("emulate", 0, bin_emulate, 0, -1, 0, "LR", NULL),
+    BUILTIN("emulate", 0, bin_emulate, 0, -1, 0, "lLR", NULL),
     BUILTIN("enable", 0, bin_enable, 0, -1, BIN_ENABLE, "afmprs", 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),
@@ -5425,10 +5425,11 @@ eval(char **argv)
 
 /**/
 int
-bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
+bin_emulate(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int opt_L = OPT_ISSET(ops, 'L');
     int opt_R = OPT_ISSET(ops, 'R');
+    int opt_l = OPT_ISSET(ops, 'l');
     int saveemulation, savehackchar;
     int ret = 1, new_emulation;
     unsigned int savepatterns;
@@ -5443,7 +5444,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
     /* without arguments just print current emulation */
     if (!shname) {
 	if (opt_L || opt_R) {
-	    zwarnnam("emulate", "not enough arguments");
+	    zwarnnam(nam, "not enough arguments");
 	    return 1;
 	}
 
@@ -5471,27 +5472,43 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
 
     /* with single argument set current emulation */
     if (!argv[1]) {
-	emulate(shname, opt_R, &emulation, opts);
+	char *cmdopts;
+	if (opt_l) {
+	    cmdopts = (char *)zhalloc(OPT_SIZE);
+	    memcpy(cmdopts, opts, OPT_SIZE);
+	} else
+	    cmdopts = opts;
+	emulate(shname, opt_R, &emulation, cmdopts);
 	if (opt_L)
-	    opts[LOCALOPTIONS] = opts[LOCALTRAPS] = opts[LOCALPATTERNS] = 1;
+	    cmdopts[LOCALOPTIONS] = cmdopts[LOCALTRAPS] =
+		cmdopts[LOCALPATTERNS] = 1;
+	if (opt_l) {
+	    list_emulate_options(cmdopts, opt_R);
+	    return 0;
+	}
 	clearpatterndisables();
 	return 0;
     }
 
+    if (opt_l) {
+	zwarnnam(nam, "too many arguments for -l");
+	return 1;
+    }
+
     argv++;
     memcpy(saveopts, opts, sizeof(opts));
     memcpy(new_opts, opts, sizeof(opts));
     savehackchar = keyboardhackchar;
     emulate(shname, opt_R, &new_emulation, new_opts);
     optlist = newlinklist();
-    if (parseopts("emulate", &argv, new_opts, &cmd, optlist)) {
+    if (parseopts(nam, &argv, new_opts, &cmd, optlist)) {
 	ret = 1;
 	goto restore;
     }
 
     /* parseopts() has consumed anything that looks like an option */
     if (*argv) {
-	zwarnnam("emulate", "unknown argument %s", *argv);
+	zwarnnam(nam, "unknown argument %s", *argv);
 	goto restore;
     }
 
@@ -5510,7 +5527,7 @@ bin_emulate(UNUSED(char *nam), char **argv, Options ops, UNUSED(int func))
      */
     if (cmd) {
 	if (opt_L) {
-	    zwarnnam("emulate", "option -L incompatible with -c");
+	    zwarnnam(nam, "option -L incompatible with -c");
 	    goto restore2;
 	}
 	*--argv = cmd;	/* on stack, never free()d, see execbuiltin() */
diff --git a/Src/options.c b/Src/options.c
index 3bf9f39..2678626 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -902,3 +902,33 @@ printoptionlist_printequiv(int optno)
     optno *= (isneg ? -1 : 1);
     printf("  equivalent to --%s%s\n", isneg ? "no-" : "", optns[optno-1].node.nam);
 }
+
+/**/
+static char *print_emulate_opts;
+
+/**/
+static void
+print_emulate_option(HashNode hn, int fully)
+{
+    Optname on = (Optname) hn;
+
+    if (!(on->node.flags & OPT_ALIAS) &&
+	((fully && !(on->node.flags & OPT_SPECIAL)) ||
+	 (on->node.flags & OPT_EMULATE)))
+    {
+	if (!print_emulate_opts[on->optno])
+	    fputs("no", stdout);
+	puts(on->node.nam);
+    }
+}
+
+/*
+ * List the settings of options associated with an emulation
+ */
+
+/**/
+void list_emulate_options(char *cmdopts, int fully)
+{
+    print_emulate_opts = cmdopts;
+    scanhashtable(optiontab, 1, 0, 0, print_emulate_option, fully);
+}


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: emulate -l to list options that would change
  2015-10-31 20:40 PATCH: emulate -l to list options that would change Peter Stephenson
@ 2015-11-01  0:03 ` Bart Schaefer
  2015-11-01 18:15   ` Peter Stephenson
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2015-11-01  0:03 UTC (permalink / raw)
  To: Zsh hackers list

On Oct 31,  8:40pm, Peter Stephenson wrote:
}
} This fixes it so that "emulate -l [-LR] <mode>" tells you what options would
} change if you executed "emulate [-LR] <mode>".  This is incompatible with
} additional options (including a -c argument).

It would be quite helpful if there were an extension to the zsh/parameter
module that could retrieve this information without having to fork and
capture $(emulate ...).


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH: emulate -l to list options that would change
  2015-11-01  0:03 ` Bart Schaefer
@ 2015-11-01 18:15   ` Peter Stephenson
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 2015-11-01 18:15 UTC (permalink / raw)
  To: Zsh hackers list

On Sat, 31 Oct 2015 17:03:03 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Oct 31,  8:40pm, Peter Stephenson wrote:
> }
> } This fixes it so that "emulate -l [-LR] <mode>" tells you what options would
> } change if you executed "emulate [-LR] <mode>".  This is incompatible with
> } additional options (including a -c argument).
> 
> It would be quite helpful if there were an extension to the zsh/parameter
> module that could retrieve this information without having to fork and
> capture $(emulate ...).

Yes, it would, but zsh's one-level-deep parameter system and lack of
namespaces doesn't make it obvious what a convenient way of doing this
would be.

If we use the information to help make the options set in completion
more manageable, for example, the thing to do would probably be set a
variable via a one off $(eumlate -l zsh) in compinit (though it needs
more work than that since that doesn't give us the set of options we
want).

pws


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-11-01 18:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-31 20:40 PATCH: emulate -l to list options that would change Peter Stephenson
2015-11-01  0:03 ` Bart Schaefer
2015-11-01 18:15   ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).