|
|
1.1 ! root 1: /*************************************************************************** ! 2: * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE * ! 3: * is provided to you without charge, and with no warranty. You may give * ! 4: * away copies of JOVE, including sources, provided that this notice is * ! 5: * included in all the files. * ! 6: ***************************************************************************/ ! 7: ! 8: #include "jove.h" ! 9: #include "re.h" ! 10: #include "ctype.h" ! 11: #include "disp.h" ! 12: private void to_sent proto((int)); ! 13: ! 14: private int line_pos; ! 15: ! 16: void ! 17: f_char(n) ! 18: register int n; ! 19: { ! 20: if (n < 0) { ! 21: b_char(-n); ! 22: return; ! 23: } ! 24: while (--n >= 0) { ! 25: if (eolp()) { /* Go to the next Line */ ! 26: if (curline->l_next == 0) ! 27: break; ! 28: SetLine(curline->l_next); ! 29: } else ! 30: curchar += 1; ! 31: } ! 32: } ! 33: ! 34: void ! 35: b_char(n) ! 36: register int n; ! 37: { ! 38: if (n < 0) { ! 39: f_char(-n); ! 40: return; ! 41: } ! 42: while (--n >= 0) { ! 43: if (bolp()) { ! 44: if (curline->l_prev == 0) ! 45: break; ! 46: SetLine(curline->l_prev); ! 47: Eol(); ! 48: } else ! 49: curchar -= 1; ! 50: } ! 51: } ! 52: ! 53: void ! 54: ForChar() ! 55: { ! 56: f_char(arg_value()); ! 57: } ! 58: ! 59: void ! 60: BackChar() ! 61: { ! 62: b_char(arg_value()); ! 63: } ! 64: ! 65: void ! 66: NextLine() ! 67: { ! 68: if ((curline == curbuf->b_last) && eolp()) ! 69: complain(NullStr); ! 70: line_move(FORWARD, arg_value(), YES); ! 71: } ! 72: ! 73: void ! 74: PrevLine() ! 75: { ! 76: if ((curline == curbuf->b_first) && bolp()) ! 77: complain(NullStr); ! 78: line_move(BACKWARD, arg_value(), YES); ! 79: } ! 80: ! 81: /* moves to a different line in DIR; LINE_CMD says whether this is ! 82: being called from NextLine() or PrevLine(), in which case it tries ! 83: to line up the column with the column of the current line */ ! 84: ! 85: void ! 86: line_move(dir, n, line_cmd) ! 87: int dir, ! 88: n, ! 89: line_cmd; ! 90: { ! 91: Line *(*proc) proto((Line *, int)) = ! 92: (dir == FORWARD) ? next_line : prev_line; ! 93: Line *line; ! 94: ! 95: line = (*proc)(curline, n); ! 96: if (line == curline) { ! 97: if (dir == FORWARD) ! 98: Eol(); ! 99: else ! 100: Bol(); ! 101: return; ! 102: } ! 103: ! 104: if (line_cmd) { ! 105: this_cmd = LINECMD; ! 106: if (last_cmd != LINECMD) ! 107: line_pos = calc_pos(linebuf, curchar); ! 108: } ! 109: SetLine(line); /* curline is in linebuf now */ ! 110: if (line_cmd) ! 111: curchar = how_far(curline, line_pos); ! 112: } ! 113: ! 114: /* returns what cur_char should be for that position col */ ! 115: ! 116: int ! 117: how_far(line, col) ! 118: Line *line; ! 119: int col; ! 120: { ! 121: register char *lp; ! 122: register int pos, ! 123: c; ! 124: char *base; ! 125: ! 126: base = lp = lcontents(line); ! 127: pos = 0; ! 128: ! 129: while (pos < col && (c = (*lp & CHARMASK)) != '\0') { ! 130: if (c == '\t') ! 131: pos += (tabstop - (pos % tabstop)); ! 132: else if (isctrl(c)) ! 133: pos += 2; ! 134: else ! 135: pos += 1; ! 136: lp += 1; ! 137: } ! 138: ! 139: return lp - base; ! 140: } ! 141: ! 142: void ! 143: Bol() ! 144: { ! 145: curchar = 0; ! 146: } ! 147: ! 148: void ! 149: Eol() ! 150: { ! 151: curchar = length(curline); ! 152: } ! 153: ! 154: void ! 155: Eof() ! 156: { ! 157: PushPntp(curbuf->b_last); ! 158: ToLast(); ! 159: } ! 160: ! 161: void ! 162: Bof() ! 163: { ! 164: PushPntp(curbuf->b_first); ! 165: ToFirst(); ! 166: } ! 167: ! 168: /* Move forward (if dir > 0) or backward (if dir < 0) a sentence. Deals ! 169: with all the kludgery involved with paragraphs, and moving backwards ! 170: is particularly yucky. */ ! 171: ! 172: private void ! 173: to_sent(dir) ! 174: int dir; ! 175: { ! 176: Bufpos *new, ! 177: old; ! 178: ! 179: DOTsave(&old); ! 180: ! 181: new = dosearch("^[ \t]*$\\|[?.!]", dir, YES); ! 182: if (new == 0) { ! 183: if (dir == BACKWARD) ! 184: ToFirst(); ! 185: else ! 186: ToLast(); ! 187: return; ! 188: } ! 189: SetDot(new); ! 190: if (dir < 0) { ! 191: to_word(1); ! 192: if ((old.p_line == curline && old.p_char <= curchar) || ! 193: (inorder(new->p_line, new->p_char, old.p_line, old.p_char) && ! 194: inorder(old.p_line, old.p_char, curline, curchar))) { ! 195: SetDot(new); ! 196: to_sent(dir); ! 197: } ! 198: return; /* We're there? */ ! 199: } ! 200: if (blnkp(linebuf)) { ! 201: Bol(); ! 202: b_char(1); ! 203: if (old.p_line == curline && old.p_char >= curchar) { ! 204: to_word(1); /* Oh brother this is painful */ ! 205: to_sent(1); ! 206: } ! 207: } else { ! 208: curchar = REbom + 1; /* Just after the [?.!] */ ! 209: if (LookingAt("[\")] *\\|[\")]$", linebuf, curchar)) ! 210: curchar += 1; ! 211: else if (!eolp() && !LookingAt(" *", linebuf, curchar)) ! 212: to_sent(dir); ! 213: } ! 214: } ! 215: ! 216: void ! 217: Bos() ! 218: { ! 219: register int num = arg_value(); ! 220: ! 221: if (num < 0) { ! 222: negate_arg_value(); ! 223: Eos(); ! 224: return; ! 225: } ! 226: ! 227: while (--num >= 0) { ! 228: to_sent(-1); ! 229: if (bobp()) ! 230: break; ! 231: } ! 232: } ! 233: ! 234: void ! 235: Eos() ! 236: { ! 237: register int num = arg_value(); ! 238: ! 239: if (num < 0) { ! 240: negate_arg_value(); ! 241: Bos(); ! 242: return; ! 243: } ! 244: ! 245: while (--num >= 0) { ! 246: to_sent(1); ! 247: if (eobp()) ! 248: break; ! 249: } ! 250: } ! 251: ! 252: void ! 253: f_word(num) ! 254: register int num; ! 255: { ! 256: register char c; ! 257: if (num < 0) { ! 258: b_word(-num); ! 259: return; ! 260: } ! 261: while (--num >= 0) { ! 262: to_word(FORWARD); ! 263: while ((c = linebuf[curchar]) != 0 && isword(c)) ! 264: curchar += 1; ! 265: if (eobp()) ! 266: break; ! 267: } ! 268: this_cmd = 0; /* Semi kludge to stop some unfavorable behavior */ ! 269: } ! 270: ! 271: void ! 272: b_word(num) ! 273: register int num; ! 274: { ! 275: register char c; ! 276: ! 277: if (num < 0) { ! 278: f_word(-num); ! 279: return; ! 280: } ! 281: while (--num >= 0) { ! 282: to_word(BACKWARD); ! 283: while (!bolp() && (c = linebuf[curchar - 1], isword(c))) ! 284: curchar -= 1; ! 285: if (bobp()) ! 286: break; ! 287: } ! 288: this_cmd = 0; ! 289: } ! 290: ! 291: void ! 292: ForWord() ! 293: { ! 294: f_word(arg_value()); ! 295: } ! 296: ! 297: void ! 298: BackWord() ! 299: { ! 300: b_word(arg_value()); ! 301: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.