xref: /csrg-svn/lib/libedit/chared.c (revision 54210)
1*54210Sbostic /*-
2*54210Sbostic  * Copyright (c) 1992 The Regents of the University of California.
3*54210Sbostic  * All rights reserved.
4*54210Sbostic  *
5*54210Sbostic  * This code is derived from software contributed to Berkeley by
6*54210Sbostic  * Christos Zoulas of Cornell University.
7*54210Sbostic  *
8*54210Sbostic  * %sccs.include.redist.c%
9*54210Sbostic  */
10*54210Sbostic 
11*54210Sbostic #ifndef lint
12*54210Sbostic static char sccsid[] = "@(#)chared.c	5.1 (Berkeley) 06/22/92";
13*54210Sbostic #endif /* not lint */
14*54210Sbostic 
15*54210Sbostic /*
16*54210Sbostic  * el.chared.c: Character editor utilities
17*54210Sbostic  */
18*54210Sbostic #include "sys.h"
19*54210Sbostic 
20*54210Sbostic #include <stdlib.h>
21*54210Sbostic #include "el.h"
22*54210Sbostic 
23*54210Sbostic /* cv_undo():
24*54210Sbostic  *	Handle state for the vi undo command
25*54210Sbostic  */
26*54210Sbostic protected void
27*54210Sbostic cv_undo(el, action, size, ptr)
28*54210Sbostic     EditLine *el;
29*54210Sbostic     int action, size;
30*54210Sbostic     char *ptr;
31*54210Sbostic {
32*54210Sbostic     c_undo_t *vu = &el->el_chared.c_undo;
33*54210Sbostic     vu->action = action;
34*54210Sbostic     vu->ptr    = ptr;
35*54210Sbostic     vu->isize  = size;
36*54210Sbostic     (void) memcpy(vu->buf, vu->ptr, size);
37*54210Sbostic #ifdef DEBUG_UNDO
38*54210Sbostic     (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n",
39*54210Sbostic 		   vu->ptr, vu->isize, vu->dsize);
40*54210Sbostic #endif
41*54210Sbostic }
42*54210Sbostic 
43*54210Sbostic 
44*54210Sbostic /* c_insert():
45*54210Sbostic  *	Insert num characters
46*54210Sbostic  */
47*54210Sbostic protected void
48*54210Sbostic c_insert(el, num)
49*54210Sbostic     EditLine *el;
50*54210Sbostic     int num;
51*54210Sbostic {
52*54210Sbostic     char *cp;
53*54210Sbostic 
54*54210Sbostic     if (el->el_line.lastchar + num >= el->el_line.limit)
55*54210Sbostic 	return;			/* can't go past end of buffer */
56*54210Sbostic 
57*54210Sbostic     if (el->el_line.cursor < el->el_line.lastchar) {
58*54210Sbostic 	/* if I must move chars */
59*54210Sbostic 	for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
60*54210Sbostic 	    cp[num] = *cp;
61*54210Sbostic     }
62*54210Sbostic     el->el_line.lastchar += num;
63*54210Sbostic } /* end c_insert */
64*54210Sbostic 
65*54210Sbostic 
66*54210Sbostic /* c_delafter():
67*54210Sbostic  *	Delete num characters after the cursor
68*54210Sbostic  */
69*54210Sbostic protected void
70*54210Sbostic c_delafter(el, num)
71*54210Sbostic     EditLine *el;
72*54210Sbostic     int num;
73*54210Sbostic {
74*54210Sbostic 
75*54210Sbostic     if (el->el_line.cursor + num > el->el_line.lastchar)
76*54210Sbostic 	num = el->el_line.lastchar - el->el_line.cursor;
77*54210Sbostic 
78*54210Sbostic     if (num > 0) {
79*54210Sbostic 	char *cp;
80*54210Sbostic 
81*54210Sbostic 	if (el->el_map.current != el->el_map.emacs)
82*54210Sbostic 	    cv_undo(el, INSERT, num, el->el_line.cursor);
83*54210Sbostic 
84*54210Sbostic 	for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
85*54210Sbostic 	    *cp = cp[num];
86*54210Sbostic 
87*54210Sbostic 	el->el_line.lastchar -= num;
88*54210Sbostic     }
89*54210Sbostic }
90*54210Sbostic 
91*54210Sbostic 
92*54210Sbostic /* c_delbefore():
93*54210Sbostic  *	Delete num characters before the cursor
94*54210Sbostic  */
95*54210Sbostic protected void
96*54210Sbostic c_delbefore(el, num)
97*54210Sbostic     EditLine *el;
98*54210Sbostic     int num;
99*54210Sbostic {
100*54210Sbostic 
101*54210Sbostic     if (el->el_line.cursor - num < el->el_line.buffer)
102*54210Sbostic 	num = el->el_line.cursor - el->el_line.buffer;
103*54210Sbostic 
104*54210Sbostic     if (num > 0) {
105*54210Sbostic 	char *cp;
106*54210Sbostic 
107*54210Sbostic 	if (el->el_map.current != el->el_map.emacs)
108*54210Sbostic 	    cv_undo(el, INSERT, num, el->el_line.cursor - num);
109*54210Sbostic 
110*54210Sbostic 	for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++)
111*54210Sbostic 	    *cp = cp[num];
112*54210Sbostic 
113*54210Sbostic 	el->el_line.lastchar -= num;
114*54210Sbostic     }
115*54210Sbostic }
116*54210Sbostic 
117*54210Sbostic 
118*54210Sbostic /* ce__isword():
119*54210Sbostic  *	Return if p is part of a word according to emacs
120*54210Sbostic  */
121*54210Sbostic protected int
122*54210Sbostic ce__isword(p)
123*54210Sbostic     int p;
124*54210Sbostic {
125*54210Sbostic     return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL;
126*54210Sbostic }
127*54210Sbostic 
128*54210Sbostic 
129*54210Sbostic /* cv__isword():
130*54210Sbostic  *	Return if p is part of a word according to vi
131*54210Sbostic  */
132*54210Sbostic protected int
133*54210Sbostic cv__isword(p)
134*54210Sbostic     int p;
135*54210Sbostic {
136*54210Sbostic     return !isspace(p);
137*54210Sbostic }
138*54210Sbostic 
139*54210Sbostic 
140*54210Sbostic /* c__prev_word():
141*54210Sbostic  *	Find the previous word
142*54210Sbostic  */
143*54210Sbostic protected char *
144*54210Sbostic c__prev_word(p, low, n, wtest)
145*54210Sbostic     register char *p, *low;
146*54210Sbostic     register int n;
147*54210Sbostic     int (*wtest) __P((int));
148*54210Sbostic {
149*54210Sbostic     p--;
150*54210Sbostic 
151*54210Sbostic     while (n--) {
152*54210Sbostic 	while ((p >= low) && !(*wtest)((unsigned char) *p))
153*54210Sbostic 	    p--;
154*54210Sbostic 	while ((p >= low) && (*wtest)((unsigned char) *p))
155*54210Sbostic 	    p--;
156*54210Sbostic     }
157*54210Sbostic 
158*54210Sbostic     /* cp now points to one character before the word */
159*54210Sbostic     p++;
160*54210Sbostic     if (p < low)
161*54210Sbostic 	p = low;
162*54210Sbostic     /* cp now points where we want it */
163*54210Sbostic     return p;
164*54210Sbostic }
165*54210Sbostic 
166*54210Sbostic 
167*54210Sbostic /* c__next_word():
168*54210Sbostic  *	Find the next word
169*54210Sbostic  */
170*54210Sbostic protected char *
171*54210Sbostic c__next_word(p, high, n, wtest)
172*54210Sbostic     register char *p, *high;
173*54210Sbostic     register int n;
174*54210Sbostic     int (*wtest) __P((int));
175*54210Sbostic {
176*54210Sbostic     while (n--) {
177*54210Sbostic 	while ((p < high) && !(*wtest)((unsigned char) *p))
178*54210Sbostic 	    p++;
179*54210Sbostic 	while ((p < high) && (*wtest)((unsigned char) *p))
180*54210Sbostic 	    p++;
181*54210Sbostic     }
182*54210Sbostic     if (p > high)
183*54210Sbostic 	p = high;
184*54210Sbostic     /* p now points where we want it */
185*54210Sbostic     return p;
186*54210Sbostic }
187*54210Sbostic 
188*54210Sbostic /* cv_next_word():
189*54210Sbostic  *	Find the next word vi style
190*54210Sbostic  */
191*54210Sbostic protected char *
192*54210Sbostic cv_next_word(el, p, high, n, wtest)
193*54210Sbostic     EditLine *el;
194*54210Sbostic     register char *p, *high;
195*54210Sbostic     register int n;
196*54210Sbostic     int (*wtest) __P((int));
197*54210Sbostic {
198*54210Sbostic     int test;
199*54210Sbostic 
200*54210Sbostic     while (n--) {
201*54210Sbostic     	test = (*wtest)((unsigned char) *p);
202*54210Sbostic 	while ((p < high) && (*wtest)((unsigned char) *p) == test)
203*54210Sbostic 	    p++;
204*54210Sbostic 	/*
205*54210Sbostic 	 * vi historically deletes with cw only the word preserving the
206*54210Sbostic 	 * trailing whitespace! This is not what 'w' does..
207*54210Sbostic 	 */
208*54210Sbostic 	if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
209*54210Sbostic 	    while ((p < high) && isspace((unsigned char) *p))
210*54210Sbostic 		p++;
211*54210Sbostic     }
212*54210Sbostic 
213*54210Sbostic     /* p now points where we want it */
214*54210Sbostic     if (p > high)
215*54210Sbostic 	return high;
216*54210Sbostic     else
217*54210Sbostic 	return p;
218*54210Sbostic }
219*54210Sbostic 
220*54210Sbostic 
221*54210Sbostic /* cv_prev_word():
222*54210Sbostic  *	Find the previous word vi style
223*54210Sbostic  */
224*54210Sbostic protected char *
225*54210Sbostic cv_prev_word(el, p, low, n, wtest)
226*54210Sbostic     EditLine *el;
227*54210Sbostic     register char *p, *low;
228*54210Sbostic     register int n;
229*54210Sbostic     int (*wtest) __P((int));
230*54210Sbostic {
231*54210Sbostic     int test;
232*54210Sbostic 
233*54210Sbostic     while (n--) {
234*54210Sbostic 	p--;
235*54210Sbostic 	/*
236*54210Sbostic 	 * vi historically deletes with cb only the word preserving the
237*54210Sbostic 	 * leading whitespace! This is not what 'b' does..
238*54210Sbostic 	 */
239*54210Sbostic 	if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
240*54210Sbostic 	    while ((p > low) && isspace((unsigned char) *p))
241*54210Sbostic 		p--;
242*54210Sbostic 	test = (*wtest)((unsigned char) *p);
243*54210Sbostic 	while ((p >= low) && (*wtest)((unsigned char) *p) == test)
244*54210Sbostic 	    p--;
245*54210Sbostic 	p++;
246*54210Sbostic 	while (isspace((unsigned char) *p))
247*54210Sbostic 		p++;
248*54210Sbostic     }
249*54210Sbostic 
250*54210Sbostic     /* p now points where we want it */
251*54210Sbostic     if (p < low)
252*54210Sbostic 	return low;
253*54210Sbostic     else
254*54210Sbostic 	return p;
255*54210Sbostic }
256*54210Sbostic 
257*54210Sbostic 
258*54210Sbostic #ifdef notdef
259*54210Sbostic /* c__number():
260*54210Sbostic  *	Ignore character p points to, return number appearing after that.
261*54210Sbostic  * 	A '$' by itself means a big number; "$-" is for negative; '^' means 1.
262*54210Sbostic  * 	Return p pointing to last char used.
263*54210Sbostic  */
264*54210Sbostic protected char *
265*54210Sbostic c__number(p, num, dval)
266*54210Sbostic     char *p;	/* character position */
267*54210Sbostic     int *num;	/* Return value	*/
268*54210Sbostic     int dval;	/* dval is the number to subtract from like $-3 */
269*54210Sbostic {
270*54210Sbostic     register int i;
271*54210Sbostic     register int sign = 1;
272*54210Sbostic 
273*54210Sbostic     if (*++p == '^') {
274*54210Sbostic 	*num = 1;
275*54210Sbostic 	return p;
276*54210Sbostic     }
277*54210Sbostic     if (*p == '$') {
278*54210Sbostic 	if (*++p != '-') {
279*54210Sbostic 	    *num = 0x7fffffff;	/* Handle $ */
280*54210Sbostic 	    return --p;
281*54210Sbostic 	}
282*54210Sbostic 	sign = -1;		/* Handle $- */
283*54210Sbostic 	++p;
284*54210Sbostic     }
285*54210Sbostic     for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
286*54210Sbostic 	continue;
287*54210Sbostic     *num = (sign < 0 ? dval - i : i);
288*54210Sbostic     return --p;
289*54210Sbostic }
290*54210Sbostic #endif
291*54210Sbostic 
292*54210Sbostic /* cv_delfini():
293*54210Sbostic  *	Finish vi delete action
294*54210Sbostic  */
295*54210Sbostic protected void
296*54210Sbostic cv_delfini(el)
297*54210Sbostic     EditLine *el;
298*54210Sbostic {
299*54210Sbostic     register int size;
300*54210Sbostic     int oaction;
301*54210Sbostic 
302*54210Sbostic     if (el->el_chared.c_vcmd.action & INSERT)
303*54210Sbostic 	el->el_map.current = el->el_map.key;
304*54210Sbostic 
305*54210Sbostic     oaction = el->el_chared.c_vcmd.action;
306*54210Sbostic     el->el_chared.c_vcmd.action = NOP;
307*54210Sbostic 
308*54210Sbostic     if (el->el_chared.c_vcmd.pos == 0)
309*54210Sbostic 	return;
310*54210Sbostic 
311*54210Sbostic 
312*54210Sbostic     if (el->el_line.cursor > el->el_chared.c_vcmd.pos) {
313*54210Sbostic 	size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
314*54210Sbostic 	c_delbefore(el, size);
315*54210Sbostic 	el->el_line.cursor = el->el_chared.c_vcmd.pos;
316*54210Sbostic 	re_refresh_cursor(el);
317*54210Sbostic     }
318*54210Sbostic     else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
319*54210Sbostic 	size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
320*54210Sbostic 	c_delafter(el, size);
321*54210Sbostic     }
322*54210Sbostic     else {
323*54210Sbostic 	size = 1;
324*54210Sbostic 	c_delafter(el, size);
325*54210Sbostic     }
326*54210Sbostic     switch (oaction) {
327*54210Sbostic     case DELETE|INSERT:
328*54210Sbostic 	el->el_chared.c_undo.action = DELETE|INSERT;
329*54210Sbostic 	break;
330*54210Sbostic     case DELETE:
331*54210Sbostic 	el->el_chared.c_undo.action = INSERT;
332*54210Sbostic 	break;
333*54210Sbostic     case NOP:
334*54210Sbostic     case INSERT:
335*54210Sbostic     default:
336*54210Sbostic 	abort();
337*54210Sbostic 	break;
338*54210Sbostic     }
339*54210Sbostic 
340*54210Sbostic 
341*54210Sbostic     el->el_chared.c_undo.ptr = el->el_line.cursor;
342*54210Sbostic     el->el_chared.c_undo.dsize = size;
343*54210Sbostic }
344*54210Sbostic 
345*54210Sbostic 
346*54210Sbostic #ifdef notdef
347*54210Sbostic /* ce__endword():
348*54210Sbostic  *	Go to the end of this word according to emacs
349*54210Sbostic  */
350*54210Sbostic protected char *
351*54210Sbostic ce__endword(p, high, n)
352*54210Sbostic     char *p, *high;
353*54210Sbostic     int n;
354*54210Sbostic {
355*54210Sbostic     p++;
356*54210Sbostic 
357*54210Sbostic     while (n--) {
358*54210Sbostic 	while ((p < high) && isspace((unsigned char) *p))
359*54210Sbostic 	    p++;
360*54210Sbostic 	while ((p < high) && !isspace((unsigned char) *p))
361*54210Sbostic 	    p++;
362*54210Sbostic     }
363*54210Sbostic 
364*54210Sbostic     p--;
365*54210Sbostic     return p;
366*54210Sbostic }
367*54210Sbostic #endif
368*54210Sbostic 
369*54210Sbostic 
370*54210Sbostic /* cv__endword():
371*54210Sbostic  *	Go to the end of this word according to vi
372*54210Sbostic  */
373*54210Sbostic protected char *
374*54210Sbostic cv__endword(p, high, n)
375*54210Sbostic     char *p, *high;
376*54210Sbostic     int n;
377*54210Sbostic {
378*54210Sbostic     p++;
379*54210Sbostic 
380*54210Sbostic     while (n--) {
381*54210Sbostic 	while ((p < high) && isspace((unsigned char) *p))
382*54210Sbostic 	    p++;
383*54210Sbostic 
384*54210Sbostic 	if (isalnum((unsigned char) *p))
385*54210Sbostic 	    while ((p < high) && isalnum((unsigned char) *p))
386*54210Sbostic 		p++;
387*54210Sbostic 	else
388*54210Sbostic 	    while ((p < high) && !(isspace((unsigned char) *p) ||
389*54210Sbostic 				   isalnum((unsigned char) *p)))
390*54210Sbostic 		p++;
391*54210Sbostic     }
392*54210Sbostic     p--;
393*54210Sbostic     return p;
394*54210Sbostic }
395*54210Sbostic 
396*54210Sbostic /* ch_init():
397*54210Sbostic  *	Initialize the character editor
398*54210Sbostic  */
399*54210Sbostic protected int
400*54210Sbostic ch_init(el)
401*54210Sbostic     EditLine *el;
402*54210Sbostic {
403*54210Sbostic     el->el_line.buffer              = (char *)  el_malloc(EL_BUFSIZ);
404*54210Sbostic     (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
405*54210Sbostic     el->el_line.cursor              = el->el_line.buffer;
406*54210Sbostic     el->el_line.lastchar            = el->el_line.buffer;
407*54210Sbostic     el->el_line.limit  		    = &el->el_line.buffer[EL_BUFSIZ - 2];
408*54210Sbostic 
409*54210Sbostic     el->el_chared.c_undo.buf        = (char *)  el_malloc(EL_BUFSIZ);
410*54210Sbostic     (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
411*54210Sbostic     el->el_chared.c_undo.action     = NOP;
412*54210Sbostic     el->el_chared.c_undo.isize      = 0;
413*54210Sbostic     el->el_chared.c_undo.dsize      = 0;
414*54210Sbostic     el->el_chared.c_undo.ptr        = el->el_line.buffer;
415*54210Sbostic 
416*54210Sbostic     el->el_chared.c_vcmd.action     = NOP;
417*54210Sbostic     el->el_chared.c_vcmd.pos        = el->el_line.buffer;
418*54210Sbostic     el->el_chared.c_vcmd.ins        = el->el_line.buffer;
419*54210Sbostic 
420*54210Sbostic     el->el_chared.c_kill.buf        = (char *)  el_malloc(EL_BUFSIZ);
421*54210Sbostic     (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
422*54210Sbostic     el->el_chared.c_kill.mark       = el->el_line.buffer;
423*54210Sbostic     el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
424*54210Sbostic 
425*54210Sbostic     el->el_map.current              = el->el_map.key;
426*54210Sbostic 
427*54210Sbostic     el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
428*54210Sbostic     el->el_state.doingarg  = 0;
429*54210Sbostic     el->el_state.metanext  = 0;
430*54210Sbostic     el->el_state.argument  = 1;
431*54210Sbostic     el->el_state.lastcmd   = ED_UNASSIGNED;
432*54210Sbostic 
433*54210Sbostic     el->el_chared.c_macro.level     = -1;
434*54210Sbostic     el->el_chared.c_macro.macro     = (char **) el_malloc(EL_MAXMACRO *
435*54210Sbostic 						          sizeof(char *));
436*54210Sbostic     return 0;
437*54210Sbostic }
438*54210Sbostic 
439*54210Sbostic /* ch_reset():
440*54210Sbostic  *	Reset the character editor
441*54210Sbostic  */
442*54210Sbostic protected void
443*54210Sbostic ch_reset(el)
444*54210Sbostic     EditLine *el;
445*54210Sbostic {
446*54210Sbostic     el->el_line.cursor              = el->el_line.buffer;
447*54210Sbostic     el->el_line.lastchar            = el->el_line.buffer;
448*54210Sbostic 
449*54210Sbostic     el->el_chared.c_undo.action     = NOP;
450*54210Sbostic     el->el_chared.c_undo.isize      = 0;
451*54210Sbostic     el->el_chared.c_undo.dsize      = 0;
452*54210Sbostic     el->el_chared.c_undo.ptr        = el->el_line.buffer;
453*54210Sbostic 
454*54210Sbostic     el->el_chared.c_vcmd.action     = NOP;
455*54210Sbostic     el->el_chared.c_vcmd.pos        = el->el_line.buffer;
456*54210Sbostic     el->el_chared.c_vcmd.ins        = el->el_line.buffer;
457*54210Sbostic 
458*54210Sbostic     el->el_chared.c_kill.mark       = el->el_line.buffer;
459*54210Sbostic 
460*54210Sbostic     el->el_map.current              = el->el_map.key;
461*54210Sbostic 
462*54210Sbostic     el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
463*54210Sbostic     el->el_state.doingarg  = 0;
464*54210Sbostic     el->el_state.metanext  = 0;
465*54210Sbostic     el->el_state.argument  = 1;
466*54210Sbostic     el->el_state.lastcmd   = ED_UNASSIGNED;
467*54210Sbostic 
468*54210Sbostic     el->el_chared.c_macro.level     = -1;
469*54210Sbostic 
470*54210Sbostic     el->el_history.eventno = 0;
471*54210Sbostic }
472*54210Sbostic 
473*54210Sbostic 
474*54210Sbostic /* ch_end():
475*54210Sbostic  *	Free the data structures used by the editor
476*54210Sbostic  */
477*54210Sbostic protected void
478*54210Sbostic ch_end(el)
479*54210Sbostic     EditLine *el;
480*54210Sbostic {
481*54210Sbostic     el_free((ptr_t) el->el_line.buffer);
482*54210Sbostic     el->el_line.buffer = NULL;
483*54210Sbostic     el->el_line.limit = NULL;
484*54210Sbostic     el_free((ptr_t) el->el_chared.c_undo.buf);
485*54210Sbostic     el->el_chared.c_undo.buf = NULL;
486*54210Sbostic     el_free((ptr_t) el->el_chared.c_kill.buf);
487*54210Sbostic     el->el_chared.c_kill.buf = NULL;
488*54210Sbostic     el_free((ptr_t) el->el_chared.c_macro.macro);
489*54210Sbostic     el->el_chared.c_macro.macro = NULL;
490*54210Sbostic     ch_reset(el);
491*54210Sbostic }
492*54210Sbostic 
493*54210Sbostic 
494*54210Sbostic /* el_insertstr():
495*54210Sbostic  *	Insert string at cursorI
496*54210Sbostic  */
497*54210Sbostic public int
498*54210Sbostic el_insertstr(el, s)
499*54210Sbostic     EditLine *el;
500*54210Sbostic     char   *s;
501*54210Sbostic {
502*54210Sbostic     int len;
503*54210Sbostic 
504*54210Sbostic     if ((len = strlen(s)) == 0)
505*54210Sbostic 	return -1;
506*54210Sbostic     if (el->el_line.lastchar + len >= el->el_line.limit)
507*54210Sbostic 	return -1;
508*54210Sbostic 
509*54210Sbostic     c_insert(el, len);
510*54210Sbostic     while (*s)
511*54210Sbostic 	*el->el_line.cursor++ = *s++;
512*54210Sbostic     return 0;
513*54210Sbostic }
514*54210Sbostic 
515*54210Sbostic 
516*54210Sbostic /* el_deletestr():
517*54210Sbostic  *	Delete num characters before the cursor
518*54210Sbostic  */
519*54210Sbostic public void
520*54210Sbostic el_deletestr(el, n)
521*54210Sbostic     EditLine *el;
522*54210Sbostic     int     n;
523*54210Sbostic {
524*54210Sbostic     if (n <= 0)
525*54210Sbostic 	return;
526*54210Sbostic 
527*54210Sbostic     if (el->el_line.cursor < &el->el_line.buffer[n])
528*54210Sbostic 	return;
529*54210Sbostic 
530*54210Sbostic     c_delbefore(el, n);		/* delete before dot */
531*54210Sbostic     el->el_line.cursor -= n;
532*54210Sbostic     if (el->el_line.cursor < el->el_line.buffer)
533*54210Sbostic 	el->el_line.cursor = el->el_line.buffer;
534*54210Sbostic }
535*54210Sbostic 
536*54210Sbostic /* c_gets():
537*54210Sbostic  *	Get a string
538*54210Sbostic  */
539*54210Sbostic protected int
540*54210Sbostic c_gets(el, buf)
541*54210Sbostic     EditLine *el;
542*54210Sbostic     char *buf;
543*54210Sbostic {
544*54210Sbostic     char ch;
545*54210Sbostic     int len = 0;
546*54210Sbostic 
547*54210Sbostic     for (ch = 0; ch == 0;) {
548*54210Sbostic 	if (el_getc(el, &ch) != 1)
549*54210Sbostic 	    return ed_end_of_file(el, 0);
550*54210Sbostic 	switch (ch) {
551*54210Sbostic 	case 0010:	/* Delete and backspace */
552*54210Sbostic 	case 0177:
553*54210Sbostic 	    if (len > 1) {
554*54210Sbostic 		*el->el_line.cursor-- = '\0';
555*54210Sbostic 		el->el_line.lastchar = el->el_line.cursor;
556*54210Sbostic 		buf[len--] = '\0';
557*54210Sbostic 	    }
558*54210Sbostic 	    else {
559*54210Sbostic 		el->el_line.buffer[0] = '\0';
560*54210Sbostic 		el->el_line.lastchar = el->el_line.buffer;
561*54210Sbostic 		el->el_line.cursor = el->el_line.buffer;
562*54210Sbostic 		return CC_REFRESH;
563*54210Sbostic 	    }
564*54210Sbostic 	    re_refresh(el);
565*54210Sbostic 	    ch = 0;
566*54210Sbostic 	    break;
567*54210Sbostic 
568*54210Sbostic 	case 0033:	/* ESC */
569*54210Sbostic 	case '\r':	/* Newline */
570*54210Sbostic 	case '\n':
571*54210Sbostic 	    break;
572*54210Sbostic 
573*54210Sbostic 	default:
574*54210Sbostic 	    if (len >= EL_BUFSIZ)
575*54210Sbostic 		term_beep(el);
576*54210Sbostic 	    else {
577*54210Sbostic 		buf[len++] = ch;
578*54210Sbostic 		*el->el_line.cursor++ = ch;
579*54210Sbostic 		el->el_line.lastchar = el->el_line.cursor;
580*54210Sbostic 	    }
581*54210Sbostic 	    re_refresh(el);
582*54210Sbostic 	    ch = 0;
583*54210Sbostic 	    break;
584*54210Sbostic 	}
585*54210Sbostic     }
586*54210Sbostic     buf[len] = ch;
587*54210Sbostic     return len;
588*54210Sbostic }
589*54210Sbostic 
590*54210Sbostic 
591*54210Sbostic /* c_hpos():
592*54210Sbostic  *	Return the current horizontal position of the cursor
593*54210Sbostic  */
594*54210Sbostic protected int
595*54210Sbostic c_hpos(el)
596*54210Sbostic     EditLine *el;
597*54210Sbostic {
598*54210Sbostic     char *ptr;
599*54210Sbostic 
600*54210Sbostic     /*
601*54210Sbostic      * Find how many characters till the beginning of this line.
602*54210Sbostic      */
603*54210Sbostic     if (el->el_line.cursor == el->el_line.buffer)
604*54210Sbostic 	return 0;
605*54210Sbostic     else {
606*54210Sbostic 	for (ptr = el->el_line.cursor - 1;
607*54210Sbostic 	     ptr >= el->el_line.buffer && *ptr != '\n';
608*54210Sbostic 	     ptr--)
609*54210Sbostic 	    continue;
610*54210Sbostic 	return el->el_line.cursor - ptr - 1;
611*54210Sbostic     }
612*54210Sbostic }
613