Esempio n. 1
0
int
viforwardword(char **args)
{
    int n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = backwardword(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	int nl;
	if (Z_vialnum(zleline[zlecs]))
	    while (zlecs != zlell && Z_vialnum(zleline[zlecs]))
		INCCS();
	else
	    while (zlecs != zlell && !Z_vialnum(zleline[zlecs]) &&
		    !ZC_inblank(zleline[zlecs]))
		INCCS();
	if (wordflag && !n)
	    return 0;
	nl = (zleline[zlecs] == ZWC('\n'));
	while (zlecs != zlell && nl < 2 && ZC_inblank(zleline[zlecs])) {
	    INCCS();
	    nl += (zleline[zlecs] == ZWC('\n'));
	}
    }
    return 0;
}
Esempio n. 2
0
File: zle_vi.c Progetto: Osse/zsh
int
vireplacechars(UNUSED(char **args))
{
    ZLE_INT_T ch;
    int n = zmult, fail = 0, newchars = 0;

    if (n > 0) {
	int pos = zlecs;
	while (n-- > 0) {
	    if (pos == zlell || zleline[pos] == ZWC('\n')) {
		fail = 1;
		break;
	    }
	    newchars++;
	    INCPOS(pos);
	}
	n = pos - zlecs;
    }
    startvichange(1);
    /* check argument range */
    if (n < 1 || fail) {
	if(vichgrepeat)
	    vigetkey();
	if(vichgflag) {
	    free(vichgbuf);
	    vichgbuf = NULL;
	    vichgflag = 0;
	}
	return 1;
    }
    /* get key */
    if((ch = vigetkey()) == ZLEEOF) {
	vichgflag = 0;
	return 1;
    }
    /* do change */
    if (ch == ZWC('\r') || ch == ZWC('\n')) {
	/* <return> handled specially */
	zlecs += n - 1;
	backkill(n - 1, CUT_RAW);
	zleline[zlecs++] = '\n';
    } else {
	/*
	 * Make sure we delete displayed characters, including
	 * attach combining characters. n includes this as a raw
	 * buffer offset.
	 * Use shiftchars so as not to adjust the cursor position;
	 * we are overwriting anything that remains directly.
	 */
	if (n > newchars)
	    shiftchars(zlecs, n - newchars);
	else if (n < newchars)
	    spaceinline(newchars - n);
	while (newchars--)
	    zleline[zlecs++] = ch;
	zlecs--;
    }
    vichgflag = 0;
    return 0;
}
Esempio n. 3
0
int
viforwardword(char **args)
{
    int n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = vibackwardword(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	int nl;
	int cc = wordclass(zleline[zlecs]);
	while (zlecs != zlell && wordclass(zleline[zlecs]) == cc) {
	    INCCS();
	}
	if (wordflag && !n)
	    return 0;
	nl = (zleline[zlecs] == ZWC('\n'));
	while (zlecs != zlell && nl < 2 && ZC_inblank(zleline[zlecs])) {
	    INCCS();
	    nl += (zleline[zlecs] == ZWC('\n'));
	}
    }
    return 0;
}
Esempio n. 4
0
mod_export int
getzlequery(void)
{
    ZLE_INT_T c;
#ifdef FIONREAD
    int val;

    /* check for typeahead, which is treated as a negative response */
    ioctl(SHTTY, FIONREAD, (char *)&val);
    if (val) {
	putc('n', shout);
	return 0;
    }
#endif

    /* get a character from the tty and interpret it */
    c = getfullchar(0);
    if (c == ZWC('\t'))
	c = ZWC('y');
    else if (ZC_icntrl(c) || c == ZLEEOF)
	c = ZWC('n');
    else
	c = ZC_tolower(c);
    /* echo response and return */
    if (c != ZWC('\n')) {
	REFRESH_ELEMENT re;
	re.chr = c;
	re.atr = 0;
	zwcputc(&re, NULL);
    }
    return c == ZWC('y');
}
Esempio n. 5
0
int
vibackwardblankword(char **args)
{
    int n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = viforwardblankword(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	int nl = 0;
	while (zlecs) {
	    int pos = zlecs;
	    DECPOS(pos);
	    if (!ZC_inblank(zleline[pos]))
		break;
	    nl += (zleline[pos] == ZWC('\n'));
	    if (nl == 2) break;
	    zlecs = pos;
	}
	while (zlecs) {
	    int pos = zlecs;
	    DECPOS(pos);
	    if (ZC_inblank(zleline[pos]))
		break;
	    zlecs = pos;
	}
    }
    return 0;
}
Esempio n. 6
0
File: zle_vi.c Progetto: Osse/zsh
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;
}
Esempio n. 7
0
File: zle_vi.c Progetto: Osse/zsh
int
vijoin(UNUSED(char **args))
{
    int x, pos;

    startvichange(-1);
    if ((x = findeol()) == zlell)
	return 1;
    zlecs = x + 1;
    pos = zlecs;
    for (; zlecs != zlell && ZC_iblank(zleline[zlecs]); INCPOS(zlecs))
	;
    x = 1 + (zlecs - pos);
    backdel(x, CUT_RAW);
    if (zlecs) {
	int pos = zlecs;
	DECPOS(pos);
	if (ZC_iblank(zleline[pos])) {
	    zlecs = pos;
	    return 0;
	}
    }
    spaceinline(1);
    zleline[zlecs] = ZWC(' ');
    return 0;
}
Esempio n. 8
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();
    }
}
Esempio n. 9
0
mod_export void
makesuffixstr(char *f, char *s, int n)
{
    if (f) {
	zsfree(suffixfunc);
	suffixfunc = ztrdup(f);
	suffixfunclen = n;
    } else if (s) {
	int inv, i, z = 0;
	ZLE_STRING_T ws, lasts, wptr;

	if (*s == '^' || *s == '!') {
	    inv = 1;
	    s++;
	} else
	    inv = 0;
	s = getkeystring(s, &i, GETKEYS_SUFFIX, &z);
	s = metafy(s, i, META_USEHEAP);
	ws = stringaszleline(s, 0, &i, NULL, NULL);

	if (z)
	    suffixnoinslen = inv ? 0 : n;
	else if (inv) {
	    /*
	     * negative match, \- wasn't present, so it *should*
	     * have this suffix length
	     */
	    suffixnoinslen = n;
	}

	lasts = wptr = ws;
	while (i) {
	    if (i >= 3 && wptr[1] == ZWC('-')) {
		ZLE_CHAR_T str[2];

		if (wptr > lasts)
		    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
			      lasts, wptr - lasts, n);
		str[0] = *wptr;
		str[1] = wptr[2];
		addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0,
			  str, 2, n);

		wptr += 3;
		i -= 3;
		lasts = wptr;
	    } else {
		wptr++;
		i--;
	    }
	}
	if (wptr > lasts)
	    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
		      lasts, wptr - lasts, n);
	free(ws);
    } else
	makesuffix(n);
}
Esempio n. 10
0
int
findeol(void)
{
    int x = zlecs;

    while (x != zlell && zleline[x] != ZWC('\n'))
	x++;
    return x;
}
Esempio n. 11
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;
}
Esempio n. 12
0
int
findbol(void)
{
    int x = zlecs;

    while (x > 0 && zleline[x - 1] != ZWC('\n'))
	x--;
    return x;
}
Esempio n. 13
0
mod_export void
makesuffixstr(char *f, char *s, int n)
{
    if (f) {
	zsfree(suffixfunc);
	suffixfunc = ztrdup(f);
	suffixfunclen = n;
    } else if (s) {
	int inv, i, z = 0;
	ZLE_STRING_T ws, lasts, wptr;

	if (*s == '^' || *s == '!') {
	    inv = 1;
	    s++;
	} else
	    inv = 0;
	s = getkeystring(s, &i, GETKEYS_SUFFIX, &z);
	s = metafy(s, i, META_USEHEAP);
	ws = stringaszleline(s, 0, &i, NULL, NULL);

	/* Remove suffix on uninsertable characters if  \- was given *
	 * and the character class wasn't negated -- or vice versa.  */
	suffixnoinsrem = z ^ inv;
	suffixlen = n;

	lasts = wptr = ws;
	while (i) {
	    if (i >= 3 && wptr[1] == ZWC('-')) {
		ZLE_CHAR_T str[2];

		if (wptr > lasts)
		    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
			      lasts, wptr - lasts, n);
		str[0] = *wptr;
		str[1] = wptr[2];
		addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0,
			  str, 2, n);

		wptr += 3;
		i -= 3;
		lasts = wptr;
	    } else {
		wptr++;
		i--;
	    }
	}
	if (wptr > lasts)
	    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
		      lasts, wptr - lasts, n);
	free(ws);
    } else
	makesuffix(n);
}
Esempio n. 14
0
int
whatcursorposition(UNUSED(char **args))
{
    char msg[100];
    char *s = msg, *mbstr;
    int bol = findbol(), len;
    ZLE_CHAR_T c = zleline[zlecs];

    if (zlecs == zlell)
	strucpy(&s, "EOF");
    else {
	strucpy(&s, "Char: ");
	switch (c) {
	case ZWC(' '):
	    strucpy(&s, "SPC");
	    break;
	case ZWC('\t'):
	    strucpy(&s, "TAB");
	    break;
	case ZWC('\n'):
	    strucpy(&s, "LFD");
	    break;
	default:
	    /*
	     * convert a single character, remembering it may
	     * turn into a multibyte string or be metafied.
	     */
	    mbstr = zlelineasstring(zleline+zlecs, 1, 0, &len, NULL, 1);
	    strcpy(s, mbstr);
	    s += len;
	}
	sprintf(s, " (0%o, %u, 0x%x)", (unsigned int)c,
		(unsigned int)c, (unsigned int)c);
	s += strlen(s);
    }
    sprintf(s, "  point %d of %d(%d%%)  column %d", zlecs+1, zlell+1,
	    zlell ? 100 * zlecs / zlell : 0, zlecs - bol);
    showmsg(msg);
    return 0;
}
Esempio n. 15
0
int
killline(char **args)
{
    int i = 0, n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = backwardkillline(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	if (zleline[zlecs] == ZWC('\n'))
	    zlecs++, i++;
	else
	    while (zlecs != zlell && zleline[zlecs] != ZWC('\n'))
		zlecs++, i++;
    }
    backkill(i, CUT_RAW);
    clearlist = 1;
    return 0;
}
Esempio n. 16
0
int
vibackwardword(char **args)
{
    int n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = backwardword(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	int nl = 0;
	while (zlecs) {
	    DECCS();
	    if (!ZC_inblank(zleline[zlecs]))
		break;
	    nl += (zleline[zlecs] == ZWC('\n'));
	    if (nl == 2) {
		INCCS();
		break;
	    }
	}
	if (zlecs) {
	    int pos = zlecs;
	    if (Z_vialnum(zleline[pos])) {
		for (;;) {
		    zlecs = pos;
		    if (zlecs == 0)
			break;
		    DECPOS(pos);
		    if (!Z_vialnum(zleline[pos]))
			break;
		}
	    } else {
		for (;;) {
		    zlecs = pos;
		    if (zlecs == 0)
			break;
		    DECPOS(pos);
		    if (Z_vialnum(zleline[pos]) || ZC_inblank(zleline[pos]))
			break;
		}
	    }
	}
    }
    return 0;
}
Esempio n. 17
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;
}
Esempio n. 18
0
int
vijoin(UNUSED(char **args))
{
    int x, pos;
    int n = zmult;
    int visual = region_active;

    startvichange(-1);
    if (n < 1)
	return 1;
    if (visual && zlecs > mark) {
	exchangepointandmark(zlenoargs);
	x = findeol();
	if (x >= mark) {
	    exchangepointandmark(zlenoargs);
	    return 1;
	}
    } else if ((x = findeol()) == zlell || (visual && x >= mark))
	return 1;

    while (n) {
	zlecs = x + 1;
	pos = zlecs;
	for (; zlecs != zlell && ZC_iblank(zleline[zlecs]); INCPOS(zlecs))
	    ;
	x = 1 + (zlecs - pos);
	backdel(x, CUT_RAW);
	if (zlecs) {
	    int pos = zlecs;
	    DECPOS(pos);
	    if (ZC_iblank(zleline[pos])) {
		zlecs = pos;
		return 0;
	    }
	}
	spaceinline(1);
	zleline[zlecs] = ZWC(' ');
	if ((!visual && --n < 2) || (x = findeol()) == zlell || (visual && x >= mark))
	    return 0;
    }
    return 0;
}
Esempio n. 19
0
int
vibackwardword(char **args)
{
    int n = zmult;

    if (n < 0) {
	int ret;
	zmult = -n;
	ret = viforwardword(args);
	zmult = n;
	return ret;
    }
    while (n--) {
	int nl = 0;
	while (zlecs) {
	    DECCS();
	    if (!ZC_inblank(zleline[zlecs]))
		break;
	    nl += (zleline[zlecs] == ZWC('\n'));
	    if (nl == 2) {
		INCCS();
		break;
	    }
	}
	if (zlecs) {
	    int pos = zlecs;
	    int cc = wordclass(zleline[pos]);
	    for (;;) {
		zlecs = pos;
		if (zlecs == 0)
		    break;
		DECPOS(pos);
		if (wordclass(zleline[pos]) != cc || ZC_inblank(zleline[pos]))
		    break;
	    }
	}
    }
    return 0;
}
Esempio n. 20
0
static ZLE_STRING_T
makequote(ZLE_STRING_T str, size_t *len)
{
    int qtct = 0;
    ZLE_STRING_T l, ol;
    ZLE_STRING_T end = str + *len;

    for (l = str; l < end; l++)
	if (*l == ZWC('\''))
	    qtct++;
    *len += 2 + qtct*3;
    l = ol = (ZLE_STRING_T)zhalloc(*len * ZLE_CHAR_SIZE);
    *l++ = ZWC('\'');
    for (; str < end; str++)
	if (*str == ZWC('\'')) {
	    *l++ = ZWC('\'');
	    *l++ = ZWC('\\');
	    *l++ = ZWC('\'');
	    *l++ = ZWC('\'');
	} else
	    *l++ = *str;
    *l++ = ZWC('\'');
    return ol;
}
Esempio n. 21
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;
}
Esempio n. 22
0
File: zle_vi.c Progetto: Osse/zsh
int
visetbuffer(UNUSED(char **args))
{
    ZLE_INT_T ch;

    if ((zmod.flags & MOD_VIBUF) ||
	(((ch = getfullchar(0)) < ZWC('1') || ch > ZWC('9')) &&
	 (ch < ZWC('a') || ch > ZWC('z')) &&
	 (ch < ZWC('A') || ch > ZWC('Z'))))
	return 1;
    if (ch >= ZWC('A') && ch <= ZWC('Z'))	/* needed in cut() */
	zmod.flags |= MOD_VIAPP;
    else
	zmod.flags &= ~MOD_VIAPP;
    /* FIXME how portable is it for multibyte encoding? */
    zmod.vibuf = ZC_tolower(ch);
    if (ch >= ZWC('1') && ch <= ZWC('9'))
	zmod.vibuf += - (int)ZWC('1') + 26;
    else
	zmod.vibuf += - (int)ZWC('a');
    zmod.flags |= MOD_VIBUF;
    prefixflag = 1;
    return 0;
}
Esempio n. 23
0
mod_export char *
zlelineasstring(ZLE_STRING_T instr, int inll, int incs, int *outllp,
		int *outcsp, int useheap)
{
    int outcs, outll, sub;
    struct region_highlight *rhp;

#ifdef MULTIBYTE_SUPPORT
    char *s;
    int i, j;
    size_t mb_len = 0;
    mbstate_t mbs;

    s = zalloc(inll * MB_CUR_MAX + 1);

    outcs = 0;
    memset(&mbs, 0, sizeof(mbs));
    for (i=0; i < inll; i++) {
	if (incs == 0)
	    outcs = mb_len;
	incs--;
	if (region_highlights && outcsp == &zlemetacs) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		if (rhp->flags & ZRH_PREDISPLAY)
		    sub = predisplaylen;
		else
		    sub = 0;
		if (rhp->start - sub == 0)
		    rhp->start_meta = sub + mb_len;
		rhp->start--;
		if (rhp->end - sub == 0)
		    rhp->end_meta = sub + mb_len;
		rhp->end--;
	    }
	}
