/*	$NetBSD: common.c,v 1.29 2012/03/24 20:08:43 christos Exp $	*/

/*-
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Christos Zoulas of Cornell University.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.29 2012/03/24 20:08:43 christos Exp $");
#endif
#endif /* not lint && not SCCSID */

/*
 * common.c: Common Editor functions
 */
#include "el.h"

/* ed_end_of_file():
 *	Indicate end of file
 *	[^D]
 */
protected el_action_t
/*ARGSUSED*/
ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
{

	re_goto_bottom(el);
	*el->el_line.lastchar = '\0';
	return CC_EOF;
}


/* ed_insert():
 *	Add character to the line
 *	Insert a character [bound to all insert keys]
 */
protected el_action_t
ed_insert(EditLine *el, Int c)
{
	int count = el->el_state.argument;

	if (c == '\0')
		return CC_ERROR;

	if (el->el_line.lastchar + el->el_state.argument >=
	    el->el_line.limit) {
		/* end of buffer space, try to allocate more */
		if (!ch_enlargebufs(el, (size_t) count))
			return CC_ERROR;	/* error allocating more */
	}

	if (count == 1) {
		if (el->el_state.inputmode == MODE_INSERT
		    || el->el_line.cursor >= el->el_line.lastchar)
			c_insert(el, 1);

		*el->el_line.cursor++ = c;
		re_fastaddc(el);		/* fast refresh for one char. */
	} else {
		if (el->el_state.inputmode != MODE_REPLACE_1)
			c_insert(el, el->el_state.argument);

		while (count-- && el->el_line.cursor < el->el_line.lastchar)
			*el->el_line.cursor++ = c;
		re_refresh(el);
	}

	if (el->el_state.inputmode == MODE_REPLACE_1)
		return vi_command_mode(el, 0);

	return CC_NORM;
}


/* ed_delete_prev_word():
 *	Delete from beginning of current word to cursor
 *	[M-^?] [^W]
 */
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
	Char *cp, *p, *kp;

	if (el->el_line.cursor == el->el_line.buffer)
		return CC_ERROR;

	cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
	    el->el_state.argument, ce__isword);

	for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
		*kp++ = *p;
	el->el_chared.c_kill.last = kp;

	c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
	el->el_line.cursor = cp;
	if (el->el_line.cursor < el->el_line.buffer)
		el->el_line.cursor = el->el_line.buffer; /* bounds check */
	return CC_REFRESH;
}


/* ed_delete_next_char():
 *	Delete character under cursor
 *	[^D] [x]
 */
protected el_action_t
/*ARGSUSED*/
ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
#ifdef DEBUG_EDIT
#define	EL	el->el_line
	(void) fprintf(el->el_errlfile,
	    "\nD(b: %x(%s)  c: %x(%s) last: %x(%s) limit: %x(%s)\n",
	    EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
	    EL.lastchar, EL.limit, EL.limit);
#endif
	if (el->el_line.cursor == el->el_line.lastchar) {
			/* if I'm at the end */
		if (el->el_map.type == MAP_VI) {
			if (el->el_line.cursor == el->el_line.buffer) {
				/* if I'm also at the beginning */
#ifdef KSHVI
				return CC_ERROR;
#else
				/* then do an EOF */
				terminal_writec(el, c);
				return CC_EOF;
#endif
			} else {
#ifdef KSHVI
				el->el_line.cursor--;
#else
				return CC_ERROR;
#endif
			}
		} else
				return CC_ERROR;
	}
	c_delafter(el, el->el_state.argument);	/* delete after dot */
	if (el->el_map.type == MAP_VI &&
	    el->el_line.cursor >= el->el_line.lastchar &&
	    el->el_line.cursor > el->el_line.buffer)
			/* bounds check */
		el->el_line.cursor = el->el_line.lastchar - 1;
	return CC_REFRESH;
}


/* ed_kill_line():
 *	Cut to the end of line
 *	[^K] [^K]
 */
