Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Implement zle -P



This lets you say
% zle -P mywidget prototypewidget myfunction
and it will work like zle -N mywidget myfunction except it will behave
like prototypewidget in Various Ways™.

---

I haven't tested this much (for completion functions, not at all) yet,
but it works for the case in the current thread, see example at the
bottom. Does it look overall sane? I'm not very sure on which/how/where
all these flags are checked and set. The final argument should probably
be optional and default to the first, like for zle -N, but zle -C doesn't
seem to do that, and that's the code I mostly copied.

I don't see any reason to change zle -N to call into zle -P internally though.

% zle -P myyank yank myyank
% myyank () {
    zle -M hello
    local oldbuf=$CUTBUFFER CUTBUFFER=${(U)CUTBUFFER
    zle .yank
    CUTBUFFER=$oldbuf
}
  # put asdfdδ in the cutbuffer here
  # press yank and myyank alternatingly
% asdfdδASDFDΔASDFDΔASDFDΔasdfdδasdfdδasdfdδASDFDΔASDFDΔASDFDΔ
  # each word gets highlighted appropriately in both cases

 Src/Zle/zle_main.c   |  5 +++--
 Src/Zle/zle_thingy.c | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index c1b70e7..d4592ba 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1396,7 +1396,8 @@ execzlefunc(Thingy func, char **args, int set_bindk)
 	    opts[XTRACE] = oxt;
 	    sfcontext = osc;
 	    endparamscope();
-	    lastcmd = 0;
+	    if (!(w->flags & ZLE_NOTCOMMAND))
+		lastcmd = w->flags;
 	    r = 1;
 	    redup(osi, 0);
 	}
@@ -1975,7 +1976,7 @@ zle_main_entry(int cmd, va_list ap)
 static struct builtin bintab[] = {
     BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
     BUILTIN("vared",   0, bin_vared,   1,  1, 0, "aAcef:hi:M:m:p:r:t:", NULL),
-    BUILTIN("zle",     0, bin_zle,     0, -1, 0, "aAcCDFgGIKlLmMNrRTUw", NULL),
+    BUILTIN("zle",     0, bin_zle,     0, -1, 0, "aAcCDFgGIKlLmMNPrRTUw", NULL),
 };
 
 /* The order of the entries in this table has to match the *HOOK
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 7fd3a59..e648838 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -347,6 +347,7 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func))
 	{ 'A', bin_zle_link, 2,  2 },
 	{ 'N', bin_zle_new,  1,  2 },
 	{ 'C', bin_zle_complete, 3, 3 },
+	{ 'P', bin_zle_prototype, 3, 3},
 	{ 'R', bin_zle_refresh, 0, -1 },
 	{ 'M', bin_zle_mesg, 1, 1 },
 	{ 'U', bin_zle_unget, 1, 1 },
@@ -591,6 +592,42 @@ bin_zle_new(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 
 /**/
 static int
+bin_zle_prototype(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
+{
+    Thingy t;
+    Widget w, pw;
+
+    t = rthingy((args[1][0] == '.') ? args[1] : dyncat(".", args[1]));
+    pw = t->widget;
+    unrefthingy(t);
+
+    if (!pw) {
+	zwarnnam(name, "invalid widget `%s'", args[1]);
+	return 1;
+    }
+    w = zalloc(sizeof(*w));
+    w->flags = pw->flags & ~WIDGET_INT;
+    w->first = NULL;
+    if (w->flags & WIDGET_NCOMP) {
+	w->u.comp.fn = pw->u.fn;
+	w->u.comp.wid = ztrdup(args[1]);
+	w->u.comp.func = ztrdup(args[2]);
+    } else {
+	w->u.fnnam = ztrdup(args[2]);
+    }
+    if (bindwidget(w, rthingy(args[0]))) {
+	freewidget(w);
+	zwarnnam(name, "widget name `%s' is protected", args[0]);
+	return 1;
+    }
+    if (w->flags & WIDGET_NCOMP)
+	hascompwidgets++;
+
+    return 0;
+}
+
+/**/
+static int
 bin_zle_complete(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     Thingy t;
-- 
2.5.0



Messages sorted by: Reverse Date, Date, Thread, Author