#ifdef __STDC_ISO_10646__
	if (ZSH_INVALID_WCHAR_TEST(instr[i])) {
	    s[mb_len++] = ZSH_INVALID_WCHAR_TO_CHAR(instr[i]);
	} else
#endif
	{
	    j = wcrtomb(s + mb_len, instr[i], &mbs);
	    if (j == -1) {
		/* invalid char */
		s[mb_len++] = ZWC('?');
		memset(&mbs, 0, sizeof(mbs));
	    } else {
		mb_len += j;
	    }
	}
    }
    if (incs == 0)
	outcs = mb_len;
    if (region_highlights && outcsp == &zlemetacs) {
	for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
	     rhp < region_highlights + n_region_highlights;
	     rhp++) {
	    if (rhp->flags & ZRH_PREDISPLAY)
		sub = predisplaylen;
	    else
		sub = 0;
	    if (rhp->start - sub == 0)
		rhp->start_meta = sub + mb_len;
	    if (rhp->end - sub == 0)
		rhp->end_meta = sub + mb_len;
	}
    }
    s[mb_len] = '\0';

    outll = mb_len;
#else
    outll = inll;
    outcs = incs;
    if (region_highlights && outcsp == &zlemetacs) {
	for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
	     rhp < region_highlights + n_region_highlights;
	     rhp++) {
	    rhp->start_meta = rhp->start;
	    rhp->end_meta = rhp->end;
	}
    }
