summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2002-06-24 09:51:59 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2002-06-24 09:51:59 +0000
commit36765a58a66362673e9e0e5f05ba7ba4612c9c1a (patch)
tree47606a9835c863f386d8065871aa7e9deeda4ead
parent273067d55d66db3909a6c38a56935606b4d08e57 (diff)
downloadzsh-36765a58a66362673e9e0e5f05ba7ba4612c9c1a.tar.gz
zsh-36765a58a66362673e9e0e5f05ba7ba4612c9c1a.tar.xz
zsh-36765a58a66362673e9e0e5f05ba7ba4612c9c1a.zip
17350: add $CUTBUFFER and $killring zle parameters
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/zle.yo30
-rw-r--r--Src/Zle/zle_params.c129
3 files changed, 156 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 46034dc2c..31ed2fee3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2002-06-24  Peter Stephenson  <pws@csr.com>
+
+	* 17350: Src/zle_params.c, Doc/Zsh/zle.yo: Add $CUTBUFFER and
+	$killring zle parameters.
+
 2002-06-22  Bart Schaefer  <schaefer@zsh.org>
 
 	* users/5073: Completion/compdump: use `typeset +f' instead of
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 9a15530b9..f7210e7a6 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -589,10 +589,10 @@ cursor remains at the same offset, unless that would put it outside the
 buffer.
 )
 vindex(BUFFERLINES)
-item(tt(BUFFERLINES))(
+item(tt(BUFFERLINES) (integer))(
 The number of screen lines needed for the edit buffer currently
 displayed on screen (i.e. without any changes to the preceding
-parameters done after the last redisplay).
+parameters done after the last redisplay); read-only.
 )
 vindex(CURSOR)
 item(tt(CURSOR) (integer))(
@@ -601,21 +601,35 @@ The offset of the cursor, within the edit buffer.  This is in the range
 Attempts to move the cursor outside the buffer will result in the
 cursor being moved to the appropriate end of the buffer.
 )
+vindex(CUTBUFFER)
+item(tt(CUTBUFFER) (scalar))(
+The last item to be cut using one of the `tt(kill-)' commands; the
+string which the next yank would insert in the line.
+)
 vindex(HISTNO)
 item(tt(HISTNO) (integer))(
-The current history number.
+The current history number; read-only.
 )
 vindex(KEYMAP)
 item(tt(KEYMAP) (scalar))(
-The name of the currently selected keymap.
+The name of the currently selected keymap; read-only.
 )
 vindex(KEYS)
 item(tt(KEYS) (scalar))(
-The keys typed to invoke this widget, as a literal string.
+The keys typed to invoke this widget, as a literal string; read-only.
+)
+vindex(killring)
+item(tt(killring) (array))(
+The array of previously killed items, with the most recently killed first.
+This gives the items that would be retrieved by a tt(yank-pop) in the
+same order, up to eight (which is the maximum stored internally).
+Unlike a normal array, only a maximum of eight elements may be written;
+any extra are ignored.  If fewer than eight elements are given, the
+remaining elements of the kill ring will be treated as undefined.
 )
 vindex(LASTWIDGET)
 item(tt(LASTWIDGET) (scalar))(
-The name of the last widget that was executed.
+The name of the last widget that was executed; read-only.
 )
 vindex(LBUFFER)
 item(tt(LBUFFER) (scalar))(
@@ -640,7 +654,7 @@ item(tt(PENDING) (integer))(
 The number of bytes pending for input, i.e. the number of bytes which have
 already been typed and can immediately be read. On systems where the shell
 is not able to get this information, this parameter will always have a
-value of zero.
+value of zero.  Read-only.
 )
 vindex(PREBUFFER)
 item(tt(PREBUFFER) (scalar))(
@@ -656,7 +670,7 @@ cursor remains between the old tt($LBUFFER) and the new tt($RBUFFER).
 )
 vindex(WIDGET)
 item(tt(WIDGET) (scalar))(
-The name of the widget currently being executed.
+The name of the widget currently being executed; read-only.
 )
 enditem()
 sect(Standard Widgets)
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index dfdc0dcd7..e2bbdd20b 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -81,6 +81,10 @@ static struct zleparam {
         zleunsetfn, NULL },
     { "PENDING", PM_INTEGER | PM_READONLY, NULL, FN(get_pending),
         zleunsetfn, NULL },
+    { "CUTBUFFER", PM_SCALAR, FN(set_cutbuffer), FN(get_cutbuffer),
+	unset_cutbuffer, NULL },
+    { "killring", PM_ARRAY, FN(set_killring), FN(get_killring),
+	unset_killring, NULL },
     { NULL, 0, NULL, NULL, NULL, NULL }
 };
 
