about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Doc/Zsh/zle.yo3
-rw-r--r--Src/Zle/zle_main.c26
-rw-r--r--Src/init.c2
-rw-r--r--Src/signals.c2
-rw-r--r--Src/zsh.h4
5 files changed, 36 insertions, 1 deletions
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 241b90a21..820774173 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -115,6 +115,9 @@ outside ZLE, that value is temporarily inaccessible, but will return
 when the widget function exits.  These special parameters in fact have
 local scope, like parameters created in a function using tt(local).
 
+Inside completion widgets and traps called while ZLE is active, these
+parameters are available read-only.
+
 startitem()
 vindex(BUFFER)
 item(tt(BUFFER) (scalar))(
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 020710f07..1ba625685 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -992,6 +992,28 @@ trashzle(void)
 	kungetct = 0;
 }
 
+/* Hook functions. Used to allow access to zle parameters if zle is
+ * active. */
+
+static int
+zlebeforetrap(Hookdef dummy, void *dat)
+{
+    if (zleactive) {
+	startparamscope();
+	makezleparams(1);
+    }
+    return 0;
+}
+
+static int
+zleaftertrap(Hookdef dummy, void *dat)
+{
+    if (zleactive)
+	endparamscope();
+
+    return 0;
+}
+
 static struct builtin bintab[] = {
     BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaMldDANmrsLR", NULL),
     BUILTIN("vared",   0, bin_vared,   1,  7, 0, NULL,             NULL),
@@ -1049,6 +1071,8 @@ setup_(Module m)
 int
 boot_(Module m)
 {
+    addhookfunc("before_trap", (Hookfn) zlebeforetrap);
+    addhookfunc("after_trap", (Hookfn) zleaftertrap);
     addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
     addhookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
     return 0;
@@ -1063,6 +1087,8 @@ cleanup_(Module m)
 	    NULL, 0);
 	return 1;
     }
+    deletehookfunc("before_trap", (Hookfn) zlebeforetrap);
+    deletehookfunc("after_trap", (Hookfn) zleaftertrap);
     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
     deletehookdefs(m->nam, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
     return 0;
diff --git a/Src/init.c b/Src/init.c
index fa3102a9b..288f95f1b 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -90,6 +90,8 @@ mod_export sigset_t sigchld_mask;
 /**/
 mod_export struct hookdef zshhooks[] = {
     HOOKDEF("exit", NULL, HOOKF_ALL),
+    HOOKDEF("before_trap", NULL, HOOKF_ALL),
+    HOOKDEF("after_trap", NULL, HOOKF_ALL),
 };
 
 /* keep executing lists until EOF found */
diff --git a/Src/signals.c b/Src/signals.c
index d97e50dc2..7edf6f56e 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -894,6 +894,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
     lexsave();
     execsave();
     breaks = 0;
+    runhookdef(BEFORETRAPHOOK, NULL);
     if (*sigtr & ZSIG_FUNC) {
 	int osc = sfcontext;
 
@@ -912,6 +913,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
 	zsfree(name);
     } else
 	execode(sigfn, 1, 0);
+    runhookdef(AFTERTRAPHOOK, NULL);
 
     if (trapreturn > 0)
 	trapret = trapreturn;
diff --git a/Src/zsh.h b/Src/zsh.h
index ee07ec461..41add5c35 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1675,4 +1675,6 @@ typedef unsigned char * (*ZleReadFn) _((char *, char *, int));
 /* Hooks in core.                      */
 /***************************************/
 
-#define EXITHOOK (zshhooks + 0)
+#define EXITHOOK       (zshhooks + 0)
+#define BEFORETRAPHOOK (zshhooks + 1)
+#define AFTERTRAPHOOK  (zshhooks + 2)