about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/options.yo16
-rw-r--r--Src/exec.c12
-rw-r--r--Src/options.c6
4 files changed, 33 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index c6daa5998..6146209cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2022-11-02  Jun-ichi Takimoto  <takimoto-j@kba.biglobe.ne.jp>
+
+	* 50851: Doc/Zsh/options.yo, Src/exec.c, Src/options.c: restore
+	state (such as typtab) when returning from a function with
+	localoptions (but do not take care of EMACS/VI options).
+
 2022-10-31  Bart Schaefer  <schaefer@zsh.org>
 
 	* 50855: Doc/Zsh/builtins.yo, Doc/Zsh/params.yo: Clarify how
diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index bf73664c9..445052617 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -2550,10 +2550,12 @@ pindex(NO_EMACS)
 pindex(NOEMACS)
 item(tt(EMACS))(
 If ZLE is loaded, turning on this option has the equivalent effect
-of `tt(bindkey -e)'.  In addition, the VI option is unset.
+of `tt(bindkey -e)'.  In addition, the tt(VI) option is unset.
 Turning it off has no effect.  The option setting is
-not guaranteed to reflect the current keymap.  This option is
-provided for compatibility; tt(bindkey) is the recommended interface.
+not guaranteed to reflect the current keymap, and the tt(LOCALOPTIONS)
+option does not work correctly. This option is provided only for
+compatibility, and its use is highly discouraged.  tt(bindkey) is the
+recommended interface.
 )
 pindex(OVERSTRIKE)
 pindex(NO_OVERSTRIKE)
@@ -2582,10 +2584,12 @@ pindex(NO_VI)
 pindex(NOVI)
 item(tt(VI))(
 If ZLE is loaded, turning on this option has the equivalent effect
-of `tt(bindkey -v)'.  In addition, the EMACS option is unset.
+of `tt(bindkey -v)'.  In addition, the tt(EMACS) option is unset.
 Turning it off has no effect.  The option setting is
-not guaranteed to reflect the current keymap.  This option is
-provided for compatibility; tt(bindkey) is the recommended interface.
+not guaranteed to reflect the current keymap, and the tt(LOCALOPTIONS)
+option does not work correctly. This option is provided only for
+compatibility, and its use is highly discouraged.  tt(bindkey) is the
+recommended interface.
 )
 pindex(ZLE)
 pindex(NO_ZLE)
diff --git a/Src/exec.c b/Src/exec.c
index f2911807c..c8bcf4ee5 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -5961,11 +5961,23 @@ doshfunc(Shfunc shfunc, LinkList doshargs, int noreturnval)
 	    emulation = funcsave->emulation;
 	    sticky = funcsave->sticky;
 	} else if (isset(LOCALOPTIONS)) {
+	    /* we need to call inittyptab() if these options change */
+	    int init_typtab =
+#ifdef MULTIBYTE_SUPPORT
+			funcsave->opts[MULTIBYTE] != opts[MULTIBYTE] ||
+#endif
+			funcsave->opts[BANGHIST] != opts[BANGHIST] ||
+			funcsave->opts[SHINSTDIN] != opts[SHINSTDIN];
+	    /* take care of SUNKEYBOARDHACK but not of EMACS/VI */
+	    if (funcsave->opts[SUNKEYBOARDHACK] != opts[SUNKEYBOARDHACK])
+		keyboardhackchar = funcsave->opts[SUNKEYBOARDHACK] ? '`' : '\0';
 	    /* restore all shell options except PRIVILEGED and RESTRICTED */
 	    funcsave->opts[PRIVILEGED] = opts[PRIVILEGED];
 	    funcsave->opts[RESTRICTED] = opts[RESTRICTED];
 	    memcpy(opts, funcsave->opts, sizeof(opts));
 	    emulation = funcsave->emulation;
+	    if (init_typtab)
+		inittyptab();
 	} else {
 	    /* just restore a couple. */
 	    opts[XTRACE] = funcsave->opts[XTRACE];
diff --git a/Src/options.c b/Src/options.c
index a1fe918fc..a994b563e 100644
--- a/Src/options.c
+++ b/Src/options.c
@@ -904,7 +904,11 @@ dosetopt(int optno, int value, int force, char *new_opts)
 	keyboardhackchar = (value ? '`' : '\0');
     }
     new_opts[optno] = value;
-    if (optno == BANGHIST || optno == SHINSTDIN)
+    if (
+#ifdef MULTIBYTE_SUPPORT
+	optno == MULTIBYTE ||
+#endif
+	optno == BANGHIST || optno == SHINSTDIN)
 	inittyptab();
     return 0;
 }