xref: /csrg-svn/lib/libedit/chared.c (revision 61275)
154210Sbostic /*-
2*61275Sbostic  * Copyright (c) 1992, 1993
3*61275Sbostic  *	The Regents of the University of California.  All rights reserved.
454210Sbostic  *
554210Sbostic  * This code is derived from software contributed to Berkeley by
654210Sbostic  * Christos Zoulas of Cornell University.
754210Sbostic  *
854210Sbostic  * %sccs.include.redist.c%
954210Sbostic  */
1054210Sbostic 
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61275Sbostic static char sccsid[] = "@(#)chared.c	8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454210Sbostic 
1554210Sbostic /*
1654624Schristos  * chared.c: Character editor utilities
1754210Sbostic  */
1854210Sbostic #include "sys.h"
1954210Sbostic 
2054210Sbostic #include <stdlib.h>
2154210Sbostic #include "el.h"
2254210Sbostic 
2354210Sbostic /* cv_undo():
2454210Sbostic  *	Handle state for the vi undo command
2554210Sbostic  */
2654210Sbostic protected void
cv_undo(el,action,size,ptr)2754210Sbostic cv_undo(el, action, size, ptr)
2854210Sbostic     EditLine *el;
2954210Sbostic     int action, size;
3054210Sbostic     char *ptr;
3154210Sbostic {
3254210Sbostic     c_undo_t *vu = &el->el_chared.c_undo;
3354210Sbostic     vu->action = action;
3454210Sbostic     vu->ptr    = ptr;
3554210Sbostic     vu->isize  = size;
3654210Sbostic     (void) memcpy(vu->buf, vu->ptr, size);
3754210Sbostic #ifdef DEBUG_UNDO
3854210Sbostic     (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
3954210Sbostic 		   vu->ptr, vu->isize, vu->dsize);
4054210Sbostic #endif
4154210Sbostic }
4254210Sbostic 
4354210Sbostic 
4454210Sbostic /* c_insert():
4554210Sbostic  *	Insert num characters
4654210Sbostic  */
4754210Sbostic protected void
c_insert(el,num)4854210Sbostic c_insert(el, num)
4954210Sbostic     EditLine *el;
5054210Sbostic     int num;
5154210Sbostic {
5254210Sbostic     char *cp;
5354210Sbostic 
5454210Sbostic     if (el->el_line.lastchar + num >= el->el_line.limit)
5554210Sbostic 	return;			/* can't go past end of buffer */
5654210Sbostic 
5754210Sbostic     if (el->el_line.cursor < el->el_line.lastchar) {
5854210Sbostic 	/* if I must move chars */
5954210Sbostic 	for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
6054210Sbostic 	    cp[num] = *cp;
6154210Sbostic     }
6254210Sbostic     el->el_line.lastchar += num;
6354210Sbostic } /* end c_insert */
6454210Sbostic 
6554210Sbostic 
6654210Sbostic /* c_delafter():
6754210Sbostic  *	Delete num characters after the cursor
6854210Sbostic  */
6954210Sbostic protected void
c_delafter(el,num)7054210Sbostic c_delafter(el, num)
7154210Sbostic     EditLine *el;
7254210Sbostic     int num;
7354210Sbostic {
7454210Sbostic 
7554210Sbostic     if (el->el_line.cursor + num > el->el_line.lastchar)
7654210Sbostic 	num = el->el_line.lastchar - el->el_line.cursor;
7754210Sbostic 
7854210Sbostic     if (num > 0) {
7954210Sbostic 	char *cp;
8054210Sbostic 
8154210Sbostic 	if (el->el_map.current != el->el_map.emacs)
8254210Sbostic 	    cv_undo(el, INSERT, num, el->el_line.cursor);
8354210Sbostic 
8454210Sbostic 	for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
8554210Sbostic 	    *cp = cp[num];
8654210Sbostic 
8754210Sbostic 	el->el_line.lastchar -= num;
8854210Sbostic     }
8954210Sbostic }
9054210Sbostic 
9154210Sbostic 
9254210Sbostic /* c_delbefore():
9354210Sbostic  *	Delete num characters before the cursor
9454210Sbostic  */
9554210Sbostic protected void
c_delbefore(el,num)9654210Sbostic c_delbefore(el, num)
9754210Sbostic     EditLine *el;
9854210Sbostic     int num;
9954210Sbostic {
10054210Sbostic 
10154210Sbostic     if (el->el_line.cursor - num < el->el_line.buffer)
10254210Sbostic 	num = el->el_line.cursor - el->el_line.buffer;
10354210Sbostic 
10454210Sbostic     if (num > 0) {
10554210Sbostic 	char *cp;
10654210Sbostic 
10754210Sbostic 	if (el->el_map.current != el->el_map.emacs)
10854210Sbostic 	    cv_undo(el, INSERT, num, el->el_line.cursor - num);
10954210Sbostic 
11054210Sbostic 	for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++)
11154210Sbostic 	    *cp = cp[num];
11254210Sbostic 
11354210Sbostic 	el->el_line.lastchar -= num;
11454210Sbostic     }
11554210Sbostic }
11654210Sbostic 
11754210Sbostic 
11854210Sbostic /* ce__isword():
11954210Sbostic  *	Return if p is part of a word according to emacs
12054210Sbostic  */
12154210Sbostic protected int
ce__isword(p)12254210Sbostic ce__isword(p)
12354210Sbostic     int p;
12454210Sbostic {
12554210Sbostic     return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL;
12654210Sbostic }
12754210Sbostic 
12854210Sbostic 
12954210Sbostic /* cv__isword():
13054210Sbostic  *	Return if p is part of a word according to vi
13154210Sbostic  */
13254210Sbostic protected int
cv__isword(p)13354210Sbostic cv__isword(p)
13454210Sbostic     int p;
13554210Sbostic {
13654210Sbostic     return !isspace(p);
13754210Sbostic }
13854210Sbostic 
13954210Sbostic 
14054210Sbostic /* c__prev_word():
14154210Sbostic  *	Find the previous word
14254210Sbostic  */
14354210Sbostic protected char *
c__prev_word(p,low,n,wtest)14454210Sbostic c__prev_word(p, low, n, wtest)
14554210Sbostic     register char *p, *low;
14654210Sbostic     register int n;
14754210Sbostic     int (*wtest) __P((int));
14854210Sbostic {
14954210Sbostic     p--;
15054210Sbostic 
15154210Sbostic     while (n--) {
15254210Sbostic 	while ((p >= low) && !(*wtest)((unsigned char) *p))
15354210Sbostic 	    p--;
15454210Sbostic 	while ((p >= low) && (*wtest)((unsigned char) *p))
15554210Sbostic 	    p--;
15654210Sbostic     }
15754210Sbostic 
15854210Sbostic     /* cp now points to one character before the word */
15954210Sbostic     p++;
16054210Sbostic     if (p < low)
16154210Sbostic 	p = low;
16254210Sbostic     /* cp now points where we want it */
16354210Sbostic     return p;
16454210Sbostic }
16554210Sbostic 
16654210Sbostic 
16754210Sbostic /* c__next_word():
16854210Sbostic  *	Find the next word
16954210Sbostic  */
17054210Sbostic protected char *
c__next_word(p,high,n,wtest)17154210Sbostic c__next_word(p, high, n, wtest)
17254210Sbostic     register char *p, *high;
17354210Sbostic     register int n;
17454210Sbostic     int (*wtest) __P((int));
17554210Sbostic {
17654210Sbostic     while (n--) {
17754210Sbostic 	while ((p < high) && !(*wtest)((unsigned char) *p))
17854210Sbostic 	    p++;
17954210Sbostic 	while ((p < high) && (*wtest)((unsigned char) *p))
18054210Sbostic 	    p++;
18154210Sbostic     }
18254210Sbostic     if (p > high)
18354210Sbostic 	p = high;
18454210Sbostic     /* p now points where we want it */
18554210Sbostic     return p;
18654210Sbostic }
18754210Sbostic 
18854210Sbostic /* cv_next_word():
18954210Sbostic  *	Find the next word vi style
19054210Sbostic  */
19154210Sbostic protected char *
cv_next_word(el,p,high,n,wtest)19254210Sbostic cv_next_word(el, p, high, n, wtest)
19354210Sbostic     EditLine *el;
19454210Sbostic     register char *p, *high;
19554210Sbostic     register int n;
19654210Sbostic     int (*wtest) __P((int));
19754210Sbostic {
19854210Sbostic     int test;
19954210Sbostic 
20054210Sbostic     while (n--) {
20154210Sbostic     	test = (*wtest)((unsigned char) *p);
20254210Sbostic 	while ((p < high) && (*wtest)((unsigned char) *p) == test)
20354210Sbostic 	    p++;
20454210Sbostic 	/*
20554210Sbostic 	 * vi historically deletes with cw only the word preserving the
20654210Sbostic 	 * trailing whitespace! This is not what 'w' does..
20754210Sbostic 	 */
20854210Sbostic 	if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
20954210Sbostic 	    while ((p < high) && isspace((unsigned char) *p))
21054210Sbostic 		p++;
21154210Sbostic     }
21254210Sbostic 
21354210Sbostic     /* p now points where we want it */
21454210Sbostic     if (p > high)
21554210Sbostic 	return high;
21654210Sbostic     else
21754210Sbostic 	return p;
21854210Sbostic }
21954210Sbostic 
22054210Sbostic 
22154210Sbostic /* cv_prev_word():
22254210Sbostic  *	Find the previous word vi style
22354210Sbostic  */
22454210Sbostic protected char *
cv_prev_word(el,p,low,n,wtest)22554210Sbostic cv_prev_word(el, p, low, n, wtest)
22654210Sbostic     EditLine *el;
22754210Sbostic     register char *p, *low;
22854210Sbostic     register int n;
22954210Sbostic     int (*wtest) __P((int));
23054210Sbostic {
23154210Sbostic     int test;
23254210Sbostic 
23354210Sbostic     while (n--) {
23454210Sbostic 	p--;
23554210Sbostic 	/*
23654210Sbostic 	 * vi historically deletes with cb only the word preserving the
23754210Sbostic 	 * leading whitespace! This is not what 'b' does..
23854210Sbostic 	 */
23954210Sbostic 	if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
24054210Sbostic 	    while ((p > low) && isspace((unsigned char) *p))
24154210Sbostic 		p--;
24254210Sbostic 	test = (*wtest)((unsigned char) *p);
24354210Sbostic 	while ((p >= low) && (*wtest)((unsigned char) *p) == test)
24454210Sbostic 	    p--;
24554210Sbostic 	p++;
24654210Sbostic 	while (isspace((unsigned char) *p))
24754210Sbostic 		p++;
24854210Sbostic     }
24954210Sbostic 
25054210Sbostic     /* p now points where we want it */
25154210Sbostic     if (p < low)
25254210Sbostic 	return low;
25354210Sbostic     else
25454210Sbostic 	return p;
25554210Sbostic }
25654210Sbostic 
25754210Sbostic 
25854210Sbostic #ifdef notdef
25954210Sbostic /* c__number():
26054210Sbostic  *	Ignore character p points to, return number appearing after that.
26154210Sbostic  * 	A '$' by itself means a big number; "$-" is for negative; '^' means 1.
26254210Sbostic  * 	Return p pointing to last char used.
26354210Sbostic  */
26454210Sbostic protected char *
c__number(p,num,dval)26554210Sbostic c__number(p, num, dval)
26654210Sbostic     char *p;	/* character position */
26754210Sbostic     int *num;	/* Return value	*/
26854210Sbostic     int dval;	/* dval is the number to subtract from like $-3 */
26954210Sbostic {
27054210Sbostic     register int i;
27154210Sbostic     register int sign = 1;
27254210Sbostic 
27354210Sbostic     if (*++p == '^') {
27454210Sbostic 	*num = 1;
27554210Sbostic 	return p;
27654210Sbostic     }
27754210Sbostic     if (*p == '$') {
27854210Sbostic 	if (*++p != '-') {
27954210Sbostic 	    *num = 0x7fffffff;	/* Handle $ */
28054210Sbostic 	    return --p;
28154210Sbostic 	}
28254210Sbostic 	sign = -1;		/* Handle $- */
28354210Sbostic 	++p;
28454210Sbostic     }
28554210Sbostic     for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
28654210Sbostic 	continue;
28754210Sbostic     *num = (sign < 0 ? dval - i : i);
28854210Sbostic     return --p;
28954210Sbostic }
29054210Sbostic #endif
29154210Sbostic 
29254210Sbostic /* cv_delfini():
29354210Sbostic  *	Finish vi delete action
29454210Sbostic  */
29554210Sbostic protected void
cv_delfini(el)29654210Sbostic cv_delfini(el)
29754210Sbostic     EditLine *el;
29854210Sbostic {
29954210Sbostic     register int size;
30054210Sbostic     int oaction;
30154210Sbostic 
30254210Sbostic     if (el->el_chared.c_vcmd.action & INSERT)
30354210Sbostic 	el->el_map.current = el->el_map.key;
30454210Sbostic 
30554210Sbostic     oaction = el->el_chared.c_vcmd.action;
30654210Sbostic     el->el_chared.c_vcmd.action = NOP;
30754210Sbostic 
30854210Sbostic     if (el->el_chared.c_vcmd.pos == 0)
30954210Sbostic 	return;
31054210Sbostic 
31154210Sbostic 
31254210Sbostic     if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
31354210Sbostic 	size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
31454210Sbostic 	c_delbefore(el, size);
31554210Sbostic 	el->el_line.cursor = el->el_chared.c_vcmd.pos;
31654210Sbostic 	re_refresh_cursor(el);
31754210Sbostic     }
31854210Sbostic     else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
31954210Sbostic 	size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
32054210Sbostic 	c_delafter(el, size);
32154210Sbostic     }
32254210Sbostic     else {
32354210Sbostic 	size = 1;
32454210Sbostic 	c_delafter(el, size);
32554210Sbostic     }
32654210Sbostic     switch (oaction) {
32754210Sbostic     case DELETE|INSERT:
32854210Sbostic 	el->el_chared.c_undo.action = DELETE|INSERT;
32954210Sbostic 	break;
33054210Sbostic     case DELETE:
33154210Sbostic 	el->el_chared.c_undo.action = INSERT;
33254210Sbostic 	break;
33354210Sbostic     case NOP:
33454210Sbostic     case INSERT:
33554210Sbostic     default:
33654210Sbostic 	abort();
33754210Sbostic 	break;
33854210Sbostic     }
33954210Sbostic 
34054210Sbostic 
34154210Sbostic     el->el_chared.c_undo.ptr = el->el_line.cursor;
34254210Sbostic     el->el_chared.c_undo.dsize = size;
34354210Sbostic }
34454210Sbostic 
34554210Sbostic 
34654210Sbostic #ifdef notdef
34754210Sbostic /* ce__endword():
34854210Sbostic  *	Go to the end of this word according to emacs
34954210Sbostic  */
35054210Sbostic protected char *
ce__endword(p,high,n)35154210Sbostic ce__endword(p, high, n)
35254210Sbostic     char *p, *high;
35354210Sbostic     int n;
35454210Sbostic {
35554210Sbostic     p++;
35654210Sbostic 
35754210Sbostic     while (n--) {
35854210Sbostic 	while ((p < high) && isspace((unsigned char) *p))
35954210Sbostic 	    p++;
36054210Sbostic 	while ((p < high) && !isspace((unsigned char) *p))
36154210Sbostic 	    p++;
36254210Sbostic     }
36354210Sbostic 
36454210Sbostic     p--;
36554210Sbostic     return p;
36654210Sbostic }
36754210Sbostic #endif
36854210Sbostic 
36954210Sbostic 
37054210Sbostic /* cv__endword():
37154210Sbostic  *	Go to the end of this word according to vi
37254210Sbostic  */
37354210Sbostic protected char *
cv__endword(p,high,n)37454210Sbostic cv__endword(p, high, n)
37554210Sbostic     char *p, *high;
37654210Sbostic     int n;
37754210Sbostic {
37854210Sbostic     p++;
37954210Sbostic 
38054210Sbostic     while (n--) {
38154210Sbostic 	while ((p < high) && isspace((unsigned char) *p))
38254210Sbostic 	    p++;
38354210Sbostic 
38454210Sbostic 	if (isalnum((unsigned char) *p))
38554210Sbostic 	    while ((p < high) && isalnum((unsigned char) *p))
38654210Sbostic 		p++;
38754210Sbostic 	else
38854210Sbostic 	    while ((p < high) && !(isspace((unsigned char) *p) ||
38954210Sbostic 				   isalnum((unsigned char) *p)))
39054210Sbostic 		p++;
39154210Sbostic     }
39254210Sbostic     p--;
39354210Sbostic     return p;
39454210Sbostic }
39554210Sbostic 
39654210Sbostic /* ch_init():
39754210Sbostic  *	Initialize the character editor
39854210Sbostic  */
39954210Sbostic protected int
ch_init(el)40054210Sbostic ch_init(el)
40154210Sbostic     EditLine *el;
40254210Sbostic {
40354210Sbostic     el->el_line.buffer              = (char *)  el_malloc(EL_BUFSIZ);
40454210Sbostic     (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
40554210Sbostic     el->el_line.cursor              = el->el_line.buffer;
40654210Sbostic     el->el_line.lastchar            = el->el_line.buffer;
40754210Sbostic     el->el_line.limit  		    = &el->el_line.buffer[EL_BUFSIZ - 2];
40854210Sbostic 
40954210Sbostic     el->el_chared.c_undo.buf        = (char *)  el_malloc(EL_BUFSIZ);
41054210Sbostic     (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
41154210Sbostic     el->el_chared.c_undo.action     = NOP;
41254210Sbostic     el->el_chared.c_undo.isize      = 0;
41354210Sbostic     el->el_chared.c_undo.dsize      = 0;
41454210Sbostic     el->el_chared.c_undo.ptr        = el->el_line.buffer;
41554210Sbostic 
41654210Sbostic     el->el_chared.c_vcmd.action     = NOP;
41754210Sbostic     el->el_chared.c_vcmd.pos        = el->el_line.buffer;
41854210Sbostic     el->el_chared.c_vcmd.ins        = el->el_line.buffer;
41954210Sbostic 
42054210Sbostic     el->el_chared.c_kill.buf        = (char *)  el_malloc(EL_BUFSIZ);
42154210Sbostic     (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
42254210Sbostic     el->el_chared.c_kill.mark       = el->el_line.buffer;
42354210Sbostic     el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
42454210Sbostic 
42554210Sbostic     el->el_map.current              = el->el_map.key;
42654210Sbostic 
42754210Sbostic     el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
42854210Sbostic     el->el_state.doingarg  = 0;
42954210Sbostic     el->el_state.metanext  = 0;
43054210Sbostic     el->el_state.argument  = 1;
43154210Sbostic     el->el_state.lastcmd   = ED_UNASSIGNED;
43254210Sbostic 
43354624Schristos     el->el_chared.c_macro.nline     = NULL;
43454210Sbostic     el->el_chared.c_macro.level     = -1;
43554210Sbostic     el->el_chared.c_macro.macro     = (char **) el_malloc(EL_MAXMACRO *
43654210Sbostic 						          sizeof(char *));
43754210Sbostic     return 0;
43854210Sbostic }
43954210Sbostic 
44054210Sbostic /* ch_reset():
44154210Sbostic  *	Reset the character editor
44254210Sbostic  */
44354210Sbostic protected void
ch_reset(el)44454210Sbostic ch_reset(el)
44554210Sbostic     EditLine *el;
44654210Sbostic {
44754210Sbostic     el->el_line.cursor              = el->el_line.buffer;
44854210Sbostic     el->el_line.lastchar            = el->el_line.buffer;
44954210Sbostic 
45054210Sbostic     el->el_chared.c_undo.action     = NOP;
45154210Sbostic     el->el_chared.c_undo.isize      = 0;
45254210Sbostic     el->el_chared.c_undo.dsize      = 0;
45354210Sbostic     el->el_chared.c_undo.ptr        = el->el_line.buffer;
45454210Sbostic 
45554210Sbostic     el->el_chared.c_vcmd.action     = NOP;
45654210Sbostic     el->el_chared.c_vcmd.pos        = el->el_line.buffer;
45754210Sbostic     el->el_chared.c_vcmd.ins        = el->el_line.buffer;
45854210Sbostic 
45954210Sbostic     el->el_chared.c_kill.mark       = el->el_line.buffer;
46054210Sbostic 
46154210Sbostic     el->el_map.current              = el->el_map.key;
46254210Sbostic 
46354210Sbostic     el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
46454210Sbostic     el->el_state.doingarg  = 0;
46554210Sbostic     el->el_state.metanext  = 0;
46654210Sbostic     el->el_state.argument  = 1;
46754210Sbostic     el->el_state.lastcmd   = ED_UNASSIGNED;
46854210Sbostic 
46954210Sbostic     el->el_chared.c_macro.level     = -1;
47054210Sbostic 
47154210Sbostic     el->el_history.eventno = 0;
47254210Sbostic }
47354210Sbostic 
47454210Sbostic 
47554210Sbostic /* ch_end():
47654210Sbostic  *	Free the data structures used by the editor
47754210Sbostic  */
47854210Sbostic protected void
ch_end(el)47954210Sbostic ch_end(el)
48054210Sbostic     EditLine *el;
48154210Sbostic {
48254210Sbostic     el_free((ptr_t) el->el_line.buffer);
48354210Sbostic     el->el_line.buffer = NULL;
48454210Sbostic     el->el_line.limit = NULL;
48554210Sbostic     el_free((ptr_t) el->el_chared.c_undo.buf);
48654210Sbostic     el->el_chared.c_undo.buf = NULL;
48754210Sbostic     el_free((ptr_t) el->el_chared.c_kill.buf);
48854210Sbostic     el->el_chared.c_kill.buf = NULL;
48954210Sbostic     el_free((ptr_t) el->el_chared.c_macro.macro);
49054210Sbostic     el->el_chared.c_macro.macro = NULL;
49154210Sbostic     ch_reset(el);
49254210Sbostic }
49354210Sbostic 
49454210Sbostic 
49554210Sbostic /* el_insertstr():
49654210Sbostic  *	Insert string at cursorI
49754210Sbostic  */
49854210Sbostic public int
el_insertstr(el,s)49954210Sbostic el_insertstr(el, s)
50054210Sbostic     EditLine *el;
50154210Sbostic     char   *s;
50254210Sbostic {
50354210Sbostic     int len;
50454210Sbostic 
50554210Sbostic     if ((len = strlen(s)) == 0)
50654210Sbostic 	return -1;
50754210Sbostic     if (el->el_line.lastchar + len >= el->el_line.limit)
50854210Sbostic 	return -1;
50954210Sbostic 
51054210Sbostic     c_insert(el, len);
51154210Sbostic     while (*s)
51254210Sbostic 	*el->el_line.cursor++ = *s++;
51354210Sbostic     return 0;
51454210Sbostic }
51554210Sbostic 
51654210Sbostic 
51754210Sbostic /* el_deletestr():
51854210Sbostic  *	Delete num characters before the cursor
51954210Sbostic  */
52054210Sbostic public void
el_deletestr(el,n)52154210Sbostic el_deletestr(el, n)
52254210Sbostic     EditLine *el;
52354210Sbostic     int     n;
52454210Sbostic {
52554210Sbostic     if (n <= 0)
52654210Sbostic 	return;
52754210Sbostic 
52854210Sbostic     if (el->el_line.cursor < &el->el_line.buffer[n])
52954210Sbostic 	return;
53054210Sbostic 
53154210Sbostic     c_delbefore(el, n);		/* delete before dot */
53254210Sbostic     el->el_line.cursor -= n;
53354210Sbostic     if (el->el_line.cursor < el->el_line.buffer)
53454210Sbostic 	el->el_line.cursor = el->el_line.buffer;
53554210Sbostic }
53654210Sbostic 
53754210Sbostic /* c_gets():
53854210Sbostic  *	Get a string
53954210Sbostic  */
54054210Sbostic protected int
c_gets(el,buf)54154210Sbostic c_gets(el, buf)
54254210Sbostic     EditLine *el;
54354210Sbostic     char *buf;
54454210Sbostic {
54554210Sbostic     char ch;
54654210Sbostic     int len = 0;
54754210Sbostic 
54854210Sbostic     for (ch = 0; ch == 0;) {
54954210Sbostic 	if (el_getc(el, &ch) != 1)
55054210Sbostic 	    return ed_end_of_file(el, 0);
55154210Sbostic 	switch (ch) {
55254210Sbostic 	case 0010:	/* Delete and backspace */
55354210Sbostic 	case 0177:
55454210Sbostic 	    if (len > 1) {
55554210Sbostic 		*el->el_line.cursor-- = '\0';
55654210Sbostic 		el->el_line.lastchar = el->el_line.cursor;
55754210Sbostic 		buf[len--] = '\0';
55854210Sbostic 	    }
55954210Sbostic 	    else {
56054210Sbostic 		el->el_line.buffer[0] = '\0';
56154210Sbostic 		el->el_line.lastchar = el->el_line.buffer;
56254210Sbostic 		el->el_line.cursor = el->el_line.buffer;
56354210Sbostic 		return CC_REFRESH;
56454210Sbostic 	    }
56554210Sbostic 	    re_refresh(el);
56654210Sbostic 	    ch = 0;
56754210Sbostic 	    break;
56854210Sbostic 
56954210Sbostic 	case 0033:	/* ESC */
57054210Sbostic 	case '\r':	/* Newline */
57154210Sbostic 	case '\n':
57254210Sbostic 	    break;
57354210Sbostic 
57454210Sbostic 	default:
57554210Sbostic 	    if (len >= EL_BUFSIZ)
57654210Sbostic 		term_beep(el);
57754210Sbostic 	    else {
57854210Sbostic 		buf[len++] = ch;
57954210Sbostic 		*el->el_line.cursor++ = ch;
58054210Sbostic 		el->el_line.lastchar = el->el_line.cursor;
58154210Sbostic 	    }
58254210Sbostic 	    re_refresh(el);
58354210Sbostic 	    ch = 0;
58454210Sbostic 	    break;
58554210Sbostic 	}
58654210Sbostic     }
58754210Sbostic     buf[len] = ch;
58854210Sbostic     return len;
58954210Sbostic }
59054210Sbostic 
59154210Sbostic 
59254210Sbostic /* c_hpos():
59354210Sbostic  *	Return the current horizontal position of the cursor
59454210Sbostic  */
59554210Sbostic protected int
c_hpos(el)59654210Sbostic c_hpos(el)
59754210Sbostic     EditLine *el;
59854210Sbostic {
59954210Sbostic     char *ptr;
60054210Sbostic 
60154210Sbostic     /*
60254210Sbostic      * Find how many characters till the beginning of this line.
60354210Sbostic      */
60454210Sbostic     if (el->el_line.cursor == el->el_line.buffer)
60554210Sbostic 	return 0;
60654210Sbostic     else {
60754210Sbostic 	for (ptr = el->el_line.cursor - 1;
60854210Sbostic 	     ptr >= el->el_line.buffer && *ptr != '\n';
60954210Sbostic 	     ptr--)
61054210Sbostic 	    continue;
61154210Sbostic 	return el->el_line.cursor - ptr - 1;
61254210Sbostic     }
61354210Sbostic }
614