Exemple #1
0
int
viputafter(UNUSED(char **args))
{
    Cutbuffer buf = &cutbuf;
    int n = zmult;

    startvichange(-1);
    if (n < 0)
	return 1;
    if (zmod.flags & MOD_VIBUF)
	buf = &vibuf[zmod.vibuf];
    if (!buf->buf)
	return 1;
    if(buf->flags & CUTBUFFER_LINE) {
	zlecs = findeol();
	spaceinline(buf->len + 1);
	zleline[zlecs++] = ZWC('\n');
	ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
	vifirstnonblank(zlenoargs);
    } else {
	if (zlecs != findeol())
	    INCCS();
	while (n--) {
	    spaceinline(buf->len);
	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
	    zlecs += buf->len;
	}
	if (zlecs)
	    DECCS();
    }
    return 0;
}
Exemple #2
0
int
quoteregion(UNUSED(char **args))
{
    ZLE_STRING_T str;
    size_t len;
    int extra = invicmdmode();

    if (mark > zlell)
	mark = zlell;
    if (region_active == 2) {
	int a, b;
	regionlines(&a, &b);
	zlecs = a;
	mark = b;
	extra = 0;
    } else if (mark < zlecs) {
	int tmp = mark;
	mark = zlecs;
	zlecs = tmp;
    }
    if (extra)
	INCPOS(mark);
    str = (ZLE_STRING_T)hcalloc((len = mark - zlecs) *
	ZLE_CHAR_SIZE);
    ZS_memcpy(str, zleline + zlecs, len);
    foredel(len, CUT_RAW);
    str = makequote(str, &len);
    spaceinline(len);
    ZS_memcpy(zleline + zlecs, str, len);
    mark = zlecs;
    zlecs += len;
    return 0;
}
Exemple #3
0
void
mkundoent(void)
{
    int pre, suf;
    int sh = zlell < lastll ? zlell : lastll;
    struct change *ch;

    UNMETACHECK();
    if(lastll == zlell && !ZS_memcmp(lastline, zleline, zlell)) {
	lastcs = zlecs;
	return;
    }
    for(pre = 0; pre < sh && zleline[pre] == lastline[pre]; )
	pre++;
    for(suf = 0; suf < sh - pre &&
	zleline[zlell - 1 - suf] == lastline[lastll - 1 - suf]; )
	suf++;
    ch = zalloc(sizeof(*ch));
    ch->next = NULL;
    ch->hist = histline;
    ch->off = pre;
    ch->old_cs = lastcs;
    ch->new_cs = zlecs;
    if(suf + pre == lastll) {
	ch->del = NULL;
	ch->dell = 0;
    } else {
	ch->dell = lastll - pre - suf;
	ch->del = (ZLE_STRING_T)zalloc(ch->dell * ZLE_CHAR_SIZE);
	ZS_memcpy(ch->del, lastline + pre, ch->dell);
    }
    if(suf + pre == zlell) {
	ch->ins = NULL;
	ch->insl = 0;
    } else {
	ch->insl = zlell - pre - suf;
	ch->ins = (ZLE_STRING_T)zalloc(ch->insl * ZLE_CHAR_SIZE);
	ZS_memcpy(ch->ins, zleline + pre, ch->insl);
    }
    if(nextchanges) {
	ch->flags = CH_PREV;
	ch->prev = endnextchanges;
	endnextchanges->flags |= CH_NEXT;
	endnextchanges->next = ch;
    } else {
	nextchanges = ch;
	ch->flags = 0;
	ch->prev = NULL;
    }
    ch->changeno = ++undo_changeno;
    endnextchanges = ch;
}
Exemple #4
0
static void
transpose_swap(int start, int middle, int end)
{
    int len1, len2;
    ZLE_STRING_T first;

    len1 = middle - start;
    len2 = end - middle;

    first = (ZLE_STRING_T)zalloc(len1 * ZLE_CHAR_SIZE);
    ZS_memcpy(first, zleline + start, len1);
    /* Move may be overlapping... */
    ZS_memmove(zleline + start, zleline + middle, len2);
    ZS_memcpy(zleline + start + len2, first, len1);
    zfree(first, len1 * ZLE_CHAR_SIZE);
}
Exemple #5
0
int
copyprevshellword(UNUSED(char **args))
{
    LinkList l;
    LinkNode n;
    int i;
    char *p = NULL;

    if (zmult <= 0)
	return 1;

    if ((l = bufferwords(NULL, NULL, &i, LEXFLAGS_ZLE))) {
	i -= (zmult-1);
	if (i < 0)
	    return 1;
        for (n = firstnode(l); n; incnode(n))
            if (!i--) {
                p = getdata(n);
                break;
            }
    }

    if (p) {
	int len;
	ZLE_STRING_T lineadd = stringaszleline(p, 0, &len, NULL, NULL);

	spaceinline(len);
	ZS_memcpy(zleline + zlecs, lineadd, len);
	zlecs += len;

	free(lineadd);
    }
    return 0;
}
Exemple #6
0
/* position: 0 is before, 1 after, 2 split the line */
static void pastebuf(Cutbuffer buf, int mult, int position)
{
    int cc;
    if (buf->flags & CUTBUFFER_LINE) {
	if (position == 2) {
	    if (!zlecs)
		position = 0;
	    else if (zlecs == zlell)
		position = 1;
	}
	if (position == 2) {
	    yankb = zlecs;
	    spaceinline(buf->len + 2);
	    zleline[zlecs++] = ZWC('\n');
	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
	    zlecs += buf->len;
	    zleline[zlecs] = ZWC('\n');
	    yanke = zlecs + 1;
	} else if (position != 0) {
	    yankb = zlecs = findeol();
	    spaceinline(buf->len + 1);
	    zleline[zlecs++] = ZWC('\n');
	    yanke = zlecs + buf->len;
	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
	} else {
	    yankb = zlecs = findbol();
	    spaceinline(buf->len + 1);
	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
	    yanke = zlecs + buf->len + 1;
	    zleline[zlecs + buf->len] = ZWC('\n');
	}
	vifirstnonblank(zlenoargs);
    } else {
	if (position == 1 && zlecs != findeol())
	    INCCS();
	yankb = zlecs;
	cc = buf->len;
	while (mult--) {
	    spaceinline(cc);
	    ZS_memcpy(zleline + zlecs, buf->buf, cc);
	    zlecs += cc;
	}
	yanke = zlecs;
	if (zlecs && invicmdmode())
	    DECCS();
    }
}
Exemple #7
0
int
yankpop(UNUSED(char **args))
{
    int cc, kctstart = kct;
    Cutbuffer buf;

    if (!(lastcmd & ZLE_YANK) || !kring || !kctbuf) {
	kctbuf = NULL;
	return 1;
    }
    do {
	/*
	 * This is supposed to make the yankpop loop
	 *   original buffer -> kill ring in order -> original buffer -> ...
	 * where the original buffer is -1 and the remainder are
	 * indices into the kill ring, remember that we need to start
	 * that at kringnum rather than zero.
	 */
	if (kct == -1)
	    kct = kringnum;
	else {
	    int kctnew = (kct + kringsize - 1) % kringsize;
	    if (kctnew == kringnum)
		kct = -1;
	    else
		kct = kctnew;
	}
	if (kct == -1)
	    buf = kctbuf;	/* Use original cutbuffer */
	else
	    buf = kring+kct;	/* Use somewhere in the kill ring */
	/* Careful to prevent infinite looping */
	if (kct == kctstart)
	    return 1;
	/*
	 * Skip unset buffers instead of stopping as we used to do.
	 * Also skip zero-length buffers.
	 * There are two reasons for this:
	 * 1. We now map the array $killring directly into the
	 *    killring, instead of via some extra size-checking logic.
	 *    When $killring has been set, a buffer will always have
	 *    at least a zero-length string in it.
	 * 2. The old logic was inconsistent; when the kill ring
	 *    was full, we could loop round and round it, otherwise
	 *    we just stopped when we hit the first empty buffer.
	 */
    } while (!buf->buf || *buf->buf == ZWC('\0'));

    zlecs = yankb;
    foredel(yanke - yankb, CUT_RAW);
    cc = buf->len;
    spaceinline(cc);
    ZS_memcpy(zleline + zlecs, buf->buf, cc);
    zlecs += cc;
    yanke = zlecs;
    return 0;
}
Exemple #8
0
void
setlastline(void)
{
    UNMETACHECK();
    if(lastlinesz != linesz)
	lastline = realloc(lastline, (lastlinesz = linesz) * ZLE_CHAR_SIZE);
    ZS_memcpy(lastline, zleline, (lastll = zlell));
    lastcs = zlecs;
}
Exemple #9
0
int
quoteline(UNUSED(char **args))
{
    ZLE_STRING_T str;
    size_t len = zlell;

    str = makequote(zleline, &len);
    sizeline(len);
    ZS_memcpy(zleline, str, len);
    zlecs = zlell = len;
    return 0;
}
Exemple #10
0
void
initundo(void)
{
    nextchanges = NULL;
    changes = curchange = zalloc(sizeof(*curchange));
    curchange->prev = curchange->next = NULL;
    curchange->del = curchange->ins = NULL;
    curchange->dell = curchange->insl = 0;
    lastline = zalloc((lastlinesz = linesz) * ZLE_CHAR_SIZE);
    ZS_memcpy(lastline, zleline, (lastll = zlell));
    lastcs = zlecs;
}
Exemple #11
0
int
quoteregion(UNUSED(char **args))
{
    ZLE_STRING_T str;
    size_t len;

    if (mark > zlell)
	mark = zlell;
    if (mark < zlecs) {
	int tmp = mark;
	mark = zlecs;
	zlecs = tmp;
    }
    str = (ZLE_STRING_T)hcalloc((len = mark - zlecs) * ZLE_CHAR_SIZE);
    ZS_memcpy(str, zleline + zlecs, len);
    foredel(len, CUT_RAW);
    str = makequote(str, &len);
    spaceinline(len);
    ZS_memcpy(zleline + zlecs, str, len);
    mark = zlecs;
    zlecs += len;
    return 0;
}
Exemple #12
0
mod_export void
addsuffix(int tp, int flags, ZLE_STRING_T chars, int lenstr, int lensuf)
{
    struct suffixset *newsuf = zalloc(sizeof(struct suffixset));
    newsuf->next = suffixlist;
    suffixlist = newsuf;

    newsuf->tp = tp;
    newsuf->flags = flags;
    if (lenstr) {
	newsuf->chars = zalloc(lenstr*sizeof(ZLE_CHAR_T));
	ZS_memcpy(newsuf->chars, chars, lenstr);
    } else
	newsuf->chars = NULL;
    newsuf->lenstr = lenstr;
    newsuf->lensuf = lensuf;
}
Exemple #13
0
static void
set_rbuffer(UNUSED(Param pm), char *x)
{
    ZLE_STRING_T y;
    int len;

    if (x && *x != ZWC('\0'))
	y = stringaszleline(x, 0, &len, NULL, NULL);
    else
	y = ZWS(""), len = 0;
    sizeline(zlell = zlecs + len);
    ZS_memcpy(zleline + zlecs, y, len);
    zsfree(x);
    if (len)
	free(y);
    fixsuffix();
    menucmp = 0;
}
Exemple #14
0
static int
applychange(struct change *ch)
{
    if(ch->hist != histline) {
	zle_setline(quietgethist(ch->hist));
	zlecs = ch->old_cs;
	return 0;
    }
    zlecs = ch->off;
    if(ch->del)
	foredel(ch->dell, CUT_RAW);
    if(ch->ins) {
	spaceinline(ch->insl);
	ZS_memcpy(zleline + zlecs, ch->ins, ch->insl);
	zlecs += ch->insl;
    }
    zlecs = ch->new_cs;
    return 1;
}
Exemple #15
0
int
copyprevword(UNUSED(char **args))
{
    int len, t0 = zlecs, t1;

    if (zmult > 0) {
	int count = zmult;

	for (;;) {
	    t1 = t0;

	    while (t0) {
		int prev = t0;
		DECPOS(prev);
		if (ZC_iword(zleline[prev]))
		    break;
		t0 = prev;
	    }
	    while (t0) {
		int prev = t0;
		DECPOS(prev);
		if (!ZC_iword(zleline[prev]))
		    break;
		t0 = prev;
	    }

	    if (!--count)
		break;
	    if (t0 == 0)
		return 1;
	}
    }
    else
	return 1;
    len = t1 - t0;
    spaceinline(len);
    ZS_memcpy(zleline + zlecs, zleline + t0, len);
    zlecs += len;
    return 0;
}
Exemple #16
0
int
yank(UNUSED(char **args))
{
    int n = zmult;

    if (n < 0)
	return 1;
    if (zmod.flags & MOD_VIBUF)
	kctbuf = &vibuf[zmod.vibuf];
    else
	kctbuf = &cutbuf;
    if (!kctbuf->buf)
	return 1;
    yankb = yankcs = mark = zlecs;
    while (n--) {
	kct = -1;
	spaceinline(kctbuf->len);
	ZS_memcpy(zleline + zlecs, kctbuf->buf, kctbuf->len);
	zlecs += kctbuf->len;
	yanke = zlecs;
    }
    return 0;
}
Exemple #17
0
static int
getvirange(int wf)
{
    int pos = zlecs, mpos = mark, ret = 0;
    int visual = region_active; /* movement command might set it */
    int mult1 = zmult, hist1 = histline;
    Thingy k2;

    if (visual) {
	if (!zlell)
	    return -1;
	pos = mark;
	vilinerange = (visual == 2);
	region_active = 0;
    } else {
	virangeflag = 1;
	wordflag = wf;
	mark = -1;
	/* use operator-pending keymap if one exists */
	Keymap km = openkeymap("viopp");
	if (km)
	    selectlocalmap(km);
	/* Now we need to execute the movement command, to see where it *
	 * actually goes.  virangeflag here indicates to the movement   *
	 * function that it should place the cursor at the end of the   *
	 * range, rather than where the cursor would actually go if it  *
	 * were executed normally.  This makes a difference to some     *
	 * commands, but not all.  For example, if searching forward    *
	 * for a character, under normal circumstances the cursor lands *
	 * on the character.  For a range, the range must include the   *
	 * character, so the cursor gets placed after the character if  *
	 * virangeflag is set.                                          */
	zmod.flags &= ~MOD_TMULT;
	do {
	    vilinerange = 0;
	    prefixflag = 0;
	    if (!(k2 = getkeycmd()) || (k2->flags & DISABLED) ||
		    k2 == Th(z_sendbreak)) {
		wordflag = 0;
		virangeflag = 0;
		mark = mpos;
		return -1;
	    }
	    /*
	     * With k2 == bindk, the command key is repeated:
	     * a number of lines is used.  If the function used
	     * returns 1, we fail.
	     */
	    if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs, 1))
		ret = -1;
	    if(vichgrepeat)
		zmult = mult1;
	    else
		zmult = mult1 * zmod.tmult;
	} while(prefixflag && !ret);
	wordflag = 0;
	selectlocalmap(NULL);

	/* It is an error to use a non-movement command to delimit the *
	 * range.  We here reject the case where the command modified  *
	 * the line, or selected a different history line.             */
	if (histline != hist1 || zlell != lastll || memcmp(zleline, lastline, zlell)) {
	    histline = hist1;
	    ZS_memcpy(zleline, lastline, zlell = lastll);
	    zlecs = pos;
	    mark = mpos;
	    virangeflag = 0;
	    return -1;
	}

	/* Can't handle an empty file.  Also, if the movement command *
	 * failed, or didn't move, it is an error.                    */
	if (!zlell || (zlecs == pos && (mark == -1 || mark == zlecs) &&
		    virangeflag != 2) || ret == -1) {
	    mark = mpos;
	    virangeflag = 0;
	    return -1;
	}
	virangeflag = 0;

	/* if the mark has moved, ignore the original cursor position *
	 * and use the mark.                                          */
	if (mark != -1)
	    pos = mark;
    }
    mark = mpos;

    /* Get the range the right way round.  zlecs is placed at the *
     * start of the range, and pos (the return value of this   *
     * function) is the end.                                   */
    if (zlecs > pos) {
	int tmp = zlecs;
	zlecs = pos;
	pos = tmp;
    }

    /* visual selection mode needs to include additional position */
    if (visual == 1 && pos < zlell && invicmdmode())
	INCPOS(pos);

    /* Was it a line-oriented move?  If so, the command will have set *
     * the vilinerange flag.  In this case, entire lines are taken,   *
     * rather than just the sequence of characters delimited by pos   *
     * and zlecs.  The terminating newline is left out of the range,  *
     * which the real command must deal with appropriately.  At this  *
     * point we just need to make the range encompass entire lines.   */
    vilinerange = (zmod.flags & MOD_LINE) ||
	    (vilinerange && !(zmod.flags & MOD_CHAR));
    if (vilinerange) {
	int newcs = findbol();
	lastcol = zlecs - newcs;
	zlecs = pos;
	pos = findeol();
	zlecs = newcs;
    } else if (!visual) {
	/* for a character-wise move don't include a newline at the *
	 * end of the range                                         */
	int prev = pos;
	DECPOS(prev);
	if (zleline[prev] == ZWC('\n'))
	    pos = prev;
    }
    return pos;
}
Exemple #18
0
int
transposewords(UNUSED(char **args))
{
    int p1, p2, p3, p4, pt, len, x = zlecs, pos;
    ZLE_STRING_T temp, pp;
    int n = zmult;
    int neg = n < 0, ocs = zlecs;

    if (neg)
	n = -n;

    while (x != zlell && zleline[x] != ZWC('\n') && !ZC_iword(zleline[x]))
	INCPOS(x);

    if (x == zlell || zleline[x] == ZWC('\n')) {
	x = zlecs;
	while (x) {
	    if (ZC_iword(zleline[x]))
		break;
	    pos = x;
	    DECPOS(pos);
	    if (zleline[pos] == ZWC('\n'))
		break;
	    x = pos;
	}
	if (!x)
	    return 1;
	pos = x;
	DECPOS(pos);
	if (zleline[pos] == ZWC('\n'))
	    return 1;
    }

    for (p4 = x; p4 != zlell && ZC_iword(zleline[p4]); INCPOS(p4))
	;

    for (p3 = p4; p3; ) {
	pos = p3;
	DECPOS(pos);
	if (!ZC_iword(zleline[pos]))
	    break;
	p3 = pos;
    }

    if (!p3)
	return 1;

    p1 = p2 = pt = p3;

    while (n--) {
	for (p2 = pt; p2; ) {
	    pos = p2;
	    DECPOS(pos);
	    if (ZC_iword(zleline[pos]))
		break;
	    p2 = pos;
	}
	if (!p2)
	    return 1;
	for (p1 = p2; p1; ) {
	    pos = p1;
	    DECPOS(pos);
	    if (!ZC_iword(zleline[pos]))
		break;
	    p1 = pos;
	}
	pt = p1;
    }

    pp = temp = (ZLE_STRING_T)zhalloc((p4 - p1)*ZLE_CHAR_SIZE);
    len = p4 - p3;
    ZS_memcpy(pp, zleline + p3, len);
    pp += len;
    len = p3 - p2;
    ZS_memcpy(pp, zleline + p2, len);
    pp += len;
    ZS_memcpy(pp, zleline + p1, p2 - p1);

    ZS_memcpy(zleline + p1, temp, p4 - p1);

    if (neg)
	zlecs = ocs;
    else
	zlecs = p4;

    return 0;
}
Exemple #19
0
static int
getvirange(int wf)
{
    int pos = zlecs, ret = 0;
    int mult1 = zmult, hist1 = histline;
    Thingy k2;

    virangeflag = 1;
    wordflag = wf;
    /* Now we need to execute the movement command, to see where it *
     * actually goes.  virangeflag here indicates to the movement   *
     * function that it should place the cursor at the end of the   *
     * range, rather than where the cursor would actually go if it  *
     * were executed normally.  This makes a difference to some     *
     * commands, but not all.  For example, if searching forward    *
     * for a character, under normal circumstances the cursor lands *
     * on the character.  For a range, the range must include the   *
     * character, so the cursor gets placed after the character if  *
     * virangeflag is set.  vi-match-bracket needs to change the    *
     * value of virangeflag under some circumstances, meaning that  *
     * we need to change the *starting* position.                   */
    zmod.flags &= ~MOD_TMULT;
    do {
	vilinerange = 0;
	prefixflag = 0;
	if (!(k2 = getkeycmd()) || (k2->flags & DISABLED) ||
		k2 == Th(z_sendbreak)) {
	    wordflag = 0;
	    virangeflag = 0;
	    return -1;
	}
	/*
	 * With k2 == bindk, the command key is repeated:
	 * a number of lines is used.  If the function used
	 * returns 1, we fail.
	 */
	if ((k2 == bindk) ? dovilinerange() : execzlefunc(k2, zlenoargs, 1))
	    ret = -1;
	if(vichgrepeat)
	    zmult = mult1;
	else
	    zmult = mult1 * zmod.tmult;
    } while(prefixflag && !ret);
    wordflag = 0;
    virangeflag = 0;

    /* It is an error to use a non-movement command to delimit the *
     * range.  We here reject the case where the command modified  *
     * the line, or selected a different history line.             */
    if (histline != hist1 || zlell != lastll || memcmp(zleline, lastline, zlell)) {
	histline = hist1;
	ZS_memcpy(zleline, lastline, zlell = lastll);
	zlecs = pos;
	return -1;
    }

    /* Can't handle an empty file.  Also, if the movement command *
     * failed, or didn't move, it is an error.                    */
    if (!zlell || (zlecs == pos && virangeflag != 2) || ret == -1)
	return -1;

    /* vi-match-bracket changes the value of virangeflag when *
     * moving to the opening bracket, meaning that we need to *
     * change the *starting* position.                        */
    if(virangeflag == -1)
    {
	int origcs = zlecs;
	zlecs = pos;
	INCCS();
	pos = zlecs;
	zlecs = origcs;
    }

    /* Get the range the right way round.  zlecs is placed at the *
     * start of the range, and pos (the return value of this   *
     * function) is the end.                                   */
    if (zlecs > pos) {
	int tmp = zlecs;
	zlecs = pos;
	pos = tmp;
    }

    /* Was it a line-oriented move?  If so, the command will have set *
     * the vilinerange flag.  In this case, entire lines are taken,   *
     * rather than just the sequence of characters delimited by pos   *
     * and zlecs.  The terminating newline is left out of the range,     *
     * which the real command must deal with appropriately.  At this  *
     * point we just need to make the range encompass entire lines.   */
    if(vilinerange) {
	int newcs = findbol();
	zlecs = pos;
	pos = findeol();
	zlecs = newcs;
    }
    return pos;
}
Exemple #20
0
void
cuttext(ZLE_STRING_T line, int ct, int flags)
{
    if (!ct)
	return;

    UNMETACHECK();
    if (zmod.flags & MOD_VIBUF) {
	struct cutbuffer *b = &vibuf[zmod.vibuf];

	if (!(zmod.flags & MOD_VIAPP) || !b->buf) {
	    free(b->buf);
	    b->buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE);
	    ZS_memcpy(b->buf, line, ct);
	    b->len = ct;
	    b->flags = vilinerange ? CUTBUFFER_LINE : 0;
	} else {
	    int len = b->len;

	    if(vilinerange)
		b->flags |= CUTBUFFER_LINE;
	    b->buf = (ZLE_STRING_T)
		realloc((char *)b->buf,
			(ct + len + !!(b->flags & CUTBUFFER_LINE))
			* ZLE_CHAR_SIZE);
	    if (b->flags & CUTBUFFER_LINE)
		b->buf[len++] = ZWC('\n');
	    ZS_memcpy(b->buf + len, line, ct);
	    b->len = len + ct;
	}
	return;
    } else {
	/* Save in "1, shifting "1-"8 along to "2-"9 */
	int n;
	free(vibuf[34].buf);
	for(n=34; n>26; n--)
	    vibuf[n] = vibuf[n-1];
	vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE);
	ZS_memcpy(vibuf[26].buf, line, ct);
	vibuf[26].len = ct;
	vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0;
    }
    if (!cutbuf.buf) {
	cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE);
	cutbuf.buf[0] = ZWC('\0');
	cutbuf.len = cutbuf.flags = 0;
    } else if (!(lastcmd & ZLE_KILL) || (flags & CUT_REPLACE)) {
	Cutbuffer kptr;
	if (!kring) {
	    kringsize = KRINGCTDEF;
	    kring = (Cutbuffer)zshcalloc(kringsize * sizeof(struct cutbuffer));
	} else
	    kringnum = (kringnum + 1) % kringsize;
	kptr = kring + kringnum;
	if (kptr->buf)
	    free(kptr->buf);
	*kptr = cutbuf;
	cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE);
	cutbuf.buf[0] = ZWC('\0');
	cutbuf.len = cutbuf.flags = 0;
    }
    if (flags & (CUT_FRONT|CUT_REPLACE)) {
	ZLE_STRING_T s = (ZLE_STRING_T)zalloc((cutbuf.len + ct)*ZLE_CHAR_SIZE);

	ZS_memcpy(s, line, ct);
	ZS_memcpy(s + ct, cutbuf.buf, cutbuf.len);
	free(cutbuf.buf);
	cutbuf.buf = s;
	cutbuf.len += ct;
    } else {
	cutbuf.buf = realloc((char *)cutbuf.buf,
			     (cutbuf.len + ct) * ZLE_CHAR_SIZE);
	ZS_memcpy(cutbuf.buf + cutbuf.len, line, ct);
	cutbuf.len += ct;
    }
    if(vilinerange)
	cutbuf.flags |= CUTBUFFER_LINE;
    else
	cutbuf.flags &= ~CUTBUFFER_LINE;
}