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

Annotation of src/lib/libedit/common.c, Revision 1.41

1.41    ! christos    1: /*     $NetBSD: common.c,v 1.40 2016/03/02 19:24:20 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.16      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.11      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[] = "@(#)common.c   8.1 (Berkeley) 6/4/93";
1.2       lukem      39: #else
1.41    ! christos   40: __RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
1.2       lukem      41: #endif
1.1       cgd        42: #endif /* not lint && not SCCSID */
                     43:
                     44: /*
                     45:  * common.c: Common Editor functions
                     46:  */
1.37      christos   47: #include <ctype.h>
                     48: #include <string.h>
                     49:
1.1       cgd        50: #include "el.h"
1.35      christos   51: #include "common.h"
                     52: #include "parse.h"
                     53: #include "vi.h"
1.1       cgd        54:
1.8       simonb     55: /* ed_end_of_file():
1.1       cgd        56:  *     Indicate end of file
                     57:  *     [^D]
                     58:  */
                     59: protected el_action_t
                     60: /*ARGSUSED*/
1.31      christos   61: ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem      62: {
                     63:
                     64:        re_goto_bottom(el);
                     65:        *el->el_line.lastchar = '\0';
1.26      christos   66:        return CC_EOF;
1.1       cgd        67: }
                     68:
                     69:
1.8       simonb     70: /* ed_insert():
1.1       cgd        71:  *     Add character to the line
                     72:  *     Insert a character [bound to all insert keys]
                     73:  */
                     74: protected el_action_t
1.31      christos   75: ed_insert(EditLine *el, wint_t c)
1.9       lukem      76: {
1.13      christos   77:        int count = el->el_state.argument;
1.1       cgd        78:
1.9       lukem      79:        if (c == '\0')
1.26      christos   80:                return CC_ERROR;
1.1       cgd        81:
1.9       lukem      82:        if (el->el_line.lastchar + el->el_state.argument >=
1.10      jdolecek   83:            el->el_line.limit) {
                     84:                /* end of buffer space, try to allocate more */
1.13      christos   85:                if (!ch_enlargebufs(el, (size_t) count))
1.10      jdolecek   86:                        return CC_ERROR;        /* error allocating more */
                     87:        }
1.9       lukem      88:
1.13      christos   89:        if (count == 1) {
1.12      christos   90:                if (el->el_state.inputmode == MODE_INSERT
                     91:                    || el->el_line.cursor >= el->el_line.lastchar)
                     92:                        c_insert(el, 1);
1.9       lukem      93:
1.30      christos   94:                *el->el_line.cursor++ = (Char)c;
1.9       lukem      95:                re_fastaddc(el);                /* fast refresh for one char. */
                     96:        } else {
1.12      christos   97:                if (el->el_state.inputmode != MODE_REPLACE_1)
                     98:                        c_insert(el, el->el_state.argument);
1.9       lukem      99:
1.13      christos  100:                while (count-- && el->el_line.cursor < el->el_line.lastchar)
1.30      christos  101:                        *el->el_line.cursor++ = (Char)c;
1.9       lukem     102:                re_refresh(el);
                    103:        }
1.1       cgd       104:
1.9       lukem     105:        if (el->el_state.inputmode == MODE_REPLACE_1)
1.12      christos  106:                return vi_command_mode(el, 0);
1.1       cgd       107:
1.26      christos  108:        return CC_NORM;
1.1       cgd       109: }
                    110:
                    111:
1.8       simonb    112: /* ed_delete_prev_word():
1.1       cgd       113:  *     Delete from beginning of current word to cursor
                    114:  *     [M-^?] [^W]
                    115:  */
                    116: protected el_action_t
                    117: /*ARGSUSED*/
1.31      christos  118: ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     119: {
1.24      christos  120:        Char *cp, *p, *kp;
1.9       lukem     121:
                    122:        if (el->el_line.cursor == el->el_line.buffer)
1.26      christos  123:                return CC_ERROR;
1.9       lukem     124:
                    125:        cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
                    126:            el->el_state.argument, ce__isword);
                    127:
                    128:        for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
                    129:                *kp++ = *p;
                    130:        el->el_chared.c_kill.last = kp;
                    131:
1.22      christos  132:        c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
1.9       lukem     133:        el->el_line.cursor = cp;
                    134:        if (el->el_line.cursor < el->el_line.buffer)
                    135:                el->el_line.cursor = el->el_line.buffer; /* bounds check */
1.26      christos  136:        return CC_REFRESH;
1.1       cgd       137: }
                    138:
                    139:
1.8       simonb    140: /* ed_delete_next_char():
1.1       cgd       141:  *     Delete character under cursor
                    142:  *     [^D] [x]
                    143:  */
                    144: protected el_action_t
                    145: /*ARGSUSED*/
1.31      christos  146: ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       147: {
1.27      christos  148: #ifdef DEBUG_EDIT
1.9       lukem     149: #define        EL      el->el_line
1.40      christos  150:        (void) fprintf(el->el_errfile,
1.41    ! christos  151:            "\nD(b: %p(%ls)  c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
1.6       christos  152:            EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
                    153:            EL.lastchar, EL.limit, EL.limit);
1.1       cgd       154: #endif
1.9       lukem     155:        if (el->el_line.cursor == el->el_line.lastchar) {
                    156:                        /* if I'm at the end */
                    157:                if (el->el_map.type == MAP_VI) {
                    158:                        if (el->el_line.cursor == el->el_line.buffer) {
                    159:                                /* if I'm also at the beginning */
1.1       cgd       160: #ifdef KSHVI
1.26      christos  161:                                return CC_ERROR;
1.1       cgd       162: #else
1.19      christos  163:                                /* then do an EOF */
1.25      christos  164:                                terminal_writec(el, c);
1.26      christos  165:                                return CC_EOF;
1.1       cgd       166: #endif
1.9       lukem     167:                        } else {
1.1       cgd       168: #ifdef KSHVI
1.9       lukem     169:                                el->el_line.cursor--;
1.1       cgd       170: #else
1.26      christos  171:                                return CC_ERROR;
1.1       cgd       172: #endif
1.9       lukem     173:                        }
1.29      christos  174:                } else
1.26      christos  175:                                return CC_ERROR;
1.1       cgd       176:        }
1.9       lukem     177:        c_delafter(el, el->el_state.argument);  /* delete after dot */
1.29      christos  178:        if (el->el_map.type == MAP_VI &&
                    179:            el->el_line.cursor >= el->el_line.lastchar &&
1.9       lukem     180:            el->el_line.cursor > el->el_line.buffer)
                    181:                        /* bounds check */
                    182:                el->el_line.cursor = el->el_line.lastchar - 1;
1.26      christos  183:        return CC_REFRESH;
1.1       cgd       184: }
                    185:
                    186:
1.8       simonb    187: /* ed_kill_line():
1.1       cgd       188:  *     Cut to the end of line
                    189:  *     [^K] [^K]
                    190:  */
                    191: protected el_action_t
                    192: /*ARGSUSED*/
1.31      christos  193: ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     194: {
1.24      christos  195:        Char *kp, *cp;
1.9       lukem     196:
                    197:        cp = el->el_line.cursor;
                    198:        kp = el->el_chared.c_kill.buf;
                    199:        while (cp < el->el_line.lastchar)
                    200:                *kp++ = *cp++;  /* copy it */
                    201:        el->el_chared.c_kill.last = kp;
                    202:                        /* zap! -- delete to end */
                    203:        el->el_line.lastchar = el->el_line.cursor;
1.26      christos  204:        return CC_REFRESH;
1.1       cgd       205: }
                    206:
                    207:
1.8       simonb    208: /* ed_move_to_end():
1.1       cgd       209:  *     Move cursor to the end of line
                    210:  *     [^E] [^E]
                    211:  */
                    212: protected el_action_t
                    213: /*ARGSUSED*/
