summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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)
{