#endif

    /*
     * *outcsp and *outllp are to be indexes into the final string,
     * not character offsets, so we need to take account of any
     * metafiable characters.
     */
    if (outcsp != NULL || outllp != NULL) {
#ifdef MULTIBYTE_SUPPORT
	char *strp = s;
#else
	char *strp = instr;
#endif
	char *stopcs = strp + outcs;
	char *stopll = strp + outll;
	char *startp = strp;

	if (region_highlights && outcsp == &zlemetacs) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		/* Used as temporary storage */
		rhp->start = rhp->start_meta;
		rhp->end = rhp->end_meta;
	    }
	}
	while (strp < stopll) {
	    if (imeta(*strp)) {
		if (strp < stopcs)
		    outcs++;
		if (region_highlights && outcsp == &zlemetacs) {
		    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
			 rhp < region_highlights + n_region_highlights;
			 rhp++) {
			if (rhp->flags & ZRH_PREDISPLAY)
			    sub = predisplaylen;
			else
			    sub = 0;
			if (strp < startp + rhp->start - sub) {
			    rhp->start_meta++;
			}
			if (strp < startp + rhp->end - sub) {
			    rhp->end_meta++;
			}
		    }
		}
		outll++;
	    }
	    strp++;
	}
	if (outcsp != NULL)
	    *outcsp = outcs;
	if (outllp != NULL)
	    *outllp = outll;
    }

