/* * Implements the vi "L" command. * * Move to the last (or nth last) line in window */ int gotoeos(int f, int n) { LINE *last = DOT.l; int nn; n = need_at_least(f, n, 1); /* first get to the end */ DOT.l = curwp->w_line.l; nn = curwp->w_ntrows; while ((nn -= line_height(curwp, DOT.l)) > 0) { if (is_last_line(DOT, curbp)) break; DOT.l = lforw(DOT.l); } #ifdef WMDLINEWRAP /* adjust if we pointed to a line-fragment */ if (w_val(curwp, WMDLINEWRAP) && nn < 0 && DOT.l != curwp->w_line.l) DOT.l = lback(DOT.l); #endif /* and then go back up */ /* (we're either at eos or eof) */ while (--n != 0) { if (sameline(DOT, curwp->w_line)) break; DOT.l = lback(DOT.l); } if (DOT.l != last) curwp->w_flag |= WFMOVE; return firstnonwhite(FALSE, 1); }
/* * Implements the vi "H" command. * * Move to first (or nth) line in window */ int gotobos(int f, int n) { LINE *last = DOT.l; int nn = curwp->w_ntrows; n = need_at_least(f, n, 1); DOT.l = curwp->w_line.l; while (--n != 0) { if (is_last_line(DOT, curbp)) break; nn -= line_height(curwp, DOT.l); DOT.l = lforw(DOT.l); } if (DOT.l != last) curwp->w_flag |= WFMOVE; return firstnonwhite(FALSE, 1); }
int forwredo(int f, int n) { int status = TRUE; TRACE((T_CALLED "forwundo(%d,%d)\n", f, n)); n = need_at_least(f, n, 1); if ((status = check_editable(curbp)) == TRUE) { while ((status == TRUE) && n--) { status = undoworker(FORW); if (status) { mlwrite("[change redone]"); } else { mlwarn("[No more changes to redo]"); } } curbp->b_udstkindx = BACK; /* flip to other stack */ } return status; }
int inf_undo(int f, int n) { int status = TRUE; TRACE((T_CALLED "undo(%d,%d)\n", f, n)); n = need_at_least(f, n, 1); if ((status = check_editable(curbp)) == TRUE) { curbp->b_udstkindx ^= 1; /* flip to other stack */ while ((status == TRUE) && n--) { if ((status = undoworker(curbp->b_udstkindx)) == TRUE) { mlwrite("[change %sdone]", curbp->b_udstkindx == BACK ? "un" : "re"); } else { mlwarn("[No more changes to %s]", curbp->b_udstkindx == BACK ? "undo" : "redo"); } } curbp->b_udstkindx ^= 1; /* flip to other stack */ } returnCode(status); }
int multimotion(int f, int n) { const CMDFUNC *cfp; int status, c, waserr; int pasting; REGIONSHAPE shape; MARK savedot; MARK savemark; MARK realdot; BUFFER *origbp = curbp; static int wassweephack = FALSE; /* Use the repeat-count as a shortcut to specify the type of selection. * I'd use int-casts of the enum value, but declaring enums with * specific values isn't 100% portable. */ n = need_at_least(f, n, 1); if (n == 3) regionshape = rgn_RECTANGLE; else if (n == 2) regionshape = rgn_FULLLINE; else regionshape = rgn_EXACT; shape = regionshape; sweephack = FALSE; savedot = DOT; switch (doingsweep) { case TRUE: /* the same command terminates as starts the sweep */ if (doingsweep) { do_sweep(FALSE); } mlforce("[Sweeping: Completed]"); regionshape = shape; /* since the terminating 'q' is executed as a motion, we have now lost the value of sweephack we were interested in, the one that tells us to include DOT.o in the selection. so we preserved it in wassweephack, and restore it here. */ if (wassweephack) sweephack = wassweephack; return TRUE; case SORTOFTRUE: if (doingsweep != TRUE) { do_sweep(TRUE); } sweepmsg("Begin cursor sweep..."); sel_extend(TRUE, (regionshape != rgn_RECTANGLE && sweephack)); savedot = MK; TRACE(("MOUSE BEGIN DOT: %d.%d MK %d.%d\n", line_no(curbp, DOT.l), DOT.o, line_no(curbp, MK.l), MK.o)); break; case FALSE: if (doingsweep != TRUE) { do_sweep(TRUE); } sweepmsg("Begin cursor sweep..."); (void) sel_begin(); (void) sel_setshape(shape); break; } waserr = TRUE; /* to force message "state-machine" */ realdot = DOT; pasting = FALSE; while (doingsweep) { /* Fix up the screen */ (void) update(FALSE); /* get the next command from the keyboard */ c = kbd_seq(); if (ABORTED(c) || curbp != origbp) { return release_selection(FALSE); } f = FALSE; n = 1; do_repeats(&c, &f, &n); /* and execute the command */ cfp = SelectKeyBinding(c); if ((cfp != NULL) && ((cfp->c_flags & (GOAL | MOTION)) != 0)) { MARK testdot; wassweephack = sweephack; sweephack = FALSE; TRACE(("MOUSE TEST DOT: %d.%d MK %d.%d\n", line_no(curbp, DOT.l), DOT.o, line_no(curbp, MK.l), MK.o)); testdot = DOT; status = execute(cfp, f, n); switch (status) { case SEL_RELEASE: TRACE(("MOUSE SEL_RELEASE %d.%d\n", line_no(curbp, DOT.l), DOT.o)); return release_selection(TRUE); case SEL_PASTE: pasting = TRUE; /* FALLTHRU */ case SEL_FINISH: do_sweep(FALSE); break; case SORTOFTRUE: TRACE(("MOUSE selection pending %d.%d -> %d.%d\n", line_no(curbp, realdot.l), realdot.o, line_no(curbp, testdot.l), testdot.o)); realdot = testdot; break; case SEL_BEGIN: savedot = MK; TRACE(("MOUSE SEL_BEGIN...\n")); /*FALLTHRU */ case SEL_EXTEND: TRACE(("MOUSE SEL_EXTEND from %d.%d to %d.%d\n", line_no(curbp, savedot.l), savedot.o, line_no(curbp, DOT.l), DOT.o)); /*FALLTHRU */ case TRUE: if (waserr && doingsweep) { sweepmsg("Sweeping..."); waserr = FALSE; } realdot = DOT; DOT = savedot; (void) sel_begin(); DOT = realdot; TRACE(("MOUSE LOOP save: %d.%d real %d.%d, mark %d.%d\n", line_no(curbp, savedot.l), savedot.o, line_no(curbp, realdot.l), realdot.o, line_no(curbp, MK.l), MK.o)); (void) sel_setshape(shape); /* we sometimes want to include DOT.o in the selection (unless it's a rectangle, in which case it's taken care of elsewhere) */ sel_extend(TRUE, (regionshape != rgn_RECTANGLE && sweephack)); break; default: sweepmsg("Sweeping: Motion failed."); waserr = TRUE; break; } } else { sweepmsg("Sweeping: Only motions permitted"); waserr = TRUE; } } regionshape = shape; /* if sweephack is set here, it's because the last motion had it set */ if (doingopcmd) pre_op_dot = savedot; savedot = DOT; savemark = MK; DOT = realdot; TRACE(("MOUSE SAVE DOT: %d.%d MK %d.%d\n", line_no(curbp, DOT.l), DOT.o, line_no(curbp, MK.l), MK.o)); if ((regionshape != rgn_RECTANGLE) && sweephack) { if (dot_vs_mark() < 0) MK.o += BytesAt(MK.l, MK.o); else DOT.o += BytesAt(DOT.l, DOT.o); } status = yankregion(); DOT = savedot; MK = savemark; sweephack = wassweephack = FALSE; if (status == TRUE && pasting) status = SEL_PASTE; return status; }