about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2016-11-17 12:27:52 +0100
committerOliver Kiddle <opk@zsh.org>2016-11-17 12:27:52 +0100
commit6d991ce177d8821592b27158d4a96343a63e6745 (patch)
treedd8b6996c90dc2cae052fa8ae4c02f2b7e5a235f
parent7d2f8050088f61444fc6117cf1e7bfe8d440d73c (diff)
downloadzsh-6d991ce177d8821592b27158d4a96343a63e6745.tar.gz
zsh-6d991ce177d8821592b27158d4a96343a63e6745.tar.xz
zsh-6d991ce177d8821592b27158d4a96343a63e6745.zip
39952: add registers special parameter to provide access to the vi register buffers from a zle widget function
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/zle.yo6
-rw-r--r--Src/Zle/zle_params.c99
3 files changed, 111 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index cdc89a86d..973414520 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-17  Oliver Kiddle  <opk@zsh.org>
+
+	* 39952: Src/Zle/zle_params.c, Doc/Zsh/zle.yo: add registers
+	special parameter to provide access to the vi register
+	buffers from a zle widget function
+
 2016-11-16  Oliver Kiddle  <opk@zsh.org>
 
 	* 39945: Src/Zle/compcore.c, Completion/Base/Core/_message,
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 21681e5e7..fe6a7e93b 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -991,6 +991,12 @@ 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 register 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 c6387bfc7..2400bfb00 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)
 {