/* * 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; }
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); }
/* * 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); }
/* * 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; }
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; }
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); }