1.31      christos  214: ed_move_to_end(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       215: {
1.9       lukem     216:
                    217:        el->el_line.cursor = el->el_line.lastchar;
                    218:        if (el->el_map.type == MAP_VI) {
1.13      christos  219:                if (el->el_chared.c_vcmd.action != NOP) {
1.9       lukem     220:                        cv_delfini(el);
1.26      christos  221:                        return CC_REFRESH;
1.9       lukem     222:                }
1.21      aymeric   223: #ifdef VI_MOVE
                    224:                el->el_line.cursor--;
                    225: #endif
1.1       cgd       226:        }
1.26      christos  227:        return CC_CURSOR;
1.1       cgd       228: }
                    229:
                    230:
1.8       simonb    231: /* ed_move_to_beg():
1.1       cgd       232:  *     Move cursor to the beginning of line
                    233:  *     [^A] [^A]
                    234:  */
                    235: protected el_action_t
                    236: /*ARGSUSED*/
1.31      christos  237: ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     238: {
                    239:
                    240:        el->el_line.cursor = el->el_line.buffer;
                    241:
                    242:        if (el->el_map.type == MAP_VI) {
                    243:                        /* We want FIRST non space character */
1.41    ! christos  244:                while (iswspace(*el->el_line.cursor))
1.9       lukem     245:                        el->el_line.cursor++;
1.13      christos  246:                if (el->el_chared.c_vcmd.action != NOP) {
1.9       lukem     247:                        cv_delfini(el);
1.26      christos  248:                        return CC_REFRESH;
1.9       lukem     249:                }
1.1       cgd       250:        }
1.26      christos  251:        return CC_CURSOR;
1.1       cgd       252: }
                    253:
                    254:
1.8       simonb    255: /* ed_transpose_chars():
1.1       cgd       256:  *     Exchange the character to the left of the cursor with the one under it
                    257:  *     [^T] [^T]
                    258:  */
                    259: protected el_action_t
1.31      christos  260: ed_transpose_chars(EditLine *el, wint_t c)
1.9       lukem     261: {
                    262:
                    263:        if (el->el_line.cursor < el->el_line.lastchar) {
                    264:                if (el->el_line.lastchar <= &el->el_line.buffer[1])
1.26      christos  265:                        return CC_ERROR;
1.9       lukem     266:                else
                    267:                        el->el_line.cursor++;
                    268:        }
                    269:        if (el->el_line.cursor > &el->el_line.buffer[1]) {
                    270:                /* must have at least two chars entered */
                    271:                c = el->el_line.cursor[-2];
                    272:                el->el_line.cursor[-2] = el->el_line.cursor[-1];
1.30      christos  273:                el->el_line.cursor[-1] = (Char)c;
1.26      christos  274:                return CC_REFRESH;
1.9       lukem     275:        } else
1.26      christos  276:                return CC_ERROR;
1.1       cgd       277: }
                    278:
                    279:
1.8       simonb    280: /* ed_next_char():
1.1       cgd       281:  *     Move to the right one character
                    282:  *     [^F] [^F]
                    283:  */
                    284: protected el_action_t
                    285: /*ARGSUSED*/
1.31      christos  286: ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       287: {
1.24      christos  288:        Char *lim = el->el_line.lastchar;
1.1       cgd       289:
1.13      christos  290:        if (el->el_line.cursor >= lim ||
                    291:            (el->el_line.cursor == lim - 1 &&
                    292:            el->el_map.type == MAP_VI &&
                    293:            el->el_chared.c_vcmd.action == NOP))
1.26      christos  294:                return CC_ERROR;
1.1       cgd       295:
1.9       lukem     296:        el->el_line.cursor += el->el_state.argument;
1.13      christos  297:        if (el->el_line.cursor > lim)
                    298:                el->el_line.cursor = lim;
1.1       cgd       299:
1.9       lukem     300:        if (el->el_map.type == MAP_VI)
1.13      christos  301:                if (el->el_chared.c_vcmd.action != NOP) {
1.9       lukem     302:                        cv_delfini(el);
1.26      christos  303:                        return CC_REFRESH;
1.9       lukem     304:                }
1.26      christos  305:        return CC_CURSOR;
1.1       cgd       306: }
                    307:
                    308:
1.8       simonb    309: /* ed_prev_word():
1.1       cgd       310:  *     Move to the beginning of the current word
                    311:  *     [M-b] [b]
                    312:  */
                    313: protected el_action_t
                    314: /*ARGSUSED*/
1.31      christos  315: ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       316: {
                    317:
1.9       lukem     318:        if (el->el_line.cursor == el->el_line.buffer)
1.26      christos  319:                return CC_ERROR;
1.1       cgd       320:
1.9       lukem     321:        el->el_line.cursor = c__prev_word(el->el_line.cursor,
                    322:            el->el_line.buffer,
                    323:            el->el_state.argument,
                    324:            ce__isword);
1.1       cgd       325:
1.9       lukem     326:        if (el->el_map.type == MAP_VI)
1.13      christos  327:                if (el->el_chared.c_vcmd.action != NOP) {
1.9       lukem     328:                        cv_delfini(el);
1.26      christos  329:                        return CC_REFRESH;
1.9       lukem     330:                }
1.26      christos  331:        return CC_CURSOR;
1.1       cgd       332: }
                    333:
                    334:
1.8       simonb    335: /* ed_prev_char():
1.1       cgd       336:  *     Move to the left one character
                    337:  *     [^B] [^B]
                    338:  */
                    339: protected el_action_t
                    340: /*ARGSUSED*/
1.31      christos  341: ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       342: {
                    343:
1.9       lukem     344:        if (el->el_line.cursor > el->el_line.buffer) {
                    345:                el->el_line.cursor -= el->el_state.argument;
                    346:                if (el->el_line.cursor < el->el_line.buffer)
                    347:                        el->el_line.cursor = el->el_line.buffer;
                    348:
                    349:                if (el->el_map.type == MAP_VI)
1.13      christos  350:                        if (el->el_chared.c_vcmd.action != NOP) {
1.9       lukem     351:                                cv_delfini(el);
1.26      christos  352:                                return CC_REFRESH;
1.9       lukem     353:                        }
1.26      christos  354:                return CC_CURSOR;
1.9       lukem     355:        } else
1.26      christos  356:                return CC_ERROR;
1.1       cgd       357: }
                    358:
                    359:
1.8       simonb    360: /* ed_quoted_insert():
1.1       cgd       361:  *     Add the next character typed verbatim
                    362:  *     [^V] [^V]
                    363:  */
                    364: protected el_action_t
1.31      christos  365: ed_quoted_insert(EditLine *el, wint_t c)
1.9       lukem     366: {
                    367:        int num;
                    368:
                    369:        tty_quotemode(el);
1.39      christos  370:        num = el_wgetc(el, &c);
1.9       lukem     371:        tty_noquotemode(el);
                    372:        if (num == 1)
1.26      christos  373:                return ed_insert(el, c);
1.9       lukem     374:        else
1.26      christos  375:                return ed_end_of_file(el, 0);
1.1       cgd       376: }
                    377:
                    378:
1.8       simonb    379: /* ed_digit():
1.1       cgd       380:  *     Adds to argument or enters a digit
                    381:  */
                    382: protected el_action_t
1.31      christos  383: ed_digit(EditLine *el, wint_t c)
1.9       lukem     384: {
                    385:
1.41    ! christos  386:        if (!iswdigit(c))
1.26      christos  387:                return CC_ERROR;
1.9       lukem     388:
                    389:        if (el->el_state.doingarg) {
                    390:                        /* if doing an arg, add this in... */
                    391:                if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
                    392:                        el->el_state.argument = c - '0';
                    393:                else {
                    394:                        if (el->el_state.argument > 1000000)
1.26      christos  395:                                return CC_ERROR;
1.9       lukem     396:                        el->el_state.argument =
                    397:                            (el->el_state.argument * 10) + (c - '0');
                    398:                }
1.26      christos  399:                return CC_ARGHACK;
1.12      christos  400:        }
1.9       lukem     401:
1.12      christos  402:        return ed_insert(el, c);
1.1       cgd       403: }
                    404:
                    405:
1.8       simonb    406: /* ed_argument_digit():
1.1       cgd       407:  *     Digit that starts argument
                    408:  *     For ESC-n
                    409:  */
                    410: protected el_action_t
1.31      christos  411: ed_argument_digit(EditLine *el, wint_t c)
1.9       lukem     412: {
                    413:
1.41    ! christos  414:        if (!iswdigit(c))
1.26      christos  415:                return CC_ERROR;
1.9       lukem     416:
                    417:        if (el->el_state.doingarg) {
                    418:                if (el->el_state.argument > 1000000)
1.26      christos  419:                        return CC_ERROR;
1.9       lukem     420:                el->el_state.argument = (el->el_state.argument * 10) +
                    421:                    (c - '0');
                    422:        } else {                /* else starting an argument */
                    423:                el->el_state.argument = c - '0';
                    424:                el->el_state.doingarg = 1;
                    425:        }
1.26      christos  426:        return CC_ARGHACK;
1.1       cgd       427: }
                    428:
                    429:
1.8       simonb    430: /* ed_unassigned():
1.1       cgd       431:  *     Indicates unbound character
                    432:  *     Bound to keys that are not assigned
                    433:  */
                    434: protected el_action_t
                    435: /*ARGSUSED*/
1.28      christos  436: ed_unassigned(EditLine *el __attribute__((__unused__)),
1.31      christos  437:     wint_t c __attribute__((__unused__)))
1.9       lukem     438: {
                    439:
1.26      christos  440:        return CC_ERROR;
1.1       cgd       441: }
                    442:
                    443:
                    444: /**
                    445:  ** TTY key handling.
                    446:  **/
                    447:
1.8       simonb    448: /* ed_tty_sigint():
1.1       cgd       449:  *     Tty interrupt character
                    450:  *     [^C]
                    451:  */
                    452: protected el_action_t
                    453: /*ARGSUSED*/
1.38      christos  454: ed_tty_sigint(EditLine *el __attribute__((__unused__)),
1.31      christos  455:              wint_t c __attribute__((__unused__)))
1.8       simonb    456: {
1.9       lukem     457:
1.26      christos  458:        return CC_NORM;
1.1       cgd       459: }
                    460:
                    461:
1.8       simonb    462: /* ed_tty_dsusp():
1.1       cgd       463:  *     Tty delayed suspend character
                    464:  *     [^Y]
                    465:  */
                    466: protected el_action_t
                    467: /*ARGSUSED*/
1.38      christos  468: ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
1.31      christos  469:             wint_t c __attribute__((__unused__)))
1.1       cgd       470: {
1.9       lukem     471:
1.26      christos  472:        return CC_NORM;
1.1       cgd       473: }
                    474:
                    475:
1.8       simonb    476: /* ed_tty_flush_output():
1.1       cgd       477:  *     Tty flush output characters
                    478:  *     [^O]
                    479:  */
                    480: protected el_action_t
                    481: /*ARGSUSED*/
1.38      christos  482: ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
1.31      christos  483:                    wint_t c __attribute__((__unused__)))
1.1       cgd       484: {
1.9       lukem     485:
1.26      christos  486:        return CC_NORM;
1.1       cgd       487: }
                    488:
                    489:
1.8       simonb    490: /* ed_tty_sigquit():
1.1       cgd       491:  *     Tty quit character
                    492:  *     [^\]
                    493:  */
                    494: protected el_action_t
                    495: /*ARGSUSED*/
1.38      christos  496: ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
1.31      christos  497:               wint_t c __attribute__((__unused__)))
1.1       cgd       498: {
1.9       lukem     499:
1.26      christos  500:        return CC_NORM;
1.1       cgd       501: }
                    502:
                    503:
1.8       simonb    504: /* ed_tty_sigtstp():
1.1       cgd       505:  *     Tty suspend character
                    506:  *     [^Z]
                    507:  */
                    508: protected el_action_t
                    509: /*ARGSUSED*/
1.38      christos  510: ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
1.31      christos  511:               wint_t c __attribute__((__unused__)))
1.1       cgd       512: {
1.9       lukem     513:
1.26      christos  514:        return CC_NORM;
1.1       cgd       515: }
                    516:
                    517:
1.8       simonb    518: /* ed_tty_stop_output():
1.1       cgd       519:  *     Tty disallow output characters
                    520:  *     [^S]
                    521:  */
                    522: protected el_action_t
                    523: /*ARGSUSED*/
1.38      christos  524: ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
1.31      christos  525:                   wint_t c __attribute__((__unused__)))
1.1       cgd       526: {
1.9       lukem     527:
1.26      christos  528:        return CC_NORM;
1.1       cgd       529: }
                    530:
                    531:
1.8       simonb    532: /* ed_tty_start_output():
1.1       cgd       533:  *     Tty allow output characters
                    534:  *     [^Q]
                    535:  */
                    536: protected el_action_t
                    537: /*ARGSUSED*/
1.38      christos  538: ed_tty_start_output(EditLine *el __attribute__((__unused__)),
1.31      christos  539:                    wint_t c __attribute__((__unused__)))
1.1       cgd       540: {
1.9       lukem     541:
1.26      christos  542:        return CC_NORM;
1.1       cgd       543: }
                    544:
                    545:
1.8       simonb    546: /* ed_newline():
1.1       cgd       547:  *     Execute command
                    548:  *     [^J]
                    549:  */
                    550: protected el_action_t
                    551: /*ARGSUSED*/
1.31      christos  552: ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     553: {
                    554:
                    555:        re_goto_bottom(el);
                    556:        *el->el_line.lastchar++ = '\n';
                    557:        *el->el_line.lastchar = '\0';
1.26      christos  558:        return CC_NEWLINE;
1.1       cgd       559: }
                    560:
                    561:
1.8       simonb    562: /* ed_delete_prev_char():
1.1       cgd       563:  *     Delete the character to the left of the cursor
                    564:  *     [^?]
                    565:  */
                    566: protected el_action_t
                    567: /*ARGSUSED*/
1.31      christos  568: ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     569: {
                    570:
                    571:        if (el->el_line.cursor <= el->el_line.buffer)
1.26      christos  572:                return CC_ERROR;
1.9       lukem     573:
                    574:        c_delbefore(el, el->el_state.argument);
                    575:        el->el_line.cursor -= el->el_state.argument;
                    576:        if (el->el_line.cursor < el->el_line.buffer)
                    577:                el->el_line.cursor = el->el_line.buffer;
1.26      christos  578:        return CC_REFRESH;
1.1       cgd       579: }
                    580:
                    581:
1.8       simonb    582: /* ed_clear_screen():
1.1       cgd       583:  *     Clear screen leaving current line at the top
                    584:  *     [^L]
                    585:  */
                    586: protected el_action_t
                    587: /*ARGSUSED*/