@@ -333,3 +337,128 @@ get_pending(Param pm)
 {
     return noquery(0);
 }
+
+/**/
+static char *
+get_cutbuffer(Param pm)
+{
+    if (cutbuf.buf)
+	return metafy(cutbuf.buf, cutbuf.len, META_HEAPDUP);
+    else
+	return "";
+}
+
+
+/**/
+static void
+set_cutbuffer(Param pm, char *x)
+{
+    if (cutbuf.buf)
+	free(cutbuf.buf);
+    cutbuf.flags = 0;
+    if (x) {
+	unmetafy(x, &cutbuf.len);
+	cutbuf.buf = zalloc(cutbuf.len);
+	strcpy((char *)cutbuf.buf, x);
+	zsfree(x);
+    } else {
+	cutbuf.buf = NULL;
+	cutbuf.len = 0;
+    }
+}
+
+/**/
+static void
+unset_cutbuffer(Param pm, int exp)
+{
+    if (exp) {
+	stdunsetfn(pm, exp);
+	if (cutbuf.buf) {
+	    free(cutbuf.buf);
+	    cutbuf.buf = NULL;
+	    cutbuf.len = 0;
+	}
+    }
+}
+
+/**/
+static void
+set_killring(Param pm, char **x)
+{
+    int kpos, kcnt;
+    char **p;
+
+    kcnt = 0;
+    kpos = kringnum;
+
+    if (x) {
+	/*
+	 * Insert the elements into the kill ring, up to a maximum
+	 * of KRINGCT.  We always handle the ring in the order
+	 * a series of yank-pops would show, i.e. starting with
+	 * the most recently cut and going backwards.
+	 */
+	for (p = x; kcnt < KRINGCT && *p; kcnt++, p++) {
+	    Cutbuffer kptr = kring + kpos;
+	    if (kptr->buf)
+		free(kptr->buf);
+	    kptr->buf = (char *)zalloc(strlen(*p));
+	    strcpy(kptr->buf, *p);
+	    unmetafy(kptr->buf, &kptr->len);
+	    kptr->flags = 0;
+	    kpos = (kpos + KRINGCT - 1) % KRINGCT;
+	}
+	freearray(x);
+    }
+    /*
+     * Any values unsupplied are to be unset.
+     */
+    for (; kcnt < KRINGCT; kcnt++) {
+	Cutbuffer kptr = kring + kpos;
+	if (kptr->buf) {
+	    free(kptr->buf);
+	    kptr->buf = NULL;
+	    kptr->flags = kptr->len = 0;
+	}
+	kpos = (kpos + KRINGCT - 1) % KRINGCT;
+    }
+}
+
+/**/
+static char **
+get_killring(Param pm)
+{
+    /*
+     * Return the kill ring with the most recently killed first.
+     * Stop as soon as we find something which isn't set, i.e.
+     * don't fill in bogus entries.
+     */
+    int kpos, kcnt;
+    char **ret, **p;
+
+    for (kpos = kringnum, kcnt = 0; kcnt < KRINGCT; kcnt++) {
+	if (!kring[kpos].buf)
+	    break;
+	kpos = (kpos + KRINGCT - 1) % KRINGCT;
+    }
+
+    p = ret = (char **)zhalloc((kcnt+1) * sizeof(char *));
+
+    for (kpos = kringnum; kcnt; kcnt--) {
+	*p++ = metafy((char *)kring[kpos].buf, kring[kpos].len, META_HEAPDUP);
+	kpos = (kpos + KRINGCT - 1) % KRINGCT;
+    }
+    *p = NULL;
+
+    return ret;
+}
+
+/**/
+static void
+unset_killring(Param pm, int exp)
+{
+    if (exp) {
+	set_killring(pm, NULL);
+	stdunsetfn(pm, exp);
+    }
+}