|
|
1.1 ! root 1: /* ! 2: * The routines in this file move the cursor around on the screen. ! 3: * They compute a new value for the cursor, then adjust ".". ! 4: * The display code always updates the cursor location, so only moves ! 5: * between lines, or functions that adjust the top line in the window ! 6: * and invalidate the framing, are hard. ! 7: */ ! 8: #include <stdio.h> ! 9: #include "ed.h" ! 10: ! 11: /* ! 12: * Move the cursor to the beginning of the current line. ! 13: * Trivial. ! 14: */ ! 15: gotobol(f, n) ! 16: { ! 17: curwp->w_doto = 0; ! 18: return (TRUE); ! 19: } ! 20: ! 21: /* ! 22: * Move the cursor backwards by "n" characters. If "n" is less than ! 23: * zero call "forwchar" to actually do the move. Otherwise compute ! 24: * the new cursor location. Error if you try and move out of the buffer. ! 25: * Set the flag if the line pointer for dot changes. ! 26: */ ! 27: backchar(f, n) ! 28: register int n; ! 29: { ! 30: register LINE *lp; ! 31: ! 32: if (n < 0) ! 33: return (forwchar(f, -n)); ! 34: while (n--) { ! 35: if (curwp->w_doto == 0) { ! 36: if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) ! 37: return (FALSE); ! 38: curwp->w_dotp = lp; ! 39: curwp->w_doto = llength(lp); ! 40: curwp->w_flag |= WFMOVE; ! 41: } else ! 42: curwp->w_doto--; ! 43: } ! 44: return (TRUE); ! 45: } ! 46: ! 47: /* ! 48: * Move the cursor to the end of the current line. Trivial. ! 49: * No errors. ! 50: */ ! 51: gotoeol(f, n) ! 52: { ! 53: curwp->w_doto = llength(curwp->w_dotp); ! 54: return (TRUE); ! 55: } ! 56: ! 57: /* ! 58: * Move the cursor forwards by "n" characters. If "n" is less than ! 59: * zero call "backchar" to actually do the move. Otherwise compute ! 60: * the new cursor location, and move ".". Error if you try and move ! 61: * off the end of the buffer. Set the flag if the line pointer ! 62: * for dot changes. ! 63: */ ! 64: forwchar(f, n) ! 65: register int n; ! 66: { ! 67: if (n < 0) ! 68: return (backchar(f, -n)); ! 69: while (n--) { ! 70: if (curwp->w_doto == llength(curwp->w_dotp)) { ! 71: if (curwp->w_dotp == curbp->b_linep) ! 72: return (FALSE); ! 73: curwp->w_dotp = lforw(curwp->w_dotp); ! 74: curwp->w_doto = 0; ! 75: curwp->w_flag |= WFMOVE; ! 76: } else ! 77: curwp->w_doto++; ! 78: } ! 79: return (TRUE); ! 80: } ! 81: ! 82: /* ! 83: * Goto the beginning of the buffer. ! 84: * Massive adjustment of dot. This is considered to be hard motion; ! 85: * it really isn't if the original value of dot is the same as the ! 86: * new value of dot. ! 87: * Normally bound to "M-<". ! 88: */ ! 89: gotobob(f, n) ! 90: { ! 91: curwp->w_dotp = lforw(curbp->b_linep); ! 92: curwp->w_doto = 0; ! 93: curwp->w_flag |= WFHARD; ! 94: return (TRUE); ! 95: } ! 96: ! 97: /* ! 98: * Move to the end of the buffer. ! 99: * Dot is always put at the end of the file (ZJ). The standard screen code does ! 100: * most of the hard parts of update. Bound to "M->". ! 101: */ ! 102: gotoeob(f, n) ! 103: { ! 104: curwp->w_dotp = curbp->b_linep; ! 105: curwp->w_doto = 0; ! 106: curwp->w_flag |= WFHARD; ! 107: return (TRUE); ! 108: } ! 109: ! 110: /* ! 111: * Move forward by full lines. ! 112: * If the number of lines to move is less than zero, call the backward line ! 113: * function to actually do it. The last command controls how the goal column ! 114: * is set. Bound to "C-N". No errors are possible. ! 115: */ ! 116: forwline(f, n) ! 117: { ! 118: register LINE *dlp; ! 119: ! 120: if (n < 0) ! 121: return (backline(f, -n)); ! 122: if ((lastflag&CFCPCN) == 0) /* Reset goal if last */ ! 123: curgoal = curcol; /* not C-P or C-N */ ! 124: thisflag |= CFCPCN; ! 125: dlp = curwp->w_dotp; ! 126: while (n-- && dlp!=curbp->b_linep) ! 127: dlp = lforw(dlp); ! 128: curwp->w_dotp = dlp; ! 129: curwp->w_doto = getgoal(dlp); ! 130: curwp->w_flag |= WFMOVE; ! 131: return (TRUE); ! 132: } ! 133: ! 134: /* ! 135: * This function is like "forwline", but goes backwards. ! 136: * The scheme is exactly the same. Check for arguments that are ! 137: * less than zero and call your alternate. Figure out the new line and ! 138: * call "movedot" to perform the motion. No errors are possible. ! 139: * Bound to "C-P". ! 140: */ ! 141: backline(f, n) ! 142: { ! 143: register LINE *dlp; ! 144: ! 145: if (n < 0) ! 146: return (forwline(f, -n)); ! 147: if ((lastflag&CFCPCN) == 0) /* Reset goal if the */ ! 148: curgoal = curcol; /* last isn't C-P, C-N */ ! 149: thisflag |= CFCPCN; ! 150: dlp = curwp->w_dotp; ! 151: while (n-- && lback(dlp)!=curbp->b_linep) ! 152: dlp = lback(dlp); ! 153: curwp->w_dotp = dlp; ! 154: curwp->w_doto = getgoal(dlp); ! 155: curwp->w_flag |= WFMOVE; ! 156: return (TRUE); ! 157: } ! 158: ! 159: /* ! 160: * This routine, given a pointer to a LINE, and the current cursor goal ! 161: * column, return the best choice for the offset. The offset is returned. ! 162: * Used by "C-N" and "C-P". ! 163: */ ! 164: getgoal(dlp) ! 165: register LINE *dlp; ! 166: { ! 167: unsigned c; ! 168: register int col; ! 169: register int newcol; ! 170: register int dbo; ! 171: ! 172: col = 0; ! 173: dbo = 0; ! 174: while (dbo != llength(dlp)) { ! 175: c = lgetc(dlp, dbo); ! 176: newcol = col; ! 177: switch (dblchr(c)) { ! 178: case 2: ! 179: taber(newcol); ! 180: break; ! 181: case 1: ! 182: ++newcol; ! 183: } ! 184: ++newcol; ! 185: if (newcol > curgoal) ! 186: break; ! 187: col = newcol; ! 188: ++dbo; ! 189: } ! 190: return (dbo); ! 191: } ! 192: ! 193: /* ! 194: * Scroll forward by a specified number of lines, or by a full page if ! 195: * no argument. ! 196: * The "2" in the arithmetic on the window size is the overlap; this value is ! 197: * the default overlap value in ITS EMACS. Because this zaps the top line in ! 198: * the display window, we have to do a hard update. ! 199: * Bound to "C-V". ! 200: */ ! 201: forwpage(f, n) ! 202: register int n; ! 203: { ! 204: register LINE *lp; ! 205: ! 206: if (f == FALSE) { ! 207: n = curwp->w_ntrows - 2; /* Default scroll. */ ! 208: if (n <= 0) /* Forget the overlap */ ! 209: n = 1; /* if tiny window. */ ! 210: } else if (n < 0) ! 211: return (backpage(f, -n)); ! 212: #if CVMVAS ! 213: else /* Convert from pages */ ! 214: n *= curwp->w_ntrows; /* to lines. */ ! 215: #endif ! 216: lp = curwp->w_linep; ! 217: while (n-- && lp!=curbp->b_linep) ! 218: lp = lforw(lp); ! 219: curwp->w_linep = lp; ! 220: curwp->w_dotp = lp; ! 221: curwp->w_doto = 0; ! 222: curwp->w_flag |= WFHARD; ! 223: return (TRUE); ! 224: } ! 225: ! 226: /* ! 227: * This command is like "forwpage", but it goes backwards. ! 228: * The "2", like above, is the overlap between the two windows. The ! 229: * value is from the ITS EMACS manual. We do a hard update for exactly ! 230: * the same reason. ! 231: * Bound to "M-V". ! 232: */ ! 233: backpage(f, n) ! 234: register int n; ! 235: { ! 236: register LINE *lp; ! 237: ! 238: if (f == FALSE) { ! 239: n = curwp->w_ntrows - 2; /* Default scroll. */ ! 240: if (n <= 0) /* Don't blow up if the */ ! 241: n = 1; /* window is tiny. */ ! 242: } else if (n < 0) ! 243: return (forwpage(f, -n)); ! 244: #if CVMVAS ! 245: else /* Convert from pages */ ! 246: n *= curwp->w_ntrows; /* to lines. */ ! 247: #endif ! 248: lp = curwp->w_linep; ! 249: while (n-- && lback(lp)!=curbp->b_linep) ! 250: lp = lback(lp); ! 251: curwp->w_linep = lp; ! 252: curwp->w_dotp = lp; ! 253: curwp->w_doto = 0; ! 254: curwp->w_flag |= WFHARD; ! 255: return (TRUE); ! 256: } ! 257: ! 258: /* ! 259: * Set the mark in the current window to the value of "." in the window. ! 260: * No errors are possible. ! 261: * Bound to "M-.". ! 262: */ ! 263: setmark(f, n) ! 264: { ! 265: curwp->w_markp = curwp->w_dotp; ! 266: curwp->w_marko = curwp->w_doto; ! 267: mlwrite("[Mark set]"); ! 268: return (TRUE); ! 269: } ! 270: ! 271: /* ! 272: * Swap the values of "." and "mark" in the current window. ! 273: * This is pretty easy, because all of the hard work gets done by the ! 274: * standard routine that moves the mark about. The only possible error is ! 275: * "no mark". ! 276: * Bound to "C-X C-X". ! 277: */ ! 278: swapmark(f, n) ! 279: { ! 280: register LINE *odotp; ! 281: register int odoto; ! 282: ! 283: if (curwp->w_markp == NULL) { ! 284: mlwrite("No mark in this window"); ! 285: return (FALSE); ! 286: } ! 287: odotp = curwp->w_dotp; ! 288: odoto = curwp->w_doto; ! 289: curwp->w_dotp = curwp->w_markp; ! 290: curwp->w_doto = curwp->w_marko; ! 291: curwp->w_markp = odotp; ! 292: curwp->w_marko = odoto; ! 293: curwp->w_flag |= WFMOVE; ! 294: return (TRUE); ! 295: } ! 296: ! 297: /* ! 298: * Go to a specific line in the buffer, mostly for ! 299: * looking up errors in C programs, which give the ! 300: * error a line number. If an argument is present, then ! 301: * it is the line number, else prompt for a line number ! 302: * to use. ! 303: */ ! 304: gotoline(f, n) ! 305: register int n; ! 306: { ! 307: register LINE *clp; ! 308: register int s; ! 309: uchar buf[32]; ! 310: ! 311: if (f == FALSE) { ! 312: if ((s=mlreply("Goto line: ", buf, sizeof(buf))) != TRUE) ! 313: return (s); ! 314: n = atoi(buf); ! 315: } ! 316: if (n <= 0) { ! 317: mlwrite("Bad line"); ! 318: return (FALSE); ! 319: } ! 320: clp = lforw(curbp->b_linep); /* "clp" is first line */ ! 321: while (n != 1) { ! 322: if (clp == curbp->b_linep) { ! 323: mlwrite("Line too large"); ! 324: return (FALSE); ! 325: } ! 326: clp = lforw(clp); ! 327: --n; ! 328: } ! 329: curwp->w_dotp = clp; ! 330: curwp->w_doto = 0; ! 331: curwp->w_flag |= WFMOVE; ! 332: return (TRUE); ! 333: } ! 334: ! 335: /* ! 336: * Go to a specific line from the original file, mostly for ! 337: * looking up errors in C programs, which give the ! 338: * error a line number. If an argument is present, then ! 339: * it is the line number, else prompt for a line number ! 340: * to use. ! 341: */ ! 342: gotofline(f, n) ! 343: register int n; ! 344: { ! 345: register LINE *clp; ! 346: register int s; ! 347: uchar buf[32]; ! 348: ! 349: if (f == FALSE) { ! 350: if ((s=mlreply("Goto line: ", buf, sizeof(buf))) != TRUE) ! 351: return (s); ! 352: n = atoi(buf); ! 353: } ! 354: if (n <= 0) { ! 355: mlwrite("Bad line"); ! 356: return (FALSE); ! 357: } ! 358: clp = lforw(curbp->b_linep); /* "clp" is first line */ ! 359: while (n != l_number(clp)) { ! 360: if (clp == curbp->b_linep) { ! 361: mlwrite("Line not in buffer"); ! 362: return (FALSE); ! 363: } ! 364: clp = lforw(clp); ! 365: } ! 366: curwp->w_dotp = clp; ! 367: curwp->w_doto = 0; ! 368: curwp->w_flag |= WFMOVE; ! 369: return (TRUE); ! 370: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.