1.31      christos  588: ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     589: {
                    590:
1.25      christos  591:        terminal_clear_screen(el);      /* clear the whole real screen */
1.9       lukem     592:        re_clear_display(el);   /* reset everything */
1.26      christos  593:        return CC_REFRESH;
1.1       cgd       594: }
                    595:
                    596:
1.8       simonb    597: /* ed_redisplay():
1.1       cgd       598:  *     Redisplay everything
                    599:  *     ^R
                    600:  */
                    601: protected el_action_t
                    602: /*ARGSUSED*/
1.38      christos  603: ed_redisplay(EditLine *el __attribute__((__unused__)),
1.31      christos  604:             wint_t c __attribute__((__unused__)))
1.1       cgd       605: {
1.9       lukem     606:
1.26      christos  607:        return CC_REDISPLAY;
1.1       cgd       608: }
                    609:
                    610:
1.8       simonb    611: /* ed_start_over():
1.1       cgd       612:  *     Erase current line and start from scratch
                    613:  *     [^G]
                    614:  */
                    615: protected el_action_t
                    616: /*ARGSUSED*/
1.31      christos  617: ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       618: {
1.9       lukem     619:
1.17      christos  620:        ch_reset(el, 0);
1.26      christos  621:        return CC_REFRESH;
1.1       cgd       622: }
                    623:
                    624:
1.8       simonb    625: /* ed_sequence_lead_in():
1.1       cgd       626:  *     First character in a bound sequence
                    627:  *     Placeholder for external keys
                    628:  */
                    629: protected el_action_t
                    630: /*ARGSUSED*/
1.38      christos  631: ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
1.31      christos  632:                    wint_t c __attribute__((__unused__)))
1.1       cgd       633: {
1.9       lukem     634:
1.26      christos  635:        return CC_NORM;
1.1       cgd       636: }
                    637:
                    638:
1.8       simonb    639: /* ed_prev_history():
1.1       cgd       640:  *     Move to the previous history line
                    641:  *     [^P] [k]
                    642:  */
                    643: protected el_action_t
                    644: /*ARGSUSED*/
1.31      christos  645: ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     646: {
                    647:        char beep = 0;
1.13      christos  648:        int sv_event = el->el_history.eventno;
1.9       lukem     649:
1.12      christos  650:        el->el_chared.c_undo.len = -1;
1.9       lukem     651:        *el->el_line.lastchar = '\0';           /* just in case */
                    652:
                    653:        if (el->el_history.eventno == 0) {      /* save the current buffer
                    654:                                                 * away */
1.24      christos  655:                (void) Strncpy(el->el_history.buf, el->el_line.buffer,
1.9       lukem     656:                    EL_BUFSIZ);
                    657:                el->el_history.last = el->el_history.buf +
                    658:                    (el->el_line.lastchar - el->el_line.buffer);
                    659:        }
                    660:        el->el_history.eventno += el->el_state.argument;
                    661:
                    662:        if (hist_get(el) == CC_ERROR) {
1.13      christos  663:                if (el->el_map.type == MAP_VI) {
                    664:                        el->el_history.eventno = sv_event;
                    665:                }
1.9       lukem     666:                beep = 1;
                    667:                /* el->el_history.eventno was fixed by first call */
                    668:                (void) hist_get(el);
                    669:        }
                    670:        if (beep)
1.13      christos  671:                return CC_REFRESH_BEEP;
                    672:        return CC_REFRESH;
1.1       cgd       673: }
                    674:
                    675:
1.8       simonb    676: /* ed_next_history():
1.1       cgd       677:  *     Move to the next history line
                    678:  *     [^N] [j]
                    679:  */
                    680: protected el_action_t
                    681: /*ARGSUSED*/
1.31      christos  682: ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       683: {
1.13      christos  684:        el_action_t beep = CC_REFRESH, rval;
1.1       cgd       685:
1.12      christos  686:        el->el_chared.c_undo.len = -1;
1.9       lukem     687:        *el->el_line.lastchar = '\0';   /* just in case */
1.1       cgd       688:
1.9       lukem     689:        el->el_history.eventno -= el->el_state.argument;
1.1       cgd       690:
1.9       lukem     691:        if (el->el_history.eventno < 0) {
                    692:                el->el_history.eventno = 0;
1.13      christos  693:                beep = CC_REFRESH_BEEP;
1.9       lukem     694:        }
1.13      christos  695:        rval = hist_get(el);
                    696:        if (rval == CC_REFRESH)
                    697:                return beep;
                    698:        return rval;
                    699:
1.1       cgd       700: }
                    701:
                    702:
1.8       simonb    703: /* ed_search_prev_history():
1.1       cgd       704:  *     Search previous in history for a line matching the current
                    705:  *     next search history [M-P] [K]
                    706:  */
                    707: protected el_action_t
                    708: /*ARGSUSED*/
1.31      christos  709: ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     710: {
1.24      christos  711:        const Char *hp;
1.9       lukem     712:        int h;
1.36      christos  713:        int found = 0;
1.9       lukem     714:
                    715:        el->el_chared.c_vcmd.action = NOP;
1.12      christos  716:        el->el_chared.c_undo.len = -1;
1.9       lukem     717:        *el->el_line.lastchar = '\0';   /* just in case */
                    718:        if (el->el_history.eventno < 0) {
1.1       cgd       719: #ifdef DEBUG_EDIT
1.9       lukem     720:                (void) fprintf(el->el_errfile,
                    721:                    "e_prev_search_hist(): eventno < 0;\n");
1.1       cgd       722: #endif
1.9       lukem     723:                el->el_history.eventno = 0;
1.26      christos  724:                return CC_ERROR;
1.9       lukem     725:        }
                    726:        if (el->el_history.eventno == 0) {
1.24      christos  727:                (void) Strncpy(el->el_history.buf, el->el_line.buffer,
1.9       lukem     728:                    EL_BUFSIZ);
                    729:                el->el_history.last = el->el_history.buf +
                    730:                    (el->el_line.lastchar - el->el_line.buffer);
                    731:        }
                    732:        if (el->el_history.ref == NULL)
1.26      christos  733:                return CC_ERROR;
1.1       cgd       734:
1.9       lukem     735:        hp = HIST_FIRST(el);
                    736:        if (hp == NULL)
1.26      christos  737:                return CC_ERROR;
1.1       cgd       738:
1.9       lukem     739:        c_setpat(el);           /* Set search pattern !! */
1.1       cgd       740:
1.9       lukem     741:        for (h = 1; h <= el->el_history.eventno; h++)
                    742:                hp = HIST_NEXT(el);
1.1       cgd       743:
1.9       lukem     744:        while (hp != NULL) {
1.1       cgd       745: #ifdef SDEBUG
1.9       lukem     746:                (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
1.1       cgd       747: #endif
1.24      christos  748:                if ((Strncmp(hp, el->el_line.buffer, (size_t)
1.9       lukem     749:                            (el->el_line.lastchar - el->el_line.buffer)) ||
                    750:                        hp[el->el_line.lastchar - el->el_line.buffer]) &&
                    751:                    c_hmatch(el, hp)) {
1.36      christos  752:                        found = 1;
1.9       lukem     753:                        break;
                    754:                }
                    755:                h++;
                    756:                hp = HIST_NEXT(el);
                    757:        }
1.1       cgd       758:
1.9       lukem     759:        if (!found) {
1.1       cgd       760: #ifdef SDEBUG
1.9       lukem     761:                (void) fprintf(el->el_errfile, "not found\n");
1.1       cgd       762: #endif
1.26      christos  763:                return CC_ERROR;
1.9       lukem     764:        }
                    765:        el->el_history.eventno = h;
1.1       cgd       766:
1.26      christos  767:        return hist_get(el);
1.1       cgd       768: }
                    769:
                    770:
1.8       simonb    771: /* ed_search_next_history():
1.1       cgd       772:  *     Search next in history for a line matching the current
                    773:  *     [M-N] [J]
                    774:  */
                    775: protected el_action_t
                    776: /*ARGSUSED*/
1.31      christos  777: ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
1.1       cgd       778: {
1.24      christos  779:        const Char *hp;
1.9       lukem     780:        int h;
1.36      christos  781:        int found = 0;
1.1       cgd       782:
1.9       lukem     783:        el->el_chared.c_vcmd.action = NOP;
1.12      christos  784:        el->el_chared.c_undo.len = -1;
1.9       lukem     785:        *el->el_line.lastchar = '\0';   /* just in case */
1.1       cgd       786:
1.9       lukem     787:        if (el->el_history.eventno == 0)
1.26      christos  788:                return CC_ERROR;
1.1       cgd       789:
1.9       lukem     790:        if (el->el_history.ref == NULL)
1.26      christos  791:                return CC_ERROR;
1.1       cgd       792:
1.9       lukem     793:        hp = HIST_FIRST(el);
                    794:        if (hp == NULL)
1.26      christos  795:                return CC_ERROR;
1.1       cgd       796:
1.9       lukem     797:        c_setpat(el);           /* Set search pattern !! */
1.1       cgd       798:
1.9       lukem     799:        for (h = 1; h < el->el_history.eventno && hp; h++) {
1.1       cgd       800: #ifdef SDEBUG
1.9       lukem     801:                (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
1.1       cgd       802: #endif
1.24      christos  803:                if ((Strncmp(hp, el->el_line.buffer, (size_t)
1.9       lukem     804:                            (el->el_line.lastchar - el->el_line.buffer)) ||
                    805:                        hp[el->el_line.lastchar - el->el_line.buffer]) &&
                    806:                    c_hmatch(el, hp))
                    807:                        found = h;
                    808:                hp = HIST_NEXT(el);
                    809:        }
1.1       cgd       810:
1.9       lukem     811:        if (!found) {           /* is it the current history number? */
                    812:                if (!c_hmatch(el, el->el_history.buf)) {
1.1       cgd       813: #ifdef SDEBUG
1.9       lukem     814:                        (void) fprintf(el->el_errfile, "not found\n");
1.1       cgd       815: #endif
1.26      christos  816:                        return CC_ERROR;
1.9       lukem     817:                }
1.1       cgd       818:        }
1.9       lukem     819:        el->el_history.eventno = found;
1.1       cgd       820:
1.26      christos  821:        return hist_get(el);
1.1       cgd       822: }
                    823:
                    824:
                    825: /* ed_prev_line():
                    826:  *     Move up one line
                    827:  *     Could be [k] [^p]
                    828:  */
                    829: protected el_action_t
                    830: /*ARGSUSED*/
1.31      christos  831: ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     832: {
1.24      christos  833:        Char *ptr;
1.9       lukem     834:        int nchars = c_hpos(el);
1.8       simonb    835:
1.9       lukem     836:        /*
                    837:          * Move to the line requested
                    838:          */
                    839:        if (*(ptr = el->el_line.cursor) == '\n')
                    840:                ptr--;
                    841:
                    842:        for (; ptr >= el->el_line.buffer; ptr--)
                    843:                if (*ptr == '\n' && --el->el_state.argument <= 0)
                    844:                        break;
                    845:
                    846:        if (el->el_state.argument > 0)
1.26      christos  847:                return CC_ERROR;
1.9       lukem     848:
                    849:        /*
                    850:          * Move to the beginning of the line
                    851:          */
                    852:        for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
                    853:                continue;
                    854:
                    855:        /*
                    856:          * Move to the character requested
                    857:          */
                    858:        for (ptr++;
                    859:            nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
                    860:            ptr++)
                    861:                continue;
                    862:
                    863:        el->el_line.cursor = ptr;
1.26      christos  864:        return CC_CURSOR;
1.1       cgd       865: }
                    866:
                    867:
                    868: /* ed_next_line():
                    869:  *     Move down one line
                    870:  *     Could be [j] [^n]
                    871:  */
                    872: protected el_action_t
                    873: /*ARGSUSED*/
1.31      christos  874: ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     875: {
1.24      christos  876:        Char *ptr;
1.9       lukem     877:        int nchars = c_hpos(el);
1.8       simonb    878:
1.9       lukem     879:        /*
                    880:          * Move to the line requested
                    881:          */
                    882:        for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
                    883:                if (*ptr == '\n' && --el->el_state.argument <= 0)
                    884:                        break;
                    885:
                    886:        if (el->el_state.argument > 0)
1.26      christos  887:                return CC_ERROR;
1.9       lukem     888:
                    889:        /*
                    890:          * Move to the character requested
                    891:          */
                    892:        for (ptr++;
                    893:            nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
                    894:            ptr++)
                    895:                continue;
                    896:
                    897:        el->el_line.cursor = ptr;
1.26      christos  898:        return CC_CURSOR;
1.1       cgd       899: }
                    900:
                    901:
1.8       simonb    902: /* ed_command():
1.1       cgd       903:  *     Editline extended command
                    904:  *     [M-X] [:]
                    905:  */
                    906: protected el_action_t
                    907: /*ARGSUSED*/
1.31      christos  908: ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
1.9       lukem     909: {
1.24      christos  910:        Char tmpbuf[EL_BUFSIZ];
1.9       lukem     911:        int tmplen;
                    912:
1.24      christos  913:        tmplen = c_gets(el, tmpbuf, STR("\n: "));
1.25      christos  914:        terminal__putc(el, '\n');
1.9       lukem     915:
1.14      christos  916:        if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
1.25      christos  917:                terminal_beep(el);
1.9       lukem     918:
1.14      christos  919:        el->el_map.current = el->el_map.key;
                    920:        re_clear_display(el);
                    921:        return CC_REFRESH;
1.1       cgd       922: }

CVSweb <webmaster@jp.NetBSD.org>