BSD 2 development
[unix-history] / .ref-BSD-1 / ex-1.1 / ex_voperate.c
CommitLineData
5e6208eb
BJ
1#include "ex.h"
2#ifdef VISUAL
3#include "ex_tty.h"
4#include "ex_vis.h"
5/*
6 * Ex - a text editor
7 * Bill Joy UCB September 1977
8 */
9
10#define blank() white(wcursor[0])
11
12int beep(), vmove(), vdelete(), vchange(), vyankit(), vgrabit();
13
14operate(c, cnt)
15 register int c, cnt;
16{
17 register int i;
18 int (*moveop)(), (*deleteop)(), listchar();
19 register int (*op)();
20 extern int (*Putchar)();
21 char subop;
22 static char lastFKND, lastFCHR;
23
24 moveop = vmove;
25 deleteop = vdelete;
26 wcursor = cursor;
27 dir = 1;
28 subop = 0;
29 switch (c) {
30 case '@':
31 case CTRL(x):
32 wcursor = linebuf;
33 vdelete('@');
34 return;
35 case 'd':
36 moveop = vdelete;
37 deleteop = beep;
38 break;
39 case 's':
40 ungetkey(' ');
41 subop++;
42 case 'c':
43 if (c == 'c' && workcmd[0] == 'C')
44 subop++;
45 moveop = vchange;
46 deleteop = beep;
47 break;
48 case 'y':
49 moveop = vyankit;
50 deleteop = beep;
51 break;
52 case 'g':
53 moveop = vgrabit;
54 deleteop = beep;
55 break;
56 case 'r':
57 if (cnt > strlen(cursor))
58 goto errlab;
59 if (*cursor == '\t' || Putchar == &listchar)
60 vgotoCL(column(cursor - 1));
61 c = getesc();
62 if (c == 0) {
63 vfixcurs();
64 return;
65 }
66 ungetkey(c);
67 strcpy(vutmp, linebuf);
68 vundkind = VCHNG;
69 wcursor = cursor + cnt;
70 setLAST();
71 strcpy(cursor, wcursor);
72 vappend('r', cnt, 0);
73 *lastcp++ = c;
74 setLAST();
75 return;
76 default:
77 goto nocount;
78 }
79 if (digit(peekkey()) && peekkey() != '0') {
80 cnt =* vgetcnt();
81 Xcnt = cnt;
82 if (cnt < 0) {
83 beep();
84 return;
85 }
86 }
87 c = getesc();
88 if (c == 0)
89 return;
90 if (!subop)
91 *lastcp++ = c;
92 if (NDSPACE && NDSPACE[0] == c && NDSPACE[1] == 0)
93 goto space;
94nocount:
95 switch (c) {
96 case CTRL(w):
97 c = 'B';
98 case 'b':
99 case 'B':
100 dir = -1;
101 case 'W':
102 case 'w':
103 wdkind = c & ' ';
104 op = moveop;
105 if (edge())
106 goto errlab;
107 while (cnt > 0 && !edge()) {
108 word(op, cnt);
109 cnt--;
110 }
111 break;
112#ifdef UNIMP
113 case 'E':
114 dir = -1;
115 case 'e':
116 wdkind = 1;
117 op = moveop;
118 if (edge())
119 goto errlab;
120 while (cnt > 1 && !edge()) {
121 word(op, cnt);
122 cnt--;
123 }
124 eend(op, cnt);
125 break;
126#endif
127 case '0':
128 wcursor = linebuf;
129 op = moveop;
130 break;
131 case ';':
132 if (lastFKND == 0) {
133 beep();
134 return;
135 }
136 c = lastFKND;
137 ungetkey(lastFCHR);
138 subop++;
139 goto nocount;
140 case 'F': /* inverted find */
141 case 'T':
142 dir = -1;
143 case 'f': /* find */
144 case 't':
145 i = getesc();
146 if (i == 0)
147 return;
148 if (!subop)
149 *lastcp++ = i;
150 lastFKND = c;
151 lastFCHR = i;
152 while (cnt > 0) {
153 if (find(i) == 0)
154 goto errlab;
155 cnt--;
156 }
157 switch (c) {
158 case 'T':
159 wcursor++;
160 break;
161 case 't':
162 wcursor--;
163 case 'f':
164fixup:
165 if (moveop != vmove)
166 wcursor++;
167 break;
168 }
169 op = moveop;
170 break;
171 case '|':
172 if (Xhadcnt) {
173 if (Pline == &numbline)
174 cnt =+ 8;
175 vmovcol = cnt;
176 }
177 vmoving = 1;
178 wcursor = vfindcol(cnt);
179 op = moveop;
180 break;
181 case '^':
182 wcursor = vskipwh(linebuf);
183 op = moveop;
184 break;
185 case '$':
186 wcursor = strend(linebuf) - 1;
187 goto fixup;
188 case 'h':
189 case CTRL(h):
190 dir = -1;
191 case ' ':
192space:
193 case 'l':
194 op = moveop;
195 if (margin() || op == &vmove && edge())
196 goto errlab;
197moveit:
198 while (cnt > 0 && !margin()) {
199 wcursor =+ dir;
200 cnt--;
201 }
202 if (margin() && op == &vmove || wcursor < linebuf)
203 wcursor =- dir;
204 break;
205 case 'D':
206 cnt = INF;
207 goto deleteit;
208 case 'X': /* inverted delete */
209 case '#': /* "oex" delete */
210 dir = -1;
211deleteit:
212 case 'x': /* delete */
213 if (margin())
214 goto errlab;
215 while (cnt > 0 && !margin()) {
216 wcursor =+ dir;
217 cnt--;
218 }
219 op = deleteop;
220 break;
221 default:
222errlab:
223 beep();
224 return;
225 }
226 (*op)(c);
227}
228
229find(c)
230 char c;
231{
232
233 for(;;) {
234 if (edge())
235 return (0);
236 wcursor =+ dir;
237 if (*wcursor == c)
238 return (1);
239 }
240}
241
242word(op, cnt)
243 register int (*op)();
244 int cnt;
245{
246 register int which;
247 register char *iwc;
248
249 if (dir == 1) {
250 iwc = wcursor;
251 /*
252 * Word going forward.
253 * Determine whether the character under
254 * the cursor is a "word" character.
255 * If it is, skip through such
256 * else through nonesuch.
257 */
258 which = wordch(wcursor);
259 while (!margin() && wordof(which, wcursor))
260 wcursor++;
261 /*
262 * Unless this the last segment of a change
263 * we want to skip blanks.
264 */
265 if (op != vchange || cnt > 1)
266 while (!margin() && blank())
267 wcursor++;
268 else
269 if (wcursor == iwc && *iwc)
270 wcursor++;
271 /*
272 * Can't move off end
273 */
274 if (op == vmove && margin())
275 wcursor--;
276 } else {
277 /*
278 * Word going backwards.
279 * First skip through blanks, then through word
280 * or non-word characters.
281 */
282 wcursor--;
283 while (!margin() && blank())
284 wcursor--;
285 if (!margin()) {
286 which = wordch(wcursor);
287 while (!margin() && wordof(which, wcursor))
288 wcursor--;
289 }
290 if (margin() || !wordof(which, wcursor))
291 wcursor++;
292 }
293}
294
295#ifdef UNIMP
296eend(op, cnt)
297 register int (*op)();
298 int cnt;
299{
300 register int which;
301 register char *iwc;
302
303 if (dir == 1) {
304 if (!margin())
305 wcursor++;
306 while (!margin() && blank())
307 wcursor++;
308 which = wordch(wcursor);
309 while (!margin() && wordof(which, wcursor))
310 wcursor++;
311 if (cnt == 1 && op != &vchange && op != &vdelete)
312 wcursor--;
313 } else {
314 if (!blank()) {
315 which = wordch(wcursor);
316 while (!margin() && wordof(which, wcursor))
317 wcursor--;
318 }
319 while (!margin() && blank())
320 wcursor--;
321 if (margin())
322 wcursor++;
323 }
324}
325#endif
326
327wordof(which, wcursor)
328 char which, *wcursor;
329{
330
331 if (white(*wcursor))
332 return (0);
333 return (!wdkind || wordch(wcursor) == which);
334}
335
336wordch(wcursor)
337 char *wcursor;
338{
339 register int c;
340
341 c = wcursor[0];
342 return (letter(c) || digit(c) || c == '_');
343}
344
345edge()
346{
347
348 if (linebuf[0] == 0)
349 return (1);
350 if (dir == 1)
351 return (wcursor[1] == 0);
352 else
353 return (wcursor == linebuf);
354}
355
356margin()
357{
358
359 return (wcursor < linebuf || wcursor[0] == 0);
360}
361
362beep()
363{
364 vputc('\07');
365}
366#endif