protected el_action_t
/*ARGSUSED*/
ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
	Char *kp, *cp;

	cp = el->el_line.cursor;
	kp = el->el_chared.c_kill.buf;
	while (cp < el->el_line.lastchar)
		*kp++ = *cp++;	/* copy it */
	el->el_chared.c_kill.last = kp;
			/* zap! -- delete to end */
	el->el_line.lastchar = el->el_line.cursor;
	return CC_REFRESH;
}


/* ed_move_to_end():
 *	Move cursor to the end of line
 *	[^E] [^E]
 */
protected el_action_t
/*ARGSUSED*/
ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
{

	el->el_line.cursor = el->el_line.lastchar;
	if (el->el_map.type == MAP_VI) {
		if (el->el_chared.c_vcmd.action != NOP) {
			cv_delfini(el);
			return CC_REFRESH;
		}
#ifdef VI_MOVE
		el->el_line.cursor--;
#endif
	}
	return CC_CURSOR;
}


/* ed_move_to_beg():
 *	Move cursor to the beginning of line
 *	[^A] [^A]
 */
protected el_action_t
/*ARGSUSED*/
ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
{

	el->el_line.cursor = el->el_line.buffer;

	if (el->el_map.type == MAP_VI) {
			/* We want FIRST non space character */
		while (Isspace(*el->el_line.cursor))
			el->el_line.cursor++;
		if (el->el_chared.c_vcmd.action != NOP) {
			cv_delfini(el);
			return CC_REFRESH;
		}
	}
	return CC_CURSOR;
}


/* ed_transpose_chars():
 *	Exchange the character to the left of the cursor with the one under it
 *	[^T] [^T]
 */
protected el_action_t
ed_transpose_chars(EditLine *el, Int c)
{

	if (el->el_line.cursor < el->el_line.lastchar) {
		if (el->el_line.lastchar <= &el->el_line.buffer[1])
			return CC_ERROR;
		else
			el->el_line.cursor++;
	}
	if (el->el_line.cursor > &el->el_line.buffer[1]) {
		/* must have at least two chars entered */
		c = el->el_line.cursor[-2];
		el->el_line.cursor[-2] = el->el_line.cursor[-1];
		el->el_line.cursor[-1] = c;
		return CC_REFRESH;
	} else
		return CC_ERROR;
}


/* ed_next_char():
 *	Move to the right one character
 *	[^F] [^F]
 */
protected el_action_t
/*ARGSUSED*/
ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
	Char *lim = el->el_line.lastchar;

	if (el->el_line.cursor >= lim ||
	    (el->el_line.cursor == lim - 1 &&
	    el->el_map.type == MAP_VI &&
	    el->el_chared.c_vcmd.action == NOP))
		return CC_ERROR;

	el->el_line.cursor += el->el_state.argument;
	if (el->el_line.cursor > lim)
		el->el_line.cursor = lim;

	if (el->el_map.type == MAP_VI)
		if (el->el_chared.c_vcmd.action != NOP) {
			cv_delfini(el);
			return CC_REFRESH;
		}
	return CC_CURSOR;
}


/* ed_prev_word():
 *	Move to the beginning of the current word
 *	[M-b] [b]
 */
protected el_action_t
/*ARGSUSED*/
ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{

	if (el->el_line.cursor == el->el_line.buffer)
		return CC_ERROR;

	el->el_line.cursor = c__prev_word(el->el_line.cursor,
	    el->el_line.buffer,
	    el->el_state.argument,
	    ce__isword);

	if (el->el_map.type == MAP_VI)
		if (el->el_chared.c_vcmd.action != NOP) {
			cv_delfini(el);
			return CC_REFRESH;
		}
	return CC_CURSOR;
}


/* ed_prev_char():
 *	Move to the left one character
 *	[^B] [^B]
 */
