Пример #1
0
/*
 * Go to the end of the current sentence.  Like gotobosent(), if we skip into
 * an empty line, return at that point.
 */
int
gotoeosent(int f, int n)
{
    regexp *exp;
    int s;
    int empty = is_empty_line(DOT);

    exp = b_val_rexp(curbp, VAL_SENTENCES)->reg;
    /* if we're on the end of a sentence now, don't bother scanning
       further, or we'll miss the immediately following sentence */
    if (!(lregexec(exp, DOT.l, DOT.o, llength(DOT.l)) &&
	  exp->startp[0] - lvalue(DOT.l) == DOT.o)) {
	if (findpat(f, n, exp, FORWARD) != TRUE) {
	    DOT = curbp->b_line;
	} else if (empty || !is_at_end_of_line(DOT)) {
	    s = forwchar(TRUE, RegexpLen(exp));
	    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
		LINE *lp = DOT.l;
		s = forwchar(TRUE, 1);
		if (lp != DOT.l)
		    break;
	    }
	}
    } else {
	s = forwchar(TRUE, RegexpLen(exp));
	while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot())))
	    s = forwchar(TRUE, 1);
    }
    return TRUE;
}
Пример #2
0
void
on_double_click(void)
{
    MARK save;

    save = DOT;
    TRACE(("MOUSE double-click DOT %d.%d\n", line_no(curbp, DOT.l), DOT.o));
    sel_release();
    if (!is_at_end_of_line(DOT)
	&& !isSpace(CharAtDot())) {
	while (DOT.o > 0) {
	    DOT.o -= BytesBefore(DOT.l, DOT.o);
	    if (isSpace(CharAtDot())) {
		DOT.o += BytesAt(DOT.l, DOT.o);
		break;
	    }
	}
	sel_begin();
	MK = DOT;
	while (!is_at_end_of_line(DOT)) {
	    DOT.o += BytesAt(DOT.l, DOT.o);
	    if (is_at_end_of_line(DOT)
		|| isSpace(CharAtDot())) {
		DOT.o -= BytesBefore(DOT.l, DOT.o);
		break;
	    }
	}
	sel_extend(FALSE, TRUE);
    }
    DOT = save;
    update(TRUE);
}
Пример #3
0
/*
 * Move the cursor forwards by "n" characters. If "n" is less than zero call
 * "backchar" to actually do the move. Otherwise compute the new cursor
 * location, and move ".". Error if you try and move off the end of the
 * buffer. Set the flag if the line pointer for dot changes.
 */
int
forwchar(int f, int n)
{
    int rc = TRUE;

    n = need_a_count(f, n, 1);

    if (n < 0) {
	rc = backchar(f, -n);
    } else {
	while (n--) {
	    /* if an explicit arg was given, allow us to land
	       on the newline, else skip it */
	    if (is_at_end_of_line(DOT) ||
		(f == FALSE && !insertmode &&
		 llength(DOT.l) && DOT.o == llength(DOT.l) - 1)) {
		if (is_header_line(DOT, curbp) ||
		    is_last_line(DOT, curbp)) {
		    rc = FALSE;
		    break;
		}
		DOT.l = lforw(DOT.l);
		DOT.o = w_left_margin(curwp);
		curwp->w_flag |= WFMOVE;
	    } else {
		DOT.o += BytesAt(DOT.l, DOT.o);
	    }
	}
    }
    return (rc);
}
Пример #4
0
/*
 * Go to the beginning of the current sentence. If we skip into an empty line
 * (from a non-empty line), return at that point -- that's what vi does.
 */
