[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.52

1.52    ! christos    1: /*     $NetBSD: chared.c,v 1.51 2016/04/11 00:22: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.52    ! christos   40: __RCSID("$NetBSD: chared.c,v 1.51 2016/04/11 00:22: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:  */
1.46      christos   47: #include <ctype.h>
1.1       cgd        48: #include <stdlib.h>
1.46      christos   49: #include <string.h>
1.45      christos   50:
1.1       cgd        51: #include "el.h"
1.45      christos   52: #include "common.h"
1.1       cgd        53:
1.26      sketch     54: private void ch__clearmacro (EditLine *);
1.24      christos   55:
1.12      jdolecek   56: /* value to leave unused in line buffer */
                     57: #define        EL_LEAVE        2
                     58:
1.1       cgd        59: /* cv_undo():
                     60:  *     Handle state for the vi undo command
                     61:  */
                     62: protected void
1.17      christos   63: cv_undo(EditLine *el)
1.9       lukem      64: {
                     65:        c_undo_t *vu = &el->el_chared.c_undo;
1.17      christos   66:        c_redo_t *r = &el->el_chared.c_redo;
1.27      christos   67:        size_t size;
1.16      christos   68:
1.17      christos   69:        /* Save entire line for undo */
1.35      christos   70:        size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
                     71:        vu->len = (ssize_t)size;
1.27      christos   72:        vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
1.28      christos   73:        (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
1.16      christos   74:
1.17      christos   75:        /* save command info for redo */
                     76:        r->count = el->el_state.doingarg ? el->el_state.argument : 0;
                     77:        r->action = el->el_chared.c_vcmd.action;
                     78:        r->pos = r->buf;
                     79:        r->cmd = el->el_state.thiscmd;
                     80:        r->ch = el->el_state.thisch;
                     81: }
                     82:
                     83: /* cv_yank():
                     84:  *     Save yank/delete data for paste
                     85:  */
                     86: protected void
1.52    ! christos   87: cv_yank(EditLine *el, const wchar_t *ptr, int size)
1.17      christos   88: {
                     89:        c_kill_t *k = &el->el_chared.c_kill;
                     90:
1.35      christos   91:        (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
1.17      christos   92:        k->last = k->buf + size;
1.1       cgd        93: }
                     94:
                     95:
1.7       simonb     96: /* c_insert():
1.1       cgd        97:  *     Insert num characters
                     98:  */
                     99: protected void
1.9       lukem     100: c_insert(EditLine *el, int num)
                    101: {
1.52    ! christos  102:        wchar_t *cp;
1.9       lukem     103:
1.17      christos  104:        if (el->el_line.lastchar + num >= el->el_line.limit) {
1.27      christos  105:                if (!ch_enlargebufs(el, (size_t)num))
1.17      christos  106:                        return;         /* can't go past end of buffer */
                    107:        }
1.9       lukem     108:
                    109:        if (el->el_line.cursor < el->el_line.lastchar) {
                    110:                /* if I must move chars */
                    111:                for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
                    112:                        cp[num] = *cp;
                    113:        }
                    114:        el->el_line.lastchar += num;
                    115: }
1.1       cgd       116:
                    117:
                    118: /* c_delafter():
                    119:  *     Delete num characters after the cursor
                    120:  */
                    121: protected void
1.9       lukem     122: c_delafter(EditLine *el, int num)
1.1       cgd       123: {
                    124:
1.9       lukem     125:        if (el->el_line.cursor + num > el->el_line.lastchar)
1.27      christos  126:                num = (int)(el->el_line.lastchar - el->el_line.cursor);
1.1       cgd       127:
1.17      christos  128:        if (el->el_map.current != el->el_map.emacs) {
                    129:                cv_undo(el);
                    130:                cv_yank(el, el->el_line.cursor, num);
                    131:        }
1.16      christos  132:
1.9       lukem     133:        if (num > 0) {
1.52    ! christos  134:                wchar_t *cp;
1.1       cgd       135:
1.9       lukem     136:                for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
                    137:                        *cp = cp[num];
1.1       cgd       138:
1.9       lukem     139:                el->el_line.lastchar -= num;
                    140:        }
1.1       cgd       141: }
                    142:
                    143:
1.22      mycroft   144: /* c_delafter1():
                    145:  *     Delete the character after the cursor, do not yank
                    146:  */
                    147: protected void
                    148: c_delafter1(EditLine *el)
                    149: {
1.52    ! christos  150:        wchar_t *cp;
1.22      mycroft   151:
                    152:        for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
                    153:                *cp = cp[1];
                    154:
                    155:        el->el_line.lastchar--;
                    156: }
                    157:
                    158:
1.1       cgd       159: /* c_delbefore():
                    160:  *     Delete num characters before the cursor
                    161:  */
                    162: protected void
1.9       lukem     163: c_delbefore(EditLine *el, int num)
1.1       cgd       164: {
                    165:
1.9       lukem     166:        if (el->el_line.cursor - num < el->el_line.buffer)
1.27      christos  167:                num = (int)(el->el_line.cursor - el->el_line.buffer);
1.1       cgd       168:
1.17      christos  169:        if (el->el_map.current != el->el_map.emacs) {
                    170:                cv_undo(el);
                    171:                cv_yank(el, el->el_line.cursor - num, num);
                    172:        }
1.16      christos  173:
1.9       lukem     174:        if (num > 0) {
1.52    ! christos  175:                wchar_t *cp;
1.1       cgd       176:
1.9       lukem     177:                for (cp = el->el_line.cursor - num;
                    178:                    cp <= el->el_line.lastchar;
                    179:                    cp++)
                    180:                        *cp = cp[num];
1.1       cgd       181:
1.9       lukem     182:                el->el_line.lastchar -= num;
                    183:        }
1.1       cgd       184: }
                    185:
                    186:
1.22      mycroft   187: /* c_delbefore1():
                    188:  *     Delete the character before the cursor, do not yank
                    189:  */
                    190: protected void
                    191: c_delbefore1(EditLine *el)
                    192: {
1.52    ! christos  193:        wchar_t *cp;
1.22      mycroft   194:
                    195:        for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
                    196:                *cp = cp[1];
                    197:
                    198:        el->el_line.lastchar--;
                    199: }
                    200:
                    201:
1.1       cgd       202: /* ce__isword():
                    203:  *     Return if p is part of a word according to emacs
                    204:  */
                    205: protected int
1.41      christos  206: ce__isword(wint_t p)
1.1       cgd       207: {
1.51      christos  208:        return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
1.1       cgd       209: }
                    210:
                    211:
                    212: /* cv__isword():
                    213:  *     Return if p is part of a word according to vi
                    214:  */
                    215: protected int
1.41      christos  216: cv__isword(wint_t p)
1.1       cgd       217: {
1.50      christos  218:        if (iswalnum(p) || p == L'_')
1.17      christos  219:                return 1;
1.50      christos  220:        if (iswgraph(p))
1.17      christos  221:                return 2;
                    222:        return 0;
1.16      christos  223: }
                    224:
                    225:
                    226: /* cv__isWord():
                    227:  *     Return if p is part of a big word according to vi
                    228:  */
                    229: protected int
1.41      christos  230: cv__isWord(wint_t p)
1.16      christos  231: {
1.50      christos  232:        return !iswspace(p);
1.1       cgd       233: }
                    234:
                    235:
                    236: /* c__prev_word():
                    237:  *     Find the previous word
                    238:  */
1.52    ! christos  239: protected wchar_t *
        !           240: c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
1.9       lukem     241: {
                    242:        p--;
                    243:
                    244:        while (n--) {
1.28      christos  245:                while ((p >= low) && !(*wtest)(*p))
1.9       lukem     246:                        p--;
1.28      christos  247:                while ((p >= low) && (*wtest)(*p))
1.9       lukem     248:                        p--;
                    249:        }
                    250:
                    251:        /* cp now points to one character before the word */
                    252:        p++;
                    253:        if (p < low)
                    254:                p = low;
                    255:        /* cp now points where we want it */
1.32      christos  256:        return p;
1.1       cgd       257: }
                    258:
                    259:
                    260: /* c__next_word():
                    261:  *     Find the next word
                    262:  */
1.52    ! christos  263: protected wchar_t *
        !           264: c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
1.9       lukem     265: {
                    266:        while (n--) {
1.28      christos  267:                while ((p < high) && !(*wtest)(*p))
1.9       lukem     268:                        p++;
1.28      christos  269:                while ((p < high) && (*wtest)(*p))
1.9       lukem     270:                        p++;
                    271:        }
                    272:        if (p > high)
                    273:                p = high;
                    274:        /* p now points where we want it */
1.32      christos  275:        return p;
1.1       cgd       276: }
                    277:
                    278: /* cv_next_word():
                    279:  *     Find the next word vi style
                    280:  */
1.52    ! christos  281: protected wchar_t *
        !           282: cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
        !           283:     int (*wtest)(wint_t))
1.9       lukem     284: {
                    285:        int test;
                    286:
                    287:        while (n--) {
1.28      christos  288:                test = (*wtest)(*p);
                    289:                while ((p < high) && (*wtest)(*p) == test)
1.9       lukem     290:                        p++;
                    291:                /*
                    292:                 * vi historically deletes with cw only the word preserving the
                    293:                 * trailing whitespace! This is not what 'w' does..
                    294:                 */
1.16      christos  295:                if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
1.50      christos  296:                        while ((p < high) && iswspace(*p))
1.9       lukem     297:                                p++;
                    298:        }
1.1       cgd       299:
1.9       lukem     300:        /* p now points where we want it */
                    301:        if (p > high)
1.32      christos  302:                return high;
1.9       lukem     303:        else
1.32      christos  304:                return p;
1.1       cgd       305: }
                    306:
                    307:
                    308: /* cv_prev_word():
                    309:  *     Find the previous word vi style
                    310:  */
1.52    ! christos  311: protected wchar_t *
        !           312: cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
1.1       cgd       313: {
1.9       lukem     314:        int test;
1.1       cgd       315:
1.16      christos  316:        p--;
1.9       lukem     317:        while (n--) {
1.50      christos  318:                while ((p > low) && iswspace(*p))
1.16      christos  319:                        p--;
1.28      christos  320:                test = (*wtest)(*p);
                    321:                while ((p >= low) && (*wtest)(*p) == test)
1.9       lukem     322:                        p--;
                    323:        }
1.16      christos  324:        p++;
1.1       cgd       325:
1.9       lukem     326:        /* p now points where we want it */
                    327:        if (p < low)
1.32      christos  328:                return low;
1.9       lukem     329:        else
1.32      christos  330:                return p;
1.1       cgd       331: }
                    332:
                    333:
                    334: /* cv_delfini():
                    335:  *     Finish vi delete action
                    336:  */
                    337: protected void
1.9       lukem     338: cv_delfini(EditLine *el)
1.1       cgd       339: {
1.9       lukem     340:        int size;
1.17      christos  341:        int action = el->el_chared.c_vcmd.action;
1.1       cgd       342:
1.17      christos  343:        if (action & INSERT)
1.9       lukem     344:                el->el_map.current = el->el_map.key;
1.1       cgd       345:
1.9       lukem     346:        if (el->el_chared.c_vcmd.pos == 0)
1.17      christos  347:                /* sanity */
1.9       lukem     348:                return;
                    349:
1.27      christos  350:        size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
1.17      christos  351:        if (size == 0)
                    352:                size = 1;
1.16      christos  353:        el->el_line.cursor = el->el_chared.c_vcmd.pos;
1.17      christos  354:        if (action & YANK) {
                    355:                if (size > 0)
                    356:                        cv_yank(el, el->el_line.cursor, size);
                    357:                else
                    358:                        cv_yank(el, el->el_line.cursor + size, -size);
1.9       lukem     359:        } else {
1.17      christos  360:                if (size > 0) {
                    361:                        c_delafter(el, size);
                    362:                        re_refresh_cursor(el);
                    363:                } else  {
                    364:                        c_delbefore(el, -size);
                    365:                        el->el_line.cursor += size;
                    366:                }
1.9       lukem     367:        }
1.17      christos  368:        el->el_chared.c_vcmd.action = NOP;
1.1       cgd       369: }
                    370:
                    371:
                    372: /* cv__endword():
                    373:  *     Go to the end of this word according to vi
                    374:  */
1.52    ! christos  375: protected wchar_t *
        !           376: cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
1.9       lukem     377: {
1.16      christos  378:        int test;
                    379:
1.9       lukem     380:        p++;
1.1       cgd       381:
1.9       lukem     382:        while (n--) {
1.50      christos  383:                while ((p < high) && iswspace(*p))
1.9       lukem     384:                        p++;
                    385:
1.28      christos  386:                test = (*wtest)(*p);
                    387:                while ((p < high) && (*wtest)(*p) == test)
1.16      christos  388:                        p++;
1.9       lukem     389:        }
                    390:        p--;
1.32      christos  391:        return p;
1.1       cgd       392: }
                    393:
                    394: /* ch_init():
                    395:  *     Initialize the character editor
                    396:  */
                    397: protected int
1.9       lukem     398: ch_init(EditLine *el)
1.1       cgd       399: {
1.24      christos  400:        c_macro_t *ma = &el->el_chared.c_macro;
                    401:
1.28      christos  402:        el->el_line.buffer              = el_malloc(EL_BUFSIZ *
                    403:            sizeof(*el->el_line.buffer));
1.11      christos  404:        if (el->el_line.buffer == NULL)
1.32      christos  405:                return -1;
1.11      christos  406:
1.28      christos  407:        (void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
                    408:            sizeof(*el->el_line.buffer));
1.9       lukem     409:        el->el_line.cursor              = el->el_line.buffer;
                    410:        el->el_line.lastchar            = el->el_line.buffer;
1.16      christos  411:        el->el_line.limit               = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
1.9       lukem     412:
1.28      christos  413:        el->el_chared.c_undo.buf        = el_malloc(EL_BUFSIZ *
                    414:            sizeof(*el->el_chared.c_undo.buf));
1.11      christos  415:        if (el->el_chared.c_undo.buf == NULL)
1.32      christos  416:                return -1;
1.28      christos  417:        (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
                    418:            sizeof(*el->el_chared.c_undo.buf));
1.16      christos  419:        el->el_chared.c_undo.len        = -1;
                    420:        el->el_chared.c_undo.cursor     = 0;
1.28      christos  421:        el->el_chared.c_redo.buf        = el_malloc(EL_BUFSIZ *
                    422:            sizeof(*el->el_chared.c_redo.buf));
1.17      christos  423:        if (el->el_chared.c_redo.buf == NULL)
1.32      christos  424:                return -1;
1.17      christos  425:        el->el_chared.c_redo.pos        = el->el_chared.c_redo.buf;
                    426:        el->el_chared.c_redo.lim        = el->el_chared.c_redo.buf + EL_BUFSIZ;
                    427:        el->el_chared.c_redo.cmd        = ED_UNASSIGNED;
1.9       lukem     428:
                    429:        el->el_chared.c_vcmd.action     = NOP;
                    430:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
                    431:
1.28      christos  432:        el->el_chared.c_kill.buf        = el_malloc(EL_BUFSIZ *
                    433:            sizeof(*el->el_chared.c_kill.buf));
1.11      christos  434:        if (el->el_chared.c_kill.buf == NULL)
1.32      christos  435:                return -1;
1.28      christos  436:        (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
                    437:            sizeof(*el->el_chared.c_kill.buf));
1.9       lukem     438:        el->el_chared.c_kill.mark       = el->el_line.buffer;
                    439:        el->el_chared.c_kill.last       = el->el_chared.c_kill.buf;
1.29      christos  440:        el->el_chared.c_resizefun       = NULL;
                    441:        el->el_chared.c_resizearg       = NULL;
1.40      christos  442:        el->el_chared.c_aliasfun        = NULL;
                    443:        el->el_chared.c_aliasarg        = NULL;
1.9       lukem     444:
                    445:        el->el_map.current              = el->el_map.key;
                    446:
                    447:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    448:        el->el_state.doingarg           = 0;
                    449:        el->el_state.metanext           = 0;
                    450:        el->el_state.argument           = 1;
                    451:        el->el_state.lastcmd            = ED_UNASSIGNED;
                    452:
1.24      christos  453:        ma->level       = -1;
                    454:        ma->offset      = 0;
1.28      christos  455:        ma->macro       = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
1.24      christos  456:        if (ma->macro == NULL)
1.32      christos  457:                return -1;
                    458:        return 0;
1.1       cgd       459: }
                    460:
                    461: /* ch_reset():
                    462:  *     Reset the character editor
                    463:  */
                    464: protected void
1.24      christos  465: ch_reset(EditLine *el, int mclear)
1.1       cgd       466: {
1.9       lukem     467:        el->el_line.cursor              = el->el_line.buffer;
                    468:        el->el_line.lastchar            = el->el_line.buffer;
1.1       cgd       469:
1.16      christos  470:        el->el_chared.c_undo.len        = -1;
                    471:        el->el_chared.c_undo.cursor     = 0;
1.1       cgd       472:
1.9       lukem     473:        el->el_chared.c_vcmd.action     = NOP;
                    474:        el->el_chared.c_vcmd.pos        = el->el_line.buffer;
1.1       cgd       475:
1.9       lukem     476:        el->el_chared.c_kill.mark       = el->el_line.buffer;
1.1       cgd       477:
1.9       lukem     478:        el->el_map.current              = el->el_map.key;
1.1       cgd       479:
1.9       lukem     480:        el->el_state.inputmode          = MODE_INSERT; /* XXX: save a default */
                    481:        el->el_state.doingarg           = 0;
                    482:        el->el_state.metanext           = 0;
                    483:        el->el_state.argument           = 1;
                    484:        el->el_state.lastcmd            = ED_UNASSIGNED;
1.1       cgd       485:
1.25      christos  486:        el->el_history.eventno          = 0;
                    487:
1.24      christos  488:        if (mclear)
                    489:                ch__clearmacro(el);
                    490: }
1.1       cgd       491:
1.24      christos  492: private void
1.27      christos  493: ch__clearmacro(EditLine *el)
1.24      christos  494: {
                    495:        c_macro_t *ma = &el->el_chared.c_macro;
                    496:        while (ma->level >= 0)
1.31      christos  497:                el_free(ma->macro[ma->level--]);
1.1       cgd       498: }
                    499:
1.12      jdolecek  500: /* ch_enlargebufs():
                    501:  *     Enlarge line buffer to be able to hold twice as much characters.
                    502:  *     Returns 1 if successful, 0 if not.
                    503:  */
                    504: protected int
1.27      christos  505: ch_enlargebufs(EditLine *el, size_t addlen)
1.12      jdolecek  506: {
1.13      lukem     507:        size_t sz, newsz;
1.52    ! christos  508:        wchar_t *newbuffer, *oldbuf, *oldkbuf;
1.12      jdolecek  509:
1.35      christos  510:        sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
1.13      lukem     511:        newsz = sz * 2;
                    512:        /*
                    513:         * If newly required length is longer than current buffer, we need
                    514:         * to make the buffer big enough to hold both old and new stuff.
                    515:         */
                    516:        if (addlen > sz) {
                    517:                while(newsz - sz < addlen)
                    518:                        newsz *= 2;
                    519:        }
                    520:
                    521:        /*
                    522:         * Reallocate line buffer.
                    523:         */
1.28      christos  524:        newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
1.13      lukem     525:        if (!newbuffer)
                    526:                return 0;
                    527:
                    528:        /* zero the newly added memory, leave old data in */
1.28      christos  529:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.47      christos  530:
1.13      lukem     531:        oldbuf = el->el_line.buffer;
                    532:
                    533:        el->el_line.buffer = newbuffer;
                    534:        el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
                    535:        el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
1.16      christos  536:        /* don't set new size until all buffers are enlarged */
                    537:        el->el_line.limit  = &newbuffer[sz - EL_LEAVE];
1.13      lukem     538:
                    539:        /*
                    540:         * Reallocate kill buffer.
                    541:         */
1.31      christos  542:        newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
                    543:            sizeof(*newbuffer));
1.13      lukem     544:        if (!newbuffer)
                    545:                return 0;
1.12      jdolecek  546:
1.13      lukem     547:        /* zero the newly added memory, leave old data in */
1.28      christos  548:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.12      jdolecek  549:
1.13      lukem     550:        oldkbuf = el->el_chared.c_kill.buf;
1.12      jdolecek  551:
1.13      lukem     552:        el->el_chared.c_kill.buf = newbuffer;
                    553:        el->el_chared.c_kill.last = newbuffer +
1.12      jdolecek  554:                                        (el->el_chared.c_kill.last - oldkbuf);
1.13      lukem     555:        el->el_chared.c_kill.mark = el->el_line.buffer +
1.12      jdolecek  556:                                        (el->el_chared.c_kill.mark - oldbuf);
                    557:
1.13      lukem     558:        /*
                    559:         * Reallocate undo buffer.
                    560:         */
1.28      christos  561:        newbuffer = el_realloc(el->el_chared.c_undo.buf,
                    562:            newsz * sizeof(*newbuffer));
1.13      lukem     563:        if (!newbuffer)
                    564:                return 0;
                    565:
                    566:        /* zero the newly added memory, leave old data in */
1.28      christos  567:        (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
1.16      christos  568:        el->el_chared.c_undo.buf = newbuffer;
1.13      lukem     569:
1.28      christos  570:        newbuffer = el_realloc(el->el_chared.c_redo.buf,
                    571:            newsz * sizeof(*newbuffer));
1.16      christos  572:        if (!newbuffer)
                    573:                return 0;
1.17      christos  574:        el->el_chared.c_redo.pos = newbuffer +
                    575:                        (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
                    576:        el->el_chared.c_redo.lim = newbuffer +
                    577:                        (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
                    578:        el->el_chared.c_redo.buf = newbuffer;
1.47      christos  579:
1.13      lukem     580:        if (!hist_enlargebuf(el, sz, newsz))
                    581:                return 0;
1.12      jdolecek  582:
1.16      christos  583:        /* Safe to set enlarged buffer size */
1.21      christos  584:        el->el_line.limit  = &el->el_line.buffer[newsz - EL_LEAVE];
1.29      christos  585:        if (el->el_chared.c_resizefun)
                    586:                (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
1.13      lukem     587:        return 1;
1.12      jdolecek  588: }
1.1       cgd       589:
                    590: /* ch_end():
                    591:  *     Free the data structures used by the editor
                    592:  */
                    593: protected void
1.9       lukem     594: ch_end(EditLine *el)
1.1       cgd       595: {
1.31      christos  596:        el_free(el->el_line.buffer);
1.9       lukem     597:        el->el_line.buffer = NULL;
                    598:        el->el_line.limit = NULL;
1.31      christos  599:        el_free(el->el_chared.c_undo.buf);
1.9       lukem     600:        el->el_chared.c_undo.buf = NULL;
1.31      christos  601:        el_free(el->el_chared.c_redo.buf);
1.17      christos  602:        el->el_chared.c_redo.buf = NULL;
                    603:        el->el_chared.c_redo.pos = NULL;
                    604:        el->el_chared.c_redo.lim = NULL;
                    605:        el->el_chared.c_redo.cmd = ED_UNASSIGNED;
1.31      christos  606:        el_free(el->el_chared.c_kill.buf);
1.9       lukem     607:        el->el_chared.c_kill.buf = NULL;
1.24      christos  608:        ch_reset(el, 1);
1.31      christos  609:        el_free(el->el_chared.c_macro.macro);
1.9       lukem     610:        el->el_chared.c_macro.macro = NULL;
1.1       cgd       611: }
                    612:
                    613:
                    614: /* el_insertstr():
                    615:  *     Insert string at cursorI
                    616:  */
                    617: public int
1.52    ! christos  618: el_winsertstr(EditLine *el, const wchar_t *s)
1.9       lukem     619: {
1.14      christos  620:        size_t len;
1.9       lukem     621:
1.51      christos  622:        if (s == NULL || (len = wcslen(s)) == 0)
1.32      christos  623:                return -1;
1.12      jdolecek  624:        if (el->el_line.lastchar + len >= el->el_line.limit) {
                    625:                if (!ch_enlargebufs(el, len))
1.32      christos  626:                        return -1;
1.12      jdolecek  627:        }
1.9       lukem     628:
1.14      christos  629:        c_insert(el, (int)len);
1.9       lukem     630:        while (*s)
                    631:                *el->el_line.cursor++ = *s++;
1.32      christos  632:        return 0;
1.1       cgd       633: }
                    634:
                    635:
                    636: /* el_deletestr():
                    637:  *     Delete num characters before the cursor
                    638:  */
                    639: public void
1.9       lukem     640: el_deletestr(EditLine *el, int n)
                    641: {
                    642:        if (n <= 0)
                    643:                return;
                    644:
                    645:        if (el->el_line.cursor < &el->el_line.buffer[n])
                    646:                return;
                    647:
                    648:        c_delbefore(el, n);             /* delete before dot */
                    649:        el->el_line.cursor -= n;
                    650:        if (el->el_line.cursor < el->el_line.buffer)
                    651:                el->el_line.cursor = el->el_line.buffer;
1.1       cgd       652: }
                    653:
1.38      christos  654: /* el_cursor():
                    655:  *     Move the cursor to the left or the right of the current position
                    656:  */
                    657: public int
                    658: el_cursor(EditLine *el, int n)
                    659: {
                    660:        if (n == 0)
                    661:                goto out;
                    662:
                    663:        el->el_line.cursor += n;
                    664:
                    665:        if (el->el_line.cursor < el->el_line.buffer)
                    666:                el->el_line.cursor = el->el_line.buffer;
                    667:        if (el->el_line.cursor > el->el_line.lastchar)
                    668:                el->el_line.cursor = el->el_line.lastchar;
                    669: out:
1.39      christos  670:        return (int)(el->el_line.cursor - el->el_line.buffer);
1.38      christos  671: }
                    672:
1.1       cgd       673: /* c_gets():
                    674:  *     Get a string
                    675:  */
                    676: protected int
1.52    ! christos  677: c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
1.9       lukem     678: {
1.27      christos  679:        ssize_t len;
1.52    ! christos  680:        wchar_t *cp = el->el_line.buffer, ch;
1.18      christos  681:
                    682:        if (prompt) {
1.51      christos  683:                len = (ssize_t)wcslen(prompt);
1.35      christos  684:                (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
1.18      christos  685:                cp += len;
                    686:        }
                    687:        len = 0;
                    688:
                    689:        for (;;) {
                    690:                el->el_line.cursor = cp;
                    691:                *cp = ' ';
                    692:                el->el_line.lastchar = cp + 1;
                    693:                re_refresh(el);
                    694:
1.52    ! christos  695:                if (el_wgetc(el, &ch) != 1) {
1.18      christos  696:                        ed_end_of_file(el, 0);
                    697:                        len = -1;
                    698:                        break;
                    699:                }
1.1       cgd       700:
1.9       lukem     701:                switch (ch) {
1.18      christos  702:
1.48      christos  703:                case L'\b':     /* Delete and backspace */
1.9       lukem     704:                case 0177:
1.27      christos  705:                        if (len == 0) {
1.18      christos  706:                                len = -1;
                    707:                                break;
1.9       lukem     708:                        }
1.49      christos  709:                        len--;
1.18      christos  710:                        cp--;
                    711:                        continue;
1.9       lukem     712:
                    713:                case 0033:      /* ESC */
1.48      christos  714:                case L'\r':     /* Newline */
                    715:                case L'\n':
1.18      christos  716:                        buf[len] = ch;
1.9       lukem     717:                        break;
                    718:
                    719:                default:
1.34      christos  720:                        if (len >= (ssize_t)(EL_BUFSIZ - 16))
1.30      christos  721:                                terminal_beep(el);
1.9       lukem     722:                        else {
                    723:                                buf[len++] = ch;
1.18      christos  724:                                *cp++ = ch;
1.9       lukem     725:                        }
1.18      christos  726:                        continue;
1.9       lukem     727:                }
1.18      christos  728:                break;
1.9       lukem     729:        }
1.18      christos  730:
                    731:        el->el_line.buffer[0] = '\0';
                    732:        el->el_line.lastchar = el->el_line.buffer;
                    733:        el->el_line.cursor = el->el_line.buffer;
1.27      christos  734:        return (int)len;
1.1       cgd       735: }
                    736:
                    737:
                    738: /* c_hpos():
                    739:  *     Return the current horizontal position of the cursor
                    740:  */
                    741: protected int
1.9       lukem     742: c_hpos(EditLine *el)
1.1       cgd       743: {
1.52    ! christos  744:        wchar_t *ptr;
1.1       cgd       745:
1.9       lukem     746:        /*
                    747:         * Find how many characters till the beginning of this line.
                    748:         */
                    749:        if (el->el_line.cursor == el->el_line.buffer)
1.32      christos  750:                return 0;
1.9       lukem     751:        else {
                    752:                for (ptr = el->el_line.cursor - 1;
                    753:                     ptr >= el->el_line.buffer && *ptr != '\n';
                    754:                     ptr--)
                    755:                        continue;
1.27      christos  756:                return (int)(el->el_line.cursor - ptr - 1);
1.9       lukem     757:        }
1.1       cgd       758: }
1.29      christos  759:
                    760: protected int
                    761: ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
                    762: {
                    763:        el->el_chared.c_resizefun = f;
                    764:        el->el_chared.c_resizearg = a;
                    765:        return 0;
                    766: }
1.40      christos  767:
                    768: protected int
                    769: ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
                    770: {
                    771:        el->el_chared.c_aliasfun = f;
                    772:        el->el_chared.c_aliasarg = a;
                    773:        return 0;
                    774: }

CVSweb <webmaster@jp.NetBSD.org>