Annotation of src/lib/libedit/chared.c, Revision 1.17
1.17 ! christos 1: /* $NetBSD: chared.c,v 1.16 2002/10/27 21:41:50 christos Exp $ */
1.2 lukem 2:
1.1 cgd 3: /*-
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * This code is derived from software contributed to Berkeley by
8: * Christos Zoulas of Cornell University.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
1.15 christos 39: #include "config.h"
1.1 cgd 40: #if !defined(lint) && !defined(SCCSID)
1.2 lukem 41: #if 0
1.1 cgd 42: static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
1.2 lukem 43: #else
1.17 ! christos 44: __RCSID("$NetBSD: chared.c,v 1.16 2002/10/27 21:41:50 christos Exp $");
1.2 lukem 45: #endif
1.1 cgd 46: #endif /* not lint && not SCCSID */
47:
1.7 simonb 48: /*
1.1 cgd 49: * chared.c: Character editor utilities
50: */
51: #include <stdlib.h>
52: #include "el.h"
53:
1.12 jdolecek 54: /* value to leave unused in line buffer */
55: #define EL_LEAVE 2
56:
1.1 cgd 57: /* cv_undo():
58: * Handle state for the vi undo command
59: */
60: protected void
1.17 ! christos 61: cv_undo(EditLine *el)
1.9 lukem 62: {
63: c_undo_t *vu = &el->el_chared.c_undo;
1.17 ! christos 64: c_redo_t *r = &el->el_chared.c_redo;
! 65: uint size;
1.16 christos 66:
1.17 ! christos 67: /* Save entire line for undo */
! 68: size = el->el_line.lastchar - el->el_line.buffer;
! 69: vu->len = size;
1.16 christos 70: vu->cursor = el->el_line.cursor - el->el_line.buffer;
1.17 ! christos 71: memcpy(vu->buf, el->el_line.buffer, size);
1.16 christos 72:
1.17 ! christos 73: /* save command info for redo */
! 74: r->count = el->el_state.doingarg ? el->el_state.argument : 0;
! 75: r->action = el->el_chared.c_vcmd.action;
! 76: r->pos = r->buf;
! 77: r->cmd = el->el_state.thiscmd;
! 78: r->ch = el->el_state.thisch;
! 79: }
! 80:
! 81: /* cv_yank():
! 82: * Save yank/delete data for paste
! 83: */
! 84: protected void
! 85: cv_yank(EditLine *el, const char *ptr, int size)
! 86: {
! 87: c_kill_t *k = &el->el_chared.c_kill;
! 88:
! 89: memcpy(k->buf, ptr, size +0u);
! 90: k->last = k->buf + size;
1.1 cgd 91: }
92:
93:
1.7 simonb 94: /* c_insert():
1.1 cgd 95: * Insert num characters
96: */
97: protected void
1.9 lukem 98: c_insert(EditLine *el, int num)
99: {
100: char *cp;
101:
1.17 ! christos 102: if (el->el_line.lastchar + num >= el->el_line.limit) {
! 103: if (!ch_enlargebufs(el, num +0u))
! 104: return; /* can't go past end of buffer */
! 105: }
1.9 lukem 106:
107: if (el->el_line.cursor < el->el_line.lastchar) {
108: /* if I must move chars */
109: for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
110: cp[num] = *cp;
111: }
112: el->el_line.lastchar += num;
113: }
1.1 cgd 114:
115:
116: /* c_delafter():
117: * Delete num characters after the cursor
118: */
119: protected void
1.9 lukem 120: c_delafter(EditLine *el, int num)
1.1 cgd 121: {
122:
1.9 lukem 123: if (el->el_line.cursor + num > el->el_line.lastchar)
124: num = el->el_line.lastchar - el->el_line.cursor;
1.1 cgd 125:
1.17 ! christos 126: if (el->el_map.current != el->el_map.emacs) {
! 127: cv_undo(el);
! 128: cv_yank(el, el->el_line.cursor, num);
! 129: }
1.16 christos 130:
1.9 lukem 131: if (num > 0) {
132: char *cp;
1.1 cgd 133:
1.9 lukem 134: for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
135: *cp = cp[num];
1.1 cgd 136:
1.9 lukem 137: el->el_line.lastchar -= num;
138: }
1.1 cgd 139: }
140:
141:
142: /* c_delbefore():
143: * Delete num characters before the cursor
144: */
145: protected void
1.9 lukem 146: c_delbefore(EditLine *el, int num)
1.1 cgd 147: {
148:
1.9 lukem 149: if (el->el_line.cursor - num < el->el_line.buffer)
150: num = el->el_line.cursor - el->el_line.buffer;
1.1 cgd 151:
1.17 ! christos 152: if (el->el_map.current != el->el_map.emacs) {
! 153: cv_undo(el);
! 154: cv_yank(el, el->el_line.cursor - num, num);
! 155: }
1.16 christos 156:
1.9 lukem 157: if (num > 0) {
158: char *cp;
1.1 cgd 159:
1.9 lukem 160: for (cp = el->el_line.cursor - num;
161: cp <= el->el_line.lastchar;
162: cp++)
163: *cp = cp[num];
1.1 cgd 164:
1.9 lukem 165: el->el_line.lastchar -= num;
166: }
1.1 cgd 167: }
168:
169:
170: /* ce__isword():
171: * Return if p is part of a word according to emacs
172: */
173: protected int
1.9 lukem 174: ce__isword(int p)
1.1 cgd 175: {
1.16 christos 176: return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
1.1 cgd 177: }
178:
179:
180: /* cv__isword():
181: * Return if p is part of a word according to vi
182: */
183: protected int
1.9 lukem 184: cv__isword(int p)
1.1 cgd 185: {
1.17 ! christos 186: if (isalnum(p) || p == '_')
! 187: return 1;
! 188: if (isgraph(p))
! 189: return 2;
! 190: return 0;
1.16 christos 191: }
192:
193:
194: /* cv__isWord():
195: * Return if p is part of a big word according to vi
196: */
197: protected int
198: cv__isWord(int p)
199: {
1.9 lukem 200: return (!isspace(p));
1.1 cgd 201: }
202:
203:
204: /* c__prev_word():
205: * Find the previous word
206: */
207: protected char *
1.9 lukem 208: c__prev_word(char *p, char *low, int n, int (*wtest)(int))
209: {
210: p--;
211:
212: while (n--) {
213: while ((p >= low) && !(*wtest)((unsigned char) *p))
214: p--;
215: while ((p >= low) && (*wtest)((unsigned char) *p))
216: p--;
217: }
218:
219: /* cp now points to one character before the word */
220: p++;
221: if (p < low)
222: p = low;
223: /* cp now points where we want it */
224: return (p);
1.1 cgd 225: }
226:
227:
228: /* c__next_word():
229: * Find the next word
230: */
231: protected char *
1.9 lukem 232: c__next_word(char *p, char *high, int n, int (*wtest)(int))
233: {
234: while (n--) {
235: while ((p < high) && !(*wtest)((unsigned char) *p))
236: p++;
237: while ((p < high) && (*wtest)((unsigned char) *p))
238: p++;
239: }
240: if (p > high)
241: p = high;
242: /* p now points where we want it */
243: return (p);
1.1 cgd 244: }
245:
246: /* cv_next_word():
247: * Find the next word vi style
248: */
249: protected char *
1.9 lukem 250: cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
251: {
252: int test;
253:
254: while (n--) {
255: test = (*wtest)((unsigned char) *p);
256: while ((p < high) && (*wtest)((unsigned char) *p) == test)
257: p++;
258: /*
259: * vi historically deletes with cw only the word preserving the
260: * trailing whitespace! This is not what 'w' does..
261: */
1.16 christos 262: if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
1.9 lukem 263: while ((p < high) && isspace((unsigned char) *p))
264: p++;
265: }
1.1 cgd 266:
1.9 lukem 267: /* p now points where we want it */
268: if (p > high)
269: return (high);
270: else
271: return (p);
1.1 cgd 272: }
273:
274:
275: /* cv_prev_word():
276: * Find the previous word vi style
277: */
278: protected char *
1.16 christos 279: cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
1.1 cgd 280: {
1.9 lukem 281: int test;
1.1 cgd 282:
1.16 christos 283: p--;
1.9 lukem 284: while (n--) {
1.16 christos 285: while ((p > low) && isspace((unsigned char) *p))
286: p--;
1.9 lukem 287: test = (*wtest)((unsigned char) *p);
288: while ((p >= low) && (*wtest)((unsigned char) *p) == test)
289: p--;
290: }
1.16 christos 291: p++;
1.1 cgd 292:
1.9 lukem 293: /* p now points where we want it */
294: if (p < low)
295: return (low);
296: else
297: return (p);
1.1 cgd 298: }
299:
300:
301: #ifdef notdef
302: /* c__number():
303: * Ignore character p points to, return number appearing after that.
304: * A '$' by itself means a big number; "$-" is for negative; '^' means 1.
305: * Return p pointing to last char used.
306: */
307: protected char *
1.9 lukem 308: c__number(
309: char *p, /* character position */
310: int *num, /* Return value */
311: int dval) /* dval is the number to subtract from like $-3 */
312: {
313: int i;
314: int sign = 1;
315:
316: if (*++p == '^') {
317: *num = 1;
318: return (p);
319: }
320: if (*p == '$') {
321: if (*++p != '-') {
322: *num = 0x7fffffff; /* Handle $ */
323: return (--p);
324: }
325: sign = -1; /* Handle $- */
326: ++p;
327: }
328: for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
329: continue;
330: *num = (sign < 0 ? dval - i : i);
331: return (--p);
1.1 cgd 332: }
333: #endif
334:
335: /* cv_delfini():
336: * Finish vi delete action
337: */
338: protected void
1.9 lukem 339: cv_delfini(EditLine *el)
1.1 cgd 340: {
1.9 lukem 341: int size;
1.17 ! christos 342: int action = el->el_chared.c_vcmd.action;
1.1 cgd 343:
1.17 ! christos 344: if (action & INSERT)
1.9 lukem 345: el->el_map.current = el->el_map.key;
1.1 cgd 346:
1.9 lukem 347: if (el->el_chared.c_vcmd.pos == 0)
1.17 ! christos 348: /* sanity */
1.9 lukem 349: return;
350:
1.17 ! christos 351: size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
! 352: if (size == 0)
! 353: size = 1;
1.16 christos 354: el->el_line.cursor = el->el_chared.c_vcmd.pos;
1.17 ! christos 355: if (action & YANK) {
! 356: if (size > 0)
! 357: cv_yank(el, el->el_line.cursor, size);
! 358: else
! 359: cv_yank(el, el->el_line.cursor + size, -size);
1.9 lukem 360: } else {
1.17 ! christos 361: if (size > 0) {
! 362: c_delafter(el, size);
! 363: re_refresh_cursor(el);
! 364: } else {
! 365: c_delbefore(el, -size);
! 366: el->el_line.cursor += size;
! 367: }
1.9 lukem 368: }
1.17 ! christos 369: el->el_chared.c_vcmd.action = NOP;
1.1 cgd 370: }
371:
372:
373: #ifdef notdef
374: /* ce__endword():
375: * Go to the end of this word according to emacs
376: */
377: protected char *
1.9 lukem 378: ce__endword(char *p, char *high, int n)
379: {
380: p++;
1.1 cgd 381:
1.9 lukem 382: while (n--) {
383: while ((p < high) && isspace((unsigned char) *p))
384: p++;
385: while ((p < high) && !isspace((unsigned char) *p))
386: p++;
387: }
388:
389: p--;
390: return (p);
1.1 cgd 391: }
392: #endif
393:
394:
395: /* cv__endword():
396: * Go to the end of this word according to vi
397: */
398: protected char *
1.16 christos 399: cv__endword(char *p, char *high, int n, int (*wtest)(int))
1.9 lukem 400: {
1.16 christos 401: int test;
402:
1.9 lukem 403: p++;
1.1 cgd 404:
1.9 lukem 405: while (n--) {
406: while ((p < high) && isspace((unsigned char) *p))
407: p++;
408:
1.16 christos 409: test = (*wtest)((unsigned char) *p);
410: while ((p < high) && (*wtest)((unsigned char) *p) == test)
411: p++;
1.9 lukem 412: }
413: p--;
414: return (p);
1.1 cgd 415: }
416:
417: /* ch_init():
418: * Initialize the character editor
419: */
420: protected int
1.9 lukem 421: ch_init(EditLine *el)
1.1 cgd 422: {
1.11 christos 423: el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
424: if (el->el_line.buffer == NULL)
425: return (-1);
426:
1.9 lukem 427: (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
428: el->el_line.cursor = el->el_line.buffer;
429: el->el_line.lastchar = el->el_line.buffer;
1.16 christos 430: el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
1.9 lukem 431:
1.11 christos 432: el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
433: if (el->el_chared.c_undo.buf == NULL)
434: return (-1);
1.9 lukem 435: (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
1.16 christos 436: el->el_chared.c_undo.len = -1;
437: el->el_chared.c_undo.cursor = 0;
1.17 ! christos 438: el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
! 439: if (el->el_chared.c_redo.buf == NULL)
1.16 christos 440: return (-1);
1.17 ! christos 441: el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
! 442: el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
! 443: el->el_chared.c_redo.cmd = ED_UNASSIGNED;
1.9 lukem 444:
445: el->el_chared.c_vcmd.action = NOP;
446: el->el_chared.c_vcmd.pos = el->el_line.buffer;
447:
448: el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
1.11 christos 449: if (el->el_chared.c_kill.buf == NULL)
450: return (-1);
1.9 lukem 451: (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
452: el->el_chared.c_kill.mark = el->el_line.buffer;
453: el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
454:
455: el->el_map.current = el->el_map.key;
456:
457: el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
458: el->el_state.doingarg = 0;
459: el->el_state.metanext = 0;
460: el->el_state.argument = 1;
461: el->el_state.lastcmd = ED_UNASSIGNED;
462:
463: el->el_chared.c_macro.nline = NULL;
464: el->el_chared.c_macro.level = -1;
465: el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO *
1.11 christos 466: sizeof(char *));
467: if (el->el_chared.c_macro.macro == NULL)
468: return (-1);
1.9 lukem 469: return (0);
1.1 cgd 470: }
471:
472: /* ch_reset():
473: * Reset the character editor
474: */
475: protected void
1.9 lukem 476: ch_reset(EditLine *el)
1.1 cgd 477: {
1.9 lukem 478: el->el_line.cursor = el->el_line.buffer;
479: el->el_line.lastchar = el->el_line.buffer;
1.1 cgd 480:
1.16 christos 481: el->el_chared.c_undo.len = -1;
482: el->el_chared.c_undo.cursor = 0;
1.1 cgd 483:
1.9 lukem 484: el->el_chared.c_vcmd.action = NOP;
485: el->el_chared.c_vcmd.pos = el->el_line.buffer;
1.1 cgd 486:
1.9 lukem 487: el->el_chared.c_kill.mark = el->el_line.buffer;
1.1 cgd 488:
1.9 lukem 489: el->el_map.current = el->el_map.key;
1.1 cgd 490:
1.9 lukem 491: el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
492: el->el_state.doingarg = 0;
493: el->el_state.metanext = 0;
494: el->el_state.argument = 1;
495: el->el_state.lastcmd = ED_UNASSIGNED;
1.1 cgd 496:
1.9 lukem 497: el->el_chared.c_macro.level = -1;
1.1 cgd 498:
1.9 lukem 499: el->el_history.eventno = 0;
1.1 cgd 500: }
501:
1.12 jdolecek 502: /* ch_enlargebufs():
503: * Enlarge line buffer to be able to hold twice as much characters.
504: * Returns 1 if successful, 0 if not.
505: */
506: protected int
507: ch_enlargebufs(el, addlen)
1.13 lukem 508: EditLine *el;
509: size_t addlen;
1.12 jdolecek 510: {
1.13 lukem 511: size_t sz, newsz;
512: char *newbuffer, *oldbuf, *oldkbuf;
1.12 jdolecek 513:
1.13 lukem 514: sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
515: newsz = sz * 2;
516: /*
517: * If newly required length is longer than current buffer, we need
518: * to make the buffer big enough to hold both old and new stuff.
519: */
520: if (addlen > sz) {
521: while(newsz - sz < addlen)
522: newsz *= 2;
523: }
524:
525: /*
526: * Reallocate line buffer.
527: */
528: newbuffer = el_realloc(el->el_line.buffer, newsz);
529: if (!newbuffer)
530: return 0;
531:
532: /* zero the newly added memory, leave old data in */
533: (void) memset(&newbuffer[sz], 0, newsz - sz);
534:
535: oldbuf = el->el_line.buffer;
536:
537: el->el_line.buffer = newbuffer;
538: el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
539: el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
1.16 christos 540: /* don't set new size until all buffers are enlarged */
541: el->el_line.limit = &newbuffer[sz - EL_LEAVE];
1.13 lukem 542:
543: /*
544: * Reallocate kill buffer.
545: */
546: newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
547: if (!newbuffer)
548: return 0;
1.12 jdolecek 549:
1.13 lukem 550: /* zero the newly added memory, leave old data in */
551: (void) memset(&newbuffer[sz], 0, newsz - sz);
1.12 jdolecek 552:
1.13 lukem 553: oldkbuf = el->el_chared.c_kill.buf;
1.12 jdolecek 554:
1.13 lukem 555: el->el_chared.c_kill.buf = newbuffer;
556: el->el_chared.c_kill.last = newbuffer +
1.12 jdolecek 557: (el->el_chared.c_kill.last - oldkbuf);
1.13 lukem 558: el->el_chared.c_kill.mark = el->el_line.buffer +
1.12 jdolecek 559: (el->el_chared.c_kill.mark - oldbuf);
560:
1.13 lukem 561: /*
562: * Reallocate undo buffer.
563: */
564: newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
565: if (!newbuffer)
566: return 0;
567:
568: /* zero the newly added memory, leave old data in */
569: (void) memset(&newbuffer[sz], 0, newsz - sz);
1.16 christos 570: el->el_chared.c_undo.buf = newbuffer;
1.13 lukem 571:
1.17 ! christos 572: newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
1.16 christos 573: if (!newbuffer)
574: return 0;
1.17 ! christos 575: el->el_chared.c_redo.pos = newbuffer +
! 576: (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
! 577: el->el_chared.c_redo.lim = newbuffer +
! 578: (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
! 579: el->el_chared.c_redo.buf = newbuffer;
1.13 lukem 580:
581: if (!hist_enlargebuf(el, sz, newsz))
582: return 0;
1.12 jdolecek 583:
1.16 christos 584: /* Safe to set enlarged buffer size */
585: el->el_line.limit = &newbuffer[newsz - EL_LEAVE];
1.13 lukem 586: return 1;
1.12 jdolecek 587: }
1.1 cgd 588:
589: /* ch_end():
590: * Free the data structures used by the editor
591: */
592: protected void
1.9 lukem 593: ch_end(EditLine *el)
1.1 cgd 594: {
1.9 lukem 595: el_free((ptr_t) el->el_line.buffer);
596: el->el_line.buffer = NULL;
597: el->el_line.limit = NULL;
598: el_free((ptr_t) el->el_chared.c_undo.buf);
599: el->el_chared.c_undo.buf = NULL;
1.17 ! christos 600: el_free((ptr_t) el->el_chared.c_redo.buf);
! 601: el->el_chared.c_redo.buf = NULL;
! 602: el->el_chared.c_redo.pos = NULL;
! 603: el->el_chared.c_redo.lim = NULL;
! 604: el->el_chared.c_redo.cmd = ED_UNASSIGNED;
1.9 lukem 605: el_free((ptr_t) el->el_chared.c_kill.buf);
606: el->el_chared.c_kill.buf = NULL;
607: el_free((ptr_t) el->el_chared.c_macro.macro);
608: el->el_chared.c_macro.macro = NULL;
609: ch_reset(el);
1.1 cgd 610: }
611:
612:
613: /* el_insertstr():
614: * Insert string at cursorI
615: */
616: public int
1.9 lukem 617: el_insertstr(EditLine *el, const char *s)
618: {
1.14 christos 619: size_t len;
1.9 lukem 620:
621: if ((len = strlen(s)) == 0)
622: return (-1);
1.12 jdolecek 623: if (el->el_line.lastchar + len >= el->el_line.limit) {
624: if (!ch_enlargebufs(el, len))
625: return (-1);
626: }
1.9 lukem 627:
1.14 christos 628: c_insert(el, (int)len);
1.9 lukem 629: while (*s)
630: *el->el_line.cursor++ = *s++;
631: return (0);
1.1 cgd 632: }
633:
634:
635: /* el_deletestr():
636: * Delete num characters before the cursor
637: */
638: public void
1.9 lukem 639: el_deletestr(EditLine *el, int n)
640: {
641: if (n <= 0)
642: return;
643:
644: if (el->el_line.cursor < &el->el_line.buffer[n])
645: return;
646:
647: c_delbefore(el, n); /* delete before dot */
648: el->el_line.cursor -= n;
649: if (el->el_line.cursor < el->el_line.buffer)
650: el->el_line.cursor = el->el_line.buffer;
1.1 cgd 651: }
652:
653: /* c_gets():
654: * Get a string
655: */
656: protected int
1.9 lukem 657: c_gets(EditLine *el, char *buf)
658: {
659: char ch;
660: int len = 0;
1.1 cgd 661:
1.9 lukem 662: for (ch = 0; ch == 0;) {
663: if (el_getc(el, &ch) != 1)
664: return (ed_end_of_file(el, 0));
665: switch (ch) {
666: case 0010: /* Delete and backspace */
667: case 0177:
668: if (len > 1) {
669: *el->el_line.cursor-- = '\0';
670: el->el_line.lastchar = el->el_line.cursor;
671: buf[len--] = '\0';
672: } else {
673: el->el_line.buffer[0] = '\0';
674: el->el_line.lastchar = el->el_line.buffer;
675: el->el_line.cursor = el->el_line.buffer;
676: return (CC_REFRESH);
677: }
678: re_refresh(el);
679: ch = 0;
680: break;
681:
682: case 0033: /* ESC */
683: case '\r': /* Newline */
684: case '\n':
685: break;
686:
687: default:
688: if (len >= EL_BUFSIZ)
689: term_beep(el);
690: else {
691: buf[len++] = ch;
692: *el->el_line.cursor++ = ch;
693: el->el_line.lastchar = el->el_line.cursor;
694: }
695: re_refresh(el);
696: ch = 0;
697: break;
698: }
699: }
700: buf[len] = ch;
701: return (len);
1.1 cgd 702: }
703:
704:
705: /* c_hpos():
706: * Return the current horizontal position of the cursor
707: */
708: protected int
1.9 lukem 709: c_hpos(EditLine *el)
1.1 cgd 710: {
1.9 lukem 711: char *ptr;
1.1 cgd 712:
1.9 lukem 713: /*
714: * Find how many characters till the beginning of this line.
715: */
716: if (el->el_line.cursor == el->el_line.buffer)
717: return (0);
718: else {
719: for (ptr = el->el_line.cursor - 1;
720: ptr >= el->el_line.buffer && *ptr != '\n';
721: ptr--)
722: continue;
723: return (el->el_line.cursor - ptr - 1);
724: }
1.1 cgd 725: }
CVSweb <webmaster@jp.NetBSD.org>