protected el_action_t
/*ARGSUSED*/
ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{

	if (el->el_line.cursor > el->el_line.buffer) {
		el->el_line.cursor -= el->el_state.argument;
		if (el->el_line.cursor < el->el_line.buffer)
			el->el_line.cursor = el->el_line.buffer;

		if (el->el_map.type == MAP_VI)
			if (el->el_chared.c_vcmd.action != NOP) {
				cv_delfini(el);
				return CC_REFRESH;
			}
		return CC_CURSOR;
	} else
		return CC_ERROR;
}


/* ed_quoted_insert():
 *	Add the next character typed verbatim
 *	[^V] [^V]
 */
protected el_action_t
ed_quoted_insert(EditLine *el, Int c)
{
	int num;
	Char tc;

	tty_quotemode(el);
	num = FUN(el,getc)(el, &tc);
	c = tc;
	tty_noquotemode(el);
	if (num == 1)
		return ed_insert(el, c);
	else
		return ed_end_of_file(el, 0);
}


/* ed_digit():
 *	Adds to argument or enters a digit
 */
protected el_action_t
ed_digit(EditLine *el, Int c)
{

	if (!Isdigit(c))
		return CC_ERROR;

	if (el->el_state.doingarg) {
			/* if doing an arg, add this in... */
		if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
			el->el_state.argument = c - '0';
		else {
			if (el->el_state.argument > 1000000)
				return CC_ERROR;
			el->el_state.argument =
			    (el->el_state.argument * 10) + (c - '0');
		}
		return CC_ARGHACK;
	}

	return ed_insert(el, c);
}


/* ed_argument_digit():
 *	Digit that starts argument
 *	For ESC-n
 */
protected el_action_t
ed_argument_digit(EditLine *el, Int c)
{

	if (!Isdigit(c))
		return CC_ERROR;

	if (el->el_state.doingarg) {
		if (el->el_state.argument > 1000000)
			return CC_ERROR;
		el->el_state.argument = (el->el_state.argument * 10) +
		    (c - '0');
	} else {		/* else starting an argument */
		el->el_state.argument = c - '0';
		el->el_state.doingarg = 1;
	}
	return CC_ARGHACK;
}


/* ed_unassigned():
 *	Indicates unbound character
 *	Bound to keys that are not assigned
 */
protected el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el __attribute__((__unused__)),
    Int c __attribute__((__unused__)))
{

	return CC_ERROR;
}


/**
 ** TTY key handling.
 **/

/* ed_tty_sigint():
 *	Tty interrupt character
 *	[^C]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)), 
	      Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_dsusp():
 *	Tty delayed suspend character
 *	[^Y]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_dsusp(EditLine *el __attribute__((__unused__)), 
	     Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_flush_output():
 *	Tty flush output characters
 *	[^O]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_flush_output(EditLine *el __attribute__((__unused__)), 
		    Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_sigquit():
 *	Tty quit character
 *	[^\]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_sigquit(EditLine *el __attribute__((__unused__)), 
	       Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_sigtstp():
 *	Tty suspend character
 *	[^Z]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), 
	       Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_stop_output():
 *	Tty disallow output characters
 *	[^S]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_stop_output(EditLine *el __attribute__((__unused__)), 
		   Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_tty_start_output():
 *	Tty allow output characters
 *	[^Q]
 */
protected el_action_t
/*ARGSUSED*/
ed_tty_start_output(EditLine *el __attribute__((__unused__)), 
		    Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_newline():
 *	Execute command
 *	[^J]
 */
protected el_action_t
/*ARGSUSED*/
ed_newline(EditLine *el, Int c __attribute__((__unused__)))
{

	re_goto_bottom(el);
	*el->el_line.lastchar++ = '\n';
	*el->el_line.lastchar = '\0';
	return CC_NEWLINE;
}


/* ed_delete_prev_char():
 *	Delete the character to the left of the cursor
 *	[^?]
 */
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{

	if (el->el_line.cursor <= el->el_line.buffer)
		return CC_ERROR;

	c_delbefore(el, el->el_state.argument);
	el->el_line.cursor -= el->el_state.argument;
	if (el->el_line.cursor < el->el_line.buffer)
		el->el_line.cursor = el->el_line.buffer;
	return CC_REFRESH;
}


/* ed_clear_screen():
 *	Clear screen leaving current line at the top
 *	[^L]
 */
protected el_action_t
/*ARGSUSED*/
ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
{

	terminal_clear_screen(el);	/* clear the whole real screen */
	re_clear_display(el);	/* reset everything */
	return CC_REFRESH;
}


/* ed_redisplay():
 *	Redisplay everything
 *	^R
 */
protected el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)), 
	     Int c __attribute__((__unused__)))
{

	return CC_REDISPLAY;
}


