154212Sbostic /*-
2*61275Sbostic * Copyright (c) 1992, 1993
3*61275Sbostic * The Regents of the University of California. All rights reserved.
454212Sbostic *
554212Sbostic * This code is derived from software contributed to Berkeley by
654212Sbostic * Christos Zoulas of Cornell University.
754212Sbostic *
854212Sbostic * %sccs.include.redist.c%
954212Sbostic */
1054212Sbostic
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61275Sbostic static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454212Sbostic
1554212Sbostic /*
1654624Schristos * common.c: Common Editor functions
1754212Sbostic */
1854212Sbostic #include "sys.h"
1954212Sbostic #include "el.h"
2054212Sbostic
2154212Sbostic /* ed_end_of_file():
2254212Sbostic * Indicate end of file
2354212Sbostic * [^D]
2454212Sbostic */
2554212Sbostic protected el_action_t
2654212Sbostic /*ARGSUSED*/
ed_end_of_file(el,c)2754212Sbostic ed_end_of_file(el, c)
2854212Sbostic EditLine *el;
2954212Sbostic int c;
3054212Sbostic {
3154212Sbostic re_goto_bottom(el);
3254212Sbostic *el->el_line.lastchar = '\0';
3354212Sbostic return CC_EOF;
3454212Sbostic }
3554212Sbostic
3654212Sbostic
3754212Sbostic /* ed_insert():
3854212Sbostic * Add character to the line
3954212Sbostic * Insert a character [bound to all insert keys]
4054212Sbostic */
4154212Sbostic protected el_action_t
ed_insert(el,c)4254212Sbostic ed_insert(el, c)
4354212Sbostic EditLine *el;
4454212Sbostic int c;
4554212Sbostic {
4654212Sbostic int i;
4754212Sbostic
4854212Sbostic if (c == '\0')
4954212Sbostic return CC_ERROR;
5054212Sbostic
5154212Sbostic if (el->el_line.lastchar + el->el_state.argument >=
5254212Sbostic el->el_line.limit)
5354212Sbostic return CC_ERROR; /* end of buffer space */
5454212Sbostic
5554212Sbostic if (el->el_state.argument == 1) {
5654212Sbostic if (el->el_state.inputmode != MODE_INSERT) {
5754212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
5854212Sbostic *el->el_line.cursor;
5954212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
6054212Sbostic c_delafter(el, 1);
6154212Sbostic }
6254212Sbostic
6354212Sbostic c_insert(el, 1);
6454212Sbostic
6554212Sbostic *el->el_line.cursor++ = c;
6654212Sbostic el->el_state.doingarg = 0; /* just in case */
6754212Sbostic re_fastaddc(el); /* fast refresh for one char. */
6854212Sbostic }
6954212Sbostic else {
7054212Sbostic if (el->el_state.inputmode != MODE_INSERT) {
7154212Sbostic
7254212Sbostic for(i = 0;i < el->el_state.argument; i++)
7354212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
7454212Sbostic el->el_line.cursor[i];
7554212Sbostic
7654212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
7754212Sbostic c_delafter(el, el->el_state.argument);
7854212Sbostic }
7954212Sbostic
8054212Sbostic c_insert(el, el->el_state.argument);
8154212Sbostic
8254212Sbostic while (el->el_state.argument--)
8354212Sbostic *el->el_line.cursor++ = c;
8454212Sbostic re_refresh(el);
8554212Sbostic }
8654212Sbostic
8754212Sbostic if (el->el_state.inputmode == MODE_REPLACE_1)
8854212Sbostic (void) vi_command_mode(el, 0);
8954212Sbostic
9054212Sbostic return CC_NORM;
9154212Sbostic }
9254212Sbostic
9354212Sbostic
9454212Sbostic /* ed_delete_prev_word():
9554212Sbostic * Delete from beginning of current word to cursor
9654212Sbostic * [M-^?] [^W]
9754212Sbostic */
9854212Sbostic protected el_action_t
9954212Sbostic /*ARGSUSED*/
ed_delete_prev_word(el,c)10054212Sbostic ed_delete_prev_word(el, c)
10154212Sbostic EditLine *el;
10254212Sbostic int c;
10354212Sbostic {
10454212Sbostic char *cp, *p, *kp;
10554212Sbostic
10654212Sbostic if (el->el_line.cursor == el->el_line.buffer)
10754212Sbostic return CC_ERROR;
10854212Sbostic
10954212Sbostic cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
11054212Sbostic el->el_state.argument, ce__isword);
11154212Sbostic
11254212Sbostic for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
11354212Sbostic *kp++ = *p;
11454212Sbostic el->el_chared.c_kill.last = kp;
11554212Sbostic
11654212Sbostic c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
11754212Sbostic el->el_line.cursor = cp;
11854212Sbostic if (el->el_line.cursor < el->el_line.buffer)
11954212Sbostic el->el_line.cursor = el->el_line.buffer; /* bounds check */
12054212Sbostic return CC_REFRESH;
12154212Sbostic }
12254212Sbostic
12354212Sbostic
12454212Sbostic /* ed_delete_next_char():
12554212Sbostic * Delete character under cursor
12654212Sbostic * [^D] [x]
12754212Sbostic */
12854212Sbostic protected el_action_t
12954212Sbostic /*ARGSUSED*/
ed_delete_next_char(el,c)13054212Sbostic ed_delete_next_char(el, c)
13154212Sbostic EditLine *el;
13254212Sbostic int c;
13354212Sbostic {
13454212Sbostic #ifdef notdef /* XXX */
13554212Sbostic #define EL el->el_line
13654212Sbostic fprintf(stderr, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
13754212Sbostic EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, EL.lastchar, EL.limit, EL.limit);
13854212Sbostic #endif
13954212Sbostic if (el->el_line.cursor == el->el_line.lastchar) {/* if I'm at the end */
14054212Sbostic if (el->el_map.type == MAP_VI) {
14154212Sbostic if (el->el_line.cursor == el->el_line.buffer) {
14254212Sbostic /* if I'm also at the beginning */
14354212Sbostic #ifdef KSHVI
14454212Sbostic return CC_ERROR;
14554212Sbostic #else
14654212Sbostic term_overwrite(el, STReof, 4);/* then do a EOF */
14754212Sbostic term__flush();
14854212Sbostic return CC_EOF;
14954212Sbostic #endif
15054212Sbostic }
15154212Sbostic else {
15254212Sbostic #ifdef KSHVI
15354212Sbostic el->el_line.cursor--;
15454212Sbostic #else
15554212Sbostic return CC_ERROR;
15654212Sbostic #endif
15754212Sbostic }
15854212Sbostic }
15954212Sbostic else {
16054212Sbostic if (el->el_line.cursor != el->el_line.buffer)
16154212Sbostic el->el_line.cursor--;
16254212Sbostic else
16354212Sbostic return CC_ERROR;
16454212Sbostic }
16554212Sbostic }
16654212Sbostic c_delafter(el, el->el_state.argument); /* delete after dot */
16754212Sbostic if (el->el_line.cursor >= el->el_line.lastchar && el->el_line.cursor > el->el_line.buffer)
16854212Sbostic el->el_line.cursor = el->el_line.lastchar - 1; /* bounds check */
16954212Sbostic return CC_REFRESH;
17054212Sbostic }
17154212Sbostic
17254212Sbostic
17354212Sbostic /* ed_kill_line():
17454212Sbostic * Cut to the end of line
17554212Sbostic * [^K] [^K]
17654212Sbostic */
17754212Sbostic protected el_action_t
17854212Sbostic /*ARGSUSED*/
ed_kill_line(el,c)17954212Sbostic ed_kill_line(el, c)
18054212Sbostic EditLine *el;
18154212Sbostic int c;
18254212Sbostic {
18354212Sbostic char *kp, *cp;
18454212Sbostic
18554212Sbostic cp = el->el_line.cursor;
18654212Sbostic kp = el->el_chared.c_kill.buf;
18754212Sbostic while (cp < el->el_line.lastchar)
18854212Sbostic *kp++ = *cp++; /* copy it */
18954212Sbostic el->el_chared.c_kill.last = kp;
19054212Sbostic el->el_line.lastchar = el->el_line.cursor; /* zap! -- delete to end */
19154212Sbostic return CC_REFRESH;
19254212Sbostic }
19354212Sbostic
19454212Sbostic
19554212Sbostic /* ed_move_to_end():
19654212Sbostic * Move cursor to the end of line
19754212Sbostic * [^E] [^E]
19854212Sbostic */
19954212Sbostic protected el_action_t
20054212Sbostic /*ARGSUSED*/
ed_move_to_end(el,c)20154212Sbostic ed_move_to_end(el, c)
20254212Sbostic EditLine *el;
20354212Sbostic int c;
20454212Sbostic {
20554212Sbostic el->el_line.cursor = el->el_line.lastchar;
20654212Sbostic if (el->el_map.type == MAP_VI) {
20754212Sbostic #ifdef VI_MOVE
20854212Sbostic el->el_line.cursor--;
20954212Sbostic #endif
21054212Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
21154212Sbostic cv_delfini(el);
21254212Sbostic return CC_REFRESH;
21354212Sbostic }
21454212Sbostic }
21554212Sbostic return CC_CURSOR;
21654212Sbostic }
21754212Sbostic
21854212Sbostic
21954212Sbostic /* ed_move_to_beg():
22054212Sbostic * Move cursor to the beginning of line
22154212Sbostic * [^A] [^A]
22254212Sbostic */
22354212Sbostic protected el_action_t
22454212Sbostic /*ARGSUSED*/
ed_move_to_beg(el,c)22554212Sbostic ed_move_to_beg(el, c)
22654212Sbostic EditLine *el;
22754212Sbostic int c;
22854212Sbostic {
22954212Sbostic el->el_line.cursor = el->el_line.buffer;
23054212Sbostic
23154212Sbostic if (el->el_map.type == MAP_VI) {
23254212Sbostic /* We want FIRST non space character */
23354212Sbostic while (isspace(*el->el_line.cursor))
23454212Sbostic el->el_line.cursor++;
23554212Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
23654212Sbostic cv_delfini(el);
23754212Sbostic return CC_REFRESH;
23854212Sbostic }
23954212Sbostic }
24054212Sbostic
24154212Sbostic return CC_CURSOR;
24254212Sbostic }
24354212Sbostic
24454212Sbostic
24554212Sbostic /* ed_transpose_chars():
24654212Sbostic * Exchange the character to the left of the cursor with the one under it
24754212Sbostic * [^T] [^T]
24854212Sbostic */
24954212Sbostic protected el_action_t
ed_transpose_chars(el,c)25054212Sbostic ed_transpose_chars(el, c)
25154212Sbostic EditLine *el;
25254212Sbostic int c;
25354212Sbostic {
25454212Sbostic if (el->el_line.cursor < el->el_line.lastchar) {
25554212Sbostic if (el->el_line.lastchar <= &el->el_line.buffer[1])
25654212Sbostic return CC_ERROR;
25754212Sbostic else
25854212Sbostic el->el_line.cursor++;
25954212Sbostic }
26054212Sbostic if (el->el_line.cursor > &el->el_line.buffer[1]) {
26154212Sbostic /* must have at least two chars entered */
26254212Sbostic c = el->el_line.cursor[-2];
26354212Sbostic el->el_line.cursor[-2] = el->el_line.cursor[-1];
26454212Sbostic el->el_line.cursor[-1] = c;
26554212Sbostic return CC_REFRESH;
26654212Sbostic }
26754212Sbostic else
26854212Sbostic return CC_ERROR;
26954212Sbostic }
27054212Sbostic
27154212Sbostic
27254212Sbostic /* ed_next_char():
27354212Sbostic * Move to the right one character
27454212Sbostic * [^F] [^F]
27554212Sbostic */
27654212Sbostic protected el_action_t
27754212Sbostic /*ARGSUSED*/
ed_next_char(el,c)27854212Sbostic ed_next_char(el, c)
27954212Sbostic EditLine *el;
28054212Sbostic int c;
28154212Sbostic {
28254212Sbostic if (el->el_line.cursor >= el->el_line.lastchar)
28354212Sbostic return CC_ERROR;
28454212Sbostic
28554212Sbostic el->el_line.cursor += el->el_state.argument;
28654212Sbostic if (el->el_line.cursor > el->el_line.lastchar)
28754212Sbostic el->el_line.cursor = el->el_line.lastchar;
28854212Sbostic
28954212Sbostic if (el->el_map.type == MAP_VI)
29054212Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
29154212Sbostic cv_delfini(el);
29254212Sbostic return CC_REFRESH;
29354212Sbostic }
29454212Sbostic
29554212Sbostic return CC_CURSOR;
29654212Sbostic }
29754212Sbostic
29854212Sbostic
29954212Sbostic /* ed_prev_word():
30054212Sbostic * Move to the beginning of the current word
30154212Sbostic * [M-b] [b]
30254212Sbostic */
30354212Sbostic protected el_action_t
30454212Sbostic /*ARGSUSED*/
ed_prev_word(el,c)30554212Sbostic ed_prev_word(el, c)
30654212Sbostic EditLine *el;
30754212Sbostic int c;
30854212Sbostic {
30954212Sbostic if (el->el_line.cursor == el->el_line.buffer)
31054212Sbostic return CC_ERROR;
31154212Sbostic
31254212Sbostic el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer,
31354212Sbostic el->el_state.argument,
31454212Sbostic ce__isword);
31554212Sbostic
31654212Sbostic if (el->el_map.type == MAP_VI)
31754212Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
31854212Sbostic cv_delfini(el);
31954212Sbostic return CC_REFRESH;
32054212Sbostic }
32154212Sbostic
32254212Sbostic return CC_CURSOR;
32354212Sbostic }
32454212Sbostic
32554212Sbostic
32654212Sbostic /* ed_prev_char():
32754212Sbostic * Move to the left one character
32854212Sbostic * [^B] [^B]
32954212Sbostic */
33054212Sbostic protected el_action_t
33154212Sbostic /*ARGSUSED*/
ed_prev_char(el,c)33254212Sbostic ed_prev_char(el, c)
33354212Sbostic EditLine *el;
33454212Sbostic int c;
33554212Sbostic {
33654212Sbostic if (el->el_line.cursor > el->el_line.buffer) {
33754212Sbostic el->el_line.cursor -= el->el_state.argument;
33854212Sbostic if (el->el_line.cursor < el->el_line.buffer)
33954212Sbostic el->el_line.cursor = el->el_line.buffer;
34054212Sbostic
34154212Sbostic if (el->el_map.type == MAP_VI)
34254212Sbostic if (el->el_chared.c_vcmd.action & DELETE) {
34354212Sbostic cv_delfini(el);
34454212Sbostic return CC_REFRESH;
34554212Sbostic }
34654212Sbostic
34754212Sbostic return CC_CURSOR;
34854212Sbostic }
34954212Sbostic else
35054212Sbostic return CC_ERROR;
35154212Sbostic }
35254212Sbostic
35354212Sbostic
35454212Sbostic /* ed_quoted_insert():
35554212Sbostic * Add the next character typed verbatim
35654212Sbostic * [^V] [^V]
35754212Sbostic */
35854212Sbostic protected el_action_t
ed_quoted_insert(el,c)35954212Sbostic ed_quoted_insert(el, c)
36054212Sbostic EditLine *el;
36154212Sbostic int c;
36254212Sbostic {
36354212Sbostic int num;
36454212Sbostic char tc;
36554212Sbostic
36654212Sbostic tty_quotemode(el);
36754212Sbostic num = el_getc(el, &tc);
36854212Sbostic c = (unsigned char) tc;
36954212Sbostic tty_noquotemode(el);
37054212Sbostic if (num == 1)
37154212Sbostic return ed_insert(el, c);
37254212Sbostic else
37354212Sbostic return ed_end_of_file(el, 0);
37454212Sbostic }
37554212Sbostic
37654212Sbostic
37754212Sbostic /* ed_digit():
37854212Sbostic * Adds to argument or enters a digit
37954212Sbostic */
38054212Sbostic protected el_action_t
ed_digit(el,c)38154212Sbostic ed_digit(el, c)
38254212Sbostic EditLine *el;
38354212Sbostic int c;
38454212Sbostic {
38554212Sbostic if (!isdigit(c))
38654212Sbostic return CC_ERROR;
38754212Sbostic
38854212Sbostic if (el->el_state.doingarg) {
38954212Sbostic /* if doing an arg, add this in... */
39054212Sbostic if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
39154212Sbostic el->el_state.argument = c - '0';
39254212Sbostic else {
39354212Sbostic if (el->el_state.argument > 1000000)
39454212Sbostic return CC_ERROR;
39554212Sbostic el->el_state.argument =
39654212Sbostic (el->el_state.argument * 10) + (c - '0');
39754212Sbostic }
39854212Sbostic return CC_ARGHACK;
39954212Sbostic }
40054212Sbostic else {
40154212Sbostic if (el->el_line.lastchar + 1 >= el->el_line.limit)
40254212Sbostic return CC_ERROR;
40354212Sbostic
40454212Sbostic if (el->el_state.inputmode != MODE_INSERT) {
40554212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
40654212Sbostic *el->el_line.cursor;
40754212Sbostic el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0';
40854212Sbostic c_delafter(el, 1);
40954212Sbostic }
41054212Sbostic c_insert(el, 1);
41154212Sbostic *el->el_line.cursor++ = c;
41254212Sbostic el->el_state.doingarg = 0;
41354212Sbostic re_fastaddc(el);
41454212Sbostic }
41554212Sbostic return CC_NORM;
41654212Sbostic }
41754212Sbostic
41854212Sbostic
41954212Sbostic /* ed_argument_digit():
42054212Sbostic * Digit that starts argument
42154212Sbostic * For ESC-n
42254212Sbostic */
42354212Sbostic protected el_action_t
ed_argument_digit(el,c)42454212Sbostic ed_argument_digit(el, c)
42554212Sbostic EditLine *el;
42654212Sbostic register int c;
42754212Sbostic {
42854212Sbostic if (!isdigit(c))
42954212Sbostic return CC_ERROR;
43054212Sbostic
43154212Sbostic if (el->el_state.doingarg) {
43254212Sbostic if (el->el_state.argument > 1000000)
43354212Sbostic return CC_ERROR;
43454212Sbostic el->el_state.argument = (el->el_state.argument * 10) + (c - '0');
43554212Sbostic }
43654212Sbostic else { /* else starting an argument */
43754212Sbostic el->el_state.argument = c - '0';
43854212Sbostic el->el_state.doingarg = 1;
43954212Sbostic }
44054212Sbostic return CC_ARGHACK;
44154212Sbostic }
44254212Sbostic
44354212Sbostic
44454212Sbostic /* ed_unassigned():
44554212Sbostic * Indicates unbound character
44654212Sbostic * Bound to keys that are not assigned
44754212Sbostic */
44854212Sbostic protected el_action_t
44954212Sbostic /*ARGSUSED*/
ed_unassigned(el,c)45054212Sbostic ed_unassigned(el, c)
45154212Sbostic EditLine *el;
45254212Sbostic int c;
45354212Sbostic {
45454212Sbostic term_beep(el);
45554212Sbostic term__flush();
45654212Sbostic return CC_NORM;
45754212Sbostic }
45854212Sbostic
45954212Sbostic
46054212Sbostic /**
46154212Sbostic ** TTY key handling.
46254212Sbostic **/
46354212Sbostic
46454212Sbostic /* ed_tty_sigint():
46554212Sbostic * Tty interrupt character
46654212Sbostic * [^C]
46754212Sbostic */
46854212Sbostic protected el_action_t
46954212Sbostic /*ARGSUSED*/
ed_tty_sigint(el,c)47054212Sbostic ed_tty_sigint(el, c)
47154212Sbostic EditLine *el;
47254212Sbostic int c;
47354212Sbostic {
47454212Sbostic return CC_NORM;
47554212Sbostic }
47654212Sbostic
47754212Sbostic
47854212Sbostic /* ed_tty_dsusp():
47954212Sbostic * Tty delayed suspend character
48054212Sbostic * [^Y]
48154212Sbostic */
48254212Sbostic protected el_action_t
48354212Sbostic /*ARGSUSED*/
ed_tty_dsusp(el,c)48454212Sbostic ed_tty_dsusp(el, c)
48554212Sbostic EditLine *el;
48654212Sbostic int c;
48754212Sbostic {
48854212Sbostic return CC_NORM;
48954212Sbostic }
49054212Sbostic
49154212Sbostic
49254212Sbostic /* ed_tty_flush_output():
49354212Sbostic * Tty flush output characters
49454212Sbostic * [^O]
49554212Sbostic */
49654212Sbostic protected el_action_t
49754212Sbostic /*ARGSUSED*/
ed_tty_flush_output(el,c)49854212Sbostic ed_tty_flush_output(el, c)
49954212Sbostic EditLine *el;
50054212Sbostic int c;
50154212Sbostic {
50254212Sbostic return CC_NORM;
50354212Sbostic }
50454212Sbostic
50554212Sbostic
50654212Sbostic /* ed_tty_sigquit():
50754212Sbostic * Tty quit character
50854212Sbostic * [^\]
50954212Sbostic */
51054212Sbostic protected el_action_t
51154212Sbostic /*ARGSUSED*/
ed_tty_sigquit(el,c)51254212Sbostic ed_tty_sigquit(el, c)
51354212Sbostic EditLine *el;
51454212Sbostic int c;
51554212Sbostic {
51654212Sbostic return CC_NORM;
51754212Sbostic }
51854212Sbostic
51954212Sbostic
52054212Sbostic /* ed_tty_sigtstp():
52154212Sbostic * Tty suspend character
52254212Sbostic * [^Z]
52354212Sbostic */
52454212Sbostic protected el_action_t
52554212Sbostic /*ARGSUSED*/
ed_tty_sigtstp(el,c)52654212Sbostic ed_tty_sigtstp(el, c)
52754212Sbostic EditLine *el;
52854212Sbostic int c;
52954212Sbostic {
53054212Sbostic return CC_NORM;
53154212Sbostic }
53254212Sbostic
53354212Sbostic
53454212Sbostic /* ed_tty_stop_output():
53554212Sbostic * Tty disallow output characters
53654212Sbostic * [^S]
53754212Sbostic */
53854212Sbostic protected el_action_t
53954212Sbostic /*ARGSUSED*/
ed_tty_stop_output(el,c)54054212Sbostic ed_tty_stop_output(el, c)
54154212Sbostic EditLine *el;
54254212Sbostic int c;
54354212Sbostic {
54454212Sbostic return CC_NORM;
54554212Sbostic }
54654212Sbostic
54754212Sbostic
54854212Sbostic /* ed_tty_start_output():
54954212Sbostic * Tty allow output characters
55054212Sbostic * [^Q]
55154212Sbostic */
55254212Sbostic protected el_action_t
55354212Sbostic /*ARGSUSED*/
ed_tty_start_output(el,c)55454212Sbostic ed_tty_start_output(el, c)
55554212Sbostic EditLine *el;
55654212Sbostic int c;
55754212Sbostic {
55854212Sbostic return CC_NORM;
55954212Sbostic }
56054212Sbostic
56154212Sbostic
56254212Sbostic /* ed_newline():
56354212Sbostic * Execute command
56454212Sbostic * [^J]
56554212Sbostic */
56654212Sbostic protected el_action_t
56754212Sbostic /*ARGSUSED*/
ed_newline(el,c)56854212Sbostic ed_newline(el, c)
56954212Sbostic EditLine *el;
57054212Sbostic int c;
57154212Sbostic {
57254212Sbostic re_goto_bottom(el);
57354212Sbostic *el->el_line.lastchar++ = '\n';
57454212Sbostic *el->el_line.lastchar = '\0';
57554212Sbostic if (el->el_map.type == MAP_VI)
57654212Sbostic el->el_chared.c_vcmd.ins = el->el_line.buffer;
57754212Sbostic return CC_NEWLINE;
57854212Sbostic }
57954212Sbostic
58054212Sbostic
58154212Sbostic /* ed_delete_prev_char():
58254212Sbostic * Delete the character to the left of the cursor
58354212Sbostic * [^?]
58454212Sbostic */
58554212Sbostic protected el_action_t
58654212Sbostic /*ARGSUSED*/
ed_delete_prev_char(el,c)58754212Sbostic ed_delete_prev_char(el, c)
58854212Sbostic EditLine *el;
58954212Sbostic int c;
59054212Sbostic {
59154212Sbostic if (el->el_line.cursor <= el->el_line.buffer)
59254212Sbostic return CC_ERROR;
59354212Sbostic
59454212Sbostic c_delbefore(el, el->el_state.argument);
59554212Sbostic el->el_line.cursor -= el->el_state.argument;
59654212Sbostic if (el->el_line.cursor < el->el_line.buffer)
59754212Sbostic el->el_line.cursor = el->el_line.buffer;
59854212Sbostic return CC_REFRESH;
59954212Sbostic }
60054212Sbostic
60154212Sbostic
60254212Sbostic /* ed_clear_screen():
60354212Sbostic * Clear screen leaving current line at the top
60454212Sbostic * [^L]
60554212Sbostic */
60654212Sbostic protected el_action_t
60754212Sbostic /*ARGSUSED*/
ed_clear_screen(el,c)60854212Sbostic ed_clear_screen(el, c)
60954212Sbostic EditLine *el;
61054212Sbostic int c;
61154212Sbostic {
61254212Sbostic term_clear_screen(el); /* clear the whole real screen */
61354212Sbostic re_clear_display(el); /* reset everything */
61454212Sbostic return CC_REFRESH;
61554212Sbostic }
61654212Sbostic
61754212Sbostic
61854212Sbostic /* ed_redisplay():
61954212Sbostic * Redisplay everything
62054212Sbostic * ^R
62154212Sbostic */
62254212Sbostic protected el_action_t
62354212Sbostic /*ARGSUSED*/
ed_redisplay(el,c)62454212Sbostic ed_redisplay(el, c)
62554212Sbostic EditLine *el;
62654212Sbostic int c;
62754212Sbostic {
62854212Sbostic re_clear_lines(el);
62954212Sbostic re_clear_display(el);
63054212Sbostic return CC_REFRESH;
63154212Sbostic }
63254212Sbostic
63354212Sbostic
63454212Sbostic /* ed_start_over():
63554212Sbostic * Erase current line and start from scratch
63654212Sbostic * [^G]
63754212Sbostic */
63854212Sbostic protected el_action_t
63954212Sbostic /*ARGSUSED*/
ed_start_over(el,c)64054212Sbostic ed_start_over(el, c)
64154212Sbostic EditLine *el;
64254212Sbostic int c;
64354212Sbostic {
64454212Sbostic ch_reset(el);
64554212Sbostic return CC_REFRESH;
64654212Sbostic }
64754212Sbostic
64854212Sbostic
64954212Sbostic /* ed_sequence_lead_in():
65054212Sbostic * First character in a bound sequence
65154212Sbostic * Placeholder for external keys
65254212Sbostic */
65354212Sbostic protected el_action_t
65454212Sbostic /*ARGSUSED*/
ed_sequence_lead_in(el,c)65554212Sbostic ed_sequence_lead_in(el, c)
65654212Sbostic EditLine *el;
65754212Sbostic int c;
65854212Sbostic {
65954212Sbostic return CC_NORM;
66054212Sbostic }
66154212Sbostic
66254212Sbostic
66354212Sbostic /* ed_prev_history():
66454212Sbostic * Move to the previous history line
66554212Sbostic * [^P] [k]
66654212Sbostic */
66754212Sbostic protected el_action_t
66854212Sbostic /*ARGSUSED*/
ed_prev_history(el,c)66954212Sbostic ed_prev_history(el, c)
67054212Sbostic EditLine *el;
67154212Sbostic int c;
67254212Sbostic {
67354212Sbostic char beep = 0;
67454212Sbostic
67554212Sbostic el->el_chared.c_undo.action = NOP;
67654212Sbostic *el->el_line.lastchar = '\0'; /* just in case */
67754212Sbostic
67854212Sbostic if (el->el_history.eventno == 0) { /* save the current buffer away */
67954212Sbostic (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
68054212Sbostic el->el_history.last = el->el_history.buf +
68154212Sbostic (el->el_line.lastchar - el->el_line.buffer);
68254212Sbostic }
68354212Sbostic
68454212Sbostic el->el_history.eventno += el->el_state.argument;
68554212Sbostic
68654212Sbostic if (hist_get(el) == CC_ERROR) {
68754212Sbostic beep = 1;
68854212Sbostic /* el->el_history.eventno was fixed by first call */
68954212Sbostic (void) hist_get(el);
69054212Sbostic }
69154212Sbostic
69254212Sbostic re_refresh(el);
69354212Sbostic if (beep)
69454212Sbostic return CC_ERROR;
69554212Sbostic else
69654212Sbostic return CC_NORM; /* was CC_UP_HIST */
69754212Sbostic }
69854212Sbostic
69954212Sbostic
70054212Sbostic /* ed_next_history():
70154212Sbostic * Move to the next history line
70254212Sbostic * [^N] [j]
70354212Sbostic */
70454212Sbostic protected el_action_t
70554212Sbostic /*ARGSUSED*/
ed_next_history(el,c)70654212Sbostic ed_next_history(el, c)
70754212Sbostic EditLine *el;
70854212Sbostic int c;
70954212Sbostic {
71054212Sbostic el->el_chared.c_undo.action = NOP;
71154212Sbostic *el->el_line.lastchar = '\0'; /* just in case */
71254212Sbostic
71354212Sbostic el->el_history.eventno -= el->el_state.argument;
71454212Sbostic
71554212Sbostic if (el->el_history.eventno < 0) {
71654212Sbostic el->el_history.eventno = 0;
71754212Sbostic return CC_ERROR; /* make it beep */
71854212Sbostic }
71954212Sbostic
72054212Sbostic return hist_get(el);
72154212Sbostic }
72254212Sbostic
72354212Sbostic
72454212Sbostic /* ed_search_prev_history():
72554212Sbostic * Search previous in history for a line matching the current
72654212Sbostic * next search history [M-P] [K]
72754212Sbostic */
72854212Sbostic protected el_action_t
72954212Sbostic /*ARGSUSED*/
ed_search_prev_history(el,c)73054212Sbostic ed_search_prev_history(el, c)
73154212Sbostic EditLine *el;
73254212Sbostic int c;
73354212Sbostic {
73454212Sbostic const char *hp;
73554212Sbostic int h;
73654212Sbostic bool_t found = 0;
73754212Sbostic
73854212Sbostic el->el_chared.c_vcmd.action = NOP;
73954212Sbostic el->el_chared.c_undo.action = NOP;
74054212Sbostic *el->el_line.lastchar = '\0'; /* just in case */
74154212Sbostic if (el->el_history.eventno < 0) {
74254212Sbostic #ifdef DEBUG_EDIT
74354212Sbostic (void) fprintf(el->el_errfile, "e_prev_search_hist(): eventno < 0;\n");
74454212Sbostic #endif
74554212Sbostic el->el_history.eventno = 0;
74654212Sbostic return CC_ERROR;
74754212Sbostic }
74854212Sbostic
74954212Sbostic if (el->el_history.eventno == 0) {
75054212Sbostic (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ);
75154212Sbostic el->el_history.last = el->el_history.buf +
75254212Sbostic (el->el_line.lastchar - el->el_line.buffer);
75354212Sbostic }
75454212Sbostic
75554212Sbostic
75654212Sbostic if (el->el_history.ref == NULL)
75754212Sbostic return CC_ERROR;
75854212Sbostic
75954212Sbostic hp = HIST_FIRST(el);
76054212Sbostic if (hp == NULL)
76154212Sbostic return CC_ERROR;
76254212Sbostic
76354212Sbostic c_setpat(el); /* Set search pattern !! */
76454212Sbostic
76554212Sbostic for (h = 1; h <= el->el_history.eventno; h++)
76654212Sbostic hp = HIST_NEXT(el);
76754212Sbostic
76854212Sbostic while (hp != NULL) {
76954212Sbostic #ifdef SDEBUG
77055353Schristos (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
77154212Sbostic #endif
77254212Sbostic if ((strncmp(hp, el->el_line.buffer,
77354212Sbostic el->el_line.lastchar - el->el_line.buffer) ||
77454212Sbostic hp[el->el_line.lastchar-el->el_line.buffer]) &&
77554212Sbostic c_hmatch(el, hp)) {
77654212Sbostic found++;
77754212Sbostic break;
77854212Sbostic }
77954212Sbostic h++;
78054212Sbostic hp = HIST_NEXT(el);
78154212Sbostic }
78254212Sbostic
78354212Sbostic if (!found) {
78454212Sbostic #ifdef SDEBUG
78554212Sbostic (void) fprintf(el->el_errfile, "not found\n");
78654212Sbostic #endif
78754212Sbostic return CC_ERROR;
78854212Sbostic }
78954212Sbostic
79054212Sbostic el->el_history.eventno = h;
79154212Sbostic
79254212Sbostic return hist_get(el);
79354212Sbostic }
79454212Sbostic
79554212Sbostic
79654212Sbostic /* ed_search_next_history():
79754212Sbostic * Search next in history for a line matching the current
79854212Sbostic * [M-N] [J]
79954212Sbostic */
80054212Sbostic protected el_action_t
80154212Sbostic /*ARGSUSED*/
ed_search_next_history(el,c)80254212Sbostic ed_search_next_history(el, c)
80354212Sbostic EditLine *el;
80454212Sbostic int c;
80554212Sbostic {
80654212Sbostic const char *hp;
80754212Sbostic int h;
80854212Sbostic bool_t found = 0;
80954212Sbostic
81054212Sbostic el->el_chared.c_vcmd.action = NOP;
81154212Sbostic el->el_chared.c_undo.action = NOP;
81254212Sbostic *el->el_line.lastchar = '\0'; /* just in case */
81354212Sbostic
81454212Sbostic if (el->el_history.eventno == 0)
81554212Sbostic return CC_ERROR;
81654212Sbostic
81754212Sbostic if (el->el_history.ref == NULL)
81854212Sbostic return CC_ERROR;
81954212Sbostic
82054212Sbostic hp = HIST_FIRST(el);
82154212Sbostic if (hp == NULL)
82254212Sbostic return CC_ERROR;
82354212Sbostic
82454212Sbostic c_setpat(el); /* Set search pattern !! */
82554212Sbostic
82654212Sbostic for (h = 1; h < el->el_history.eventno && hp; h++) {
82754212Sbostic #ifdef SDEBUG
82855353Schristos (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
82954212Sbostic #endif
83054212Sbostic if ((strncmp(hp, el->el_line.buffer,
83154212Sbostic el->el_line.lastchar - el->el_line.buffer) ||
83254212Sbostic hp[el->el_line.lastchar-el->el_line.buffer]) &&
83354212Sbostic c_hmatch(el, hp))
83454212Sbostic found = h;
83554212Sbostic hp = HIST_NEXT(el);
83654212Sbostic }
83754212Sbostic
83854212Sbostic if (!found) { /* is it the current history number? */
83954212Sbostic if (!c_hmatch(el, el->el_history.buf)) {
84054212Sbostic #ifdef SDEBUG
84154212Sbostic (void) fprintf(el->el_errfile, "not found\n");
84254212Sbostic #endif
84354212Sbostic return CC_ERROR;
84454212Sbostic }
84554212Sbostic }
84654212Sbostic
84754212Sbostic el->el_history.eventno = found;
84854212Sbostic
84954212Sbostic return hist_get(el);
85054212Sbostic }
85154212Sbostic
85254212Sbostic
85354212Sbostic /* ed_prev_line():
85454212Sbostic * Move up one line
85554212Sbostic * Could be [k] [^p]
85654212Sbostic */
85754212Sbostic protected el_action_t
85854212Sbostic /*ARGSUSED*/
ed_prev_line(el,c)85954212Sbostic ed_prev_line(el, c)
86054212Sbostic EditLine *el;
86154212Sbostic int c;
86254212Sbostic {
86354212Sbostic char *ptr;
86454212Sbostic int nchars = c_hpos(el);
86554212Sbostic
86654212Sbostic /*
86754212Sbostic * Move to the line requested
86854212Sbostic */
86954212Sbostic if (*(ptr = el->el_line.cursor) == '\n')
87054212Sbostic ptr--;
87154212Sbostic
87254212Sbostic for (; ptr >= el->el_line.buffer; ptr--)
87354212Sbostic if (*ptr == '\n' && --el->el_state.argument <= 0)
87454212Sbostic break;
87554212Sbostic
87654212Sbostic if (el->el_state.argument > 0)
87754212Sbostic return CC_ERROR;
87854212Sbostic
87954212Sbostic /*
88054212Sbostic * Move to the beginning of the line
88154212Sbostic */
88254212Sbostic for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
88354212Sbostic continue;
88454212Sbostic
88554212Sbostic /*
88654212Sbostic * Move to the character requested
88754212Sbostic */
88854212Sbostic for (ptr++;
88954212Sbostic nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
89054212Sbostic ptr++)
89154212Sbostic continue;
89254212Sbostic
89354212Sbostic el->el_line.cursor = ptr;
89454212Sbostic return CC_CURSOR;
89554212Sbostic }
89654212Sbostic
89754212Sbostic
89854212Sbostic /* ed_next_line():
89954212Sbostic * Move down one line
90054212Sbostic * Could be [j] [^n]
90154212Sbostic */
90254212Sbostic protected el_action_t
90354212Sbostic /*ARGSUSED*/
ed_next_line(el,c)90454212Sbostic ed_next_line(el, c)
90554212Sbostic EditLine *el;
90654212Sbostic int c;
90754212Sbostic {
90854212Sbostic char *ptr;
90954212Sbostic int nchars = c_hpos(el);
91054212Sbostic
91154212Sbostic /*
91254212Sbostic * Move to the line requested
91354212Sbostic */
91454212Sbostic for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
91554212Sbostic if (*ptr == '\n' && --el->el_state.argument <= 0)
91654212Sbostic break;
91754212Sbostic
91854212Sbostic if (el->el_state.argument > 0)
91954212Sbostic return CC_ERROR;
92054212Sbostic
92154212Sbostic /*
92254212Sbostic * Move to the character requested
92354212Sbostic */
92454212Sbostic for (ptr++;
92554212Sbostic nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
92654212Sbostic ptr++)
92754212Sbostic continue;
92854212Sbostic
92954212Sbostic el->el_line.cursor = ptr;
93054212Sbostic return CC_CURSOR;
93154212Sbostic }
93254212Sbostic
93354212Sbostic
93454212Sbostic /* ed_command():
93554212Sbostic * Editline extended command
93654212Sbostic * [M-X] [:]
93754212Sbostic */
93854212Sbostic protected el_action_t
93954212Sbostic /*ARGSUSED*/
ed_command(el,c)94054212Sbostic ed_command(el, c)
94154212Sbostic EditLine *el;
94254212Sbostic int c;
94354212Sbostic {
94454212Sbostic char tmpbuf[EL_BUFSIZ];
94554212Sbostic int tmplen;
94654212Sbostic
94754212Sbostic el->el_line.buffer[0] = '\0';
94854212Sbostic el->el_line.lastchar = el->el_line.buffer;
94954212Sbostic el->el_line.cursor = el->el_line.buffer;
95054212Sbostic
95154212Sbostic c_insert(el, 3); /* prompt + ": " */
95254212Sbostic *el->el_line.cursor++ = '\n';
95354212Sbostic *el->el_line.cursor++ = ':';
95454212Sbostic *el->el_line.cursor++ = ' ';
95554212Sbostic re_refresh(el);
95654212Sbostic
95754212Sbostic tmplen = c_gets(el, tmpbuf);
95854212Sbostic tmpbuf[tmplen] = '\0';
95954212Sbostic
96054212Sbostic el->el_line.buffer[0] = '\0';
96154212Sbostic el->el_line.lastchar = el->el_line.buffer;
96254212Sbostic el->el_line.cursor = el->el_line.buffer;
96354212Sbostic
96454212Sbostic if (parse_line(el, tmpbuf) == -1)
96554212Sbostic return CC_ERROR;
96654212Sbostic else
96754212Sbostic return CC_REFRESH;
96854212Sbostic }
969