#ifdef MULTIBYTE_SUPPORT
    if (useheap) {
	char *ret = metafy(s, mb_len, META_HEAPDUP);

	zfree(s, inll * MB_CUR_MAX + 1);

	return ret;
    }
    return metafy(s, mb_len, META_REALLOC);
#else
    return metafy(instr, inll, useheap ? META_HEAPDUP : META_DUP);
#endif
}
Esempio n. 24
0
void
doinsert(ZLE_STRING_T zstr, int len)
{
    ZLE_STRING_T s;
    ZLE_CHAR_T c1 = *zstr;	     /* first character */
    int neg = zmult < 0;             /* insert *after* the cursor? */
    int m = neg ? -zmult : zmult;    /* number of copies to insert */
    int count;

    UNMETACHECK();

    iremovesuffix(c1, 0);
    invalidatelist();

    /* In overwrite mode, don't replace newlines. */
    if (insmode || zleline[zlecs] == ZWC('\n'))
	spaceinline(m * len);
    else
    {
	int pos = zlecs, diff, i;
#ifdef MULTIBYTE_SUPPORT
	/*
	 * Calculate the number of character positions we are
	 * going to be using.  The algorithm is that
	 * anything that shows up as a logical single character
	 * (i.e. even if control, or double width, or with combining
	 * characters) is treated as 1 for the purpose of replacing
	 * what's there already.
	 *
	 * This can cause inserting of a combining character in
	 * places where it should overwrite, such as the start
	 * of a line.  However, combining characters aren't
	 * useful there anyway and this doesn't cause any
	 * particular harm.
	 */
	for (i = 0, count = 0; i < len * m; i++) {
	    if (!IS_COMBINING(zstr[i]))
		count++;
	}
#else
	count = len * m;
#endif
	/*
	 * Ensure we replace a complete combining characterfor each
	 * character we overwrite. Switch to inserting at first newline.
	 */
	for (i = count; pos < zlell && zleline[pos] != ZWC('\n') && i--; ) {
	    INCPOS(pos);
	}
	/*
	 * Calculate how many raw line places we need.
	 * pos - zlecs is the raw line distance we're replacing,
	 * m * len the number we're inserting.
	 */
	diff = pos - zlecs - m * len;
	if (diff < 0) {
	    spaceinline(-diff);
	} else if (diff > 0) {
	    /*
	     * We use shiftchars() here because we don't
	     * want combining char alignment fixed up: we
	     * are going to write over any that remain.
	     */
	    shiftchars(zlecs, diff);
	}
    }
    while (m--)
	for (s = zstr, count = len; count; s++, count--)
	    zleline[zlecs++] = *s;
    if (neg)
	zlecs += zmult * len;
    /* if we ended up on a combining character, skip over it */
    CCRIGHT();
}
Esempio n. 25
0
mod_export void
iremovesuffix(ZLE_INT_T c, int keep)
{
    if (suffixfunc) {
	Shfunc shfunc = getshfunc(suffixfunc);

	if (shfunc) {
	    LinkList args = newlinklist();
	    char buf[20];
	    int osc = sfcontext;
	    int wasmeta = (zlemetaline != 0);

	    if (wasmeta) {
		/*
		 * The suffix removal function runs as a normal
		 * ZLE function, not a completion function, so
		 * the line should be unmetafied if this was
		 * called from completion.  (It may not be since
		 * we may decide to remove the suffix later.)
		 */
		unmetafy_line();
	    }

	    sprintf(buf, "%d", suffixfunclen);
	    addlinknode(args, suffixfunc);
	    addlinknode(args, buf);

	    startparamscope();
	    makezleparams(0);
	    sfcontext = SFC_COMPLETE;
	    doshfunc(shfunc, args, 1);
	    sfcontext = osc;
	    endparamscope();

	    if (wasmeta)
		metafy_line();
	}
	zsfree(suffixfunc);
	suffixfunc = NULL;
    } else {
	int sl = 0, flags = 0;
	struct suffixset *ss;

	if (c == NO_INSERT_CHAR) {
	    sl = suffixnoinsrem ? suffixlen : 0;
	} else {
	    ZLE_CHAR_T ch = c;
	    /*
	     * Search for a match for ch in the suffix list.
	     * We stop if we encounter a match in a positive or negative
	     * list, using the suffix length specified or zero respectively.
	     * If we reached the end and passed through a negative
	     * list, we use the suffix length for that, else zero.
	     * This would break if it were possible to have negative
	     * sets with different suffix length:  that's not supposed
	     * to happen.
	     */
	    int negsuflen = 0, found = 0;

	    for (ss = suffixlist; ss; ss = ss->next) {
		switch (ss->tp) {
		case SUFTYP_POSSTR:
		    if (ZS_memchr(ss->chars, ch, ss->lenstr)) {
			sl = ss->lensuf;
			found = 1;
		    }
		    break;

		case SUFTYP_NEGSTR:
		    if (ZS_memchr(ss->chars, ch, ss->lenstr)) {
			sl = 0;
			found = 1;
		    } else {
			negsuflen = ss->lensuf;
		    }
		    break;

		case SUFTYP_POSRNG:
		    if (ss->chars[0] <= ch && ch <= ss->chars[1]) {
			sl = ss->lensuf;
			found = 1;
		    }
		    break;

		case SUFTYP_NEGRNG:
		    if (ss->chars[0] <= ch && ch <= ss->chars[1]) {
			sl = 0;
			found = 1;
		    } else {
			negsuflen = ss->lensuf;
		    }
		    break;
		}
		if (found) {
		    flags = ss->flags;
		    break;
		}
	    }

	    if (!found)
		sl = negsuflen;
	}
	if (sl) {
	    /* must be shifting wide character lengths */
	    backdel(sl, CUT_RAW);
	    if (flags & SUFFLAGS_SPACE)
	    {
		/* Add a space and advance over it */
		spaceinline(1);
		if (zlemetaline) {
		    zlemetaline[zlemetacs++] = ' ';
		} else {
		    zleline[zlecs++] = ZWC(' ');
		}
	    }
	    if (!keep)
		invalidatelist();
	}
    }
    fixsuffix();
}
Esempio n. 26
0
mod_export void
spaceinline(int ct)
{
    int i, sub;
    struct region_highlight *rhp;

    if (zlemetaline) {
	sizeline(ct + zlemetall);
	for (i = zlemetall; --i >= zlemetacs;)
	    zlemetaline[i + ct] = zlemetaline[i];
	zlemetall += ct;
	zlemetaline[zlemetall] = '\0';

	if (mark > zlemetacs)
	    mark += ct;

	if (region_highlights) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		if (rhp->flags & ZRH_PREDISPLAY)
		    sub = predisplaylen;
		else
		    sub = 0;
		if (rhp->start_meta - sub >= zlemetacs) {
		    rhp->start_meta += ct;
		}
		if (rhp->end_meta - sub >= zlemetacs) {
		    rhp->end_meta += ct;
		}
	    }
	}
    } else {
	sizeline(ct + zlell);
	for (i = zlell; --i >= zlecs;)
	    zleline[i + ct] = zleline[i];
	zlell += ct;
	zleline[zlell] = ZWC('\0');

	if (mark > zlecs)
	    mark += ct;

	if (region_highlights) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		if (rhp->flags & ZRH_PREDISPLAY)
		    sub = predisplaylen;
		else
		    sub = 0;
		if (rhp->start - sub >= zlecs) {
		    rhp->start += ct;
		}
		if (rhp->end - sub >= zlecs) {
		    rhp->end += ct;
		}
	    }
	}
    }
    region_active = 0;
}
Esempio n. 27
0
Thingy
executenamedcommand(char *prmt)
{
    Thingy cmd, retval = NULL;
    int l, len, feep = 0, listed = 0, curlist = 0;
    int ols = (listshown && validlist), olll = lastlistlen;
    char *cmdbuf, *ptr;
    char *okeymap = ztrdup(curkeymapname);

    clearlist = 1;
    /* prmt may be constant */
    prmt = ztrdup(prmt);
    l = strlen(prmt);
    cmdbuf = (char *)zhalloc(l + NAMLEN + 2
#ifdef MULTIBYTE_SUPPORT
			     + 2 * MB_CUR_MAX
#endif
			     );
    strcpy(cmdbuf, prmt);
    zsfree(prmt);
    statusline = cmdbuf;
    selectlocalmap(command_keymap);
    selectkeymap("main", 1);
    ptr = cmdbuf += l;
    len = 0;
    for (;;) {
	*ptr = '_';
	ptr[1] = '\0';
	zrefresh();
	if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
	    statusline = NULL;
	    selectkeymap(okeymap, 1);
	    zsfree(okeymap);
	    if ((listshown = ols)) {
		showinglist = -2;
		lastlistlen = olll;
	    } else if (listed)
		clearlist = listshown = 1;

	    retval = NULL;
	    goto done;
	}
	if(cmd == Th(z_clearscreen)) {
	    clearscreen(zlenoargs);
	    if (curlist) {
		int zmultsav = zmult;

		zmult = 1;
		listlist(namedcmdll);
		showinglist = 0;
		zmult = zmultsav;
	    }
	} else if(cmd == Th(z_redisplay)) {
	    redisplay(zlenoargs);
	    if (curlist) {
		int zmultsav = zmult;

		zmult = 1;
		listlist(namedcmdll);
		showinglist = 0;
		zmult = zmultsav;
	    }
	} else if(cmd == Th(z_viquotedinsert)) {
	    *ptr = '^';
	    zrefresh();
	    getfullchar(0);
	    if(LASTFULLCHAR == ZLEEOF || !LASTFULLCHAR || len >= NAMLEN)
		feep = 1;
	    else {
		int ret = zlecharasstring(LASTFULLCHAR, ptr);
		len += ret;
		ptr += ret;
		curlist = 0;
	    }
	} else if(cmd == Th(z_quotedinsert)) {
	    if(getfullchar(0) == ZLEEOF ||
	       !LASTFULLCHAR || len == NAMLEN)
		feep = 1;
	    else {
		int ret = zlecharasstring(LASTFULLCHAR, ptr);
		len += ret;
		ptr += ret;
		curlist = 0;
	    }
	} else if(cmd == Th(z_backwarddeletechar) ||
		  cmd == Th(z_vibackwarddeletechar)) {
	    if (len) {
		ptr = backwardmetafiedchar(cmdbuf, ptr, NULL);
		len = ptr - cmdbuf;
		curlist = 0;
	    }
	} else if(cmd == Th(z_killregion) || cmd == Th(z_backwardkillword) ||
		  cmd == Th(z_vibackwardkillword)) {
	    if (len)
		curlist = 0;
	    while (len) {
		convchar_t cc;
		ptr = backwardmetafiedchar(cmdbuf, ptr, &cc);
		len = ptr - cmdbuf;
		if (cc == ZWC('-'))
		    break;
	    }
	} else if(cmd == Th(z_killwholeline) || cmd == Th(z_vikillline) ||
	    	cmd == Th(z_backwardkillline)) {
	    len = 0;
	    ptr = cmdbuf;
	    if (listed)
		clearlist = listshown = 1;
	    curlist = 0;
	} else if (cmd == Th(z_bracketedpaste)) {
	    char *insert = bracketedstring();
	    size_t inslen = strlen(insert);
	    if (len + inslen > NAMLEN)
		feep = 1;
	    else {
		strcpy(ptr, insert);
		len += inslen;
		ptr += inslen;
		if (listed) {
		    clearlist = listshown = 1;
		    listed = 0;
		} else
		    curlist = 0;
	    }
	    free(insert);
	} else {
	    if(cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode)) {
		Thingy r;
		unambiguous:
		*ptr = 0;
		r = rthingy(cmdbuf);
		if (!(r->flags & DISABLED)) {
		    unrefthingy(r);
		    statusline = NULL;
		    selectkeymap(okeymap, 1);
		    zsfree(okeymap);
		    if ((listshown = ols)) {
			showinglist = -2;
			lastlistlen = olll;
		    } else if (listed)
			clearlist = listshown = 1;

		    retval = r;
		    goto done;
		}
		unrefthingy(r);
	    }
	    if(cmd == Th(z_selfinsertunmeta)) {
		fixunmeta();
		cmd = Th(z_selfinsert);
	    }
	    if (cmd == Th(z_listchoices) || cmd == Th(z_deletecharorlist) ||
		cmd == Th(z_expandorcomplete) || cmd == Th(z_completeword) ||
		cmd == Th(z_expandorcompleteprefix) || cmd == Th(z_vicmdmode) ||
		cmd == Th(z_acceptline) || lastchar == ' ' || lastchar == '\t') {
		namedcmdambig = 100;

		namedcmdll = newlinklist();

		*ptr = '\0';
		namedcmdstr = cmdbuf;
		scanhashtable(thingytab, 1, 0, DISABLED, scancompcmd, 0);
		namedcmdstr = NULL;

		if (empty(namedcmdll)) {
		    feep = 1;
		    if (listed)
			clearlist = listshown = 1;
		    curlist = 0;
		} else if (cmd == Th(z_listchoices) ||
		    cmd == Th(z_deletecharorlist)) {
		    int zmultsav = zmult;
		    *ptr = '_';
		    ptr[1] = '\0';
		    zmult = 1;
		    listlist(namedcmdll);
		    listed = curlist = 1;
		    showinglist = 0;
		    zmult = zmultsav;
		} else if (!nextnode(firstnode(namedcmdll))) {
		    strcpy(ptr = cmdbuf, peekfirst(namedcmdll));
		    len = strlen(ptr);
		    ptr += len;
		    if (cmd == Th(z_acceptline) || cmd == Th(z_vicmdmode))
			goto unambiguous;
		} else {
		    strcpy(cmdbuf, peekfirst(namedcmdll));
		    ptr = cmdbuf + namedcmdambig;
		    *ptr = '_';
		    ptr[1] = '\0';
		    if (isset(AUTOLIST) &&
			!(isset(LISTAMBIGUOUS) && namedcmdambig > len)) {
			int zmultsav = zmult;
			if (isset(LISTBEEP))
			    feep = 1;
			zmult = 1;
			listlist(namedcmdll);
			listed = curlist = 1;
			showinglist = 0;
			zmult = zmultsav;
		    }
		    len = namedcmdambig;
		}
	    } else {
		if (len == NAMLEN || cmd != Th(z_selfinsert))
		    feep = 1;
		else {
#ifdef MULTIBYTE_SUPPORT
		    if (!lastchar_wide_valid)
			getrestchar(lastchar, NULL, NULL);
		    if (lastchar_wide == WEOF)
			feep = 1;
		    else
#endif
		    if (ZC_icntrl(LASTFULLCHAR))
			feep = 1;
		    else {
			int ret = zlecharasstring(LASTFULLCHAR, ptr);
			len += ret;
			ptr += ret;
			if (listed) {
			    clearlist = listshown = 1;
			    listed = 0;
			} else
			    curlist = 0;
		    }
		}
	    }
	}
	if (feep)
	    handlefeep(zlenoargs);
	feep = 0;
    }

 done:
    selectlocalmap(NULL);
    return retval;
}
Esempio n. 28
0
char *
zleread(char **lp, char **rp, int flags, int context, char *init, char *finish)
{
    char *s, **bracket;
    int old_errno = errno;
    int tmout = getiparam("TMOUT");

#if defined(HAVE_POLL) || defined(HAVE_SELECT)
    /* may not be set, but that's OK since getiparam() returns 0 == off */
    baud = getiparam("BAUD");
    costmult = (baud) ? 3840000L / baud : 0;
#endif

    /* ZLE doesn't currently work recursively.  This is needed in case a *
     * select loop is used in a function called from ZLE.  vared handles *
     * this differently itself.                                          */
    if(zleactive) {
	char *pptbuf;
	int pptlen;

	pptbuf = unmetafy(promptexpand(lp ? *lp : NULL, 0, NULL, NULL,
				       &pmpt_attr),
			  &pptlen);
	write_loop(2, pptbuf, pptlen);
	free(pptbuf);
	return shingetline();
    }
    /*
     * The current status is what we need if we are going
     * to display a prompt.  We'll remember it here for
     * use further in.
     */
    pre_zle_status = lastval;

    keytimeout = (time_t)getiparam("KEYTIMEOUT");
    if (!shout) {
	if (SHTTY != -1)
	    init_shout();

	if (!shout)
	    return NULL;
	/* We could be smarter and default to a system read. */

	/* If we just got a new shout, make sure the terminal is set up. */
	if (termflags & TERM_UNKNOWN)
	    init_term();
    }

    fflush(shout);
    fflush(stderr);
    intr();
    insmode = unset(OVERSTRIKE);
    eofsent = 0;
    resetneeded = 0;
    fetchttyinfo = 0;
    trashedzle = 0;
    raw_lp = lp;
    lpromptbuf = promptexpand(lp ? *lp : NULL, 1, NULL, NULL, &pmpt_attr);
    raw_rp = rp;
    rpmpt_attr = pmpt_attr;
    rpromptbuf = promptexpand(rp ? *rp : NULL, 1, NULL, NULL, &rpmpt_attr);
    free_prepostdisplay();

    zlereadflags = flags;
    zlecontext = context;
    histline = curhist;
    vistartchange = -1;
    zleline = (ZLE_STRING_T)zalloc(((linesz = 256) + 2) * ZLE_CHAR_SIZE);
    *zleline = ZWC('\0');
    virangeflag = lastcmd = done = zlecs = zlell = mark = 0;
    vichgflag = 0;
    viinsbegin = 0;
    statusline = NULL;
    selectkeymap("main", 1);
    initundo();
    fixsuffix();
    if ((s = getlinknode(bufstack))) {
	setline(s, ZSL_TOEND);
	zsfree(s);
	if (stackcs != -1) {
	    zlecs = stackcs;
	    stackcs = -1;
	    if (zlecs > zlell)
		zlecs = zlell;
	    CCLEFT();
	}
	if (stackhist != -1) {
	    histline = stackhist;
	    stackhist = -1;
	}
	handleundo();
    }
    /*
     * If main is linked to the viins keymap, we need to register
     * explicitly that we're now in vi insert mode as there's
     * no user operation to indicate this.
     */
    if (openkeymap("main") == openkeymap("viins"))
	viinsert_init();
    selectlocalmap(NULL);
    if (isset(PROMPTCR))
	putc('\r', shout);
    if (tmout)
	alarm(tmout);

    /*
     * On some windowing systems we may enter this function before the
     * terminal is fully opened and sized, resulting in an infinite
     * series of SIGWINCH when the handler prints the prompt before we
     * have done so here.  Therefore, hold any such signal until the
     * first full refresh has completed.  The important bit is that the
     * handler must not see zleactive = 1 until ZLE really is active.
     * See the end of adjustwinsize() in Src/utils.c
     */
    queue_signals();

    zleactive = 1;
    resetneeded = 1;
    /*
     * Start of the main zle read.
     * Fully reset error conditions, including user interrupt.
     */
    errflag = retflag = 0;
    lastcol = -1;
    initmodifier(&zmod);
    prefixflag = 0;

    zrefresh();

    unqueue_signals();	/* Should now be safe to acknowledge SIGWINCH */

    zlecallhook(init, NULL);

    if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2)
	fputs(*bracket, shout);

    zrefresh();

    zlecore();

    if (errflag)
	setsparam((zlecontext == ZLCON_VARED) ?
		  "ZLE_VARED_ABORTED" :
		  "ZLE_LINE_ABORTED", zlegetline(NULL, NULL));

    if ((bracket = getaparam("zle_bracketed_paste")) && arrlen(bracket) == 2)
	fputs(bracket[1], shout);

    if (done && !exit_pending && !errflag)
	zlecallhook(finish, NULL);

    statusline = NULL;
    invalidatelist();
    trashzle();
    free(lpromptbuf);
    free(rpromptbuf);
    zleactive = zlereadflags = lastlistlen = zlecontext = 0;
    alarm(0);

    freeundo();
    if (eofsent || errflag || exit_pending) {
	s = NULL;
    } else {
	zleline[zlell++] = ZWC('\n');
	s = zlegetline(NULL, NULL);
    }
    free(zleline);
    zleline = NULL;
    forget_edits();
    errno = old_errno;
    /* highlight no longer valid */
    set_region_highlight(NULL, NULL);
    return s;
}
Esempio n. 29
0
void
zlecore(void)
{
    Keymap km;
#if !defined(HAVE_POLL) && defined(HAVE_SELECT)
    struct timeval tv;
    fd_set foofd;

    FD_ZERO(&foofd);
#endif

    pushheap();

    /*
     * A widget function may decide to exit the shell.
     * We never exit directly from functions, to allow
     * the shell to tidy up, so we have to test for
     * that explicitly.
     */
    while (!done && !errflag && !exit_pending) {
	UNMETACHECK();

	statusline = NULL;
	vilinerange = 0;
	reselectkeymap();
	selectlocalmap(invicmdmode() && region_active && (km = openkeymap("visual"))
	    ? km : NULL);
	bindk = getkeycmd();
	selectlocalmap(NULL);
	if (bindk) {
	    if (!zlell && isfirstln && !(zlereadflags & ZLRF_IGNOREEOF) &&
		lastchar == eofchar) {
		/*
		 * Slight hack: this relies on getkeycmd returning
		 * a value for the EOF character.  However,
		 * undefined-key is fine.  That's necessary because
		 * otherwise we can't distinguish this case from
		 * a ^C.
		 */
		eofsent = 1;
		break;
	    }
	    if (execzlefunc(bindk, zlenoargs, 0)) {
		handlefeep(zlenoargs);
		if (eofsent)
		    break;
	    }
	    handleprefixes();
	    /* for vi mode, make sure the cursor isn't somewhere illegal */
	    if (invicmdmode() && zlecs > findbol() &&
		(zlecs == zlell || zleline[zlecs] == ZWC('\n')))
		DECCS();
	    handleundo();
	} else {
	    errflag |= ERRFLAG_ERROR;
	    break;
	}
#ifdef HAVE_POLL
	if (baud && !(lastcmd & ZLE_MENUCMP)) {
	    struct pollfd pfd;
	    int to = cost * costmult / 1000; /* milliseconds */

	    if (to > 500)
		to = 500;
	    pfd.fd = SHTTY;
	    pfd.events = POLLIN;
	    if (!kungetct && poll(&pfd, 1, to) <= 0)
		zrefresh();
	} else
#else
# ifdef HAVE_SELECT
	if (baud && !(lastcmd & ZLE_MENUCMP)) {
	    FD_SET(SHTTY, &foofd);
	    tv.tv_sec = 0;
	    if ((tv.tv_usec = cost * costmult) > 500000)
		tv.tv_usec = 500000;
	    if (!kungetct && select(SHTTY+1, (SELECT_ARG_2_T) & foofd,
				    NULL, NULL, &tv) <= 0)
		zrefresh();
	} else
# endif
#endif
	    if (!kungetct)
		zrefresh();

	freeheap();
    }

    region_active = 0;
    popheap();
}
Esempio n. 30
0
void
shiftchars(int to, int cnt)
{
    struct region_highlight *rhp;
    int sub;

    if (mark >= to + cnt)
	mark -= cnt;
    else if (mark > to)
	mark = to;

    if (zlemetaline) {
	/* before to is updated... */
	if (region_highlights) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		if (rhp->flags & ZRH_PREDISPLAY)
		    sub = predisplaylen;
		else
		    sub = 0;
		if (rhp->start_meta - sub > to) {
		    if (rhp->start_meta - sub > to + cnt)
			rhp->start_meta -= cnt;
		    else
			rhp->start_meta = to;
		}
		if (rhp->end_meta - sub > to) {
		    if (rhp->end_meta - sub > to + cnt)
			rhp->end_meta -= cnt;
		    else
			rhp->end_meta = to;
		}
	    }
	}

	while (to + cnt < zlemetall) {
	    zlemetaline[to] = zlemetaline[to + cnt];
	    to++;
	}
	zlemetaline[zlemetall = to] = '\0';
    } else {
	/* before to is updated... */
	if (region_highlights) {
	    for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
		 rhp < region_highlights + n_region_highlights;
		 rhp++) {
		if (rhp->flags & ZRH_PREDISPLAY)
		    sub = predisplaylen;
		else
		    sub = 0;
		if (rhp->start - sub > to) {
		    if (rhp->start - sub > to + cnt)
			rhp->start -= cnt;
		    else
			rhp->start = to;
		}
		if (rhp->end - sub > to) {
		    if (rhp->end - sub > to + cnt)
			rhp->end -= cnt;
		    else
			rhp->end = to;
		}
	    }
	}

	while (to + cnt < zlell) {
	    zleline[to] = zleline[to + cnt];
	    to++;
	}
	zleline[zlell = to] = ZWC('\0');
    }
    region_active = 0;
}