/* ed_start_over():
 *	Erase current line and start from scratch
 *	[^G]
 */
protected el_action_t
/*ARGSUSED*/
ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
{

	ch_reset(el, 0);
	return CC_REFRESH;
}


/* ed_sequence_lead_in():
 *	First character in a bound sequence
 *	Placeholder for external keys
 */
protected el_action_t
/*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), 
		    Int c __attribute__((__unused__)))
{

	return CC_NORM;
}


/* ed_prev_history():
 *	Move to the previous history line
 *	[^P] [k]
 */
protected el_action_t
/*ARGSUSED*/
ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
	char beep = 0;
	int sv_event = el->el_history.eventno;

	el->el_chared.c_undo.len = -1;
	*el->el_line.lastchar = '\0';		/* just in case */

	if (el->el_history.eventno == 0) {	/* save the current buffer
						 * away */
		(void) Strncpy(el->el_history.buf, el->el_line.buffer,
		    EL_BUFSIZ);
		el->el_history.last = el->el_history.buf +
		    (el->el_line.lastchar - el->el_line.buffer);
	}
	el->el_history.eventno += el->el_state.argument;

	if (hist_get(el) == CC_ERROR) {
		if (el->el_map.type == MAP_VI) {
			el->el_history.eventno = sv_event;
			
		}
		beep = 1;
		/* el->el_history.eventno was fixed by first call */
		(void) hist_get(el);
	}
	if (beep)
		return CC_REFRESH_BEEP;
	return CC_REFRESH;
}


/* ed_next_history():
 *	Move to the next history line
 *	[^N] [j]
 */
protected el_action_t
/*ARGSUSED*/
ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
	el_action_t beep = CC_REFRESH, rval;

	el->el_chared.c_undo.len = -1;
	*el->el_line.lastchar = '\0';	/* just in case */

	el->el_history.eventno -= el->el_state.argument;

	if (el->el_history.eventno < 0) {
		el->el_history.eventno = 0;
		beep = CC_REFRESH_BEEP;
	}
	rval = hist_get(el);
	if (rval == CC_REFRESH)
		return beep;
	return rval;

}


/* ed_search_prev_history():
 *	Search previous in history for a line matching the current
 *	next search history [M-P] [K]
 */
protected el_action_t
/*ARGSUSED*/
ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
	const Char *hp;
	int h;
	bool_t found = 0;

	el->el_chared.c_vcmd.action = NOP;
	el->el_chared.c_undo.len = -1;
	*el->el_line.lastchar = '\0';	/* just in case */
	if (el->el_history.eventno < 0) {
#ifdef DEBUG_EDIT
		(void) fprintf(el->el_errfile,
		    "e_prev_search_hist(): eventno < 0;\n");
#endif
		el->el_history.eventno = 0;
		return CC_ERROR;
	}
	if (el->el_history.eventno == 0) {
		(void) Strncpy(el->el_history.buf, el->el_line.buffer,
		    EL_BUFSIZ);
		el->el_history.last = el->el_history.buf +
		    (el->el_line.lastchar - el->el_line.buffer);
	}
	if (el->el_history.ref == NULL)
		return CC_ERROR;

	hp = HIST_FIRST(el);
	if (hp == NULL)
		return CC_ERROR;

	c_setpat(el);		/* Set search pattern !! */

	for (h = 1; h <= el->el_history.eventno; h++)
		hp = HIST_NEXT(el);

	while (hp != NULL) {
#ifdef SDEBUG
		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
		if ((Strncmp(hp, el->el_line.buffer, (size_t)
			    (el->el_line.lastchar - el->el_line.buffer)) ||
			hp[el->el_line.lastchar - el->el_line.buffer]) &&
		    c_hmatch(el, hp)) {
			found++;
			break;
		}
		h++;
		hp = HIST_NEXT(el);
	}

	if (!found) {
#ifdef SDEBUG
		(void) fprintf(el->el_errfile, "not found\n");
#endif
		return CC_ERROR;
	}
	el->el_history.eventno = h;

	return hist_get(el);
}


