[BACK]Return to chared.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libedit

Annotation of src/lib/libedit/chared.c, Revision 1.45

1.45    ! christos    1: /*     $NetBSD: chared.c,v 1.44 2016/02/16 15:53:48 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.
1.19      agc        18:  * 3. Neither the name of the University nor the names of its contributors
1.1       cgd        19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
1.15      christos   35: #include "config.h"
1.1       cgd        36: #if !defined(lint) && !defined(SCCSID)
1.2       lukem      37: #if 0
1.1       cgd        38: static char sccsid[] = "@(#)chared.c   8.1 (Berkeley) 6/4/93";
1.2       lukem      39: #else
1.45    ! christos   40: __RCSID("$NetBSD: chared.c,v 1.44 2016/02/16 15:53:48 christos Exp $");
1.2       lukem      41: #endif
1.1       cgd        42: #endif /* not lint && not SCCSID */
                     43:
1.7       simonb     44: /*
1.1       cgd        45:  * chared.c: Character editor utilities
                     46:  */
                     47: #include <stdlib.h>
1.45    ! christos   48:
1.1       cgd        49: #include "el.h"
1.45    ! christos   50: #include "common.h"
1.1       cgd        51:
1.26      sketch     52: private void ch__clearmacro (EditLine *);
1.24      christos   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;
1.27      christos   65:        size_t size;
1.16      christos   66:
1.17      christos   67:        /* Save entire line for undo */
1.35      christos   68:        size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
                     69:        vu->len = (ssize_t)size;
