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

Re: Shift-Insert overwrites ZLE CUTBUFFER



On 10 Nov, Bart wrote:
> A useful addition to zsh/zleparameter would be a special hash of
> register-to-content mappings (emacs calls this register-alist).

The following patch adds this under the name "registers" and in
zle_params.c rather than zleparameter. That seemed more consistent with,
e.g. killring. It means that it is only available when ZLE is active
which it wouldn't really need to be (the same goes for killring) but
there are advantages to that too. For what it's worth, I think the term
"registers" is better than "buffers" and it'd be good to use the same
ones with emacs style widgets. What does the "alist" part of the emacs name
denote.

It contains just the registers 'a' to 'z' for now. Including the
numbered registers would just be a duplication of killring/CUTBUFFER.
(except the yank register - "0).

Why does makezleparams set pm->level to locallevel + 1? That seems
wrong. What does the + 1 achieve?

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 21681e5..a10c2d0 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -991,6 +991,11 @@ and tt(zle_highlight); see
 ifzman(the section CHARACTER HIGHLIGHTING below)\
 ifnzman(noderef(Character Highlighting)) for details.
 )
+vindex(registers)
+item(tt(registers) (associative array))(
+The contents of each of the `named' vi buffers. These are typically set
+using tt(vi-set-buffer) followed by a delete, change or yank command.
+)
 vindex(SUFFIX_ACTIVE)
 vindex(SUFFIX_START)
 vindex(SUFFIX_END)
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index c6387bf..2400bfb 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -118,6 +118,12 @@ static const struct gsu_integer suffixactive_gsu =
 
 static const struct gsu_array killring_gsu =
 { get_killring, set_killring, unset_killring };
+
+static const struct gsu_scalar register_gsu =
+{ strgetfn, set_register, unset_register };
+static const struct gsu_hash registers_gsu =
+{ hashgetfn, set_registers, zleunsetfn };
+
 /* implementation is in zle_refresh.c */
 static const struct gsu_array region_highlight_gsu =
 { get_region_highlight, set_region_highlight, unset_region_highlight };
@@ -181,6 +187,7 @@ mod_export void
 makezleparams(int ro)
 {
     struct zleparam *zp;
+    Param reg_param;
 
     for(zp = zleparams; zp->name; zp++) {
 	Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE|
@@ -206,6 +213,11 @@ makezleparams(int ro)
 	if ((zp->type & PM_UNSET) && (zmod.flags & (MOD_MULT|MOD_TMULT)))
 	    pm->node.flags &= ~PM_UNSET;
     }
+
+    reg_param = createspecialhash("registers", get_registers, &scan_registers,
+	    PM_LOCAL|PM_REMOVABLE);
+    reg_param->gsu.h = &registers_gsu;
+    reg_param->level = locallevel + 1;
 }
 
 /* Special unset function for ZLE special parameters: act like the standard *
@@ -712,6 +724,93 @@ unset_killring(Param pm, int exp)
     }
 }
 
+/**/
+static void
+set_register(Param pm, char *value)
+{
+    int n = 0;
+
+    if (!pm->node.nam || *pm->node.nam < 'a' || *pm->node.nam > 'z' ||
+	    pm->node.nam[1]) {
+	zerr("invalid zle register: %s", pm->node.nam);
+	return;
+    }
+
+    Cutbuffer reg = &vibuf[*pm->node.nam - 'a'];
+    if (*value)
+	reg->buf = stringaszleline(value, 0, &n, NULL, NULL);
+    reg->len = n;
+}
+
+/**/
+static void
+unset_register(Param pm, UNUSED(int exp))
+{
+    set_register(pm, "");
+}
+
+/**/
+static void
+scan_registers(UNUSED(HashTable ht), ScanFunc func, int flags)
+{
+    int i;
+    struct param pm;
+
+    memset((void *)&pm, 0, sizeof(struct param));
+    pm.node.flags = PM_SCALAR | PM_READONLY;
+    pm.gsu.s = &nullsetscalar_gsu;
+
+    for (i = 0; i < 26; i++) {
+	pm.node.nam = zhalloc(2);
+	*pm.node.nam = 'a' + i;
+	pm.node.nam[1] = '\0';
+	pm.u.str = zlelineasstring(vibuf[i].buf, vibuf[i].len, 0, NULL, NULL, 1);
+	func(&pm.node, flags);
+    }
+}
+
+/**/
+static HashNode
+get_registers(UNUSED(HashTable ht), const char *name)
+{
+    Param pm = (Param) hcalloc(sizeof(struct param));
+    pm->node.nam = dupstring(name);
+    pm->node.flags = PM_SCALAR;
+    pm->gsu.s = &register_gsu;
+
+    if (*name < 'a' || *name > 'z' || name[1]) {
+	pm->u.str = dupstring("");
+	pm->node.flags |= (PM_UNSET|PM_SPECIAL);
+    } else {
+	int reg = *name - 'a';
+	pm->u.str = zlelineasstring(vibuf[reg].buf, vibuf[reg].len, 0, NULL, NULL, 1);
+    }
+    return &pm->node;
+}
+
+/**/
+static void
+set_registers(UNUSED(Param pm), HashTable ht)
+{
+    int i;
+    HashNode hn;
+
+    if (!ht)
+        return;
+
+    for (i = 0; i < ht->hsize; i++)
+        for (hn = ht->nodes[i]; hn; hn = hn->next) {
+            struct value v;
+            v.isarr = v.flags = v.start = 0;
+            v.end = -1;
+            v.arr = NULL;
+            v.pm = (Param) hn;
+
+	    set_register(v.pm, getstrvalue(&v));
+        }
+    deleteparamtable(ht);
+}
+
 static void
 set_prepost(ZLE_STRING_T *textvar, int *lenvar, char *x)
 {



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