示例#1
0
文件: zle_vi.c 项目: Jaharmi/zsh
int
viyankwholeline(UNUSED(char **args))
{
    int bol = findbol(), oldcs = zlecs;
    int n = zmult;

    startvichange(-1);
    if (n < 1)
	return 1;
    while(n--) {
     if (zlecs > zlell) {
	zlecs = oldcs;
	return 1;
     }
     zlecs = findeol() + 1;
    }
    vilinerange = 1;
    cut(bol, zlecs - bol - 1, 0);
    zlecs = oldcs;
    return 0;
}
示例#2
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
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;
}
示例#3
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();
}
示例#4
0
文件: zle_utils.c 项目: Lujaw/zsh
void
findline(int *a, int *b)
{
    *a = findbol();
    *b = findeol();
}
示例#5
0
文件: zle_vi.c 项目: Osse/zsh
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;
}
示例#6
0
void
vibeginningofline(void)
{
    cs = findbol();
}
示例#7
0
int
getvirange(int wf)
{
    int k2, t0, startline, endline, obeep;
    int mult1, gotmult1;

    vilinerange = 0;
    startline = findbol();
    endline = findeol();
    /* get arguments for the command, and then the command key */
    mult1 = zmult;
    gotmult1 = gotmult;
    zmult = 1;
    gotmult = 0;
    lastcmd &= ~(ZLE_NEGARG | ZLE_DIGIT);
    while(1) {
	if ((k2 = getkeycmd()) < 0 || k2 == z_sendbreak) {
	    feep();
	    return -1;
	}
	if (!(zlecmds[k2].flags & ZLE_ARG))
	    break;
	(*zlecmds[k2].func) ();
	lastcmd = zlecmds[k2].flags;
    }

    /* double counts, such as in 3d4j, get multiplied, unless we're repeating */
    if(vichgrepeat && gotmult1) {
	zmult = mult1;
	gotmult = 1;
    } else if (gotmult1) {
	zmult *= mult1;
	gotmult = 1;
    }
    /* can't handle an empty file */
    if (!ll) {
	feep();
	return -1;
    }

    /* This bit handles repeated command keys, such as dd.  A number  *
     * of lines is taken as the range.  The current line is included. *
     * If the argument is positive, the lines go downward, otherwise  *
     * vice versa.  The argument gives the number of lines.           */
    if (k2 == bindk) {
	vilinerange = 1;
	if (!zmult) {
	    feep();
	    return -1;
	}
	t0 = cs;
	if (zmult > 0) {
	    while(zmult-- && cs <= ll)
		cs = findeol() + 1;
	    if (zmult != -1) {
		cs = t0;
		feep();
		return -1;
	    }
	    t0 = cs - 1;
	    cs = startline;
	    return t0;
	} else {
	    while(zmult++ && cs >= 0)
		cs = findbol() - 1;
	    if (zmult != 1) {
		cs = t0;
		feep();
		return -1;
	    }
	    cs++;
	    return endline;
	}
    }

    /* Not a movement?!  No, you can't do yd. */
    if (!(zlecmds[k2].flags & ZLE_MOVEMENT)) {
	feep();
	return -1;
    }

    /* 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.                   */
    t0 = cs;
    virangeflag = 1;
    wordflag = wf;
    obeep = opts[BEEP];
    opts[BEEP] = 0;
    (*zlecmds[k2].func) ();
    wordflag = 0;
    opts[BEEP] = obeep;
    if (cs == t0) {
	/* An error occured -- couldn't move.  The movement command didn't *
	 * feep, because we set NO_BEEP for the duration of the command.   */
	feep();
	virangeflag = 0;
	return -1;
    }
    if(virangeflag == -1)
	t0++;
    virangeflag = 0;

    /* get the range the right way round */
    if (cs > t0) {
	int tmp = cs;
	cs = t0;
	t0 = tmp;
    }

    /* Was it a line-oriented move?  In this case, entire lines are taken. *
     * 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 (zlecmds[k2].flags & ZLE_LINEMOVE) {
	int newcs = findbol();
	cs = t0;
	t0 = findeol();
	cs = newcs;
	vilinerange = 1;
    }
    return t0;
}
示例#8
0
文件: zle_vi.c 项目: MPOWER4RU/zsh
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;
}