int
gotobosent(int f, int n)
{
    MARK savepos;
    int looped = 0;
    int extra;
    int empty = is_empty_line(DOT);
    regexp *exp;
    int s = TRUE;

    savepos = DOT;
    exp = b_val_rexp(curbp, VAL_SENTENCES)->reg;

    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
	s = backchar(TRUE, 1);
	if (is_empty_line(DOT) && !empty)
	    return TRUE;
    }
  top:
    extra = 0;
    if (findpat(f, n, exp, REVERSE) != TRUE) {
	return gotobob(f, n);
    }
    s = forwchar(TRUE, RegexpLen(exp));
    while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) {
	s = forwchar(TRUE, 1);
	extra++;
    }
    if (n == 1 && samepoint(savepos, DOT)) {	/* try again */
	if (looped > 10)
	    return FALSE;
	s = backchar(TRUE, RegexpLen(exp) + extra + looped);
	while (s && is_at_end_of_line(DOT)) {
	    if (!empty && is_empty_line(DOT))
		return TRUE;
	    s = backchar(TRUE, 1);
	}
	looped++;
	goto top;

    }
    return TRUE;
}
Пример #5
0
static int
xterm_button(int c)
{
	WINDOW	*wp;
	int	event;
	int	button;
	int	x;
	int	y;
	int	status;
#if OPT_XTERM >= 3
	int	save_row = ttrow;
	int	save_col = ttcol;
	int	firstrow, lastrow;
	int	startx, endx, mousex;
	int	starty, endy, mousey;
	MARK	save_dot;
	char	temp[NSTRING];
	static	const	char	*fmt = "\033[%d;%d;%d;%d;%dT";
#endif	/* OPT_XTERM >= 3 */

	if (insertmode)
		return ABORT;

	if ((status = (global_g_val(GMDXTERM_MOUSE))) != 0) {
		beginDisplay;
		switch(c) {
		case 'M':	/* button-event */
			event	= keystroke();
			x	= XtermPos() + x_origin;
			y	= XtermPos() + y_origin;

			button	= (event & 3) + 1;
			TRACE(("M-button event:%d x:%d y:%d\n", event, x, y))
			if (button > 3) {
				endofDisplay;
				return TRUE; /* button up */
			}
			wp = row2window(y-1);
#if OPT_XTERM >= 3
			/* Tell the xterm how to highlight the selection.
			 * It won't do anything else until we do this.
			 */
			if (wp != 0) {
				firstrow = wp->w_toprow + 1;
				lastrow  = mode_row(wp) + 1;
			} else {		/* from message-line */
				firstrow = term.t_nrow ;
				lastrow  = term.t_nrow + 1;
			}
			if (y >= lastrow)	/* don't select modeline */
				y = lastrow - 1;
			(void)lsprintf(temp, fmt, 1, x, y, firstrow, lastrow);
			putpad(temp);
			TTflush();
#endif	/* OPT_XTERM >= 3 */
			/* Set the dot-location if button 1 was pressed in a
			 * window.
			 */
			if (wp != 0
			 && button == 1
			 && !reading_msg_line
			 && setcursor(y-1, x-1)) {
				/*mlerase();*/
				(void)update(TRUE);
				status = TRUE;
			} else if (button <= 3) {
#if OPT_XTERM >= 3
				/* abort the selection */
				(void)lsprintf(temp, fmt, 0, x, y, firstrow, lastrow);
				putpad(temp);
				TTflush();
#endif	/* OPT_XTERM >= 3 */
				status = ABORT;
			} else {
				status = FALSE;
			}
			break;
#if OPT_XTERM >= 3
		case 't':	/* reports valid text-location */
			x = XtermPos();
			y = XtermPos();

			TRACE(("t: x:%d y:%d\n", x, y))
			setwmark(y-1, x-1);
			yankregion();

			movecursor(save_row, save_col);
			/*mlerase();*/
			(void)update(TRUE);
			break;
		case 'T':	/* reports invalid text-location */
			/*
			 * The starting-location returned is not the location
			 * at which the mouse was pressed.  Instead, it is the
			 * top-most location of the selection.  In turn, the
			 * ending-location is the bottom-most location of the
			 * selection.  The mouse-up location is not necessarily
			 * a pointer to valid text.
			 *
			 * This case handles multi-clicking events as well as
			 * selections whose start or end location was not
			 * pointing to text.
			 */
			save_dot = DOT;
			startx = XtermPos();	/* starting-location */
			starty = XtermPos();
			endx   = XtermPos();	/* ending-location */
			endy   = XtermPos();
			mousex = XtermPos();	/* location at mouse-up */
			mousey = XtermPos();

			TRACE(("T: start(%d,%d) end(%d,%d) mouse(%d,%d)\n",
				starty, startx,
				endy,   endx,
				mousey, mousex))
			setcursor(starty - 1, startx - 1);
			setwmark (endy   - 1, endx   - 1);
			if (MK.o != 0 && !is_at_end_of_line(MK))
				MK.o += 1;
			yankregion();

			DOT = save_dot;
			movecursor(save_row, save_col);
			/*mlerase();*/
			(void)update(TRUE);
			break;
#endif /* OPT_XTERM >= 3 */
		default:
			status = FALSE;
		}
		endofDisplay;
	}
Пример #6
0
static int
getfence(
int ch, /* fence type to match against */
int sdir) /* direction to scan if we're not on a fence to begin with */
{
	MARK	oldpos; 	/* original pointer */
	register int ofence = 0;	/* open fence */
	int s, i;
	int key = CPP_UNKNOWN;
	char *C_fences, *ptr;
	int fch;

	/* save the original cursor position */
	oldpos = DOT;

	/* ch may have been passed, if being used internally */
	if (!ch) {
		if ((i = firstchar(DOT.l)) < 0)	/* offset of first nonblank */
			return FALSE;		/* line is entirely blank */

		if (DOT.o <= i && (ch = lgetc(DOT.l,i)) == '#') {
			if (llength(DOT.l) < i+3)
				return FALSE;
		} else if ((ch = char_at(DOT)) == '/' || ch == '*') {
			/* EMPTY */;
		} else if (sdir == FORWARD) {
			/* get the current character */
			if (oldpos.o < llength(oldpos.l)) {
				do {
					ch = char_at(oldpos);
				} while(!is_user_fence(ch, (int *)0) &&
					++oldpos.o < llength(oldpos.l));
			}
			if (is_at_end_of_line(oldpos)) {
				return FALSE;
			}
		} else {
			/* get the current character */
			if (oldpos.o >= 0) {
				do {
					ch = char_at(oldpos);
				} while(!is_user_fence(ch, (int *)0) &&
					--oldpos.o >= 0);
			}

			if (oldpos.o < 0) {
				return FALSE;
			}
		}

		/* we've at least found a fence -- move us that far */
		DOT.o = oldpos.o;
	}

	fch = ch;

	/* is it a "special" fence char? */
	C_fences = "/*#";
	ptr = strchr(C_fences, ch);
	
	if (!ptr) {
		ofence = is_user_fence(ch, &sdir);
		if (ofence)
			fch = PAIRED_FENCE_CH;
	}

	/* setup proper matching fence */
	switch (fch) {
		case PAIRED_FENCE_CH:
			/* NOTHING */
			break;
		case '#':
			if ((i = firstchar(DOT.l)) < 0)
				return FALSE;	/* line is entirely blank */
			if ((i = nextchar(DOT.l, i+1)) >= 0
			 && ((key = cpp_keyword(DOT.l, i)) != CPP_UNKNOWN))
			 	break;
			return FALSE;
		case '*':
			ch = '/';
			if (NextCharIs('/')) {
				sdir = REVERSE;
				forwchar(TRUE,1);
				break;
			} else if (PrevCharIs('/')) {
				sdir = FORWARD;
				backchar(TRUE,1);
				if (doingopcmd)
					pre_op_dot = DOT;
				break;
			}
			return FALSE;
		case '/':
			if (NextCharIs('*')) {
				sdir = FORWARD;
				break;
			} else if (PrevCharIs('*')) {
				sdir = REVERSE;
				break;
			}
			/* FALL THROUGH */
		default: 
			return(FALSE);
	}

	/* ops are inclusive of the endpoint */
	if (doingopcmd && sdir == REVERSE) {
		forwchar(TRUE,1);
		pre_op_dot = DOT;
		backchar(TRUE,1);
	}

	if (key != CPP_UNKNOWN) {  /* we're searching for a cpp keyword */
		s = cpp_fence(sdir, key);
	} else if (ch == '/') {
		s = comment_fence(sdir);
	} else {
		s = simple_fence(sdir, ch, ofence);
	}

	if (s == TRUE)
		return TRUE;

	/* restore the current position */
	DOT = oldpos;
	return(FALSE);
}