xref: /csrg-svn/lib/libedit/common.c (revision 61275)
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