Annotation of src/lib/libedit/common.c, Revision 1.41
1.41 ! christos 1: /* $NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $ */
1.2 lukem 2:
1.1 cgd 3: /*-
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Christos Zoulas of Cornell University.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
1.16 agc 18: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
1.11 christos 35: #include "config.h"
1.1 cgd 36: #if !defined(lint) && !defined(SCCSID)
1.2 lukem 37: #if 0
1.1 cgd 38: static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
1.2 lukem 39: #else
1.41 ! christos 40: __RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
1.2 lukem 41: #endif
1.1 cgd 42: #endif /* not lint && not SCCSID */
43:
44: /*
45: * common.c: Common Editor functions
46: */
1.37 christos 47: #include <ctype.h>
48: #include <string.h>
49:
1.1 cgd 50: #include "el.h"
1.35 christos 51: #include "common.h"
52: #include "parse.h"
53: #include "vi.h"
1.1 cgd 54:
1.8 simonb 55: /* ed_end_of_file():
1.1 cgd 56: * Indicate end of file
57: * [^D]
58: */
59: protected el_action_t
60: /*ARGSUSED*/
1.31 christos 61: ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 62: {
63:
64: re_goto_bottom(el);
65: *el->el_line.lastchar = '\0';
1.26 christos 66: return CC_EOF;
1.1 cgd 67: }
68:
69:
1.8 simonb 70: /* ed_insert():
1.1 cgd 71: * Add character to the line
72: * Insert a character [bound to all insert keys]
73: */
74: protected el_action_t
1.31 christos 75: ed_insert(EditLine *el, wint_t c)
1.9 lukem 76: {
1.13 christos 77: int count = el->el_state.argument;
1.1 cgd 78:
1.9 lukem 79: if (c == '\0')
1.26 christos 80: return CC_ERROR;
1.1 cgd 81:
1.9 lukem 82: if (el->el_line.lastchar + el->el_state.argument >=
1.10 jdolecek 83: el->el_line.limit) {
84: /* end of buffer space, try to allocate more */
1.13 christos 85: if (!ch_enlargebufs(el, (size_t) count))
1.10 jdolecek 86: return CC_ERROR; /* error allocating more */
87: }
1.9 lukem 88:
1.13 christos 89: if (count == 1) {
1.12 christos 90: if (el->el_state.inputmode == MODE_INSERT
91: || el->el_line.cursor >= el->el_line.lastchar)
92: c_insert(el, 1);
1.9 lukem 93:
1.30 christos 94: *el->el_line.cursor++ = (Char)c;
1.9 lukem 95: re_fastaddc(el); /* fast refresh for one char. */
96: } else {
1.12 christos 97: if (el->el_state.inputmode != MODE_REPLACE_1)
98: c_insert(el, el->el_state.argument);
1.9 lukem 99:
1.13 christos 100: while (count-- && el->el_line.cursor < el->el_line.lastchar)
1.30 christos 101: *el->el_line.cursor++ = (Char)c;
1.9 lukem 102: re_refresh(el);
103: }
1.1 cgd 104:
1.9 lukem 105: if (el->el_state.inputmode == MODE_REPLACE_1)
1.12 christos 106: return vi_command_mode(el, 0);
1.1 cgd 107:
1.26 christos 108: return CC_NORM;
1.1 cgd 109: }
110:
111:
1.8 simonb 112: /* ed_delete_prev_word():
1.1 cgd 113: * Delete from beginning of current word to cursor
114: * [M-^?] [^W]
115: */
116: protected el_action_t
117: /*ARGSUSED*/
1.31 christos 118: ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 119: {
1.24 christos 120: Char *cp, *p, *kp;
1.9 lukem 121:
122: if (el->el_line.cursor == el->el_line.buffer)
1.26 christos 123: return CC_ERROR;
1.9 lukem 124:
125: cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
126: el->el_state.argument, ce__isword);
127:
128: for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
129: *kp++ = *p;
130: el->el_chared.c_kill.last = kp;
131:
1.22 christos 132: c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
1.9 lukem 133: el->el_line.cursor = cp;
134: if (el->el_line.cursor < el->el_line.buffer)
135: el->el_line.cursor = el->el_line.buffer; /* bounds check */
1.26 christos 136: return CC_REFRESH;
1.1 cgd 137: }
138:
139:
1.8 simonb 140: /* ed_delete_next_char():
1.1 cgd 141: * Delete character under cursor
142: * [^D] [x]
143: */
144: protected el_action_t
145: /*ARGSUSED*/
1.31 christos 146: ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 147: {
1.27 christos 148: #ifdef DEBUG_EDIT
1.9 lukem 149: #define EL el->el_line
1.40 christos 150: (void) fprintf(el->el_errfile,
1.41 ! christos 151: "\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
1.6 christos 152: EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
153: EL.lastchar, EL.limit, EL.limit);
1.1 cgd 154: #endif
1.9 lukem 155: if (el->el_line.cursor == el->el_line.lastchar) {
156: /* if I'm at the end */
157: if (el->el_map.type == MAP_VI) {
158: if (el->el_line.cursor == el->el_line.buffer) {
159: /* if I'm also at the beginning */
1.1 cgd 160: #ifdef KSHVI
1.26 christos 161: return CC_ERROR;
1.1 cgd 162: #else
1.19 christos 163: /* then do an EOF */
1.25 christos 164: terminal_writec(el, c);
1.26 christos 165: return CC_EOF;
1.1 cgd 166: #endif
1.9 lukem 167: } else {
1.1 cgd 168: #ifdef KSHVI
1.9 lukem 169: el->el_line.cursor--;
1.1 cgd 170: #else
1.26 christos 171: return CC_ERROR;
1.1 cgd 172: #endif
1.9 lukem 173: }
1.29 christos 174: } else
1.26 christos 175: return CC_ERROR;
1.1 cgd 176: }
1.9 lukem 177: c_delafter(el, el->el_state.argument); /* delete after dot */
1.29 christos 178: if (el->el_map.type == MAP_VI &&
179: el->el_line.cursor >= el->el_line.lastchar &&
1.9 lukem 180: el->el_line.cursor > el->el_line.buffer)
181: /* bounds check */
182: el->el_line.cursor = el->el_line.lastchar - 1;
1.26 christos 183: return CC_REFRESH;
1.1 cgd 184: }
185:
186:
1.8 simonb 187: /* ed_kill_line():
1.1 cgd 188: * Cut to the end of line
189: * [^K] [^K]
190: */
191: protected el_action_t
192: /*ARGSUSED*/
1.31 christos 193: ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 194: {
1.24 christos 195: Char *kp, *cp;
1.9 lukem 196:
197: cp = el->el_line.cursor;
198: kp = el->el_chared.c_kill.buf;
199: while (cp < el->el_line.lastchar)
200: *kp++ = *cp++; /* copy it */
201: el->el_chared.c_kill.last = kp;
202: /* zap! -- delete to end */
203: el->el_line.lastchar = el->el_line.cursor;
1.26 christos 204: return CC_REFRESH;
1.1 cgd 205: }
206:
207:
1.8 simonb 208: /* ed_move_to_end():
1.1 cgd 209: * Move cursor to the end of line
210: * [^E] [^E]
211: */
212: protected el_action_t
213: /*ARGSUSED*/
1.31 christos 214: ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 215: {
1.9 lukem 216:
217: el->el_line.cursor = el->el_line.lastchar;
218: if (el->el_map.type == MAP_VI) {
1.13 christos 219: if (el->el_chared.c_vcmd.action != NOP) {
1.9 lukem 220: cv_delfini(el);
1.26 christos 221: return CC_REFRESH;
1.9 lukem 222: }
1.21 aymeric 223: #ifdef VI_MOVE
224: el->el_line.cursor--;
225: #endif
1.1 cgd 226: }
1.26 christos 227: return CC_CURSOR;
1.1 cgd 228: }
229:
230:
1.8 simonb 231: /* ed_move_to_beg():
1.1 cgd 232: * Move cursor to the beginning of line
233: * [^A] [^A]
234: */
235: protected el_action_t
236: /*ARGSUSED*/
1.31 christos 237: ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 238: {
239:
240: el->el_line.cursor = el->el_line.buffer;
241:
242: if (el->el_map.type == MAP_VI) {
243: /* We want FIRST non space character */
1.41 ! christos 244: while (iswspace(*el->el_line.cursor))
1.9 lukem 245: el->el_line.cursor++;
1.13 christos 246: if (el->el_chared.c_vcmd.action != NOP) {
1.9 lukem 247: cv_delfini(el);
1.26 christos 248: return CC_REFRESH;
1.9 lukem 249: }
1.1 cgd 250: }
1.26 christos 251: return CC_CURSOR;
1.1 cgd 252: }
253:
254:
1.8 simonb 255: /* ed_transpose_chars():
1.1 cgd 256: * Exchange the character to the left of the cursor with the one under it
257: * [^T] [^T]
258: */
259: protected el_action_t
1.31 christos 260: ed_transpose_chars(EditLine *el, wint_t c)
1.9 lukem 261: {
262:
263: if (el->el_line.cursor < el->el_line.lastchar) {
264: if (el->el_line.lastchar <= &el->el_line.buffer[1])
1.26 christos 265: return CC_ERROR;
1.9 lukem 266: else
267: el->el_line.cursor++;
268: }
269: if (el->el_line.cursor > &el->el_line.buffer[1]) {
270: /* must have at least two chars entered */
271: c = el->el_line.cursor[-2];
272: el->el_line.cursor[-2] = el->el_line.cursor[-1];
1.30 christos 273: el->el_line.cursor[-1] = (Char)c;
1.26 christos 274: return CC_REFRESH;
1.9 lukem 275: } else
1.26 christos 276: return CC_ERROR;
1.1 cgd 277: }
278:
279:
1.8 simonb 280: /* ed_next_char():
1.1 cgd 281: * Move to the right one character
282: * [^F] [^F]
283: */
284: protected el_action_t
285: /*ARGSUSED*/
1.31 christos 286: ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 287: {
1.24 christos 288: Char *lim = el->el_line.lastchar;
1.1 cgd 289:
1.13 christos 290: if (el->el_line.cursor >= lim ||
291: (el->el_line.cursor == lim - 1 &&
292: el->el_map.type == MAP_VI &&
293: el->el_chared.c_vcmd.action == NOP))
1.26 christos 294: return CC_ERROR;
1.1 cgd 295:
1.9 lukem 296: el->el_line.cursor += el->el_state.argument;
1.13 christos 297: if (el->el_line.cursor > lim)
298: el->el_line.cursor = lim;
1.1 cgd 299:
1.9 lukem 300: if (el->el_map.type == MAP_VI)
1.13 christos 301: if (el->el_chared.c_vcmd.action != NOP) {
1.9 lukem 302: cv_delfini(el);
1.26 christos 303: return CC_REFRESH;
1.9 lukem 304: }
1.26 christos 305: return CC_CURSOR;
1.1 cgd 306: }
307:
308:
1.8 simonb 309: /* ed_prev_word():
1.1 cgd 310: * Move to the beginning of the current word
311: * [M-b] [b]
312: */
313: protected el_action_t
314: /*ARGSUSED*/
1.31 christos 315: ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 316: {
317:
1.9 lukem 318: if (el->el_line.cursor == el->el_line.buffer)
1.26 christos 319: return CC_ERROR;
1.1 cgd 320:
1.9 lukem 321: el->el_line.cursor = c__prev_word(el->el_line.cursor,
322: el->el_line.buffer,
323: el->el_state.argument,
324: ce__isword);
1.1 cgd 325:
1.9 lukem 326: if (el->el_map.type == MAP_VI)
1.13 christos 327: if (el->el_chared.c_vcmd.action != NOP) {
1.9 lukem 328: cv_delfini(el);
1.26 christos 329: return CC_REFRESH;
1.9 lukem 330: }
1.26 christos 331: return CC_CURSOR;
1.1 cgd 332: }
333:
334:
1.8 simonb 335: /* ed_prev_char():
1.1 cgd 336: * Move to the left one character
337: * [^B] [^B]
338: */
339: protected el_action_t
340: /*ARGSUSED*/
1.31 christos 341: ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 342: {
343:
1.9 lukem 344: if (el->el_line.cursor > el->el_line.buffer) {
345: el->el_line.cursor -= el->el_state.argument;
346: if (el->el_line.cursor < el->el_line.buffer)
347: el->el_line.cursor = el->el_line.buffer;
348:
349: if (el->el_map.type == MAP_VI)
1.13 christos 350: if (el->el_chared.c_vcmd.action != NOP) {
1.9 lukem 351: cv_delfini(el);
1.26 christos 352: return CC_REFRESH;
1.9 lukem 353: }
1.26 christos 354: return CC_CURSOR;
1.9 lukem 355: } else
1.26 christos 356: return CC_ERROR;
1.1 cgd 357: }
358:
359:
1.8 simonb 360: /* ed_quoted_insert():
1.1 cgd 361: * Add the next character typed verbatim
362: * [^V] [^V]
363: */
364: protected el_action_t
1.31 christos 365: ed_quoted_insert(EditLine *el, wint_t c)
1.9 lukem 366: {
367: int num;
368:
369: tty_quotemode(el);
1.39 christos 370: num = el_wgetc(el, &c);
1.9 lukem 371: tty_noquotemode(el);
372: if (num == 1)
1.26 christos 373: return ed_insert(el, c);
1.9 lukem 374: else
1.26 christos 375: return ed_end_of_file(el, 0);
1.1 cgd 376: }
377:
378:
1.8 simonb 379: /* ed_digit():
1.1 cgd 380: * Adds to argument or enters a digit
381: */
382: protected el_action_t
1.31 christos 383: ed_digit(EditLine *el, wint_t c)
1.9 lukem 384: {
385:
1.41 ! christos 386: if (!iswdigit(c))
1.26 christos 387: return CC_ERROR;
1.9 lukem 388:
389: if (el->el_state.doingarg) {
390: /* if doing an arg, add this in... */
391: if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
392: el->el_state.argument = c - '0';
393: else {
394: if (el->el_state.argument > 1000000)
1.26 christos 395: return CC_ERROR;
1.9 lukem 396: el->el_state.argument =
397: (el->el_state.argument * 10) + (c - '0');
398: }
1.26 christos 399: return CC_ARGHACK;
1.12 christos 400: }
1.9 lukem 401:
1.12 christos 402: return ed_insert(el, c);
1.1 cgd 403: }
404:
405:
1.8 simonb 406: /* ed_argument_digit():
1.1 cgd 407: * Digit that starts argument
408: * For ESC-n
409: */
410: protected el_action_t
1.31 christos 411: ed_argument_digit(EditLine *el, wint_t c)
1.9 lukem 412: {
413:
1.41 ! christos 414: if (!iswdigit(c))
1.26 christos 415: return CC_ERROR;
1.9 lukem 416:
417: if (el->el_state.doingarg) {
418: if (el->el_state.argument > 1000000)
1.26 christos 419: return CC_ERROR;
1.9 lukem 420: el->el_state.argument = (el->el_state.argument * 10) +
421: (c - '0');
422: } else { /* else starting an argument */
423: el->el_state.argument = c - '0';
424: el->el_state.doingarg = 1;
425: }
1.26 christos 426: return CC_ARGHACK;
1.1 cgd 427: }
428:
429:
1.8 simonb 430: /* ed_unassigned():
1.1 cgd 431: * Indicates unbound character
432: * Bound to keys that are not assigned
433: */
434: protected el_action_t
435: /*ARGSUSED*/
1.28 christos 436: ed_unassigned(EditLine *el __attribute__((__unused__)),
1.31 christos 437: wint_t c __attribute__((__unused__)))
1.9 lukem 438: {
439:
1.26 christos 440: return CC_ERROR;
1.1 cgd 441: }
442:
443:
444: /**
445: ** TTY key handling.
446: **/
447:
1.8 simonb 448: /* ed_tty_sigint():
1.1 cgd 449: * Tty interrupt character
450: * [^C]
451: */
452: protected el_action_t
453: /*ARGSUSED*/
1.38 christos 454: ed_tty_sigint(EditLine *el __attribute__((__unused__)),
1.31 christos 455: wint_t c __attribute__((__unused__)))
1.8 simonb 456: {
1.9 lukem 457:
1.26 christos 458: return CC_NORM;
1.1 cgd 459: }
460:
461:
1.8 simonb 462: /* ed_tty_dsusp():
1.1 cgd 463: * Tty delayed suspend character
464: * [^Y]
465: */
466: protected el_action_t
467: /*ARGSUSED*/
1.38 christos 468: ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
1.31 christos 469: wint_t c __attribute__((__unused__)))
1.1 cgd 470: {
1.9 lukem 471:
1.26 christos 472: return CC_NORM;
1.1 cgd 473: }
474:
475:
1.8 simonb 476: /* ed_tty_flush_output():
1.1 cgd 477: * Tty flush output characters
478: * [^O]
479: */
480: protected el_action_t
481: /*ARGSUSED*/
1.38 christos 482: ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
1.31 christos 483: wint_t c __attribute__((__unused__)))
1.1 cgd 484: {
1.9 lukem 485:
1.26 christos 486: return CC_NORM;
1.1 cgd 487: }
488:
489:
1.8 simonb 490: /* ed_tty_sigquit():
1.1 cgd 491: * Tty quit character
492: * [^\]
493: */
494: protected el_action_t
495: /*ARGSUSED*/
1.38 christos 496: ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
1.31 christos 497: wint_t c __attribute__((__unused__)))
1.1 cgd 498: {
1.9 lukem 499:
1.26 christos 500: return CC_NORM;
1.1 cgd 501: }
502:
503:
1.8 simonb 504: /* ed_tty_sigtstp():
1.1 cgd 505: * Tty suspend character
506: * [^Z]
507: */
508: protected el_action_t
509: /*ARGSUSED*/
1.38 christos 510: ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
1.31 christos 511: wint_t c __attribute__((__unused__)))
1.1 cgd 512: {
1.9 lukem 513:
1.26 christos 514: return CC_NORM;
1.1 cgd 515: }
516:
517:
1.8 simonb 518: /* ed_tty_stop_output():
1.1 cgd 519: * Tty disallow output characters
520: * [^S]
521: */
522: protected el_action_t
523: /*ARGSUSED*/
1.38 christos 524: ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
1.31 christos 525: wint_t c __attribute__((__unused__)))
1.1 cgd 526: {
1.9 lukem 527:
1.26 christos 528: return CC_NORM;
1.1 cgd 529: }
530:
531:
1.8 simonb 532: /* ed_tty_start_output():
1.1 cgd 533: * Tty allow output characters
534: * [^Q]
535: */
536: protected el_action_t
537: /*ARGSUSED*/
1.38 christos 538: ed_tty_start_output(EditLine *el __attribute__((__unused__)),
1.31 christos 539: wint_t c __attribute__((__unused__)))
1.1 cgd 540: {
1.9 lukem 541:
1.26 christos 542: return CC_NORM;
1.1 cgd 543: }
544:
545:
1.8 simonb 546: /* ed_newline():
1.1 cgd 547: * Execute command
548: * [^J]
549: */
550: protected el_action_t
551: /*ARGSUSED*/
1.31 christos 552: ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 553: {
554:
555: re_goto_bottom(el);
556: *el->el_line.lastchar++ = '\n';
557: *el->el_line.lastchar = '\0';
1.26 christos 558: return CC_NEWLINE;
1.1 cgd 559: }
560:
561:
1.8 simonb 562: /* ed_delete_prev_char():
1.1 cgd 563: * Delete the character to the left of the cursor
564: * [^?]
565: */
566: protected el_action_t
567: /*ARGSUSED*/
1.31 christos 568: ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 569: {
570:
571: if (el->el_line.cursor <= el->el_line.buffer)
1.26 christos 572: return CC_ERROR;
1.9 lukem 573:
574: c_delbefore(el, el->el_state.argument);
575: el->el_line.cursor -= el->el_state.argument;
576: if (el->el_line.cursor < el->el_line.buffer)
577: el->el_line.cursor = el->el_line.buffer;
1.26 christos 578: return CC_REFRESH;
1.1 cgd 579: }
580:
581:
1.8 simonb 582: /* ed_clear_screen():
1.1 cgd 583: * Clear screen leaving current line at the top
584: * [^L]
585: */
586: protected el_action_t
587: /*ARGSUSED*/
1.31 christos 588: ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 589: {
590:
1.25 christos 591: terminal_clear_screen(el); /* clear the whole real screen */
1.9 lukem 592: re_clear_display(el); /* reset everything */
1.26 christos 593: return CC_REFRESH;
1.1 cgd 594: }
595:
596:
1.8 simonb 597: /* ed_redisplay():
1.1 cgd 598: * Redisplay everything
599: * ^R
600: */
601: protected el_action_t
602: /*ARGSUSED*/
1.38 christos 603: ed_redisplay(EditLine *el __attribute__((__unused__)),
1.31 christos 604: wint_t c __attribute__((__unused__)))
1.1 cgd 605: {
1.9 lukem 606:
1.26 christos 607: return CC_REDISPLAY;
1.1 cgd 608: }
609:
610:
1.8 simonb 611: /* ed_start_over():
1.1 cgd 612: * Erase current line and start from scratch
613: * [^G]
614: */
615: protected el_action_t
616: /*ARGSUSED*/
1.31 christos 617: ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 618: {
1.9 lukem 619:
1.17 christos 620: ch_reset(el, 0);
1.26 christos 621: return CC_REFRESH;
1.1 cgd 622: }
623:
624:
1.8 simonb 625: /* ed_sequence_lead_in():
1.1 cgd 626: * First character in a bound sequence
627: * Placeholder for external keys
628: */
629: protected el_action_t
630: /*ARGSUSED*/
1.38 christos 631: ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
1.31 christos 632: wint_t c __attribute__((__unused__)))
1.1 cgd 633: {
1.9 lukem 634:
1.26 christos 635: return CC_NORM;
1.1 cgd 636: }
637:
638:
1.8 simonb 639: /* ed_prev_history():
1.1 cgd 640: * Move to the previous history line
641: * [^P] [k]
642: */
643: protected el_action_t
644: /*ARGSUSED*/
1.31 christos 645: ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 646: {
647: char beep = 0;
1.13 christos 648: int sv_event = el->el_history.eventno;
1.9 lukem 649:
1.12 christos 650: el->el_chared.c_undo.len = -1;
1.9 lukem 651: *el->el_line.lastchar = '\0'; /* just in case */
652:
653: if (el->el_history.eventno == 0) { /* save the current buffer
654: * away */
1.24 christos 655: (void) Strncpy(el->el_history.buf, el->el_line.buffer,
1.9 lukem 656: EL_BUFSIZ);
657: el->el_history.last = el->el_history.buf +
658: (el->el_line.lastchar - el->el_line.buffer);
659: }
660: el->el_history.eventno += el->el_state.argument;
661:
662: if (hist_get(el) == CC_ERROR) {
1.13 christos 663: if (el->el_map.type == MAP_VI) {
664: el->el_history.eventno = sv_event;
665: }
1.9 lukem 666: beep = 1;
667: /* el->el_history.eventno was fixed by first call */
668: (void) hist_get(el);
669: }
670: if (beep)
1.13 christos 671: return CC_REFRESH_BEEP;
672: return CC_REFRESH;
1.1 cgd 673: }
674:
675:
1.8 simonb 676: /* ed_next_history():
1.1 cgd 677: * Move to the next history line
678: * [^N] [j]
679: */
680: protected el_action_t
681: /*ARGSUSED*/
1.31 christos 682: ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 683: {
1.13 christos 684: el_action_t beep = CC_REFRESH, rval;
1.1 cgd 685:
1.12 christos 686: el->el_chared.c_undo.len = -1;
1.9 lukem 687: *el->el_line.lastchar = '\0'; /* just in case */
1.1 cgd 688:
1.9 lukem 689: el->el_history.eventno -= el->el_state.argument;
1.1 cgd 690:
1.9 lukem 691: if (el->el_history.eventno < 0) {
692: el->el_history.eventno = 0;
1.13 christos 693: beep = CC_REFRESH_BEEP;
1.9 lukem 694: }
1.13 christos 695: rval = hist_get(el);
696: if (rval == CC_REFRESH)
697: return beep;
698: return rval;
699:
1.1 cgd 700: }
701:
702:
1.8 simonb 703: /* ed_search_prev_history():
1.1 cgd 704: * Search previous in history for a line matching the current
705: * next search history [M-P] [K]
706: */
707: protected el_action_t
708: /*ARGSUSED*/
1.31 christos 709: ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 710: {
1.24 christos 711: const Char *hp;
1.9 lukem 712: int h;
1.36 christos 713: int found = 0;
1.9 lukem 714:
715: el->el_chared.c_vcmd.action = NOP;
1.12 christos 716: el->el_chared.c_undo.len = -1;
1.9 lukem 717: *el->el_line.lastchar = '\0'; /* just in case */
718: if (el->el_history.eventno < 0) {
1.1 cgd 719: #ifdef DEBUG_EDIT
1.9 lukem 720: (void) fprintf(el->el_errfile,
721: "e_prev_search_hist(): eventno < 0;\n");
1.1 cgd 722: #endif
1.9 lukem 723: el->el_history.eventno = 0;
1.26 christos 724: return CC_ERROR;
1.9 lukem 725: }
726: if (el->el_history.eventno == 0) {
1.24 christos 727: (void) Strncpy(el->el_history.buf, el->el_line.buffer,
1.9 lukem 728: EL_BUFSIZ);
729: el->el_history.last = el->el_history.buf +
730: (el->el_line.lastchar - el->el_line.buffer);
731: }
732: if (el->el_history.ref == NULL)
1.26 christos 733: return CC_ERROR;
1.1 cgd 734:
1.9 lukem 735: hp = HIST_FIRST(el);
736: if (hp == NULL)
1.26 christos 737: return CC_ERROR;
1.1 cgd 738:
1.9 lukem 739: c_setpat(el); /* Set search pattern !! */
1.1 cgd 740:
1.9 lukem 741: for (h = 1; h <= el->el_history.eventno; h++)
742: hp = HIST_NEXT(el);
1.1 cgd 743:
1.9 lukem 744: while (hp != NULL) {
1.1 cgd 745: #ifdef SDEBUG
1.9 lukem 746: (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
1.1 cgd 747: #endif
1.24 christos 748: if ((Strncmp(hp, el->el_line.buffer, (size_t)
1.9 lukem 749: (el->el_line.lastchar - el->el_line.buffer)) ||
750: hp[el->el_line.lastchar - el->el_line.buffer]) &&
751: c_hmatch(el, hp)) {
1.36 christos 752: found = 1;
1.9 lukem 753: break;
754: }
755: h++;
756: hp = HIST_NEXT(el);
757: }
1.1 cgd 758:
1.9 lukem 759: if (!found) {
1.1 cgd 760: #ifdef SDEBUG
1.9 lukem 761: (void) fprintf(el->el_errfile, "not found\n");
1.1 cgd 762: #endif
1.26 christos 763: return CC_ERROR;
1.9 lukem 764: }
765: el->el_history.eventno = h;
1.1 cgd 766:
1.26 christos 767: return hist_get(el);
1.1 cgd 768: }
769:
770:
1.8 simonb 771: /* ed_search_next_history():
1.1 cgd 772: * Search next in history for a line matching the current
773: * [M-N] [J]
774: */
775: protected el_action_t
776: /*ARGSUSED*/
1.31 christos 777: ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.1 cgd 778: {
1.24 christos 779: const Char *hp;
1.9 lukem 780: int h;
1.36 christos 781: int found = 0;
1.1 cgd 782:
1.9 lukem 783: el->el_chared.c_vcmd.action = NOP;
1.12 christos 784: el->el_chared.c_undo.len = -1;
1.9 lukem 785: *el->el_line.lastchar = '\0'; /* just in case */
1.1 cgd 786:
1.9 lukem 787: if (el->el_history.eventno == 0)
1.26 christos 788: return CC_ERROR;
1.1 cgd 789:
1.9 lukem 790: if (el->el_history.ref == NULL)
1.26 christos 791: return CC_ERROR;
1.1 cgd 792:
1.9 lukem 793: hp = HIST_FIRST(el);
794: if (hp == NULL)
1.26 christos 795: return CC_ERROR;
1.1 cgd 796:
1.9 lukem 797: c_setpat(el); /* Set search pattern !! */
1.1 cgd 798:
1.9 lukem 799: for (h = 1; h < el->el_history.eventno && hp; h++) {
1.1 cgd 800: #ifdef SDEBUG
1.9 lukem 801: (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
1.1 cgd 802: #endif
1.24 christos 803: if ((Strncmp(hp, el->el_line.buffer, (size_t)
1.9 lukem 804: (el->el_line.lastchar - el->el_line.buffer)) ||
805: hp[el->el_line.lastchar - el->el_line.buffer]) &&
806: c_hmatch(el, hp))
807: found = h;
808: hp = HIST_NEXT(el);
809: }
1.1 cgd 810:
1.9 lukem 811: if (!found) { /* is it the current history number? */
812: if (!c_hmatch(el, el->el_history.buf)) {
1.1 cgd 813: #ifdef SDEBUG
1.9 lukem 814: (void) fprintf(el->el_errfile, "not found\n");
1.1 cgd 815: #endif
1.26 christos 816: return CC_ERROR;
1.9 lukem 817: }
1.1 cgd 818: }
1.9 lukem 819: el->el_history.eventno = found;
1.1 cgd 820:
1.26 christos 821: return hist_get(el);
1.1 cgd 822: }
823:
824:
825: /* ed_prev_line():
826: * Move up one line
827: * Could be [k] [^p]
828: */
829: protected el_action_t
830: /*ARGSUSED*/
1.31 christos 831: ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 832: {
1.24 christos 833: Char *ptr;
1.9 lukem 834: int nchars = c_hpos(el);
1.8 simonb 835:
1.9 lukem 836: /*
837: * Move to the line requested
838: */
839: if (*(ptr = el->el_line.cursor) == '\n')
840: ptr--;
841:
842: for (; ptr >= el->el_line.buffer; ptr--)
843: if (*ptr == '\n' && --el->el_state.argument <= 0)
844: break;
845:
846: if (el->el_state.argument > 0)
1.26 christos 847: return CC_ERROR;
1.9 lukem 848:
849: /*
850: * Move to the beginning of the line
851: */
852: for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
853: continue;
854:
855: /*
856: * Move to the character requested
857: */
858: for (ptr++;
859: nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
860: ptr++)
861: continue;
862:
863: el->el_line.cursor = ptr;
1.26 christos 864: return CC_CURSOR;
1.1 cgd 865: }
866:
867:
868: /* ed_next_line():
869: * Move down one line
870: * Could be [j] [^n]
871: */
872: protected el_action_t
873: /*ARGSUSED*/
1.31 christos 874: ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 875: {
1.24 christos 876: Char *ptr;
1.9 lukem 877: int nchars = c_hpos(el);
1.8 simonb 878:
1.9 lukem 879: /*
880: * Move to the line requested
881: */
882: for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
883: if (*ptr == '\n' && --el->el_state.argument <= 0)
884: break;
885:
886: if (el->el_state.argument > 0)
1.26 christos 887: return CC_ERROR;
1.9 lukem 888:
889: /*
890: * Move to the character requested
891: */
892: for (ptr++;
893: nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
894: ptr++)
895: continue;
896:
897: el->el_line.cursor = ptr;
1.26 christos 898: return CC_CURSOR;
1.1 cgd 899: }
900:
901:
1.8 simonb 902: /* ed_command():
1.1 cgd 903: * Editline extended command
904: * [M-X] [:]
905: */
906: protected el_action_t
907: /*ARGSUSED*/
1.31 christos 908: ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
1.9 lukem 909: {
1.24 christos 910: Char tmpbuf[EL_BUFSIZ];
1.9 lukem 911: int tmplen;
912:
1.24 christos 913: tmplen = c_gets(el, tmpbuf, STR("\n: "));
1.25 christos 914: terminal__putc(el, '\n');
1.9 lukem 915:
1.14 christos 916: if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
1.25 christos 917: terminal_beep(el);
1.9 lukem 918:
1.14 christos 919: el->el_map.current = el->el_map.key;
920: re_clear_display(el);
921: return CC_REFRESH;
1.1 cgd 922: }
CVSweb <webmaster@jp.NetBSD.org>