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 *
32268782Spfg *	$NetBSD: common.c,v 1.23 2009/02/27 04:18:45 msaitoh 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$");
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
124268782Spfg	c_delbefore(el, (int)(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) {
211148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
21284260Sobrien			cv_delfini(el);
21384260Sobrien			return (CC_REFRESH);
21484260Sobrien		}
2151573Srgrimes	}
21684260Sobrien	return (CC_CURSOR);
2171573Srgrimes}
2181573Srgrimes
2191573Srgrimes
2208870Srgrimes/* ed_move_to_beg():
2211573Srgrimes *	Move cursor to the beginning of line
2221573Srgrimes *	[^A] [^A]
2231573Srgrimes */
2241573Srgrimesprotected el_action_t
2251573Srgrimes/*ARGSUSED*/
226148834Sstefanfed_move_to_beg(EditLine *el, int c __unused)
2271573Srgrimes{
2281573Srgrimes
22984260Sobrien	el->el_line.cursor = el->el_line.buffer;
23084260Sobrien
23184260Sobrien	if (el->el_map.type == MAP_VI) {
23284260Sobrien			/* We want FIRST non space character */
23384260Sobrien		while (isspace((unsigned char) *el->el_line.cursor))
23484260Sobrien			el->el_line.cursor++;
235148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
23684260Sobrien			cv_delfini(el);
23784260Sobrien			return (CC_REFRESH);
23884260Sobrien		}
2391573Srgrimes	}
24084260Sobrien	return (CC_CURSOR);
2411573Srgrimes}
2421573Srgrimes
2431573Srgrimes
2448870Srgrimes/* ed_transpose_chars():
2451573Srgrimes *	Exchange the character to the left of the cursor with the one under it
2461573Srgrimes *	[^T] [^T]
2471573Srgrimes */
2481573Srgrimesprotected el_action_t
24984260Sobriened_transpose_chars(EditLine *el, int c)
2501573Srgrimes{
25184260Sobrien
25284260Sobrien	if (el->el_line.cursor < el->el_line.lastchar) {
25384260Sobrien		if (el->el_line.lastchar <= &el->el_line.buffer[1])
25484260Sobrien			return (CC_ERROR);
25584260Sobrien		else
25684260Sobrien			el->el_line.cursor++;
25784260Sobrien	}
25884260Sobrien	if (el->el_line.cursor > &el->el_line.buffer[1]) {
25984260Sobrien		/* must have at least two chars entered */
26084260Sobrien		c = el->el_line.cursor[-2];
26184260Sobrien		el->el_line.cursor[-2] = el->el_line.cursor[-1];
26284260Sobrien		el->el_line.cursor[-1] = c;
26384260Sobrien		return (CC_REFRESH);
26484260Sobrien	} else
26584260Sobrien		return (CC_ERROR);
2661573Srgrimes}
2671573Srgrimes
2681573Srgrimes
2698870Srgrimes/* ed_next_char():
2701573Srgrimes *	Move to the right one character
2711573Srgrimes *	[^F] [^F]
2721573Srgrimes */
2731573Srgrimesprotected el_action_t
2741573Srgrimes/*ARGSUSED*/
275148834Sstefanfed_next_char(EditLine *el, int c __unused)
2761573Srgrimes{
277148834Sstefanf	char *lim = el->el_line.lastchar;
2781573Srgrimes
279148834Sstefanf	if (el->el_line.cursor >= lim ||
280148834Sstefanf	    (el->el_line.cursor == lim - 1 &&
281148834Sstefanf	    el->el_map.type == MAP_VI &&
282148834Sstefanf	    el->el_chared.c_vcmd.action == NOP))
28384260Sobrien		return (CC_ERROR);
2841573Srgrimes
28584260Sobrien	el->el_line.cursor += el->el_state.argument;
286148834Sstefanf	if (el->el_line.cursor > lim)
287148834Sstefanf		el->el_line.cursor = lim;
2881573Srgrimes
28984260Sobrien	if (el->el_map.type == MAP_VI)
290148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
29184260Sobrien			cv_delfini(el);
29284260Sobrien			return (CC_REFRESH);
29384260Sobrien		}
29484260Sobrien	return (CC_CURSOR);
2951573Srgrimes}
2961573Srgrimes
2971573Srgrimes
2988870Srgrimes/* ed_prev_word():
2991573Srgrimes *	Move to the beginning of the current word
3001573Srgrimes *	[M-b] [b]
3011573Srgrimes */
3021573Srgrimesprotected el_action_t
3031573Srgrimes/*ARGSUSED*/
304148834Sstefanfed_prev_word(EditLine *el, int c __unused)
3051573Srgrimes{
3061573Srgrimes
30784260Sobrien	if (el->el_line.cursor == el->el_line.buffer)
30884260Sobrien		return (CC_ERROR);
3091573Srgrimes
31084260Sobrien	el->el_line.cursor = c__prev_word(el->el_line.cursor,
31184260Sobrien	    el->el_line.buffer,
31284260Sobrien	    el->el_state.argument,
31384260Sobrien	    ce__isword);
3141573Srgrimes
31584260Sobrien	if (el->el_map.type == MAP_VI)
316148834Sstefanf		if (el->el_chared.c_vcmd.action != NOP) {
31784260Sobrien			cv_delfini(el);
31884260Sobrien			return (CC_REFRESH);
31984260Sobrien		}
32084260Sobrien	return (CC_CURSOR);
3211573Srgrimes}
3221573Srgrimes
3231573Srgrimes
3248870Srgrimes/* ed_prev_char():
3251573Srgrimes *	Move to the left one character
3261573Srgrimes *	[^B] [^B]
3271573Srgrimes */
3281573Srgrimesprotected el_action_t
3291573Srgrimes/*ARGSUSED*/
330148834Sstefanfed_prev_char(EditLine *el, int c __unused)
3311573Srgrimes{
3321573Srgrimes
33384260Sobrien	if (el->el_line.cursor > el->el_line.buffer) {
33484260Sobrien		el->el_line.cursor -= el->el_state.argument;
33584260Sobrien		if (el->el_line.cursor < el->el_line.buffer)
33684260Sobrien			el->el_line.cursor = el->el_line.buffer;
3371573Srgrimes
33884260Sobrien		if (el->el_map.type == MAP_VI)
339148834Sstefanf			if (el->el_chared.c_vcmd.action != NOP) {
34084260Sobrien				cv_delfini(el);
34184260Sobrien				return (CC_REFRESH);
34284260Sobrien			}
34384260Sobrien		return (CC_CURSOR);
34484260Sobrien	} else
34584260Sobrien		return (CC_ERROR);
3461573Srgrimes}
3471573Srgrimes
3481573Srgrimes
3498870Srgrimes/* ed_quoted_insert():
3501573Srgrimes *	Add the next character typed verbatim
3511573Srgrimes *	[^V] [^V]
3521573Srgrimes */
3531573Srgrimesprotected el_action_t
35484260Sobriened_quoted_insert(EditLine *el, int c)
3551573Srgrimes{
35684260Sobrien	int num;
35784260Sobrien	char tc;
3581573Srgrimes
35984260Sobrien	tty_quotemode(el);
36084260Sobrien	num = el_getc(el, &tc);
36184260Sobrien	c = (unsigned char) tc;
36284260Sobrien	tty_noquotemode(el);
36384260Sobrien	if (num == 1)
36484260Sobrien		return (ed_insert(el, c));
36584260Sobrien	else
36684260Sobrien		return (ed_end_of_file(el, 0));
3671573Srgrimes}
3681573Srgrimes
3691573Srgrimes
3708870Srgrimes/* ed_digit():
3711573Srgrimes *	Adds to argument or enters a digit
3721573Srgrimes */
3731573Srgrimesprotected el_action_t
37484260Sobriened_digit(EditLine *el, int c)
3751573Srgrimes{
3761573Srgrimes
37784260Sobrien	if (!isdigit((unsigned char) c))
37884260Sobrien		return (CC_ERROR);
37984260Sobrien
38084260Sobrien	if (el->el_state.doingarg) {
38184260Sobrien			/* if doing an arg, add this in... */
38284260Sobrien		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
38384260Sobrien			el->el_state.argument = c - '0';
38484260Sobrien		else {
38584260Sobrien			if (el->el_state.argument > 1000000)
38684260Sobrien				return (CC_ERROR);
38784260Sobrien			el->el_state.argument =
38884260Sobrien			    (el->el_state.argument * 10) + (c - '0');
38984260Sobrien		}
39084260Sobrien		return (CC_ARGHACK);
391148834Sstefanf	}
39284260Sobrien
393148834Sstefanf	return ed_insert(el, c);
3941573Srgrimes}
3951573Srgrimes
3961573Srgrimes
3978870Srgrimes/* ed_argument_digit():
3981573Srgrimes *	Digit that starts argument
3991573Srgrimes *	For ESC-n
4001573Srgrimes */
4011573Srgrimesprotected el_action_t
40284260Sobriened_argument_digit(EditLine *el, int c)
4031573Srgrimes{
4041573Srgrimes
40584260Sobrien	if (!isdigit((unsigned char) c))
40684260Sobrien		return (CC_ERROR);
40784260Sobrien
40884260Sobrien	if (el->el_state.doingarg) {
40984260Sobrien		if (el->el_state.argument > 1000000)
41084260Sobrien			return (CC_ERROR);
41184260Sobrien		el->el_state.argument = (el->el_state.argument * 10) +
41284260Sobrien		    (c - '0');
41384260Sobrien	} else {		/* else starting an argument */
41484260Sobrien		el->el_state.argument = c - '0';
41584260Sobrien		el->el_state.doingarg = 1;
41684260Sobrien	}
41784260Sobrien	return (CC_ARGHACK);
4181573Srgrimes}
4191573Srgrimes
4201573Srgrimes
4218870Srgrimes/* ed_unassigned():
4221573Srgrimes *	Indicates unbound character
4231573Srgrimes *	Bound to keys that are not assigned
4241573Srgrimes */
4251573Srgrimesprotected el_action_t
4261573Srgrimes/*ARGSUSED*/
427148834Sstefanfed_unassigned(EditLine *el, int c __unused)
4281573Srgrimes{
42984260Sobrien
430148834Sstefanf	return (CC_ERROR);
4311573Srgrimes}
4321573Srgrimes
4331573Srgrimes
4341573Srgrimes/**
4351573Srgrimes ** TTY key handling.
4361573Srgrimes **/
4371573Srgrimes
4388870Srgrimes/* ed_tty_sigint():
4391573Srgrimes *	Tty interrupt character
4401573Srgrimes *	[^C]
4411573Srgrimes */
4421573Srgrimesprotected el_action_t
4431573Srgrimes/*ARGSUSED*/
444148834Sstefanfed_tty_sigint(EditLine *el __unused,
445148834Sstefanf	      int c __unused)
4468870Srgrimes{
44784260Sobrien
44884260Sobrien	return (CC_NORM);
4491573Srgrimes}
4501573Srgrimes
4511573Srgrimes
4528870Srgrimes/* ed_tty_dsusp():
4531573Srgrimes *	Tty delayed suspend character
4541573Srgrimes *	[^Y]
4551573Srgrimes */
4561573Srgrimesprotected el_action_t
4571573Srgrimes/*ARGSUSED*/
458148834Sstefanfed_tty_dsusp(EditLine *el __unused,
459148834Sstefanf	     int c __unused)
4601573Srgrimes{
46184260Sobrien
46284260Sobrien	return (CC_NORM);
4631573Srgrimes}
4641573Srgrimes
4651573Srgrimes
4668870Srgrimes/* ed_tty_flush_output():
4671573Srgrimes *	Tty flush output characters
4681573Srgrimes *	[^O]
4691573Srgrimes */
4701573Srgrimesprotected el_action_t
4711573Srgrimes/*ARGSUSED*/
472148834Sstefanfed_tty_flush_output(EditLine *el __unused,
473148834Sstefanf		    int c __unused)
4741573Srgrimes{
47584260Sobrien
47684260Sobrien	return (CC_NORM);
4771573Srgrimes}
4781573Srgrimes
4791573Srgrimes
4808870Srgrimes/* ed_tty_sigquit():
4811573Srgrimes *	Tty quit character
4821573Srgrimes *	[^\]
4831573Srgrimes */
4841573Srgrimesprotected el_action_t
4851573Srgrimes/*ARGSUSED*/
486148834Sstefanfed_tty_sigquit(EditLine *el __unused,
487148834Sstefanf	       int c __unused)
4881573Srgrimes{
48984260Sobrien
49084260Sobrien	return (CC_NORM);
4911573Srgrimes}
4921573Srgrimes
4931573Srgrimes
4948870Srgrimes/* ed_tty_sigtstp():
4951573Srgrimes *	Tty suspend character
4961573Srgrimes *	[^Z]
4971573Srgrimes */
4981573Srgrimesprotected el_action_t
4991573Srgrimes/*ARGSUSED*/
500148834Sstefanfed_tty_sigtstp(EditLine *el __unused,
501148834Sstefanf	       int c __unused)
5021573Srgrimes{
50384260Sobrien
50484260Sobrien	return (CC_NORM);
5051573Srgrimes}
5061573Srgrimes
5071573Srgrimes
5088870Srgrimes/* ed_tty_stop_output():
5091573Srgrimes *	Tty disallow output characters
5101573Srgrimes *	[^S]
5111573Srgrimes */
5121573Srgrimesprotected el_action_t
5131573Srgrimes/*ARGSUSED*/
514148834Sstefanfed_tty_stop_output(EditLine *el __unused,
515148834Sstefanf		   int c __unused)
5161573Srgrimes{
51784260Sobrien
51884260Sobrien	return (CC_NORM);
5191573Srgrimes}
5201573Srgrimes
5211573Srgrimes
5228870Srgrimes/* ed_tty_start_output():
5231573Srgrimes *	Tty allow output characters
5241573Srgrimes *	[^Q]
5251573Srgrimes */
5261573Srgrimesprotected el_action_t
5271573Srgrimes/*ARGSUSED*/
528148834Sstefanfed_tty_start_output(EditLine *el __unused,
529148834Sstefanf		    int c __unused)
5301573Srgrimes{
53184260Sobrien
53284260Sobrien	return (CC_NORM);
5331573Srgrimes}
5341573Srgrimes
5351573Srgrimes
5368870Srgrimes/* ed_newline():
5371573Srgrimes *	Execute command
5381573Srgrimes *	[^J]
5391573Srgrimes */
5401573Srgrimesprotected el_action_t
5411573Srgrimes/*ARGSUSED*/
542148834Sstefanfed_newline(EditLine *el, int c __unused)
5431573Srgrimes{
54484260Sobrien
54584260Sobrien	re_goto_bottom(el);
54684260Sobrien	*el->el_line.lastchar++ = '\n';
54784260Sobrien	*el->el_line.lastchar = '\0';
54884260Sobrien	return (CC_NEWLINE);
5491573Srgrimes}
5501573Srgrimes
5511573Srgrimes
5528870Srgrimes/* ed_delete_prev_char():
5531573Srgrimes *	Delete the character to the left of the cursor
5541573Srgrimes *	[^?]
5551573Srgrimes */
5561573Srgrimesprotected el_action_t
5571573Srgrimes/*ARGSUSED*/
558148834Sstefanfed_delete_prev_char(EditLine *el, int c __unused)
5591573Srgrimes{
5601573Srgrimes
56184260Sobrien	if (el->el_line.cursor <= el->el_line.buffer)
56284260Sobrien		return (CC_ERROR);
56384260Sobrien
56484260Sobrien	c_delbefore(el, el->el_state.argument);
56584260Sobrien	el->el_line.cursor -= el->el_state.argument;
56684260Sobrien	if (el->el_line.cursor < el->el_line.buffer)
56784260Sobrien		el->el_line.cursor = el->el_line.buffer;
56884260Sobrien	return (CC_REFRESH);
5691573Srgrimes}
5701573Srgrimes
5711573Srgrimes
5728870Srgrimes/* ed_clear_screen():
5731573Srgrimes *	Clear screen leaving current line at the top
5741573Srgrimes *	[^L]
5751573Srgrimes */
5761573Srgrimesprotected el_action_t
5771573Srgrimes/*ARGSUSED*/
578148834Sstefanfed_clear_screen(EditLine *el, int c __unused)
5791573Srgrimes{
58084260Sobrien
58184260Sobrien	term_clear_screen(el);	/* clear the whole real screen */
58284260Sobrien	re_clear_display(el);	/* reset everything */
58384260Sobrien	return (CC_REFRESH);
5841573Srgrimes}
5851573Srgrimes
5861573Srgrimes
5878870Srgrimes/* ed_redisplay():
5881573Srgrimes *	Redisplay everything
5891573Srgrimes *	^R
5901573Srgrimes */
5911573Srgrimesprotected el_action_t
5921573Srgrimes/*ARGSUSED*/
593148834Sstefanfed_redisplay(EditLine *el __unused,
594148834Sstefanf	     int c __unused)
5951573Srgrimes{
59684260Sobrien
59784260Sobrien	return (CC_REDISPLAY);
5981573Srgrimes}
5991573Srgrimes
6001573Srgrimes
6018870Srgrimes/* ed_start_over():
6021573Srgrimes *	Erase current line and start from scratch
6031573Srgrimes *	[^G]
6041573Srgrimes */
6051573Srgrimesprotected el_action_t
6061573Srgrimes/*ARGSUSED*/
607148834Sstefanfed_start_over(EditLine *el, int c __unused)
6081573Srgrimes{
60984260Sobrien
610148834Sstefanf	ch_reset(el, 0);
61184260Sobrien	return (CC_REFRESH);
6121573Srgrimes}
6131573Srgrimes
6141573Srgrimes
6158870Srgrimes/* ed_sequence_lead_in():
6161573Srgrimes *	First character in a bound sequence
6171573Srgrimes *	Placeholder for external keys
6181573Srgrimes */
6191573Srgrimesprotected el_action_t
6201573Srgrimes/*ARGSUSED*/
621148834Sstefanfed_sequence_lead_in(EditLine *el __unused,
622148834Sstefanf		    int c __unused)
6231573Srgrimes{
62484260Sobrien
62584260Sobrien	return (CC_NORM);
6261573Srgrimes}
6271573Srgrimes
6281573Srgrimes
6298870Srgrimes/* ed_prev_history():
6301573Srgrimes *	Move to the previous history line
6311573Srgrimes *	[^P] [k]
6321573Srgrimes */
6331573Srgrimesprotected el_action_t
6341573Srgrimes/*ARGSUSED*/
635148834Sstefanfed_prev_history(EditLine *el, int c __unused)
6361573Srgrimes{
63784260Sobrien	char beep = 0;
638148834Sstefanf	int sv_event = el->el_history.eventno;
6391573Srgrimes
640148834Sstefanf	el->el_chared.c_undo.len = -1;
64184260Sobrien	*el->el_line.lastchar = '\0';		/* just in case */
6421573Srgrimes
64384260Sobrien	if (el->el_history.eventno == 0) {	/* save the current buffer
64484260Sobrien						 * away */
64584260Sobrien		(void) strncpy(el->el_history.buf, el->el_line.buffer,
64684260Sobrien		    EL_BUFSIZ);
64784260Sobrien		el->el_history.last = el->el_history.buf +
64884260Sobrien		    (el->el_line.lastchar - el->el_line.buffer);
64984260Sobrien	}
65084260Sobrien	el->el_history.eventno += el->el_state.argument;
6511573Srgrimes
65284260Sobrien	if (hist_get(el) == CC_ERROR) {
653148834Sstefanf		if (el->el_map.type == MAP_VI) {
654148834Sstefanf			el->el_history.eventno = sv_event;
655148834Sstefanf			return CC_ERROR;
656148834Sstefanf		}
65784260Sobrien		beep = 1;
65884260Sobrien		/* el->el_history.eventno was fixed by first call */
65984260Sobrien		(void) hist_get(el);
66084260Sobrien	}
66184260Sobrien	if (beep)
662148834Sstefanf		return CC_REFRESH_BEEP;
663148834Sstefanf	return CC_REFRESH;
6641573Srgrimes}
6651573Srgrimes
6661573Srgrimes
6678870Srgrimes/* ed_next_history():
6681573Srgrimes *	Move to the next history line
6691573Srgrimes *	[^N] [j]
6701573Srgrimes */
6711573Srgrimesprotected el_action_t
6721573Srgrimes/*ARGSUSED*/
673148834Sstefanfed_next_history(EditLine *el, int c __unused)
6741573Srgrimes{
675148834Sstefanf	el_action_t beep = CC_REFRESH, rval;
6761573Srgrimes
677148834Sstefanf	el->el_chared.c_undo.len = -1;
67884260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
6791573Srgrimes
68084260Sobrien	el->el_history.eventno -= el->el_state.argument;
6811573Srgrimes
68284260Sobrien	if (el->el_history.eventno < 0) {
68384260Sobrien		el->el_history.eventno = 0;
684148834Sstefanf		beep = CC_REFRESH_BEEP;
68584260Sobrien	}
686148834Sstefanf	rval = hist_get(el);
687148834Sstefanf	if (rval == CC_REFRESH)
688148834Sstefanf		return beep;
689148834Sstefanf	return rval;
690148834Sstefanf
6911573Srgrimes}
6921573Srgrimes
6931573Srgrimes
6948870Srgrimes/* ed_search_prev_history():
6951573Srgrimes *	Search previous in history for a line matching the current
6961573Srgrimes *	next search history [M-P] [K]
6971573Srgrimes */
6981573Srgrimesprotected el_action_t
6991573Srgrimes/*ARGSUSED*/
700148834Sstefanfed_search_prev_history(EditLine *el, int c __unused)
7011573Srgrimes{
70284260Sobrien	const char *hp;
70384260Sobrien	int h;
70484260Sobrien	bool_t found = 0;
7051573Srgrimes
70684260Sobrien	el->el_chared.c_vcmd.action = NOP;
707148834Sstefanf	el->el_chared.c_undo.len = -1;
70884260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
70984260Sobrien	if (el->el_history.eventno < 0) {
7101573Srgrimes#ifdef DEBUG_EDIT
71184260Sobrien		(void) fprintf(el->el_errfile,
71284260Sobrien		    "e_prev_search_hist(): eventno < 0;\n");
7131573Srgrimes#endif
71484260Sobrien		el->el_history.eventno = 0;
71584260Sobrien		return (CC_ERROR);
71684260Sobrien	}
71784260Sobrien	if (el->el_history.eventno == 0) {
71884260Sobrien		(void) strncpy(el->el_history.buf, el->el_line.buffer,
71984260Sobrien		    EL_BUFSIZ);
72084260Sobrien		el->el_history.last = el->el_history.buf +
72184260Sobrien		    (el->el_line.lastchar - el->el_line.buffer);
72284260Sobrien	}
72384260Sobrien	if (el->el_history.ref == NULL)
72484260Sobrien		return (CC_ERROR);
7251573Srgrimes
72684260Sobrien	hp = HIST_FIRST(el);
72784260Sobrien	if (hp == NULL)
72884260Sobrien		return (CC_ERROR);
7291573Srgrimes
73084260Sobrien	c_setpat(el);		/* Set search pattern !! */
7311573Srgrimes
73284260Sobrien	for (h = 1; h <= el->el_history.eventno; h++)
73384260Sobrien		hp = HIST_NEXT(el);
7341573Srgrimes
73584260Sobrien	while (hp != NULL) {
7361573Srgrimes#ifdef SDEBUG
73784260Sobrien		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
7381573Srgrimes#endif
73984260Sobrien		if ((strncmp(hp, el->el_line.buffer, (size_t)
74084260Sobrien			    (el->el_line.lastchar - el->el_line.buffer)) ||
74184260Sobrien			hp[el->el_line.lastchar - el->el_line.buffer]) &&
74284260Sobrien		    c_hmatch(el, hp)) {
74384260Sobrien			found++;
74484260Sobrien			break;
74584260Sobrien		}
74684260Sobrien		h++;
74784260Sobrien		hp = HIST_NEXT(el);
7481573Srgrimes	}
7491573Srgrimes
75084260Sobrien	if (!found) {
7511573Srgrimes#ifdef SDEBUG
75284260Sobrien		(void) fprintf(el->el_errfile, "not found\n");
7531573Srgrimes#endif
75484260Sobrien		return (CC_ERROR);
75584260Sobrien	}
75684260Sobrien	el->el_history.eventno = h;
7571573Srgrimes
75884260Sobrien	return (hist_get(el));
7591573Srgrimes}
7601573Srgrimes
7611573Srgrimes
7628870Srgrimes/* ed_search_next_history():
7631573Srgrimes *	Search next in history for a line matching the current
7641573Srgrimes *	[M-N] [J]
7651573Srgrimes */
7661573Srgrimesprotected el_action_t
7671573Srgrimes/*ARGSUSED*/
768148834Sstefanfed_search_next_history(EditLine *el, int c __unused)
7691573Srgrimes{
77084260Sobrien	const char *hp;
77184260Sobrien	int h;
77284260Sobrien	bool_t found = 0;
7731573Srgrimes
77484260Sobrien	el->el_chared.c_vcmd.action = NOP;
775148834Sstefanf	el->el_chared.c_undo.len = -1;
77684260Sobrien	*el->el_line.lastchar = '\0';	/* just in case */
7771573Srgrimes
77884260Sobrien	if (el->el_history.eventno == 0)
77984260Sobrien		return (CC_ERROR);
7801573Srgrimes
78184260Sobrien	if (el->el_history.ref == NULL)
78284260Sobrien		return (CC_ERROR);
7831573Srgrimes
78484260Sobrien	hp = HIST_FIRST(el);
78584260Sobrien	if (hp == NULL)
78684260Sobrien		return (CC_ERROR);
7871573Srgrimes
78884260Sobrien	c_setpat(el);		/* Set search pattern !! */
7891573Srgrimes
79084260Sobrien	for (h = 1; h < el->el_history.eventno && hp; h++) {
7911573Srgrimes#ifdef SDEBUG
79284260Sobrien		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
7931573Srgrimes#endif
79484260Sobrien		if ((strncmp(hp, el->el_line.buffer, (size_t)
79584260Sobrien			    (el->el_line.lastchar - el->el_line.buffer)) ||
79684260Sobrien			hp[el->el_line.lastchar - el->el_line.buffer]) &&
79784260Sobrien		    c_hmatch(el, hp))
79884260Sobrien			found = h;
79984260Sobrien		hp = HIST_NEXT(el);
80084260Sobrien	}
8011573Srgrimes
80284260Sobrien	if (!found) {		/* is it the current history number? */
80384260Sobrien		if (!c_hmatch(el, el->el_history.buf)) {
8041573Srgrimes#ifdef SDEBUG
80584260Sobrien			(void) fprintf(el->el_errfile, "not found\n");
8061573Srgrimes#endif
80784260Sobrien			return (CC_ERROR);
80884260Sobrien		}
8091573Srgrimes	}
81084260Sobrien	el->el_history.eventno = found;
8111573Srgrimes
81284260Sobrien	return (hist_get(el));
8131573Srgrimes}
8141573Srgrimes
8151573Srgrimes
8161573Srgrimes/* ed_prev_line():
8171573Srgrimes *	Move up one line
8181573Srgrimes *	Could be [k] [^p]
8191573Srgrimes */
8201573Srgrimesprotected el_action_t
8211573Srgrimes/*ARGSUSED*/
822148834Sstefanfed_prev_line(EditLine *el, int c __unused)
8231573Srgrimes{
82484260Sobrien	char *ptr;
82584260Sobrien	int nchars = c_hpos(el);
8268870Srgrimes
82784260Sobrien	/*
82884260Sobrien         * Move to the line requested
82984260Sobrien         */
83084260Sobrien	if (*(ptr = el->el_line.cursor) == '\n')
83184260Sobrien		ptr--;
8321573Srgrimes
83384260Sobrien	for (; ptr >= el->el_line.buffer; ptr--)
83484260Sobrien		if (*ptr == '\n' && --el->el_state.argument <= 0)
83584260Sobrien			break;
8361573Srgrimes
83784260Sobrien	if (el->el_state.argument > 0)
83884260Sobrien		return (CC_ERROR);
8391573Srgrimes
84084260Sobrien	/*
84184260Sobrien         * Move to the beginning of the line
84284260Sobrien         */
84384260Sobrien	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
84484260Sobrien		continue;
8458870Srgrimes
84684260Sobrien	/*
84784260Sobrien         * Move to the character requested
84884260Sobrien         */
84984260Sobrien	for (ptr++;
85084260Sobrien	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
85184260Sobrien	    ptr++)
85284260Sobrien		continue;
8538870Srgrimes
85484260Sobrien	el->el_line.cursor = ptr;
85584260Sobrien	return (CC_CURSOR);
8561573Srgrimes}
8571573Srgrimes
8581573Srgrimes
8591573Srgrimes/* ed_next_line():
8601573Srgrimes *	Move down one line
8611573Srgrimes *	Could be [j] [^n]
8621573Srgrimes */
8631573Srgrimesprotected el_action_t
8641573Srgrimes/*ARGSUSED*/
865148834Sstefanfed_next_line(EditLine *el, int c __unused)
8661573Srgrimes{
86784260Sobrien	char *ptr;
86884260Sobrien	int nchars = c_hpos(el);
8691573Srgrimes
87084260Sobrien	/*
87184260Sobrien         * Move to the line requested
87284260Sobrien         */
87384260Sobrien	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
87484260Sobrien		if (*ptr == '\n' && --el->el_state.argument <= 0)
87584260Sobrien			break;
8761573Srgrimes
87784260Sobrien	if (el->el_state.argument > 0)
87884260Sobrien		return (CC_ERROR);
8791573Srgrimes
88084260Sobrien	/*
88184260Sobrien         * Move to the character requested
88284260Sobrien         */
88384260Sobrien	for (ptr++;
88484260Sobrien	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
88584260Sobrien	    ptr++)
88684260Sobrien		continue;
8878870Srgrimes
88884260Sobrien	el->el_line.cursor = ptr;
88984260Sobrien	return (CC_CURSOR);
8901573Srgrimes}
8911573Srgrimes
8921573Srgrimes
8938870Srgrimes/* ed_command():
8941573Srgrimes *	Editline extended command
8951573Srgrimes *	[M-X] [:]
8961573Srgrimes */
8971573Srgrimesprotected el_action_t
8981573Srgrimes/*ARGSUSED*/
899148834Sstefanfed_command(EditLine *el, int c __unused)
9001573Srgrimes{
90184260Sobrien	char tmpbuf[EL_BUFSIZ];
90284260Sobrien	int tmplen;
9031573Srgrimes
904148834Sstefanf	tmplen = c_gets(el, tmpbuf, "\n: ");
905237448Spfg	term__putc(el, '\n');
9061573Srgrimes
907148834Sstefanf	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
908148834Sstefanf		term_beep(el);
9091573Srgrimes
910148834Sstefanf	el->el_map.current = el->el_map.key;
911148834Sstefanf	re_clear_display(el);
912148834Sstefanf	return CC_REFRESH;
9131573Srgrimes}
914