common.c revision 237448
11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1992, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * This code is derived from software contributed to Berkeley by
61573Srgrimes * Christos Zoulas of Cornell University.
71573Srgrimes *
81573Srgrimes * Redistribution and use in source and binary forms, with or without
91573Srgrimes * modification, are permitted provided that the following conditions
101573Srgrimes * are met:
111573Srgrimes * 1. Redistributions of source code must retain the above copyright
121573Srgrimes *    notice, this list of conditions and the following disclaimer.
131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141573Srgrimes *    notice, this list of conditions and the following disclaimer in the
151573Srgrimes *    documentation and/or other materials provided with the distribution.
16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors
171573Srgrimes *    may be used to endorse or promote products derived from this software
181573Srgrimes *    without specific prior written permission.
191573Srgrimes *
201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301573Srgrimes * SUCH DAMAGE.
3184260Sobrien *
32167457Sstefanf *	$NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $
331573Srgrimes */
341573Srgrimes
351573Srgrimes#if !defined(lint) && !defined(SCCSID)
361573Srgrimesstatic char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
371573Srgrimes#endif /* not lint && not SCCSID */
3884260Sobrien#include <sys/cdefs.h>
3984260Sobrien__FBSDID("$FreeBSD: head/lib/libedit/common.c 237448 2012-06-22 18:01:22Z pfg $");
401573Srgrimes
411573Srgrimes/*
421573Srgrimes * common.c: Common Editor functions
431573Srgrimes */
441573Srgrimes#include "sys.h"
451573Srgrimes#include "el.h"
461573Srgrimes
478870Srgrimes/* ed_end_of_file():
481573Srgrimes *	Indicate end of file
491573Srgrimes *	[^D]
501573Srgrimes */
511573Srgrimesprotected el_action_t
521573Srgrimes/*ARGSUSED*/
53148834Sstefanfed_end_of_file(EditLine *el, int c __unused)
541573Srgrimes{
5584260Sobrien
5684260Sobrien	re_goto_bottom(el);
5784260Sobrien	*el->el_line.lastchar = '\0';
5884260Sobrien	return (CC_EOF);
591573Srgrimes}
601573Srgrimes
611573Srgrimes
628870Srgrimes/* ed_insert():
631573Srgrimes *	Add character to the line
641573Srgrimes *	Insert a character [bound to all insert keys]
651573Srgrimes */
661573Srgrimesprotected el_action_t
6784260Sobriened_insert(EditLine *el, int c)
681573Srgrimes{
69148834Sstefanf	int count = el->el_state.argument;
701573Srgrimes
7184260Sobrien	if (c == '\0')
7284260Sobrien		return (CC_ERROR);
731573Srgrimes
7484260Sobrien	if (el->el_line.lastchar + el->el_state.argument >=
7584260Sobrien	    el->el_line.limit) {
7684260Sobrien		/* end of buffer space, try to allocate more */
77148834Sstefanf		if (!ch_enlargebufs(el, (size_t) count))
7884260Sobrien			return CC_ERROR;	/* error allocating more */
7984260Sobrien	}
801573Srgrimes
81148834Sstefanf	if (count == 1) {
82148834Sstefanf		if (el->el_state.inputmode == MODE_INSERT
83148834Sstefanf		    || el->el_line.cursor >= el->el_line.lastchar)
84148834Sstefanf			c_insert(el, 1);
851573Srgrimes
8684260Sobrien		*el->el_line.cursor++ = c;
8784260Sobrien		re_fastaddc(el);		/* fast refresh for one char. */
8884260Sobrien	} else {
89148834Sstefanf		if (el->el_state.inputmode != MODE_REPLACE_1)
90148834Sstefanf			c_insert(el, el->el_state.argument);
911573Srgrimes
92148834Sstefanf		while (count-- && el->el_line.cursor < el->el_line.lastchar)
9384260Sobrien			*el->el_line.cursor++ = c;
9484260Sobrien		re_refresh(el);
9584260Sobrien	}
961573Srgrimes
9784260Sobrien	if (el->el_state.inputmode == MODE_REPLACE_1)
98148834Sstefanf		return vi_command_mode(el, 0);
991573Srgrimes
10084260Sobrien	return (CC_NORM);
1011573Srgrimes}
1021573Srgrimes
1031573Srgrimes
1048870Srgrimes/* ed_delete_prev_word():
1051573Srgrimes *	Delete from beginning of current word to cursor
1061573Srgrimes *	[M-^?] [^W]
1071573Srgrimes */
1081573Srgrimesprotected el_action_t
1091573Srgrimes/*ARGSUSED*/
110148834Sstefanfed_delete_prev_word(EditLine *el, int c __unused)
1111573Srgrimes{
11284260Sobrien	char *cp, *p, *kp;
1131573Srgrimes
11484260Sobrien	if (el->el_line.cursor == el->el_line.buffer)
11584260Sobrien		return (CC_ERROR);
1161573Srgrimes
11784260Sobrien	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
11884260Sobrien	    el->el_state.argument, ce__isword);
1191573Srgrimes
12084260Sobrien	for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
12184260Sobrien		*kp++ = *p;
12284260Sobrien	el->el_chared.c_kill.last = kp;
1231573Srgrimes
12484260Sobrien	c_delbefore(el, el->el_line.cursor - cp);	/* delete before dot */
12584260Sobrien	el->el_line.cursor = cp;
12684260Sobrien	if (el->el_line.cursor < el->el_line.buffer)
12784260Sobrien		el->el_line.cursor = el->el_line.buffer; /* bounds check */
12884260Sobrien	return (CC_REFRESH);
1291573Srgrimes}
1301573Srgrimes
1311573Srgrimes
1328870Srgrimes/* ed_delete_next_char():
1331573Srgrimes *	Delete character under cursor
1341573Srgrimes *	[^D] [x]
1351573Srgrimes */
1361573Srgrimesprotected el_action_t
1371573Srgrimes/*ARGSUSED*/
138167457Sstefanfed_delete_next_char(EditLine *el, int c)
1391573Srgrimes{
14084260Sobrien#ifdef notdef			/* XXX */
14184260Sobrien#define	EL	el->el_line
14284260Sobrien	(void) fprintf(el->el_errlfile,
14384260Sobrien	    "\nD(b: %x(%s)  c: %x(%s) last: %x(%s) limit: %x(%s)\n",
14484260Sobrien	    EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
14584260Sobrien	    EL.lastchar, EL.limit, EL.limit);
1461573Srgrimes#endif
14784260Sobrien	if (el->el_line.cursor == el->el_line.lastchar) {
14884260Sobrien			/* if I'm at the end */
14984260Sobrien		if (el->el_map.type == MAP_VI) {
15084260Sobrien			if (el->el_line.cursor == el->el_line.buffer) {
15184260Sobrien				/* if I'm also at the beginning */
1521573Srgrimes#ifdef KSHVI
15384260Sobrien				return (CC_ERROR);
1541573Srgrimes#else
155167457Sstefanf				/* then do an EOF */
156167457Sstefanf				term_writechar(el, c);
15784260Sobrien				return (CC_EOF);
1581573Srgrimes#endif
15984260Sobrien			} else {
1601573Srgrimes#ifdef KSHVI
16184260Sobrien				el->el_line.cursor--;
1621573Srgrimes#else
16384260Sobrien				return (CC_ERROR);
1641573Srgrimes#endif
16584260Sobrien			}
166212191Sjilles		} else
167212191Sjilles			return (CC_ERROR);
1681573Srgrimes	}
16984260Sobrien	c_delafter(el, el->el_state.argument);	/* delete after dot */
170212191Sjilles	if (el->el_map.type == MAP_VI &&
171212191Sjilles	    el->el_line.cursor >= el->el_line.lastchar &&
17284260Sobrien	    el->el_line.cursor > el->el_line.buffer)
17384260Sobrien			/* bounds check */
17484260Sobrien		el->el_line.cursor = el->el_line.lastchar - 1;
17584260Sobrien	return (CC_REFRESH);
1761573Srgrimes}
1771573Srgrimes
1781573Srgrimes
1798870Srgrimes/* ed_kill_line():
1801573Srgrimes *	Cut to the end of line
1811573Srgrimes *	[^K] [^K]
1821573Srgrimes */
1831573Srgrimesprotected el_action_t
1841573Srgrimes/*ARGSUSED*/
185148834Sstefanfed_kill_line(EditLine *el, int c __unused)
1861573Srgrimes{
18784260Sobrien	char *kp, *cp;
1881573Srgrimes
18984260Sobrien	cp = el->el_line.cursor;
19084260Sobrien	kp = el->el_chared.c_kill.buf;
19184260Sobrien	while (cp < el->el_line.lastchar)
19284260Sobrien		*kp++ = *cp++;	/* copy it */
19384260Sobrien	el->el_chared.c_kill.last = kp;
19484260Sobrien			/* zap! -- delete to end */
19584260Sobrien	el->el_line.lastchar = el->el_line.cursor;
19684260Sobrien	return (CC_REFRESH);
1971573Srgrimes}
1981573Srgrimes
1991573Srgrimes
2008870Srgrimes/* ed_move_to_end():
2011573Srgrimes *	Move cursor to the end of line
2021573Srgrimes *	[^E] [^E]
2031573Srgrimes */
2041573Srgrimesprotected el_action_t
2051573Srgrimes/*ARGSUSED*/
206148834Sstefanfed_move_to_end(EditLine *el, int c __unused)
2071573Srgrimes{
20884260Sobrien
20984260Sobrien	el->el_line.cursor = el->el_line.lastchar;
21084260Sobrien	if (el->el_map.type == MAP_VI) {
2111573Srgrimes#ifdef VI_MOVE
21284260Sobrien		el->el_line.cursor--;
2131573Srgrimes#endif
214148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
21584260Sobrien			cv_delfini(el);
21684260Sobrien			return (CC_REFRESH);
21784260Sobrien		}
2181573Srgrimes	}
21984260Sobrien	return (CC_CURSOR);
2201573Srgrimes}
2211573Srgrimes
2221573Srgrimes
2238870Srgrimes/* ed_move_to_beg():
2241573Srgrimes *	Move cursor to the beginning of line
2251573Srgrimes *	[^A] [^A]
2261573Srgrimes */
2271573Srgrimesprotected el_action_t
2281573Srgrimes/*ARGSUSED*/
229148834Sstefanfed_move_to_beg(EditLine *el, int c __unused)
2301573Srgrimes{
2311573Srgrimes
23284260Sobrien	el->el_line.cursor = el->el_line.buffer;
23384260Sobrien
23484260Sobrien	if (el->el_map.type == MAP_VI) {
23584260Sobrien			/* We want FIRST non space character */
23684260Sobrien		while (isspace((unsigned char) *el->el_line.cursor))
23784260Sobrien			el->el_line.cursor++;
238148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
23984260Sobrien			cv_delfini(el);
24084260Sobrien			return (CC_REFRESH);
24184260Sobrien		}
2421573Srgrimes	}
24384260Sobrien	return (CC_CURSOR);
2441573Srgrimes}
2451573Srgrimes
2461573Srgrimes
2478870Srgrimes/* ed_transpose_chars():
2481573Srgrimes *	Exchange the character to the left of the cursor with the one under it
2491573Srgrimes *	[^T] [^T]
2501573Srgrimes */
2511573Srgrimesprotected el_action_t
25284260Sobriened_transpose_chars(EditLine *el, int c)
2531573Srgrimes{
25484260Sobrien
25584260Sobrien	if (el->el_line.cursor < el->el_line.lastchar) {
25684260Sobrien		if (el->el_line.lastchar <= &el->el_line.buffer[1])
25784260Sobrien			return (CC_ERROR);
25884260Sobrien		else
25984260Sobrien			el->el_line.cursor++;
26084260Sobrien	}
26184260Sobrien	if (el->el_line.cursor > &el->el_line.buffer[1]) {
26284260Sobrien		/* must have at least two chars entered */
26384260Sobrien		c = el->el_line.cursor[-2];
26484260Sobrien		el->el_line.cursor[-2] = el->el_line.cursor[-1];
26584260Sobrien		el->el_line.cursor[-1] = c;
26684260Sobrien		return (CC_REFRESH);
26784260Sobrien	} else
26884260Sobrien		return (CC_ERROR);
2691573Srgrimes}
2701573Srgrimes
2711573Srgrimes
2728870Srgrimes/* ed_next_char():
2731573Srgrimes *	Move to the right one character
2741573Srgrimes *	[^F] [^F]
2751573Srgrimes */
2761573Srgrimesprotected el_action_t
2771573Srgrimes/*ARGSUSED*/
278148834Sstefanfed_next_char(EditLine *el, int c __unused)
2791573Srgrimes{
280148834Sstefanf	char *lim = el->el_line.lastchar;
2811573Srgrimes
282148834Sstefanf	if (el->el_line.cursor >= lim ||
283148834Sstefanf	    (el->el_line.cursor == lim - 1 &&
284148834Sstefanf	    el->el_map.type == MAP_VI &&
285148834Sstefanf	    el->el_chared.c_vcmd.action == NOP))
28684260Sobrien		return (CC_ERROR);
2871573Srgrimes
28884260Sobrien	el->el_line.cursor += el->el_state.argument;
289148834Sstefanf	if (el->el_line.cursor > lim)
290148834Sstefanf		el->el_line.cursor = lim;
2911573Srgrimes
29284260Sobrien	if (el->el_map.type == MAP_VI)
293148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
29484260Sobrien			cv_delfini(el);
29584260Sobrien			return (CC_REFRESH);
29684260Sobrien		}
29784260Sobrien	return (CC_CURSOR);
2981573Srgrimes}
2991573Srgrimes
3001573Srgrimes
3018870Srgrimes/* ed_prev_word():
3021573Srgrimes *	Move to the beginning of the current word
3031573Srgrimes *	[M-b] [b]
3041573Srgrimes */
3051573Srgrimesprotected el_action_t
3061573Srgrimes/*ARGSUSED*/
307148834Sstefanfed_prev_word(EditLine *el, int c __unused)
3081573Srgrimes{
3091573Srgrimes
31084260Sobrien	if (el->el_line.cursor == el->el_line.buffer)
31184260Sobrien		return (CC_ERROR);
3121573Srgrimes
31384260Sobrien	el->el_line.cursor = c__prev_word(el->el_line.cursor,
31484260Sobrien	    el->el_line.buffer,
31584260Sobrien	    el->el_state.argument,
31684260Sobrien	    ce__isword);
3171573Srgrimes
31884260Sobrien	if (el->el_map.type == MAP_VI)
319148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
32084260Sobrien			cv_delfini(el);
32184260Sobrien			return (CC_REFRESH);
32284260Sobrien		}
32384260Sobrien	return (CC_CURSOR);
3241573Srgrimes}
3251573Srgrimes
3261573Srgrimes
3278870Srgrimes/* ed_prev_char():
3281573Srgrimes *	Move to the left one character
3291573Srgrimes *	[^B] [^B]
3301573Srgrimes */
3311573Srgrimesprotected el_action_t
3321573Srgrimes/*ARGSUSED*/
333148834Sstefanfed_prev_char(EditLine *el, int c __unused)
3341573Srgrimes{
3351573Srgrimes
33684260Sobrien	if (el->el_line.cursor > el->el_line.buffer) {
33784260Sobrien		el->el_line.cursor -= el->el_state.argument;
33884260Sobrien		if (el->el_line.cursor < el->el_line.buffer)
33984260Sobrien			el->el_line.cursor = el->el_line.buffer;
3401573Srgrimes
34184260Sobrien		if (el->el_map.type == MAP_VI)
342148834Sstefanf			if (el->el_chared.c_vcmd.action != NOP) {
34384260Sobrien				cv_delfini(el);
34484260Sobrien				return (CC_REFRESH);
34584260Sobrien			}
34684260Sobrien		return (CC_CURSOR);
34784260Sobrien	} else
34884260Sobrien		return (CC_ERROR);
3491573Srgrimes}
3501573Srgrimes
3511573Srgrimes
3528870Srgrimes/* ed_quoted_insert():
3531573Srgrimes *	Add the next character typed verbatim
3541573Srgrimes *	[^V] [^V]
3551573Srgrimes */
3561573Srgrimesprotected el_action_t
35784260Sobriened_quoted_insert(EditLine *el, int c)
3581573Srgrimes{
35984260Sobrien	int num;
36084260Sobrien	char tc;
3611573Srgrimes
36284260Sobrien	tty_quotemode(el);
36384260Sobrien	num = el_getc(el, &tc);
36484260Sobrien	c = (unsigned char) tc;
36584260Sobrien	tty_noquotemode(el);
36684260Sobrien	if (num == 1)
36784260Sobrien		return (ed_insert(el, c));
36884260Sobrien	else
36984260Sobrien		return (ed_end_of_file(el, 0));
3701573Srgrimes}
3711573Srgrimes
3721573Srgrimes
3738870Srgrimes/* ed_digit():
3741573Srgrimes *	Adds to argument or enters a digit
3751573Srgrimes */
3761573Srgrimesprotected el_action_t
37784260Sobriened_digit(EditLine *el, int c)
3781573Srgrimes{
3791573Srgrimes
38084260Sobrien	if (!isdigit((unsigned char) c))
38184260Sobrien		return (CC_ERROR);
38284260Sobrien
38384260Sobrien	if (el->el_state.doingarg) {
38484260Sobrien			/* if doing an arg, add this in... */
38584260Sobrien		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
38684260Sobrien			el->el_state.argument = c - '0';
38784260Sobrien		else {
38884260Sobrien			if (el->el_state.argument > 1000000)
38984260Sobrien				return (CC_ERROR);
39084260Sobrien			el->el_state.argument =
39184260Sobrien			    (el->el_state.argument * 10) + (c - '0');
39284260Sobrien		}
39384260Sobrien		return (CC_ARGHACK);
394148834Sstefanf	}
39584260Sobrien
396148834Sstefanf	return ed_insert(el, c);
3971573Srgrimes}
3981573Srgrimes
3991573Srgrimes
4008870Srgrimes/* ed_argument_digit():
4011573Srgrimes *	Digit that starts argument
4021573Srgrimes *	For ESC-n
4031573Srgrimes */
4041573Srgrimesprotected el_action_t
40584260Sobriened_argument_digit(EditLine *el, int c)
4061573Srgrimes{
4071573Srgrimes
40884260Sobrien	if (!isdigit((unsigned char) c))
40984260Sobrien		return (CC_ERROR);
41084260Sobrien
41184260Sobrien	if (el->el_state.doingarg) {
41284260Sobrien		if (el->el_state.argument > 1000000)
41384260Sobrien			return (CC_ERROR);
41484260Sobrien		el->el_state.argument = (el->el_state.argument * 10) +
41584260Sobrien		    (c - '0');
41684260Sobrien	} else {		/* else starting an argument */
41784260Sobrien		el->el_state.argument = c - '0';
41884260Sobrien		el->el_state.doingarg = 1;
41984260Sobrien	}
42084260Sobrien	return (CC_ARGHACK);
4211573Srgrimes}
4221573Srgrimes
4231573Srgrimes
4248870Srgrimes/* ed_unassigned():
4251573Srgrimes *	Indicates unbound character
4261573Srgrimes *	Bound to keys that are not assigned
4271573Srgrimes */
4281573Srgrimesprotected el_action_t
4291573Srgrimes/*ARGSUSED*/
430148834Sstefanfed_unassigned(EditLine *el, int c __unused)
4311573Srgrimes{
43284260Sobrien
433148834Sstefanf	return (CC_ERROR);
4341573Srgrimes}
4351573Srgrimes
4361573Srgrimes
4371573Srgrimes/**
4381573Srgrimes ** TTY key handling.
4391573Srgrimes **/
4401573Srgrimes
4418870Srgrimes/* ed_tty_sigint():
4421573Srgrimes *	Tty interrupt character
4431573Srgrimes *	[^C]
4441573Srgrimes */
4451573Srgrimesprotected el_action_t
4461573Srgrimes/*ARGSUSED*/
447148834Sstefanfed_tty_sigint(EditLine *el __unused,
448148834Sstefanf	      int c __unused)
4498870Srgrimes{
45084260Sobrien
45184260Sobrien	return (CC_NORM);
4521573Srgrimes}
4531573Srgrimes
4541573Srgrimes
4558870Srgrimes/* ed_tty_dsusp():
4561573Srgrimes *	Tty delayed suspend character
4571573Srgrimes *	[^Y]
4581573Srgrimes */
4591573Srgrimesprotected el_action_t
4601573Srgrimes/*ARGSUSED*/
461148834Sstefanfed_tty_dsusp(EditLine *el __unused,
462148834Sstefanf	     int c __unused)
4631573Srgrimes{
46484260Sobrien
46584260Sobrien	return (CC_NORM);
4661573Srgrimes}
4671573Srgrimes
4681573Srgrimes
4698870Srgrimes/* ed_tty_flush_output():
4701573Srgrimes *	Tty flush output characters
4711573Srgrimes *	[^O]
4721573Srgrimes */
4731573Srgrimesprotected el_action_t
4741573Srgrimes/*ARGSUSED*/
475148834Sstefanfed_tty_flush_output(EditLine *el __unused,
476148834Sstefanf		    int c __unused)
4771573Srgrimes{
47884260Sobrien
47984260Sobrien	return (CC_NORM);
4801573Srgrimes}
4811573Srgrimes
4821573Srgrimes
4838870Srgrimes/* ed_tty_sigquit():
4841573Srgrimes *	Tty quit character
4851573Srgrimes *	[^\]
4861573Srgrimes */
4871573Srgrimesprotected el_action_t
4881573Srgrimes/*ARGSUSED*/
489148834Sstefanfed_tty_sigquit(EditLine *el __unused,
490148834Sstefanf	       int c __unused)
4911573Srgrimes{
49284260Sobrien
49384260Sobrien	return (CC_NORM);
4941573Srgrimes}
4951573Srgrimes
4961573Srgrimes
4978870Srgrimes/* ed_tty_sigtstp():
4981573Srgrimes *	Tty suspend character
4991573Srgrimes *	[^Z]
5001573Srgrimes */
5011573Srgrimesprotected el_action_t
5021573Srgrimes/*ARGSUSED*/
503148834Sstefanfed_tty_sigtstp(EditLine *el __unused,
504148834Sstefanf	       int c __unused)
5051573Srgrimes{
50684260Sobrien
50784260Sobrien	return (CC_NORM);
5081573Srgrimes}
5091573Srgrimes
5101573Srgrimes
5118870Srgrimes/* ed_tty_stop_output():
5121573Srgrimes *	Tty disallow output characters
5131573Srgrimes *	[^S]
5141573Srgrimes */
5151573Srgrimesprotected el_action_t
5161573Srgrimes/*ARGSUSED*/
517148834Sstefanfed_tty_stop_output(EditLine *el __unused,
518148834Sstefanf		   int c __unused)
5191573Srgrimes{
52084260Sobrien
52184260Sobrien	return (CC_NORM);
5221573Srgrimes}
5231573Srgrimes
5241573Srgrimes
5258870Srgrimes/* ed_tty_start_output():
5261573Srgrimes *	Tty allow output characters
5271573Srgrimes *	[^Q]
5281573Srgrimes */
5291573Srgrimesprotected el_action_t
5301573Srgrimes/*ARGSUSED*/
531148834Sstefanfed_tty_start_output(EditLine *el __unused,
532148834Sstefanf		    int c __unused)
5331573Srgrimes{
53484260Sobrien
53584260Sobrien	return (CC_NORM);
5361573Srgrimes}
5371573Srgrimes
5381573Srgrimes
5398870Srgrimes/* ed_newline():
5401573Srgrimes *	Execute command
5411573Srgrimes *	[^J]
5421573Srgrimes */
5431573Srgrimesprotected el_action_t
5441573Srgrimes/*ARGSUSED*/
545148834Sstefanfed_newline(EditLine *el, int c __unused)
5461573Srgrimes{
54784260Sobrien
54884260Sobrien	re_goto_bottom(el);
54984260Sobrien	*el->el_line.lastchar++ = '\n';
55084260Sobrien	*el->el_line.lastchar = '\0';
55184260Sobrien	return (CC_NEWLINE);
5521573Srgrimes}
5531573Srgrimes
5541573Srgrimes
5558870Srgrimes/* ed_delete_prev_char():
5561573Srgrimes *	Delete the character to the left of the cursor
5571573Srgrimes *	[^?]
5581573Srgrimes */
5591573Srgrimesprotected el_action_t
5601573Srgrimes/*ARGSUSED*/
561148834Sstefanfed_delete_prev_char(EditLine *el, int c __unused)
5621573Srgrimes{
5631573Srgrimes
56484260Sobrien	if (el->el_line.cursor <= el->el_line.buffer)
56584260Sobrien		return (CC_ERROR);
56684260Sobrien
56784260Sobrien	c_delbefore(el, el->el_state.argument);
56884260Sobrien	el->el_line.cursor -= el->el_state.argument;
56984260Sobrien	if (el->el_line.cursor < el->el_line.buffer)
57084260Sobrien		el->el_line.cursor = el->el_line.buffer;
57184260Sobrien	return (CC_REFRESH);
5721573Srgrimes}
5731573Srgrimes
5741573Srgrimes
5758870Srgrimes/* ed_clear_screen():
5761573Srgrimes *	Clear screen leaving current line at the top
5771573Srgrimes *	[^L]
5781573Srgrimes */
5791573Srgrimesprotected el_action_t
5801573Srgrimes/*ARGSUSED*/
581148834Sstefanfed_clear_screen(EditLine *el, int c __unused)
5821573Srgrimes{
58384260Sobrien
58484260Sobrien	term_clear_screen(el);	/* clear the whole real screen */
58584260Sobrien	re_clear_display(el);	/* reset everything */
58684260Sobrien	return (CC_REFRESH);
5871573Srgrimes}
5881573Srgrimes
5891573Srgrimes
5908870Srgrimes/* ed_redisplay():
5911573Srgrimes *	Redisplay everything
5921573Srgrimes *	^R
5931573Srgrimes */
5941573Srgrimesprotected el_action_t
5951573Srgrimes/*ARGSUSED*/
596148834Sstefanfed_redisplay(EditLine *el __unused,
597148834Sstefanf	     int c __unused)
5981573Srgrimes{
59984260Sobrien
60084260Sobrien	return (CC_REDISPLAY);
6011573Srgrimes}
6021573Srgrimes
6031573Srgrimes
6048870Srgrimes/* ed_start_over():
6051573Srgrimes *	Erase current line and start from scratch
6061573Srgrimes *	[^G]
6071573Srgrimes */
6081573Srgrimesprotected el_action_t
6091573Srgrimes/*ARGSUSED*/
610148834Sstefanfed_start_over(EditLine *el, int c __unused)
6111573Srgrimes{
61284260Sobrien
613148834Sstefanf	ch_reset(el, 0);
61484260Sobrien	return (CC_REFRESH);
6151573Srgrimes}
6161573Srgrimes
6171573Srgrimes
6188870Srgrimes/* ed_sequence_lead_in():
6191573Srgrimes *	First character in a bound sequence
6201573Srgrimes *	Placeholder for external keys
6211573Srgrimes */
6221573Srgrimesprotected el_action_t
6231573Srgrimes/*ARGSUSED*/
624148834Sstefanfed_sequence_lead_in(EditLine *el __unused,
625148834Sstefanf		    int c __unused)
6261573Srgrimes{
62784260Sobrien
62884260Sobrien	return (CC_NORM);
6291573Srgrimes}
6301573Srgrimes
6311573Srgrimes
6328870Srgrimes/* ed_prev_history():
6331573Srgrimes *	Move to the previous history line
6341573Srgrimes *	[^P] [k]
6351573Srgrimes */
6361573Srgrimesprotected el_action_t
6371573Srgrimes/*ARGSUSED*/
638148834Sstefanfed_prev_history(EditLine *el, int c __unused)
6391573Srgrimes{
64084260Sobrien	char beep = 0;
641148834Sstefanf	int sv_event = el->el_history.eventno;
6421573Srgrimes
643148834Sstefanf	el->el_chared.c_undo.len = -1;
64484260Sobrien	*el->el_line.lastchar = '\0';		/* just in case */
6451573Srgrimes
64684260Sobrien	if (el->el_history.eventno == 0) {	/* save the current buffer
64784260Sobrien						 * away */
64884260Sobrien		(void) strncpy(el->el_history.buf, el->el_line.buffer,
64984260Sobrien		    EL_BUFSIZ);
65084260Sobrien		el->el_history.last = el->el_history.buf +
65184260Sobrien		    (el->el_line.lastchar - el->el_line.buffer);
65284260Sobrien	}
65384260Sobrien	el->el_history.eventno += el->el_state.argument;
6541573Srgrimes
65584260Sobrien	if (hist_get(el) == CC_ERROR) {
656148834Sstefanf		if (el->el_map.type == MAP_VI) {
657148834Sstefanf			el->el_history.eventno = sv_event;
658148834Sstefanf			return CC_ERROR;
659148834Sstefanf		}
66084260Sobrien		beep = 1;
66184260Sobrien		/* el->el_history.eventno was fixed by first call */
66284260Sobrien		(void) hist_get(el);
66384260Sobrien	}
66484260Sobrien	if (beep)
665148834Sstefanf		return CC_REFRESH_BEEP;
666148834Sstefanf	return CC_REFRESH;
6671573Srgrimes}
6681573Srgrimes
6691573Srgrimes
6708870Srgrimes/* ed_next_history():
6711573Srgrimes *	Move to the next history line
6721573Srgrimes *	[^N] [j]
6731573Srgrimes */
6741573Srgrimesprotected el_action_t
6751573Srgrimes/*ARGSUSED*/
676148834Sstefanfed_next_history(EditLine *el, int c __unused)
6771573Srgrimes{
678148834Sstefanf	el_action_t beep = CC_REFRESH, rval;
6791573Srgrimes
680148834Sstefanf	el->el_chared.c_undo.len = -1;
68184260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
6821573Srgrimes
68384260Sobrien	el->el_history.eventno -= el->el_state.argument;
6841573Srgrimes
68584260Sobrien	if (el->el_history.eventno < 0) {
68684260Sobrien		el->el_history.eventno = 0;
687148834Sstefanf		beep = CC_REFRESH_BEEP;
68884260Sobrien	}
689148834Sstefanf	rval = hist_get(el);
690148834Sstefanf	if (rval == CC_REFRESH)
691148834Sstefanf		return beep;
692148834Sstefanf	return rval;
693148834Sstefanf
6941573Srgrimes}
6951573Srgrimes
6961573Srgrimes
6978870Srgrimes/* ed_search_prev_history():
6981573Srgrimes *	Search previous in history for a line matching the current
6991573Srgrimes *	next search history [M-P] [K]
7001573Srgrimes */
7011573Srgrimesprotected el_action_t
7021573Srgrimes/*ARGSUSED*/
703148834Sstefanfed_search_prev_history(EditLine *el, int c __unused)
7041573Srgrimes{
70584260Sobrien	const char *hp;
70684260Sobrien	int h;
70784260Sobrien	bool_t found = 0;
7081573Srgrimes
70984260Sobrien	el->el_chared.c_vcmd.action = NOP;
710148834Sstefanf	el->el_chared.c_undo.len = -1;
71184260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
71284260Sobrien	if (el->el_history.eventno < 0) {
7131573Srgrimes#ifdef DEBUG_EDIT
71484260Sobrien		(void) fprintf(el->el_errfile,
71584260Sobrien		    "e_prev_search_hist(): eventno < 0;\n");
7161573Srgrimes#endif
71784260Sobrien		el->el_history.eventno = 0;
71884260Sobrien		return (CC_ERROR);
71984260Sobrien	}
72084260Sobrien	if (el->el_history.eventno == 0) {
72184260Sobrien		(void) strncpy(el->el_history.buf, el->el_line.buffer,
72284260Sobrien		    EL_BUFSIZ);
72384260Sobrien		el->el_history.last = el->el_history.buf +
72484260Sobrien		    (el->el_line.lastchar - el->el_line.buffer);
72584260Sobrien	}
72684260Sobrien	if (el->el_history.ref == NULL)
72784260Sobrien		return (CC_ERROR);
7281573Srgrimes
72984260Sobrien	hp = HIST_FIRST(el);
73084260Sobrien	if (hp == NULL)
73184260Sobrien		return (CC_ERROR);
7321573Srgrimes
73384260Sobrien	c_setpat(el);		/* Set search pattern !! */
7341573Srgrimes
73584260Sobrien	for (h = 1; h <= el->el_history.eventno; h++)
73684260Sobrien		hp = HIST_NEXT(el);
7371573Srgrimes
73884260Sobrien	while (hp != NULL) {
7391573Srgrimes#ifdef SDEBUG
74084260Sobrien		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
7411573Srgrimes#endif
74284260Sobrien		if ((strncmp(hp, el->el_line.buffer, (size_t)
74384260Sobrien			    (el->el_line.lastchar - el->el_line.buffer)) ||
74484260Sobrien			hp[el->el_line.lastchar - el->el_line.buffer]) &&
74584260Sobrien		    c_hmatch(el, hp)) {
74684260Sobrien			found++;
74784260Sobrien			break;
74884260Sobrien		}
74984260Sobrien		h++;
75084260Sobrien		hp = HIST_NEXT(el);
7511573Srgrimes	}
7521573Srgrimes
75384260Sobrien	if (!found) {
7541573Srgrimes#ifdef SDEBUG
75584260Sobrien		(void) fprintf(el->el_errfile, "not found\n");
7561573Srgrimes#endif
75784260Sobrien		return (CC_ERROR);
75884260Sobrien	}
75984260Sobrien	el->el_history.eventno = h;
7601573Srgrimes
76184260Sobrien	return (hist_get(el));
7621573Srgrimes}
7631573Srgrimes
7641573Srgrimes
7658870Srgrimes/* ed_search_next_history():
7661573Srgrimes *	Search next in history for a line matching the current
7671573Srgrimes *	[M-N] [J]
7681573Srgrimes */
7691573Srgrimesprotected el_action_t
7701573Srgrimes/*ARGSUSED*/
771148834Sstefanfed_search_next_history(EditLine *el, int c __unused)
7721573Srgrimes{
77384260Sobrien	const char *hp;
77484260Sobrien	int h;
77584260Sobrien	bool_t found = 0;
7761573Srgrimes
77784260Sobrien	el->el_chared.c_vcmd.action = NOP;
778148834Sstefanf	el->el_chared.c_undo.len = -1;
77984260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
7801573Srgrimes
78184260Sobrien	if (el->el_history.eventno == 0)
78284260Sobrien		return (CC_ERROR);
7831573Srgrimes
78484260Sobrien	if (el->el_history.ref == NULL)
78584260Sobrien		return (CC_ERROR);
7861573Srgrimes
78784260Sobrien	hp = HIST_FIRST(el);
78884260Sobrien	if (hp == NULL)
78984260Sobrien		return (CC_ERROR);
7901573Srgrimes
79184260Sobrien	c_setpat(el);		/* Set search pattern !! */
7921573Srgrimes
79384260Sobrien	for (h = 1; h < el->el_history.eventno && hp; h++) {
7941573Srgrimes#ifdef SDEBUG
79584260Sobrien		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
7961573Srgrimes#endif
79784260Sobrien		if ((strncmp(hp, el->el_line.buffer, (size_t)
79884260Sobrien			    (el->el_line.lastchar - el->el_line.buffer)) ||
79984260Sobrien			hp[el->el_line.lastchar - el->el_line.buffer]) &&
80084260Sobrien		    c_hmatch(el, hp))
80184260Sobrien			found = h;
80284260Sobrien		hp = HIST_NEXT(el);
80384260Sobrien	}
8041573Srgrimes
80584260Sobrien	if (!found) {		/* is it the current history number? */
80684260Sobrien		if (!c_hmatch(el, el->el_history.buf)) {
8071573Srgrimes#ifdef SDEBUG
80884260Sobrien			(void) fprintf(el->el_errfile, "not found\n");
8091573Srgrimes#endif
81084260Sobrien			return (CC_ERROR);
81184260Sobrien		}
8121573Srgrimes	}
81384260Sobrien	el->el_history.eventno = found;
8141573Srgrimes
81584260Sobrien	return (hist_get(el));
8161573Srgrimes}
8171573Srgrimes
8181573Srgrimes
8191573Srgrimes/* ed_prev_line():
8201573Srgrimes *	Move up one line
8211573Srgrimes *	Could be [k] [^p]
8221573Srgrimes */
8231573Srgrimesprotected el_action_t
8241573Srgrimes/*ARGSUSED*/
825148834Sstefanfed_prev_line(EditLine *el, int c __unused)
8261573Srgrimes{
82784260Sobrien	char *ptr;
82884260Sobrien	int nchars = c_hpos(el);
8298870Srgrimes
83084260Sobrien	/*
83184260Sobrien         * Move to the line requested
83284260Sobrien         */
83384260Sobrien	if (*(ptr = el->el_line.cursor) == '\n')
83484260Sobrien		ptr--;
8351573Srgrimes
83684260Sobrien	for (; ptr >= el->el_line.buffer; ptr--)
83784260Sobrien		if (*ptr == '\n' && --el->el_state.argument <= 0)
83884260Sobrien			break;
8391573Srgrimes
84084260Sobrien	if (el->el_state.argument > 0)
84184260Sobrien		return (CC_ERROR);
8421573Srgrimes
84384260Sobrien	/*
84484260Sobrien         * Move to the beginning of the line
84584260Sobrien         */
84684260Sobrien	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
84784260Sobrien		continue;
8488870Srgrimes
84984260Sobrien	/*
85084260Sobrien         * Move to the character requested
85184260Sobrien         */
85284260Sobrien	for (ptr++;
85384260Sobrien	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
85484260Sobrien	    ptr++)
85584260Sobrien		continue;
8568870Srgrimes
85784260Sobrien	el->el_line.cursor = ptr;
85884260Sobrien	return (CC_CURSOR);
8591573Srgrimes}
8601573Srgrimes
8611573Srgrimes
8621573Srgrimes/* ed_next_line():
8631573Srgrimes *	Move down one line
8641573Srgrimes *	Could be [j] [^n]
8651573Srgrimes */
8661573Srgrimesprotected el_action_t
8671573Srgrimes/*ARGSUSED*/
868148834Sstefanfed_next_line(EditLine *el, int c __unused)
8691573Srgrimes{
87084260Sobrien	char *ptr;
87184260Sobrien	int nchars = c_hpos(el);
8721573Srgrimes
87384260Sobrien	/*
87484260Sobrien         * Move to the line requested
87584260Sobrien         */
87684260Sobrien	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
87784260Sobrien		if (*ptr == '\n' && --el->el_state.argument <= 0)
87884260Sobrien			break;
8791573Srgrimes
88084260Sobrien	if (el->el_state.argument > 0)
88184260Sobrien		return (CC_ERROR);
8821573Srgrimes
88384260Sobrien	/*
88484260Sobrien         * Move to the character requested
88584260Sobrien         */
88684260Sobrien	for (ptr++;
88784260Sobrien	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
88884260Sobrien	    ptr++)
88984260Sobrien		continue;
8908870Srgrimes
89184260Sobrien	el->el_line.cursor = ptr;
89284260Sobrien	return (CC_CURSOR);
8931573Srgrimes}
8941573Srgrimes
8951573Srgrimes
8968870Srgrimes/* ed_command():
8971573Srgrimes *	Editline extended command
8981573Srgrimes *	[M-X] [:]
8991573Srgrimes */
9001573Srgrimesprotected el_action_t
9011573Srgrimes/*ARGSUSED*/
902148834Sstefanfed_command(EditLine *el, int c __unused)
9031573Srgrimes{
90484260Sobrien	char tmpbuf[EL_BUFSIZ];
90584260Sobrien	int tmplen;
9061573Srgrimes
907148834Sstefanf	tmplen = c_gets(el, tmpbuf, "\n: ");
908237448Spfg	term__putc(el, '\n');
9091573Srgrimes
910148834Sstefanf	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
911148834Sstefanf		term_beep(el);
9121573Srgrimes
913148834Sstefanf	el->el_map.current = el->el_map.key;
914148834Sstefanf	re_clear_display(el);
915148834Sstefanf	return CC_REFRESH;
9161573Srgrimes}
917