|
|
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: #include <signal.h>
11: #ifdef ANSICODES
12: # include "termcap.h"
13: #endif
14:
15: void
16: prCTIME()
17: {
18: s_mess(": %f %s", get_time((time_t *) 0, (char *) 0, 0, -1));
19: }
20:
21: void
22: ChrToOct()
23: {
24: int c,
25: slow;
26:
27: c = waitchar(&slow);
28: if (slow)
29: message(key_strokes);
30: ins_str(sprint("\\%03o", c), NO);
31: }
32:
33: void
34: StrLength()
35: {
36: static char inquotes[] = "Where are the quotes?";
37: char *first = StrIndex(-1, linebuf, curchar, '"'),
38: *last = StrIndex(1, linebuf, curchar + 1, '"'),
39: c;
40: int numchars = 0;
41:
42: if (first == 0 || last == 0)
43: complain(inquotes);
44: first += 1;
45: while (first < last) {
46: c = *first++;
47: if (c == '\\') {
48: int num;
49:
50: if (!isdigit(*first))
51: first += 1;
52: else {
53: num = 3;
54: while (num-- && isdigit(*first++) && first < last)
55: ;
56: }
57: }
58: numchars += 1;
59: }
60: s_mess("%d characters", numchars);
61: }
62:
63: /* Transpos cur_char with cur_char - 1 */
64:
65: void
66: TransChar()
67: {
68: char before;
69:
70: if (curchar == 0 || (eolp() && curchar == 1))
71: complain((char *) 0); /* BEEP */
72: if (eolp())
73: b_char(1);
74: before = linebuf[curchar - 1];
75: del_char(BACKWARD, 1);
76: f_char(1);
77: insert_c(before, 1);
78: }
79:
80: /* Switch current line with previous one */
81:
82: void
83: TransLines()
84: {
85: disk_line old_prev;
86:
87: if (firstp(curline))
88: return;
89: lsave();
90: old_prev = curline->l_prev->l_dline;
91: curline->l_prev->l_dline = curline->l_dline;
92: curline->l_dline = old_prev;
93: getDOT();
94: if (!lastp(curline))
95: line_move(FORWARD, 1, NO);
96: modify();
97: }
98:
99: void
100: Leave()
101: {
102: longjmp(mainjmp, QUIT);
103: }
104:
105: /* If argument is specified, kill that many lines down. Otherwise,
106: if we "appear" to be at the end of a line, i.e. everything to the
107: right of the cursor is white space, we delete the line separator
108: as if we were at the end of the line. */
109:
110: void
111: KillEOL()
112: {
113: Line *line2;
114: int char2;
115: int num = arg_value();
116:
117: if (is_an_arg()) {
118: if (num == 0) { /* Kill to beginning of line */
119: line2 = curline;
120: char2 = 0;
121: } else {
122: line2 = next_line(curline, num);
123: if ((LineDist(curline, line2) < num) || (line2 == curline))
124: char2 = length(line2);
125: else
126: char2 = 0;
127: }
128: } else if (blnkp(&linebuf[curchar])) {
129: line2 = next_line(curline, 1);
130: if (line2 == curline)
131: char2 = length(curline);
132: else
133: char2 = 0;
134: } else {
135: line2 = curline;
136: char2 = length(curline);
137: }
138: reg_kill(line2, char2, 0);
139: }
140:
141: /* kill to beginning of sentence */
142:
143: void
144: KillBos()
145: {
146: negate_arg_value();
147: KillEos();
148: }
149:
150: /* Kill to end of sentence */
151:
152: void
153: KillEos()
154: {
155: Line *line1;
156: int char1;
157:
158: line1 = curline;
159: char1 = curchar;
160: Eos();
161: reg_kill(line1, char1, 1);
162: }
163:
164: void
165: KillExpr()
166: {
167: Line *line1;
168: int char1;
169:
170: line1 = curline;
171: char1 = curchar;
172: FSexpr();
173: reg_kill(line1, char1, 1);
174: }
175:
176: void
177: EscPrefix()
178: {
179: HandlePref(pref1map);
180: }
181:
182: void
183: CtlxPrefix()
184: {
185: HandlePref(pref2map);
186: }
187:
188: void
189: MiscPrefix()
190: {
191: HandlePref(miscmap);
192: }
193:
194: void
195: HandlePref(map)
196: data_obj **map;
197: {
198: register data_obj *cp;
199: register int c;
200: int slow;
201:
202: c = waitchar(&slow);
203: if (c == AbortChar) {
204: message("[Aborted]");
205: rbell();
206: return;
207: }
208:
209: if (slow)
210: message(key_strokes);
211:
212: cp = map[c];
213: if (cp == 0) {
214: s_mess("[%sunbound]", key_strokes);
215: rbell();
216: } else
217: ExecCmd(cp);
218: }
219:
220: void
221: Yank()
222: {
223: Line *line,
224: *lp;
225: Bufpos *dot;
226:
227: if (killbuf[killptr] == 0)
228: complain("[Nothing to yank!]");
229: lsave();
230: this_cmd = YANKCMD;
231: line = killbuf[killptr];
232: lp = lastline(line);
233: dot = DoYank(line, 0, lp, length(lp), curline, curchar, curbuf);
234: set_mark();
235: SetDot(dot);
236: }
237:
238: void
239: WtModBuf()
240: {
241: if (!ModBufs(NO))
242: message("[No buffers need saving]");
243: else
244: put_bufs(is_an_arg());
245: }
246:
247: void
248: put_bufs(askp)
249: {
250: register Buffer *oldb = curbuf,
251: *b;
252:
253: for (b = world; b != 0; b = b->b_next) {
254: if (!IsModified(b) || b->b_type != B_FILE)
255: continue;
256: SetBuf(b); /* Make this current Buffer */
257: if (curbuf->b_fname == 0) {
258: char *newname;
259:
260: newname = ask(NullStr, "Buffer \"%s\" needs a file name; type Return to skip: ", b->b_name);
261: if (*newname == 0)
262: continue;
263: setfname(b, newname);
264: }
265: if (askp && (yes_or_no_p("Write %s? ", curbuf->b_fname) == NO))
266: continue;
267: filemunge(curbuf->b_fname);
268: #if !(defined(MSDOS) || defined(MAC))
269: chk_mtime(curbuf, curbuf->b_fname, "save");
270: #endif
271: file_write(curbuf->b_fname, 0);
272: unmodify();
273: }
274: SetBuf(oldb);
275: }
276:
277: void
278: ToIndent()
279: {
280: register char *cp,
281: c;
282:
283: for (cp = linebuf; c = *cp; cp++)
284: if (c != ' ' && c != '\t')
285: break;
286: curchar = cp - linebuf;
287: }
288:
289: /* GoLine -- go to a line, usually wired to goto-line, ESC g or ESC G.
290: If no argument is specified it asks for a line number. */
291: void
292: GoLine()
293: {
294: Line *newline;
295:
296: #ifndef ANSICODES
297: if (!is_an_arg())
298: set_arg_value(ask_int("Line: ",10));
299: #else /* not ANSICODES */
300: if (!is_an_arg() || arg_value() <= 0) {
301: if (SP) {
302: putpad(SP, 1); /* Ask for cursor position */
303: return;
304: }
305: set_arg_value(ask_int("Line: ", 10));
306: }
307: #endif /* ANSICODES */
308: newline = next_line(curbuf->b_first, arg_value() - 1);
309: PushPntp(newline);
310: SetLine(newline);
311: }
312:
313: #ifdef ANSICODES
314: void
315: MoveToCursor(line, col)
316: {
317: register struct scrimage *sp = &PhysScreen[line];
318:
319: while (sp->s_id == 0)
320: sp = &PhysScreen[--line];
321: if (sp->s_flags & MODELINE)
322: complain((char *) 0);
323: if (curwind != sp->s_window)
324: SetWind(sp->s_window);
325: SetLine(sp->s_lp);
326: curchar = how_far(sp->s_lp, col);
327: }
328:
329: void
330: AnsiCodes()
331: {
332: int c;
333: int num1 = 0;
334: int num2;
335: static char *unsupported = "[Unsupported ANSI code received]";
336:
337: while (isdigit(c = getch()))
338: num1 = (num1 * 10) + (c - '0');
339:
340: switch (c) {
341: case ';':
342: num2 = 0;
343: while (isdigit(c = getch()))
344: num2 = (num2 * 10) + (c - '0');
345: switch (c) {
346: case 'R':
347: MoveToCursor(--num1, --num2);
348: break;
349: case 'H':
350: Eow();
351: Bol();
352: break;
353: default:
354: complain(unsupported);
355: }
356: break;
357: case 'A':
358: PrevLine();
359: break;
360: case 'B':
361: NextLine();
362: break;
363: case 'C':
364: ForChar();
365: break;
366: case 'D':
367: BackChar();
368: break;
369: case 'H':
370: Bow();
371: break;
372: case 'J':
373: if (num1 == 2) {
374: ClAndRedraw();
375: break;
376: }
377: case 'M': /* Enter */
378: PopMark();
379: break;
380: case 'P': /* PF1 */
381: ExecCmd((data_obj *) FindCmd(IncFSearch));
382: break;
383: case 'Q': /* PF2 */
384: ExecCmd((data_obj *) FindCmd(QRepSearch));
385: break;
386: case 'R': /* PF3 */
387: WtModBuf();
388: Leave();
389: break;
390: case 'S': /* PF4 */
391: KillEOL();
392: break;
393: case 'l': /* , */
394: DelNChar();
395: break;
396: case 'm': /* - */
397: DelNWord();
398: break;
399: case 'n': /* . */
400: SetMark();
401: break;
402: case 'p': /* 0 */
403: Bol();
404: NextLine();
405: break;
406: case 'q': /* 1 */
407: ForWord();
408: break;
409: case 'r': /* 2 */
410: ForChar();
411: Eol();
412: break;
413: case 's': /* 3 */
414: Yank();
415: break;
416: case 't': /* 4 */
417: ExecCmd((data_obj *) FindCmd(ForSearch));
418: break;
419: case 'u': /* 5 */
420: ExecCmd((data_obj *) FindCmd(RevSearch));
421: break;
422: case 'v': /* 6 */
423: DelReg();
424: break;
425: case 'w': /* 7 */
426: PrevPage();
427: break;
428: case 'x': /* 8 */
429: NextPage();
430: break;
431: case 'y': /* 9 */
432: DelPWord();
433: break;
434: case 'z': /* Sun function keys send <esc>[Nz */
435: switch(num1) {
436: case 193: /* L2 */
437: SetMark();
438: break;
439: case 194: /* L3 */
440: PopMark();
441: break;
442: case 195: /* L4 */
443: DelReg();
444: break;
445: case 208: /* R1 */
446: ExecCmd((data_obj *) FindCmd(QRepSearch));
447: break;
448: case 209: /* R2 */
449: ExecCmd((data_obj *) FindCmd(IncFSearch));
450: break;
451: case 210: /* R3 */
452: WtModBuf();
453: break;
454: case 211: /* R4 */
455: ExecCmd((data_obj *) FindCmd(RepSearch));
456: break;
457: case 212: /* R5 */
458: ExecCmd((data_obj *) FindCmd(IncRSearch));
459: break;
460: case 213: /* R6 */
461: Leave();
462: break;
463: case 214: /* R7 */
464: BackWord();
465: break;
466: case 215: /* R8 == UpArrow */
467: break;
468: case 216: /* R9 */
469: ForWord();
470: break;
471: case 217: /* R10 == LeftArrow */
472: break;
473: case 218: /* R11 */
474: NextWindow();
475: break;
476: case 219: /* R12 == RightArrow */
477: break;
478: case 220: /* R13 */
479: case 221: /* R14 == DownArrow */
480: break;
481: case 222: /* R15 */
482: case 225: /* F2 */
483: case 226: /* F3 */
484: case 227: /* F4 */
485: break;
486: case 228: /* F5 */
487: break;
488: case 229: /* F6 */
489: break;
490: case 230: /* F7 */
491: break;
492: case 231: /* F8 */
493: break;
494: case 232: /* F9 */
495: break;
496: default:
497: num1 = -1; /* Hack flags failure */
498: break;
499: }
500: if (num1 >= 0)
501: break;
502: default:
503: complain(unsupported);
504: }
505: }
506: #endif /* ANSICODES */
507:
508: void
509: NotModified()
510: {
511: unmodify();
512: }
513:
514: void
515: SetLMargin()
516: {
517: LMargin = calc_pos(linebuf, curchar);
518: }
519:
520: void
521: SetRMargin()
522: {
523: RMargin = calc_pos(linebuf, curchar);
524: }
525:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.