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