From 6d991ce177d8821592b27158d4a96343a63e6745 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Thu, 17 Nov 2016 12:27:52 +0100 Subject: 39952: add registers special parameter to provide access to the vi register buffers from a zle widget function --- ChangeLog | 6 ++++ Doc/Zsh/zle.yo | 6 ++++ Src/Zle/zle_params.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/ChangeLog b/ChangeLog index cdc89a86d..973414520 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-11-17 Oliver Kiddle + + * 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 * 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 = ®isters_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 = ®ister_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) { -- cgit 1.4.1