/* ed_search_next_history():
 *	Search next in history for a line matching the current
 *	[M-N] [J]
 */
protected el_action_t
/*ARGSUSED*/
ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
	const Char *hp;
	int h;
	bool_t found = 0;

	el->el_chared.c_vcmd.action = NOP;
	el->el_chared.c_undo.len = -1;
	*el->el_line.lastchar = '\0';	/* just in case */

	if (el->el_history.eventno == 0)
		return CC_ERROR;

	if (el->el_history.ref == NULL)
		return CC_ERROR;

	hp = HIST_FIRST(el);
	if (hp == NULL)
		return CC_ERROR;

	c_setpat(el);		/* Set search pattern !! */

	for (h = 1; h < el->el_history.eventno && hp; h++) {
#ifdef SDEBUG
		(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
		if ((Strncmp(hp, el->el_line.buffer, (size_t)
			    (el->el_line.lastchar - el->el_line.buffer)) ||
			hp[el->el_line.lastchar - el->el_line.buffer]) &&
		    c_hmatch(el, hp))
			found = h;
		hp = HIST_NEXT(el);
	}

	if (!found) {		/* is it the current history number? */
		if (!c_hmatch(el, el->el_history.buf)) {
#ifdef SDEBUG
			(void) fprintf(el->el_errfile, "not found\n");
#endif
			return CC_ERROR;
		}
	}
	el->el_history.eventno = found;

	return hist_get(el);
}


/* ed_prev_line():
 *	Move up one line
 *	Could be [k] [^p]
 */
protected el_action_t
/*ARGSUSED*/
ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
{
	Char *ptr;
	int nchars = c_hpos(el);

	/*
         * Move to the line requested
         */
	if (*(ptr = el->el_line.cursor) == '\n')
		ptr--;

	for (; ptr >= el->el_line.buffer; ptr--)
		if (*ptr == '\n' && --el->el_state.argument <= 0)
			break;

	if (el->el_state.argument > 0)
		return CC_ERROR;

	/*
         * Move to the beginning of the line
         */
	for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
		continue;

	/*
         * Move to the character requested
         */
	for (ptr++;
	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
	    ptr++)
		continue;

	el->el_line.cursor = ptr;
	return CC_CURSOR;
}


/* ed_next_line():
 *	Move down one line
 *	Could be [j] [^n]
 */
protected el_action_t
/*ARGSUSED*/
ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
{
	Char *ptr;
	int nchars = c_hpos(el);

	/*
         * Move to the line requested
         */
	for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
		if (*ptr == '\n' && --el->el_state.argument <= 0)
			break;

	if (el->el_state.argument > 0)
		return CC_ERROR;

	/*
         * Move to the character requested
         */
	for (ptr++;
	    nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
	    ptr++)
		continue;

	el->el_line.cursor = ptr;
	return CC_CURSOR;
}


/* ed_command():
 *	Editline extended command
 *	[M-X] [:]
 */
protected el_action_t
/*ARGSUSED*/
ed_command(EditLine *el, Int c __attribute__((__unused__)))
{
	Char tmpbuf[EL_BUFSIZ];
	int tmplen;

	tmplen = c_gets(el, tmpbuf, STR("\n: "));
	terminal__putc(el, '\n');

	if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
		terminal_beep(el);

	el->el_map.current = el->el_map.key;
	re_clear_display(el);
	return CC_REFRESH;
}