1.27      christos   70:        vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
1.28      christos   71:        (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
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
1.28      christos   85: cv_yank(EditLine *el, const Char *ptr, int size)
1.17      christos   86: {
                     87:        c_kill_t *k = &el->el_chared.c_kill;
                     88:
1.35      christos   89:        (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
1.17      christos   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: {
1.28      christos  100:        Char *cp;
1.9       lukem     101:
1.17      christos  102:        if (el->el_line.lastchar + num >= el->el_line.limit) {
1.27      christos  103:                if (!ch_enlargebufs(el, (size_t)num))
1.17      christos  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)
1.27      christos  124:                num = (int)(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) {
1.28      christos  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:
1.22      mycroft   142: /* c_delafter1():
                    143:  *     Delete the character after the cursor, do not yank
                    144:  */
                    145: protected void
                    146: c_delafter1(EditLine *el)
                    147: {
1.28      christos  148:        Char *cp;
1.22      mycroft   149:
                    150:        for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
                    151:                *cp = cp[1];
                    152:
                    153:        el->el_line.lastchar--;
                    154: }
                    155:
                    156:
1.1       cgd       157: /* c_delbefore():
                    158:  *     Delete num characters before the cursor
                    159:  */
                    160: protected void
1.9       lukem     161: c_delbefore(EditLine *el, int num)
1.1       cgd       162: {
                    163:
1.9       lukem     164:        if (el->el_line.cursor - num < el->el_line.buffer)
1.27      christos  165:                num = (int)(el->el_line.cursor - el->el_line.buffer);
1.1       cgd       166:
1.17      christos  167:        if (el->el_map.current != el->el_map.emacs) {
                    168:                cv_undo(el);
                    169:                cv_yank(el, el->el_line.cursor - num, num);
                    170:        }
1.16      christos  171:
1.9       lukem     172:        if (num > 0) {
1.28      christos  173:                Char *cp;
1.1       cgd       174:
1.9       lukem     175:                for (cp = el->el_line.cursor - num;
                    176:                    cp <= el->el_line.lastchar;
                    177:                    cp++)
                    178:                        *cp = cp[num];
1.1       cgd       179:
1.9       lukem     180:                el->el_line.lastchar -= num;
                    181:        }
1.1       cgd       182: }
                    183:
                    184:
1.22      mycroft   185: /* c_delbefore1():
                    186:  *     Delete the character before the cursor, do not yank
                    187:  */
                    188: protected void
                    189: c_delbefore1(EditLine *el)
                    190: {
1.28      christos  191:        Char *cp;
1.22      mycroft   192:
                    193:        for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
                    194:                *cp = cp[1];
                    195:
                    196:        el->el_line.lastchar--;
                    197: }
                    198:
                    199:
1.1       cgd       200: /* ce__isword():
                    201:  *     Return if p is part of a word according to emacs
                    202:  */
                    203: protected int
1.41      christos  204: ce__isword(wint_t p)
1.1       cgd       205: {
1.36      christos  206:        return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL;
1.1       cgd       207: }
                    208:
                    209:
                    210: /* cv__isword():
                    211:  *     Return if p is part of a word according to vi
                    212:  */
                    213: protected int
1.41      christos  214: cv__isword(wint_t p)
1.1       cgd       215: {
1.28      christos  216:        if (Isalnum(p) || p == '_')
1.17      christos  217:                return 1;
1.28      christos  218:        if (Isgraph(p))
1.17      christos  219:                return 2;
                    220:        return 0;
1.16      christos  221: }
                    222:
                    223:
                    224: /* cv__isWord():
                    225:  *     Return if p is part of a big word according to vi
                    226:  */
                    227: protected int
1.41      christos  228: cv__isWord(wint_t p)
1.16      christos  229: {
1.32      christos  230:        return !Isspace(p);
1.1       cgd       231: }
                    232:
                    233:
                    234: /* c__prev_word():
                    235:  *     Find the previous word
                    236:  */
1.28      christos  237: protected Char *
1.41      christos  238: c__prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
1.9       lukem     239: {
                    240:        p--;
                    241:
                    242:        while (n--) {
1.28      christos  243:                while ((p >= low) && !(*wtest)(*p))
1.9       lukem     244:                        p--;
1.28      christos  245:                while ((p >= low) && (*wtest)(*p))
1.9       lukem     246:                        p--;
                    247:        }
                    248:
                    249:        /* cp now points to one character before the word */
                    250:        p++;
                    251:        if (p < low)
                    252:                p = low;
                    253:        /* cp now points where we want it */
1.32      christos  254:        return p;
1.1       cgd       255: }
                    256:
                    257:
                    258: /* c__next_word():
                    259:  *     Find the next word
                    260:  */
1.28      christos  261: protected Char *
1.41      christos  262: c__next_word(Char *p, Char *high, int n, int (*wtest)(wint_t))
1.9       lukem     263: {
                    264:        while (n--) {
1.28      christos  265:                while ((p < high) && !(*wtest)(*p))
1.9       lukem     266:                        p++;
1.28      christos  267:                while ((p < high) && (*wtest)(*p))
1.9       lukem     268:                        p++;
                    269:        }
                    270:        if (p > high)
                    271:                p = high;
                    272:        /* p now points where we want it */
1.32      christos  273:        return p;
1.1       cgd       274: }
                    275:
                    276: /* cv_next_word():
                    277:  *     Find the next word vi style
                    278:  */
1.28      christos  279: protected Char *
1.41      christos  280: cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
1.9       lukem     281: {
                    282:        int test;
                    283:
                    284:        while (n--) {
1.28      christos  285:                test = (*wtest)(*p);
                    286:                while ((p < high) && (*wtest)(*p) == test)
1.9       lukem     287:                        p++;
                    288:                /*
                    289:                 * vi historically deletes with cw only the word preserving the
                    290:                 * trailing whitespace! This is not what 'w' does..
                    291:                 */
1.16      christos  292:                if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
1.28      christos  293:                        while ((p < high) && Isspace(*p))
1.9       lukem     294:                                p++;
                    295:        }
1.1       cgd       296:
1.9       lukem     297:        /* p now points where we want it */
                    298:        if (p > high)
1.32      christos  299:                return high;
1.9       lukem     300:        else
1.32      christos  301:                return p;
1.1       cgd       302: }
                    303:
                    304:
                    305: /* cv_prev_word():
                    306:  *     Find the previous word vi style
                    307:  */
1.28      christos  308: protected Char *
1.41      christos  309: cv_prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
1.1       cgd       310: {
1.9       lukem     311:        int test;
1.1       cgd       312:
1.16      christos  313:        p--;
1.9       lukem     314:        while (n--) {
1.28      christos  315:                while ((p > low) && Isspace(*p))
1.16      christos  316:                        p--;
1.28      christos  317:                test = (*wtest)(*p);
                    318:                while ((p >= low) && (*wtest)(*p) == test)
1.9       lukem     319:                        p--;
                    320:        }
1.16      christos  321:        p++;
1.1       cgd       322:
1.9       lukem     323:        /* p now points where we want it */
                    324:        if (p < low)
1.32      christos  325:                return low;
1.9       lukem     326:        else
1.32      christos  327:                return p;
1.1       cgd       328: }
                    329:
                    330:
                    331: /* cv_delfini():
                    332:  *     Finish vi delete action
                    333:  */
                    334: protected void
1.9       lukem     335: cv_delfini(EditLine *el)
1.1       cgd       336: {
1.9       lukem     337:        int size;
1.17      christos  338:        int action = el->el_chared.c_vcmd.action;
1.1       cgd       339:
1.17      christos  340:        if (action & INSERT)
1.9       lukem     341:                el->el_map.current = el->el_map.key;
1.1       cgd       342:
1.9       lukem     343:        if (el->el_chared.c_vcmd.pos == 0)
1.17      christos  344:                /* sanity */
1.9       lukem     345:                return;
                    346:
1.27      christos  347:        size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
1.17      christos  348:        if (size == 0)
                    349:                size = 1;
1.16      christos  350:        el->el_line.cursor = el->el_chared.c_vcmd.pos;
1.17      christos  351:        if (action & YANK) {
                    352:                if (size > 0)
                    353:                        cv_yank(el, el->el_line.cursor, size);
                    354:                else
                    355:                        cv_yank(el, el->el_line.cursor + size, -size);
1.9       lukem     356:        } else {
1.17      christos  357:                if (size > 0) {
                    358:                        c_delafter(el, size);
                    359:                        re_refresh_cursor(el);
                    360:                } else  {
                    361:                        c_delbefore(el, -size);
                    362:                        el->el_line.cursor += size;
                    363:                }
1.9       lukem     364:        }
1.17      christos  365:        el->el_chared.c_vcmd.action = NOP;
1.1       cgd       366: }
                    367:
                    368:
                    369: /* cv__endword():
                    370:  *     Go to the end of this word according to vi
                    371:  */
1.28      christos  372: protected Char *
1.41      christos  373: cv__endword(Char *p, Char *high, int n, int (*wtest)(wint_t))
1.9       lukem     374: {
1.16      christos  375:        int test;
                    376:
1.9       lukem     377:        p++;
1.1       cgd       378:
1.9       lukem     379:        while (n--) {
1.28      christos  380:                while ((p < high) && Isspace(*p))
1.9       lukem     381:                        p++;
                    382:
1.28      christos  383:                test = (*wtest)(*p);
                    384:                while ((p < high) && (*wtest)(*p) == test)
1.16      christos  385:                        p++;
1.9       lukem     386:        }
                    387:        p--;
1.32      christos  388:        return p;
1.1       cgd       389: }
                    390:
                    391: /* ch_init():
                    392:  *     Initialize the character editor
                    393:  */
                    394: protected int
1.9       lukem     395: ch_init(EditLine *el)
1.1       cgd       396: {
1.24      christos  397:        c_macro_t *ma = &el->el_chared.c_macro;
                    398:
1.28      christos  399:        el->el_line.buffer              = el_malloc(EL_BUFSIZ *
                    400:            sizeof(*el->el_line.buffer));
1.11      christos  401:        if (el->el_line.buffer == NULL)
1.32      christos  402:                return -1;
1.11      christos  403:
1.28      christos  404:        (void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
                    405:            sizeof(*el->el_line.buffer));
1.9       lukem     406:        el->el_line.cursor              = el->el_line.buffer;
                    407:        el->el_line.lastchar            = el->el_line.buffer;
1.16      christos  408:        el->el_line.limit               = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
1.9       lukem     409:
1.28      christos  410:        el->el_chared.c_undo.buf        = el_malloc(EL_BUFSIZ *
                    411:            sizeof(*el->el_chared.c_undo.buf));
1.11      christos  412:        if (el->el_chared.c_undo.buf == NULL)
1.32      christos  413:                return -1;
1.28      christos  414:        (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
                    415:            sizeof(*el->el_chared.c_undo.buf));
1.16      christos  416:        el->el_chared.c_undo.len        = -1;
                    417:        el->el_chared.c_undo.cursor     = 0;
1.28      christos  418:        el->el_chared.c_redo.buf        = el_malloc(EL_BUFSIZ *
                    419:            sizeof(*el->el_chared.c_redo.buf));
1.17      christos  420:        if (el->el_chared.c_redo.buf == NULL)
1.32      christos  421:                return -1;
1.17      christos  422:        el->el_chared.c_redo.pos        = el->el_chared.c_redo.buf;
                    423:        el->el_chared.c_redo.lim        = el->el_chared.c_redo.buf + EL_BUFSIZ;
                    424:        el->el_chared.c_redo.cmd        = ED_UNASSIGNED;
1.9       lukem     425:
                    426:        el->el_chared.c_vcmd.action     = NOP;
                    427:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
                    428:
1.28      christos  429:        el->el_chared.c_kill.buf        = el_malloc(EL_BUFSIZ *
                    430:            sizeof(*el->el_chared.c_kill.buf));
1.11      christos  431:        if (el->el_chared.c_kill.buf == NULL)
1.32      christos  432:                return -1;
1.28      christos  433:        (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
                    434:            sizeof(*el->el_chared.c_kill.buf));
1.9       lukem     435:        el->el_chared.c_kill.mark       = el->el_line.buffer;
                    436:        el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
1.29      christos  437:        el->el_chared.c_resizefun       = NULL;
                    438:        el->el_chared.c_resizearg       = NULL;
1.40      christos  439:        el->el_chared.c_aliasfun        = NULL;
                    440:        el->el_chared.c_aliasarg        = NULL;
1.9       lukem     441:
                    442:        el->el_map.current              = el->el_map.key;
                    443:
                    444:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    445:        el->el_state.doingarg           = 0;
                    446:        el->el_state.metanext           = 0;
                    447:        el->el_state.argument           = 1;
                    448:        el->el_state.lastcmd            = ED_UNASSIGNED;
                    449:
1.24      christos  450:        ma->level       = -1;
                    451:        ma->offset      = 0;
1.28      christos  452:        ma->macro       = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
1.24      christos  453:        if (ma->macro == NULL)
1.32      christos  454:                return -1;
                    455:        return 0;
1.1       cgd       456: }
                    457:
                    458: /* ch_reset():
                    459:  *     Reset the character editor
                    460:  */
                    461: protected void
1.24      christos  462: ch_reset(EditLine *el, int mclear)
1.1       cgd       463: {
1.9       lukem     464:        el->el_line.cursor              = el->el_line.buffer;
                    465:        el->el_line.lastchar            = el->el_line.buffer;
1.1       cgd       466:
1.16      christos  467:        el->el_chared.c_undo.len        = -1;
                    468:        el->el_chared.c_undo.cursor     = 0;
1.1       cgd       469:
1.9       lukem     470:        el->el_chared.c_vcmd.action     = NOP;
                    471:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
1.1       cgd       472:
1.9       lukem     473:        el->el_chared.c_kill.mark       = el->el_line.buffer;
1.1       cgd       474:
1.9       lukem     475:        el->el_map.current              = el->el_map.key;
1.1       cgd       476:
1.9       lukem     477:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    478:        el->el_state.doingarg           = 0;
                    479:        el->el_state.metanext           = 0;
                    480:        el->el_state.argument           = 1;
                    481:        el->el_state.lastcmd            = ED_UNASSIGNED;
1.1       cgd       482:
1.25      christos  483:        el->el_history.eventno          = 0;
                    484:
1.24      christos  485:        if (mclear)
                    486:                ch__clearmacro(el);
                    487: }
1.1       cgd       488:
1.24      christos  489: private void
1.27      christos  490: ch__clearmacro(EditLine *el)
1.24      christos  491: {
                    492:        c_macro_t *ma = &el->el_chared.c_macro;
                    493:        while (ma->level >= 0)
1.31      christos  494:                el_free(ma->macro[ma->level--]);
1.1       cgd       495: }
                    496:
1.12      jdolecek  497: /* ch_enlargebufs():
                    498:  *     Enlarge line buffer to be able to hold twice as much characters.
                    499:  *     Returns 1 if successful, 0 if not.
                    500:  */
                    501: protected int
1.27      christos  502: ch_enlargebufs(EditLine *el, size_t addlen)
1.12      jdolecek  503: {
1.13      lukem     504:        size_t sz, newsz;
1.28      christos  505:        Char *newbuffer, *oldbuf, *oldkbuf;
1.12      jdolecek  506:
1.35      christos  507:        sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
1.13      lukem     508:        newsz = sz * 2;
                    509:        /*
                    510:         * If newly required length is longer than current buffer, we need
                    511:         * to make the buffer big enough to hold both old and new stuff.
                    512:         */
                    513:        if (addlen > sz) {
                    514:                while(newsz - sz < addlen)
                    515:                        newsz *= 2;
                    516:        }
                    517:
                    518:        /*
                    519:         * Reallocate line buffer.
                    520:         */
1.28      christos  521:        newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
1.13      lukem     522:        if (!newbuffer)
                    523:                return 0;
                    524:
                    525:        /* zero the newly added memory, leave old data in */
1.28      christos  526:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.13      lukem     527:
                    528:        oldbuf = el->el_line.buffer;
                    529:
                    530:        el->el_line.buffer = newbuffer;
                    531:        el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
                    532:        el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
1.16      christos  533:        /* don't set new size until all buffers are enlarged */
                    534:        el->el_line.limit  = &newbuffer[sz - EL_LEAVE];
1.13      lukem     535:
                    536:        /*
                    537:         * Reallocate kill buffer.
                    538:         */
1.31      christos  539:        newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
                    540:            sizeof(*newbuffer));
1.13      lukem     541:        if (!newbuffer)
                    542:                return 0;
1.12      jdolecek  543:
1.13      lukem     544:        /* zero the newly added memory, leave old data in */
1.28      christos  545:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.12      jdolecek  546:
1.13      lukem     547:        oldkbuf = el->el_chared.c_kill.buf;
1.12      jdolecek  548:
1.13      lukem     549:        el->el_chared.c_kill.buf = newbuffer;
                    550:        el->el_chared.c_kill.last = newbuffer +
1.12      jdolecek  551:                                        (el->el_chared.c_kill.last - oldkbuf);
1.13      lukem     552:        el->el_chared.c_kill.mark = el->el_line.buffer +
1.12      jdolecek  553:                                        (el->el_chared.c_kill.mark - oldbuf);
                    554:
1.13      lukem     555:        /*
                    556:         * Reallocate undo buffer.
                    557:         */
1.28      christos  558:        newbuffer = el_realloc(el->el_chared.c_undo.buf,
                    559:            newsz * sizeof(*newbuffer));
1.13      lukem     560:        if (!newbuffer)
                    561:                return 0;
                    562:
                    563:        /* zero the newly added memory, leave old data in */
1.28      christos  564:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.16      christos  565:        el->el_chared.c_undo.buf = newbuffer;
1.13      lukem     566:
1.28      christos  567:        newbuffer = el_realloc(el->el_chared.c_redo.buf,
                    568:            newsz * sizeof(*newbuffer));
1.16      christos  569:        if (!newbuffer)
                    570:                return 0;
1.17      christos  571:        el->el_chared.c_redo.pos = newbuffer +
                    572:                        (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
                    573:        el->el_chared.c_redo.lim = newbuffer +
                    574:                        (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
                    575:        el->el_chared.c_redo.buf = newbuffer;
1.13      lukem     576:
                    577:        if (!hist_enlargebuf(el, sz, newsz))
                    578:                return 0;
1.12      jdolecek  579:
1.16      christos  580:        /* Safe to set enlarged buffer size */
1.21      christos  581:        el->el_line.limit  = &el->el_line.buffer[newsz - EL_LEAVE];
1.29      christos  582:        if (el->el_chared.c_resizefun)
                    583:                (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
1.13      lukem     584:        return 1;
1.12      jdolecek  585: }
1.1       cgd       586:
                    587: /* ch_end():
                    588:  *     Free the data structures used by the editor
                    589:  */
                    590: protected void
1.9       lukem     591: ch_end(EditLine *el)
1.1       cgd       592: {
1.31      christos  593:        el_free(el->el_line.buffer);
1.9       lukem     594:        el->el_line.buffer = NULL;
                    595:        el->el_line.limit = NULL;
1.31      christos  596:        el_free(el->el_chared.c_undo.buf);
1.9       lukem     597:        el->el_chared.c_undo.buf = NULL;
1.31      christos  598:        el_free(el->el_chared.c_redo.buf);
1.17      christos  599:        el->el_chared.c_redo.buf = NULL;
                    600:        el->el_chared.c_redo.pos = NULL;
                    601:        el->el_chared.c_redo.lim = NULL;
                    602:        el->el_chared.c_redo.cmd = ED_UNASSIGNED;
1.31      christos  603:        el_free(el->el_chared.c_kill.buf);
1.9       lukem     604:        el->el_chared.c_kill.buf = NULL;
1.24      christos  605:        ch_reset(el, 1);
1.31      christos  606:        el_free(el->el_chared.c_macro.macro);
1.9       lukem     607:        el->el_chared.c_macro.macro = NULL;
1.1       cgd       608: }
                    609:
                    610:
                    611: /* el_insertstr():
                    612:  *     Insert string at cursorI
                    613:  */
                    614: public int
1.28      christos  615: FUN(el,insertstr)(EditLine *el, const Char *s)
1.9       lukem     616: {
1.14      christos  617:        size_t len;
1.9       lukem     618:
1.37      christos  619:        if (s == NULL || (len = Strlen(s)) == 0)
1.32      christos  620:                return -1;
1.12      jdolecek  621:        if (el->el_line.lastchar + len >= el->el_line.limit) {
                    622:                if (!ch_enlargebufs(el, len))
1.32      christos  623:                        return -1;
1.12      jdolecek  624:        }
1.9       lukem     625:
1.14      christos  626:        c_insert(el, (int)len);
1.9       lukem     627:        while (*s)
                    628:                *el->el_line.cursor++ = *s++;
1.32      christos  629:        return 0;
1.1       cgd       630: }
                    631:
                    632:
                    633: /* el_deletestr():
                    634:  *     Delete num characters before the cursor
                    635:  */
                    636: public void
1.9       lukem     637: el_deletestr(EditLine *el, int n)
                    638: {
                    639:        if (n <= 0)
                    640:                return;
                    641:
                    642:        if (el->el_line.cursor < &el->el_line.buffer[n])
                    643:                return;
                    644:
                    645:        c_delbefore(el, n);             /* delete before dot */
                    646:        el->el_line.cursor -= n;
                    647:        if (el->el_line.cursor < el->el_line.buffer)
                    648:                el->el_line.cursor = el->el_line.buffer;
1.1       cgd       649: }
                    650:
1.38      christos  651: /* el_cursor():
                    652:  *     Move the cursor to the left or the right of the current position
                    653:  */
                    654: public int
                    655: el_cursor(EditLine *el, int n)
                    656: {
                    657:        if (n == 0)
                    658:                goto out;
                    659:
                    660:        el->el_line.cursor += n;
                    661:
                    662:        if (el->el_line.cursor < el->el_line.buffer)
                    663:                el->el_line.cursor = el->el_line.buffer;
                    664:        if (el->el_line.cursor > el->el_line.lastchar)
                    665:                el->el_line.cursor = el->el_line.lastchar;
                    666: out:
1.39      christos  667:        return (int)(el->el_line.cursor - el->el_line.buffer);
1.38      christos  668: }
                    669:
1.1       cgd       670: /* c_gets():
                    671:  *     Get a string
                    672:  */
                    673: protected int
1.28      christos  674: c_gets(EditLine *el, Char *buf, const Char *prompt)
1.9       lukem     675: {
1.28      christos  676:        Char ch;
1.27      christos  677:        ssize_t len;
1.28      christos  678:        Char *cp = el->el_line.buffer;
1.18      christos  679:
                    680:        if (prompt) {
1.35      christos  681:                len = (ssize_t)Strlen(prompt);
                    682:                (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
1.18      christos  683:                cp += len;
                    684:        }
                    685:        len = 0;
                    686:
                    687:        for (;;) {
                    688:                el->el_line.cursor = cp;
                    689:                *cp = ' ';
                    690:                el->el_line.lastchar = cp + 1;
                    691:                re_refresh(el);
                    692:
1.28      christos  693:                if (FUN(el,getc)(el, &ch) != 1) {
1.18      christos  694:                        ed_end_of_file(el, 0);
                    695:                        len = -1;
                    696:                        break;
                    697:                }
1.1       cgd       698:
1.9       lukem     699:                switch (ch) {
1.18      christos  700:
1.9       lukem     701:                case 0010:      /* Delete and backspace */
                    702:                case 0177:
1.27      christos  703:                        if (len == 0) {
1.18      christos  704:                                len = -1;
                    705:                                break;
1.9       lukem     706:                        }
1.18      christos  707:                        cp--;
                    708:                        continue;
1.9       lukem     709:
                    710:                case 0033:      /* ESC */
                    711:                case '\r':      /* Newline */
                    712:                case '\n':
1.18      christos  713:                        buf[len] = ch;
1.9       lukem     714:                        break;
                    715:
                    716:                default:
1.34      christos  717:                        if (len >= (ssize_t)(EL_BUFSIZ - 16))
1.30      christos  718:                                terminal_beep(el);
1.9       lukem     719:                        else {
                    720:                                buf[len++] = ch;
1.18      christos  721:                                *cp++ = ch;
1.9       lukem     722:                        }
1.18      christos  723:                        continue;
1.9       lukem     724:                }
1.18      christos  725:                break;
1.9       lukem     726:        }
1.18      christos  727:
                    728:        el->el_line.buffer[0] = '\0';
                    729:        el->el_line.lastchar = el->el_line.buffer;
                    730:        el->el_line.cursor = el->el_line.buffer;
1.27      christos  731:        return (int)len;
1.1       cgd       732: }
                    733:
                    734:
                    735: /* c_hpos():
                    736:  *     Return the current horizontal position of the cursor
                    737:  */
                    738: protected int
1.9       lukem     739: c_hpos(EditLine *el)
1.1       cgd       740: {
1.28      christos  741:        Char *ptr;
1.1       cgd       742:
1.9       lukem     743:        /*
                    744:         * Find how many characters till the beginning of this line.
                    745:         */
                    746:        if (el->el_line.cursor == el->el_line.buffer)
1.32      christos  747:                return 0;
1.9       lukem     748:        else {
                    749:                for (ptr = el->el_line.cursor - 1;
                    750:                     ptr >= el->el_line.buffer && *ptr != '\n';
                    751:                     ptr--)
                    752:                        continue;
1.27      christos  753:                return (int)(el->el_line.cursor - ptr - 1);
1.9       lukem     754:        }
1.1       cgd       755: }
1.29      christos  756:
                    757: protected int
                    758: ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
                    759: {
                    760:        el->el_chared.c_resizefun = f;
                    761:        el->el_chared.c_resizearg = a;
                    762:        return 0;
                    763: }
1.40      christos  764:
                    765: protected int
                    766: ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
                    767: {
                    768:        el->el_chared.c_aliasfun = f;
                    769:        el->el_chared.c_aliasarg = a;
                    770:        return 0;
                    771: }

CVSweb <webmaster@jp.NetBSD.org>