|
|
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.