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

Annotation of src/lib/libedit/vi.c, Revision 1.38

1.38    ! christos    1: /*     $NetBSD: vi.c,v 1.37 2011/07/29 15:16:33 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.9       christos   35: #include "config.h"
1.12      christos   36: #include <stdlib.h>
                     37: #include <unistd.h>
1.31      christos   38: #include <limits.h>
1.12      christos   39: #include <sys/wait.h>
                     40:
1.1       cgd        41: #if !defined(lint) && !defined(SCCSID)
1.2       lukem      42: #if 0
1.1       cgd        43: static char sccsid[] = "@(#)vi.c       8.1 (Berkeley) 6/4/93";
1.2       lukem      44: #else
1.38    ! christos   45: __RCSID("$NetBSD: vi.c,v 1.37 2011/07/29 15:16:33 christos Exp $");
1.2       lukem      46: #endif
1.1       cgd        47: #endif /* not lint && not SCCSID */
                     48:
                     49: /*
                     50:  * vi.c: Vi mode commands.
                     51:  */
                     52: #include "el.h"
                     53:
1.31      christos   54: private el_action_t    cv_action(EditLine *, Int);
                     55: private el_action_t    cv_paste(EditLine *, Int);
1.1       cgd        56:
                     57: /* cv_action():
                     58:  *     Handle vi actions.
                     59:  */
                     60: private el_action_t
1.31      christos   61: cv_action(EditLine *el, Int c)
1.1       cgd        62: {
                     63:
1.12      christos   64:        if (el->el_chared.c_vcmd.action != NOP) {
                     65:                /* 'cc', 'dd' and (possibly) friends */
                     66:                if (c != el->el_chared.c_vcmd.action)
                     67:                        return CC_ERROR;
                     68:
                     69:                if (!(c & YANK))
                     70:                        cv_undo(el);
                     71:                cv_yank(el, el->el_line.buffer,
1.29      christos   72:                    (int)(el->el_line.lastchar - el->el_line.buffer));
1.8       lukem      73:                el->el_chared.c_vcmd.action = NOP;
                     74:                el->el_chared.c_vcmd.pos = 0;
1.23      christos   75:                if (!(c & YANK)) {
                     76:                        el->el_line.lastchar = el->el_line.buffer;
                     77:                        el->el_line.cursor = el->el_line.buffer;
                     78:                }
1.8       lukem      79:                if (c & INSERT)
                     80:                        el->el_map.current = el->el_map.key;
1.7       simonb     81:
1.37      christos   82:                return CC_REFRESH;
1.1       cgd        83:        }
1.8       lukem      84:        el->el_chared.c_vcmd.pos = el->el_line.cursor;
                     85:        el->el_chared.c_vcmd.action = c;
1.37      christos   86:        return CC_ARGHACK;
1.1       cgd        87: }
                     88:
                     89: /* cv_paste():
                     90:  *     Paste previous deletion before or after the cursor
                     91:  */
1.3       christos   92: private el_action_t
1.31      christos   93: cv_paste(EditLine *el, Int c)
1.1       cgd        94: {
1.12      christos   95:        c_kill_t *k = &el->el_chared.c_kill;
1.30      christos   96:        size_t len = (size_t)(k->last - k->buf);
1.8       lukem      97:
1.12      christos   98:        if (k->buf == NULL || len == 0)
1.37      christos   99:                return CC_ERROR;
1.1       cgd       100: #ifdef DEBUG_PASTE
1.30      christos  101:        (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
1.1       cgd       102: #endif
                    103:
1.12      christos  104:        cv_undo(el);
1.10      christos  105:
1.8       lukem     106:        if (!c && el->el_line.cursor < el->el_line.lastchar)
                    107:                el->el_line.cursor++;
                    108:
1.30      christos  109:        c_insert(el, (int)len);
1.12      christos  110:        if (el->el_line.cursor + len > el->el_line.lastchar)
1.37      christos  111:                return CC_ERROR;
1.31      christos  112:        (void) memcpy(el->el_line.cursor, k->buf, len *
                    113:            sizeof(*el->el_line.cursor));
1.24      christos  114:
1.37      christos  115:        return CC_REFRESH;
1.1       cgd       116: }
                    117:
                    118:
1.7       simonb    119: /* vi_paste_next():
1.1       cgd       120:  *     Vi paste previous deletion to the right of the cursor
                    121:  *     [p]
                    122:  */
                    123: protected el_action_t
                    124: /*ARGSUSED*/
1.31      christos  125: vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       126: {
1.8       lukem     127:
1.37      christos  128:        return cv_paste(el, 0);
1.1       cgd       129: }
                    130:
                    131:
1.7       simonb    132: /* vi_paste_prev():
1.1       cgd       133:  *     Vi paste previous deletion to the left of the cursor
                    134:  *     [P]
                    135:  */
                    136: protected el_action_t
                    137: /*ARGSUSED*/
1.31      christos  138: vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       139: {
1.8       lukem     140:
1.37      christos  141:        return cv_paste(el, 1);
1.1       cgd       142: }
                    143:
                    144:
1.10      christos  145: /* vi_prev_big_word():
1.1       cgd       146:  *     Vi move to the previous space delimited word
                    147:  *     [B]
                    148:  */
                    149: protected el_action_t
                    150: /*ARGSUSED*/
1.31      christos  151: vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     152: {
                    153:
                    154:        if (el->el_line.cursor == el->el_line.buffer)
1.37      christos  155:                return CC_ERROR;
1.1       cgd       156:
1.10      christos  157:        el->el_line.cursor = cv_prev_word(el->el_line.cursor,
1.8       lukem     158:            el->el_line.buffer,
                    159:            el->el_state.argument,
1.10      christos  160:            cv__isWord);
1.8       lukem     161:
1.12      christos  162:        if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     163:                cv_delfini(el);
1.37      christos  164:                return CC_REFRESH;
1.8       lukem     165:        }
1.37      christos  166:        return CC_CURSOR;
1.1       cgd       167: }
                    168:
                    169:
1.7       simonb    170: /* vi_prev_word():
1.1       cgd       171:  *     Vi move to the previous word
1.10      christos  172:  *     [b]
1.1       cgd       173:  */
                    174: protected el_action_t
                    175: /*ARGSUSED*/
1.31      christos  176: vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     177: {
1.1       cgd       178:
1.8       lukem     179:        if (el->el_line.cursor == el->el_line.buffer)
1.37      christos  180:                return CC_ERROR;
1.8       lukem     181:
1.10      christos  182:        el->el_line.cursor = cv_prev_word(el->el_line.cursor,
1.8       lukem     183:            el->el_line.buffer,
                    184:            el->el_state.argument,
1.10      christos  185:            cv__isword);
1.8       lukem     186:
1.12      christos  187:        if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     188:                cv_delfini(el);
1.37      christos  189:                return CC_REFRESH;
1.8       lukem     190:        }
1.37      christos  191:        return CC_CURSOR;
1.1       cgd       192: }
                    193:
                    194:
1.10      christos  195: /* vi_next_big_word():
1.1       cgd       196:  *     Vi move to the next space delimited word
                    197:  *     [W]
                    198:  */
                    199: protected el_action_t
                    200: /*ARGSUSED*/
1.31      christos  201: vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     202: {
1.1       cgd       203:
1.12      christos  204:        if (el->el_line.cursor >= el->el_line.lastchar - 1)
1.37      christos  205:                return CC_ERROR;
1.1       cgd       206:
1.8       lukem     207:        el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
1.12      christos  208:            el->el_line.lastchar, el->el_state.argument, cv__isWord);
1.8       lukem     209:
                    210:        if (el->el_map.type == MAP_VI)
1.12      christos  211:                if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     212:                        cv_delfini(el);
1.37      christos  213:                        return CC_REFRESH;
1.8       lukem     214:                }
1.37      christos  215:        return CC_CURSOR;
1.1       cgd       216: }
                    217:
1.8       lukem     218:
1.7       simonb    219: /* vi_next_word():
1.1       cgd       220:  *     Vi move to the next word
                    221:  *     [w]
                    222:  */
                    223: protected el_action_t
                    224: /*ARGSUSED*/
1.31      christos  225: vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     226: {
1.1       cgd       227:
1.12      christos  228:        if (el->el_line.cursor >= el->el_line.lastchar - 1)
1.37      christos  229:                return CC_ERROR;
1.1       cgd       230:
1.8       lukem     231:        el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
1.12      christos  232:            el->el_line.lastchar, el->el_state.argument, cv__isword);
1.8       lukem     233:
                    234:        if (el->el_map.type == MAP_VI)
1.12      christos  235:                if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     236:                        cv_delfini(el);
1.37      christos  237:                        return CC_REFRESH;
1.8       lukem     238:                }
1.37      christos  239:        return CC_CURSOR;
1.1       cgd       240: }
                    241:
                    242:
1.7       simonb    243: /* vi_change_case():
1.1       cgd       244:  *     Vi change case of character under the cursor and advance one character
                    245:  *     [~]
                    246:  */
                    247: protected el_action_t
1.31      christos  248: vi_change_case(EditLine *el, Int c)
1.8       lukem     249: {
1.10      christos  250:        int i;
                    251:
                    252:        if (el->el_line.cursor >= el->el_line.lastchar)
1.37      christos  253:                return CC_ERROR;
1.12      christos  254:        cv_undo(el);
1.10      christos  255:        for (i = 0; i < el->el_state.argument; i++) {
1.8       lukem     256:
1.31      christos  257:                c = *el->el_line.cursor;
                    258:                if (Isupper(c))
                    259:                        *el->el_line.cursor = Tolower(c);
                    260:                else if (Islower(c))
                    261:                        *el->el_line.cursor = Toupper(c);
1.12      christos  262:
                    263:                if (++el->el_line.cursor >= el->el_line.lastchar) {
                    264:                        el->el_line.cursor--;
                    265:                        re_fastaddc(el);
                    266:                        break;
                    267:                }
1.8       lukem     268:                re_fastaddc(el);
                    269:        }
1.12      christos  270:        return CC_NORM;
1.1       cgd       271: }
                    272:
                    273:
1.7       simonb    274: /* vi_change_meta():
1.1       cgd       275:  *     Vi change prefix command
                    276:  *     [c]
                    277:  */
                    278: protected el_action_t
                    279: /*ARGSUSED*/
1.31      christos  280: vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     281: {
                    282:
                    283:        /*
                    284:          * Delete with insert == change: first we delete and then we leave in
                    285:          * insert mode.
                    286:          */
1.37      christos  287:        return cv_action(el, DELETE | INSERT);
1.1       cgd       288: }
                    289:
                    290:
1.7       simonb    291: /* vi_insert_at_bol():
1.1       cgd       292:  *     Vi enter insert mode at the beginning of line
                    293:  *     [I]
                    294:  */
                    295: protected el_action_t
                    296: /*ARGSUSED*/
1.31      christos  297: vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       298: {
                    299:
1.8       lukem     300:        el->el_line.cursor = el->el_line.buffer;
1.12      christos  301:        cv_undo(el);
1.8       lukem     302:        el->el_map.current = el->el_map.key;
1.37      christos  303:        return CC_CURSOR;
1.1       cgd       304: }
                    305:
                    306:
1.7       simonb    307: /* vi_replace_char():
1.1       cgd       308:  *     Vi replace character under the cursor with the next character typed
                    309:  *     [r]
                    310:  */
                    311: protected el_action_t
                    312: /*ARGSUSED*/
1.31      christos  313: vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     314: {
                    315:
1.12      christos  316:        if (el->el_line.cursor >= el->el_line.lastchar)
1.10      christos  317:                return CC_ERROR;
                    318:
1.8       lukem     319:        el->el_map.current = el->el_map.key;
                    320:        el->el_state.inputmode = MODE_REPLACE_1;
1.12      christos  321:        cv_undo(el);
1.37      christos  322:        return CC_ARGHACK;
1.1       cgd       323: }
                    324:
                    325:
1.7       simonb    326: /* vi_replace_mode():
1.1       cgd       327:  *     Vi enter replace mode
                    328:  *     [R]
                    329:  */
                    330: protected el_action_t
                    331: /*ARGSUSED*/
1.31      christos  332: vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     333: {
                    334:
                    335:        el->el_map.current = el->el_map.key;
                    336:        el->el_state.inputmode = MODE_REPLACE;
1.12      christos  337:        cv_undo(el);
1.37      christos  338:        return CC_NORM;
1.1       cgd       339: }
                    340:
                    341:
1.7       simonb    342: /* vi_substitute_char():
1.1       cgd       343:  *     Vi replace character under the cursor and enter insert mode
1.10      christos  344:  *     [s]
1.1       cgd       345:  */
                    346: protected el_action_t
                    347: /*ARGSUSED*/
1.31      christos  348: vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     349: {
                    350:
                    351:        c_delafter(el, el->el_state.argument);
                    352:        el->el_map.current = el->el_map.key;
1.37      christos  353:        return CC_REFRESH;
1.1       cgd       354: }
                    355:
                    356:
1.7       simonb    357: /* vi_substitute_line():
1.1       cgd       358:  *     Vi substitute entire line
                    359:  *     [S]
                    360:  */
                    361: protected el_action_t
                    362: /*ARGSUSED*/
1.31      christos  363: vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     364: {
                    365:
1.12      christos  366:        cv_undo(el);
                    367:        cv_yank(el, el->el_line.buffer,
1.29      christos  368:            (int)(el->el_line.lastchar - el->el_line.buffer));
1.8       lukem     369:        (void) em_kill_line(el, 0);
                    370:        el->el_map.current = el->el_map.key;
1.37      christos  371:        return CC_REFRESH;
1.1       cgd       372: }
                    373:
                    374:
1.7       simonb    375: /* vi_change_to_eol():
1.1       cgd       376:  *     Vi change to end of line
                    377:  *     [C]
                    378:  */
                    379: protected el_action_t
                    380: /*ARGSUSED*/
1.31      christos  381: vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     382: {
                    383:
1.12      christos  384:        cv_undo(el);
                    385:        cv_yank(el, el->el_line.cursor,
1.29      christos  386:            (int)(el->el_line.lastchar - el->el_line.cursor));
1.8       lukem     387:        (void) ed_kill_line(el, 0);
                    388:        el->el_map.current = el->el_map.key;
1.37      christos  389:        return CC_REFRESH;
1.1       cgd       390: }
                    391:
                    392:
                    393: /* vi_insert():
                    394:  *     Vi enter insert mode
                    395:  *     [i]
                    396:  */
                    397: protected el_action_t
                    398: /*ARGSUSED*/
1.31      christos  399: vi_insert(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       400: {
                    401:
1.8       lukem     402:        el->el_map.current = el->el_map.key;
1.12      christos  403:        cv_undo(el);
1.37      christos  404:        return CC_NORM;
1.1       cgd       405: }
                    406:
                    407:
                    408: /* vi_add():
1.7       simonb    409:  *     Vi enter insert mode after the cursor
1.1       cgd       410:  *     [a]
                    411:  */
                    412: protected el_action_t
                    413: /*ARGSUSED*/
1.31      christos  414: vi_add(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     415: {
                    416:        int ret;
                    417:
                    418:        el->el_map.current = el->el_map.key;
                    419:        if (el->el_line.cursor < el->el_line.lastchar) {
                    420:                el->el_line.cursor++;
                    421:                if (el->el_line.cursor > el->el_line.lastchar)
                    422:                        el->el_line.cursor = el->el_line.lastchar;
                    423:                ret = CC_CURSOR;
                    424:        } else
                    425:                ret = CC_NORM;
                    426:
1.12      christos  427:        cv_undo(el);
1.1       cgd       428:
1.37      christos  429:        return ret;
1.1       cgd       430: }
                    431:
                    432:
                    433: /* vi_add_at_eol():
                    434:  *     Vi enter insert mode at end of line
                    435:  *     [A]
                    436:  */
                    437: protected el_action_t
                    438: /*ARGSUSED*/
1.31      christos  439: vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     440: {
                    441:
                    442:        el->el_map.current = el->el_map.key;
                    443:        el->el_line.cursor = el->el_line.lastchar;
1.12      christos  444:        cv_undo(el);
1.37      christos  445:        return CC_CURSOR;
1.1       cgd       446: }
                    447:
                    448:
                    449: /* vi_delete_meta():
1.7       simonb    450:  *     Vi delete prefix command
1.1       cgd       451:  *     [d]
                    452:  */
                    453: protected el_action_t
                    454: /*ARGSUSED*/
1.31      christos  455: vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       456: {
1.8       lukem     457:
1.37      christos  458:        return cv_action(el, DELETE);
1.1       cgd       459: }
                    460:
                    461:
1.10      christos  462: /* vi_end_big_word():
1.7       simonb    463:  *     Vi move to the end of the current space delimited word
                    464:  *     [E]
1.1       cgd       465:  */
                    466: protected el_action_t
                    467: /*ARGSUSED*/
1.38    ! christos  468: vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     469: {
                    470:
                    471:        if (el->el_line.cursor == el->el_line.lastchar)
1.37      christos  472:                return CC_ERROR;
1.1       cgd       473:
1.8       lukem     474:        el->el_line.cursor = cv__endword(el->el_line.cursor,
1.10      christos  475:            el->el_line.lastchar, el->el_state.argument, cv__isWord);
1.8       lukem     476:
1.12      christos  477:        if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     478:                el->el_line.cursor++;
                    479:                cv_delfini(el);
1.37      christos  480:                return CC_REFRESH;
1.8       lukem     481:        }
1.37      christos  482:        return CC_CURSOR;
1.1       cgd       483: }
                    484:
                    485:
1.10      christos  486: /* vi_end_word():
1.1       cgd       487:  *     Vi move to the end of the current word
                    488:  *     [e]
                    489:  */
                    490: protected el_action_t
                    491: /*ARGSUSED*/
1.31      christos  492: vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     493: {
                    494:
                    495:        if (el->el_line.cursor == el->el_line.lastchar)
1.37      christos  496:                return CC_ERROR;
1.8       lukem     497:
                    498:        el->el_line.cursor = cv__endword(el->el_line.cursor,
1.10      christos  499:            el->el_line.lastchar, el->el_state.argument, cv__isword);
1.1       cgd       500:
1.12      christos  501:        if (el->el_chared.c_vcmd.action != NOP) {
1.8       lukem     502:                el->el_line.cursor++;
                    503:                cv_delfini(el);
1.37      christos  504:                return CC_REFRESH;
1.8       lukem     505:        }
1.37      christos  506:        return CC_CURSOR;
1.1       cgd       507: }
                    508:
                    509:
                    510: /* vi_undo():
                    511:  *     Vi undo last change
                    512:  *     [u]
                    513:  */
                    514: protected el_action_t
                    515: /*ARGSUSED*/
1.31      christos  516: vi_undo(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     517: {
1.10      christos  518:        c_undo_t un = el->el_chared.c_undo;
1.1       cgd       519:
1.10      christos  520:        if (un.len == -1)
                    521:                return CC_ERROR;
1.1       cgd       522:
1.10      christos  523:        /* switch line buffer and undo buffer */
                    524:        el->el_chared.c_undo.buf = el->el_line.buffer;
                    525:        el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
1.29      christos  526:        el->el_chared.c_undo.cursor =
                    527:            (int)(el->el_line.cursor - el->el_line.buffer);
1.10      christos  528:        el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
                    529:        el->el_line.buffer = un.buf;
                    530:        el->el_line.cursor = un.buf + un.cursor;
                    531:        el->el_line.lastchar = un.buf + un.len;
1.1       cgd       532:
1.37      christos  533:        return CC_REFRESH;
1.1       cgd       534: }
                    535:
                    536:
                    537: /* vi_command_mode():
                    538:  *     Vi enter command mode (use alternative key bindings)
                    539:  *     [<ESC>]
                    540:  */
                    541: protected el_action_t
                    542: /*ARGSUSED*/
1.31      christos  543: vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     544: {
                    545:
                    546:        /* [Esc] cancels pending action */
                    547:        el->el_chared.c_vcmd.action = NOP;
                    548:        el->el_chared.c_vcmd.pos = 0;
                    549:
                    550:        el->el_state.doingarg = 0;
1.1       cgd       551:
1.8       lukem     552:        el->el_state.inputmode = MODE_INSERT;
                    553:        el->el_map.current = el->el_map.alt;
1.1       cgd       554: #ifdef VI_MOVE
1.8       lukem     555:        if (el->el_line.cursor > el->el_line.buffer)
                    556:                el->el_line.cursor--;
1.1       cgd       557: #endif
1.37      christos  558:        return CC_CURSOR;
1.1       cgd       559: }
                    560:
1.8       lukem     561:
1.1       cgd       562: /* vi_zero():
1.7       simonb    563:  *     Vi move to the beginning of line
1.1       cgd       564:  *     [0]
                    565:  */
                    566: protected el_action_t
1.31      christos  567: vi_zero(EditLine *el, Int c)
1.8       lukem     568: {
                    569:
1.12      christos  570:        if (el->el_state.doingarg)
                    571:                return ed_argument_digit(el, c);
                    572:
                    573:        el->el_line.cursor = el->el_line.buffer;
                    574:        if (el->el_chared.c_vcmd.action != NOP) {
                    575:                cv_delfini(el);
1.37      christos  576:                return CC_REFRESH;
1.8       lukem     577:        }
1.37      christos  578:        return CC_CURSOR;
1.1       cgd       579: }
                    580:
                    581:
                    582: /* vi_delete_prev_char():
1.7       simonb    583:  *     Vi move to previous character (backspace)
1.10      christos  584:  *     [^H] in insert mode only
1.7       simonb    585:  */
1.1       cgd       586: protected el_action_t
                    587: /*ARGSUSED*/
1.31      christos  588: vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     589: {
1.1       cgd       590:
1.20      mycroft   591:        if (el->el_line.cursor <= el->el_line.buffer)
1.37      christos  592:                return CC_ERROR;
1.8       lukem     593:
1.20      mycroft   594:        c_delbefore1(el);
                    595:        el->el_line.cursor--;
1.37      christos  596:        return CC_REFRESH;
1.8       lukem     597: }
1.1       cgd       598:
                    599:
                    600: /* vi_list_or_eof():
                    601:  *     Vi list choices for completion or indicate end of file if empty line
                    602:  *     [^D]
                    603:  */
                    604: protected el_action_t
                    605: /*ARGSUSED*/
1.31      christos  606: vi_list_or_eof(EditLine *el, Int c)
1.1       cgd       607: {
1.8       lukem     608:
1.17      matt      609:        if (el->el_line.cursor == el->el_line.lastchar) {
                    610:                if (el->el_line.cursor == el->el_line.buffer) {
1.35      christos  611:                        terminal_writec(el, c); /* then do a EOF */
1.37      christos  612:                        return CC_EOF;
1.17      matt      613:                } else {
                    614:                        /*
                    615:                         * Here we could list completions, but it is an
                    616:                         * error right now
                    617:                         */
1.35      christos  618:                        terminal_beep(el);
1.37      christos  619:                        return CC_ERROR;
1.17      matt      620:                }
                    621:        } else {
1.1       cgd       622: #ifdef notyet
1.8       lukem     623:                re_goto_bottom(el);
                    624:                *el->el_line.lastchar = '\0';   /* just in case */
1.37      christos  625:                return CC_LIST_CHOICES;
1.17      matt      626: #else
                    627:                /*
                    628:                 * Just complain for now.
                    629:                 */
1.35      christos  630:                terminal_beep(el);
1.37      christos  631:                return CC_ERROR;
1.17      matt      632: #endif
1.8       lukem     633:        }
1.1       cgd       634: }
                    635:
                    636:
                    637: /* vi_kill_line_prev():
1.7       simonb    638:  *     Vi cut from beginning of line to cursor
1.1       cgd       639:  *     [^U]
                    640:  */
                    641: protected el_action_t
                    642: /*ARGSUSED*/
1.31      christos  643: vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     644: {
1.31      christos  645:        Char *kp, *cp;
1.8       lukem     646:
                    647:        cp = el->el_line.buffer;
                    648:        kp = el->el_chared.c_kill.buf;
                    649:        while (cp < el->el_line.cursor)
                    650:                *kp++ = *cp++;  /* copy it */
                    651:        el->el_chared.c_kill.last = kp;
1.29      christos  652:        c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
1.8       lukem     653:        el->el_line.cursor = el->el_line.buffer;        /* zap! */
1.37      christos  654:        return CC_REFRESH;
1.1       cgd       655: }
                    656:
                    657:
                    658: /* vi_search_prev():
                    659:  *     Vi search history previous
                    660:  *     [?]
                    661:  */
                    662: protected el_action_t
                    663: /*ARGSUSED*/
1.31      christos  664: vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       665: {
1.8       lukem     666:
1.37      christos  667:        return cv_search(el, ED_SEARCH_PREV_HISTORY);
1.1       cgd       668: }
                    669:
                    670:
                    671: /* vi_search_next():
                    672:  *     Vi search history next
                    673:  *     [/]
                    674:  */
                    675: protected el_action_t
                    676: /*ARGSUSED*/
1.31      christos  677: vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       678: {
1.8       lukem     679:
1.37      christos  680:        return cv_search(el, ED_SEARCH_NEXT_HISTORY);
1.1       cgd       681: }
                    682:
                    683:
                    684: /* vi_repeat_search_next():
                    685:  *     Vi repeat current search in the same search direction
                    686:  *     [n]
                    687:  */
                    688: protected el_action_t
                    689: /*ARGSUSED*/
1.31      christos  690: vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     691: {
                    692:
                    693:        if (el->el_search.patlen == 0)
1.37      christos  694:                return CC_ERROR;
1.8       lukem     695:        else
1.37      christos  696:                return cv_repeat_srch(el, el->el_search.patdir);
1.1       cgd       697: }
                    698:
                    699:
                    700: /* vi_repeat_search_prev():
                    701:  *     Vi repeat current search in the opposite search direction
                    702:  *     [N]
                    703:  */
                    704: /*ARGSUSED*/
                    705: protected el_action_t
1.31      christos  706: vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     707: {
                    708:
                    709:        if (el->el_search.patlen == 0)
1.37      christos  710:                return CC_ERROR;
1.8       lukem     711:        else
                    712:                return (cv_repeat_srch(el,
                    713:                    el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
                    714:                    ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY));
1.1       cgd       715: }
                    716:
                    717:
                    718: /* vi_next_char():
                    719:  *     Vi move to the character specified next
                    720:  *     [f]
                    721:  */
                    722: protected el_action_t
                    723: /*ARGSUSED*/
1.31      christos  724: vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       725: {
1.12      christos  726:        return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
1.1       cgd       727: }
                    728:
                    729:
                    730: /* vi_prev_char():
                    731:  *     Vi move to the character specified previous
                    732:  *     [F]
                    733:  */
                    734: protected el_action_t
                    735: /*ARGSUSED*/
1.31      christos  736: vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       737: {
1.12      christos  738:        return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
1.1       cgd       739: }
                    740:
                    741:
                    742: /* vi_to_next_char():
                    743:  *     Vi move up to the character specified next
                    744:  *     [t]
                    745:  */
                    746: protected el_action_t
                    747: /*ARGSUSED*/
1.31      christos  748: vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
1.1       cgd       749: {
1.12      christos  750:        return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
1.1       cgd       751: }
                    752:
                    753:
                    754: /* vi_to_prev_char():
                    755:  *     Vi move up to the character specified previous
                    756:  *     [T]
                    757:  */
                    758: protected el_action_t
                    759: /*ARGSUSED*/
1.31      christos  760: vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     761: {
1.12      christos  762:        return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
1.1       cgd       763: }
                    764:
                    765:
                    766: /* vi_repeat_next_char():
                    767:  *     Vi repeat current character search in the same search direction
                    768:  *     [;]
                    769:  */
                    770: protected el_action_t
                    771: /*ARGSUSED*/
1.31      christos  772: vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     773: {
                    774:
1.12      christos  775:        return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
                    776:                el->el_state.argument, el->el_search.chatflg);
1.1       cgd       777: }
                    778:
                    779:
                    780: /* vi_repeat_prev_char():
                    781:  *     Vi repeat current character search in the opposite search direction
                    782:  *     [,]
                    783:  */
                    784: protected el_action_t
                    785: /*ARGSUSED*/
1.31      christos  786: vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
1.8       lukem     787: {
1.12      christos  788:        el_action_t r;
                    789:        int dir = el->el_search.chadir;
1.8       lukem     790:
1.12      christos  791:        r = cv_csearch(el, -dir, el->el_search.chacha,
                    792:                el->el_state.argument, el->el_search.chatflg);
                    793:        el->el_search.chadir = dir;
                    794:        return r;
1.11      christos  795: }
                    796:
                    797:
                    798: /* vi_match():
                    799:  *     Vi go to matching () {} or []
                    800:  *     [%]
                    801:  */
                    802: protected el_action_t
                    803: /*ARGSUSED*/
1.38    ! christos  804: vi_match(EditLine *el, Int c __attribute__((__unused__)))
1.11      christos  805: {
1.31      christos  806:        const Char match_chars[] = STR("()[]{}");
                    807:        Char *cp;
1.29      christos  808:        size_t delta, i, count;
1.31      christos  809:        Char o_ch, c_ch;
1.11      christos  810:
                    811:        *el->el_line.lastchar = '\0';           /* just in case */
                    812:
1.31      christos  813:        i = Strcspn(el->el_line.cursor, match_chars);
1.11      christos  814:        o_ch = el->el_line.cursor[i];
                    815:        if (o_ch == 0)
                    816:                return CC_ERROR;
1.31      christos  817:        delta = Strchr(match_chars, o_ch) - match_chars;
1.11      christos  818:        c_ch = match_chars[delta ^ 1];
                    819:        count = 1;
                    820:        delta = 1 - (delta & 1) * 2;
                    821:
                    822:        for (cp = &el->el_line.cursor[i]; count; ) {
                    823:                cp += delta;
                    824:                if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
                    825:                        return CC_ERROR;
                    826:                if (*cp == o_ch)
                    827:                        count++;
                    828:                else if (*cp == c_ch)
                    829:                        count--;
                    830:        }
                    831:
                    832:        el->el_line.cursor = cp;
                    833:
1.12      christos  834:        if (el->el_chared.c_vcmd.action != NOP) {
                    835:                /* NB posix says char under cursor should NOT be deleted
                    836:                   for -ve delta - this is different to netbsd vi. */
1.11      christos  837:                if (delta > 0)
                    838:                        el->el_line.cursor++;
                    839:                cv_delfini(el);
1.37      christos  840:                return CC_REFRESH;
1.11      christos  841:        }
1.37      christos  842:        return CC_CURSOR;
1.12      christos  843: }
                    844:
                    845: /* vi_undo_line():
                    846:  *     Vi undo all changes to line
                    847:  *     [U]
                    848:  */
                    849: protected el_action_t
                    850: /*ARGSUSED*/
1.38    ! christos  851: vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  852: {
                    853:
                    854:        cv_undo(el);
                    855:        return hist_get(el);
                    856: }
                    857:
                    858: /* vi_to_column():
                    859:  *     Vi go to specified column
                    860:  *     [|]
                    861:  * NB netbsd vi goes to screen column 'n', posix says nth character
                    862:  */
                    863: protected el_action_t
                    864: /*ARGSUSED*/
1.38    ! christos  865: vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  866: {
                    867:
                    868:        el->el_line.cursor = el->el_line.buffer;
                    869:        el->el_state.argument--;
                    870:        return ed_next_char(el, 0);
                    871: }
                    872:
                    873: /* vi_yank_end():
                    874:  *     Vi yank to end of line
                    875:  *     [Y]
                    876:  */
                    877: protected el_action_t
                    878: /*ARGSUSED*/
1.38    ! christos  879: vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  880: {
                    881:
                    882:        cv_yank(el, el->el_line.cursor,
1.29      christos  883:            (int)(el->el_line.lastchar - el->el_line.cursor));
1.12      christos  884:        return CC_REFRESH;
                    885: }
                    886:
                    887: /* vi_yank():
                    888:  *     Vi yank
                    889:  *     [y]
                    890:  */
                    891: protected el_action_t
                    892: /*ARGSUSED*/
1.38    ! christos  893: vi_yank(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  894: {
                    895:
                    896:        return cv_action(el, YANK);
                    897: }
                    898:
                    899: /* vi_comment_out():
                    900:  *     Vi comment out current command
1.22      christos  901:  *     [#]
1.12      christos  902:  */
                    903: protected el_action_t
                    904: /*ARGSUSED*/
1.38    ! christos  905: vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  906: {
                    907:
                    908:        el->el_line.cursor = el->el_line.buffer;
                    909:        c_insert(el, 1);
                    910:        *el->el_line.cursor = '#';
                    911:        re_refresh(el);
                    912:        return ed_newline(el, 0);
                    913: }
                    914:
                    915: /* vi_alias():
                    916:  *     Vi include shell alias
                    917:  *     [@]
1.22      christos  918:  * NB: posix implies that we should enter insert mode, however
1.12      christos  919:  * this is against historical precedent...
                    920:  */
1.27      mrg       921: #ifdef __weak_reference
1.34      joerg     922: __weakref_visible char *my_get_alias_text(const char *)
                    923:     __weak_reference(get_alias_text);
1.33      joerg     924: #endif
1.12      christos  925: protected el_action_t
                    926: /*ARGSUSED*/
1.38    ! christos  927: vi_alias(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  928: {
1.26      christos  929: #ifdef __weak_reference
1.12      christos  930:        char alias_name[3];
                    931:        char *alias_text;
                    932:
1.33      joerg     933:        if (my_get_alias_text == 0) {
                    934:                return CC_ERROR;
                    935:        }
1.14      christos  936:
1.12      christos  937:        alias_name[0] = '_';
                    938:        alias_name[2] = 0;
                    939:        if (el_getc(el, &alias_name[1]) != 1)
                    940:                return CC_ERROR;
                    941:
1.34      joerg     942:        alias_text = my_get_alias_text(alias_name);
1.12      christos  943:        if (alias_text != NULL)
1.31      christos  944:                FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
1.12      christos  945:        return CC_NORM;
1.14      christos  946: #else
                    947:        return CC_ERROR;
                    948: #endif
1.12      christos  949: }
                    950:
                    951: /* vi_to_history_line():
                    952:  *     Vi go to specified history file line.
                    953:  *     [G]
                    954:  */
                    955: protected el_action_t
                    956: /*ARGSUSED*/
1.38    ! christos  957: vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos  958: {
                    959:        int sv_event_no = el->el_history.eventno;
                    960:        el_action_t rval;
                    961:
                    962:
                    963:        if (el->el_history.eventno == 0) {
1.31      christos  964:                 (void) Strncpy(el->el_history.buf, el->el_line.buffer,
1.12      christos  965:                     EL_BUFSIZ);
                    966:                 el->el_history.last = el->el_history.buf +
                    967:                         (el->el_line.lastchar - el->el_line.buffer);
                    968:        }
                    969:
                    970:        /* Lack of a 'count' means oldest, not 1 */
                    971:        if (!el->el_state.doingarg) {
                    972:                el->el_history.eventno = 0x7fffffff;
                    973:                hist_get(el);
                    974:        } else {
                    975:                /* This is brain dead, all the rest of this code counts
                    976:                 * upwards going into the past.  Here we need count in the
                    977:                 * other direction (to match the output of fc -l).
                    978:                 * I could change the world, but this seems to suffice.
                    979:                 */
                    980:                el->el_history.eventno = 1;
                    981:                if (hist_get(el) == CC_ERROR)
                    982:                        return CC_ERROR;
                    983:                el->el_history.eventno = 1 + el->el_history.ev.num
                    984:                                        - el->el_state.argument;
                    985:                if (el->el_history.eventno < 0) {
                    986:                        el->el_history.eventno = sv_event_no;
                    987:                        return CC_ERROR;
                    988:                }
                    989:        }
                    990:        rval = hist_get(el);
                    991:        if (rval == CC_ERROR)
                    992:                el->el_history.eventno = sv_event_no;
                    993:        return rval;
                    994: }
                    995:
                    996: /* vi_histedit():
                    997:  *     Vi edit history line with vi
                    998:  *     [v]
                    999:  */
                   1000: protected el_action_t
                   1001: /*ARGSUSED*/
1.38    ! christos 1002: vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos 1003: {
                   1004:        int fd;
                   1005:        pid_t pid;
1.29      christos 1006:        ssize_t st;
                   1007:        int status;
1.12      christos 1008:        char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
                   1009:        char *cp;
1.31      christos 1010:        size_t len;
                   1011:        Char *line;
1.12      christos 1012:
                   1013:        if (el->el_state.doingarg) {
                   1014:                if (vi_to_history_line(el, 0) == CC_ERROR)
                   1015:                        return CC_ERROR;
                   1016:        }
                   1017:
                   1018:        fd = mkstemp(tempfile);
                   1019:        if (fd < 0)
                   1020:                return CC_ERROR;
1.31      christos 1021:        len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
                   1022: #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
1.36      christos 1023:        cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
1.32      christos 1024:        if (cp == NULL) {
                   1025:                unlink(tempfile);
                   1026:                close(fd);
1.31      christos 1027:                return CC_ERROR;
1.32      christos 1028:        }
1.31      christos 1029:        line = el_malloc(len * sizeof(*line));
                   1030:        if (line == NULL) {
1.36      christos 1031:                el_free(cp);
1.31      christos 1032:                return CC_ERROR;
                   1033:        }
                   1034:        Strncpy(line, el->el_line.buffer, len);
                   1035:        line[len] = '\0';
                   1036:        ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
                   1037:        cp[TMP_BUFSIZ - 1] = '\0';
                   1038:        len = strlen(cp);
                   1039:        write(fd, cp, len);
1.12      christos 1040:        write(fd, "\n", 1);
                   1041:        pid = fork();
                   1042:        switch (pid) {
                   1043:        case -1:
                   1044:                close(fd);
                   1045:                unlink(tempfile);
1.31      christos 1046:                el_free(cp);
                   1047:                 el_free(line);
1.12      christos 1048:                return CC_ERROR;
                   1049:        case 0:
                   1050:                close(fd);
1.28      sketch   1051:                execlp("vi", "vi", tempfile, (char *)NULL);
1.12      christos 1052:                exit(0);
                   1053:                /*NOTREACHED*/
                   1054:        default:
1.29      christos 1055:                while (waitpid(pid, &status, 0) != pid)
1.12      christos 1056:                        continue;
1.29      christos 1057:                lseek(fd, (off_t)0, SEEK_SET);
1.31      christos 1058:                st = read(fd, cp, TMP_BUFSIZ);
                   1059:                if (st > 0) {
                   1060:                        len = (size_t)(el->el_line.lastchar -
                   1061:                            el->el_line.buffer);
                   1062:                        len = ct_mbstowcs(el->el_line.buffer, cp, len);
                   1063:                        if (len > 0 && el->el_line.buffer[len -1] == '\n')
                   1064:                                --len;
                   1065:                }
                   1066:                else
                   1067:                        len = 0;
                   1068:                 el->el_line.cursor = el->el_line.buffer;
                   1069:                 el->el_line.lastchar = el->el_line.buffer + len;
                   1070:                el_free(cp);
                   1071:                 el_free(line);
1.12      christos 1072:                break;
                   1073:        }
                   1074:
                   1075:        close(fd);
                   1076:        unlink(tempfile);
                   1077:        /* return CC_REFRESH; */
                   1078:        return ed_newline(el, 0);
                   1079: }
                   1080:
                   1081: /* vi_history_word():
                   1082:  *     Vi append word from previous input line
                   1083:  *     [_]
                   1084:  * Who knows where this one came from!
                   1085:  * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_'
                   1086:  */
                   1087: protected el_action_t
                   1088: /*ARGSUSED*/
1.38    ! christos 1089: vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos 1090: {
1.31      christos 1091:        const Char *wp = HIST_FIRST(el);
                   1092:        const Char *wep, *wsp;
1.12      christos 1093:        int len;
1.31      christos 1094:        Char *cp;
                   1095:        const Char *lim;
1.12      christos 1096:
                   1097:        if (wp == NULL)
                   1098:                return CC_ERROR;
                   1099:
1.13      christos 1100:        wep = wsp = 0;
1.12      christos 1101:        do {
1.31      christos 1102:                while (Isspace(*wp))
1.12      christos 1103:                        wp++;
                   1104:                if (*wp == 0)
                   1105:                        break;
                   1106:                wsp = wp;
1.31      christos 1107:                while (*wp && !Isspace(*wp))
1.12      christos 1108:                        wp++;
                   1109:                wep = wp;
1.31      christos 1110:        } while ((!el->el_state.doingarg || --el->el_state.argument > 0)
                   1111:            && *wp != 0);
1.12      christos 1112:
                   1113:        if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
                   1114:                return CC_ERROR;
                   1115:
                   1116:        cv_undo(el);
1.29      christos 1117:        len = (int)(wep - wsp);
1.12      christos 1118:        if (el->el_line.cursor < el->el_line.lastchar)
                   1119:                el->el_line.cursor++;
                   1120:        c_insert(el, len + 1);
                   1121:        cp = el->el_line.cursor;
                   1122:        lim = el->el_line.limit;
                   1123:        if (cp < lim)
                   1124:                *cp++ = ' ';
                   1125:        while (wsp < wep && cp < lim)
                   1126:                *cp++ = *wsp++;
                   1127:        el->el_line.cursor = cp;
                   1128:
                   1129:        el->el_map.current = el->el_map.key;
                   1130:        return CC_REFRESH;
                   1131: }
                   1132:
                   1133: /* vi_redo():
                   1134:  *     Vi redo last non-motion command
                   1135:  *     [.]
                   1136:  */
                   1137: protected el_action_t
                   1138: /*ARGSUSED*/
1.38    ! christos 1139: vi_redo(EditLine *el, Int c __attribute__((__unused__)))
1.12      christos 1140: {
                   1141:        c_redo_t *r = &el->el_chared.c_redo;
                   1142:
                   1143:        if (!el->el_state.doingarg && r->count) {
                   1144:                el->el_state.doingarg = 1;
                   1145:                el->el_state.argument = r->count;
                   1146:        }
                   1147:
                   1148:        el->el_chared.c_vcmd.pos = el->el_line.cursor;
                   1149:        el->el_chared.c_vcmd.action = r->action;
                   1150:        if (r->pos != r->buf) {
                   1151:                if (r->pos + 1 > r->lim)
                   1152:                        /* sanity */
                   1153:                        r->pos = r->lim - 1;
                   1154:                r->pos[0] = 0;
1.31      christos 1155:                FUN(el,push)(el, r->buf);
1.12      christos 1156:        }
                   1157:
                   1158:        el->el_state.thiscmd = r->cmd;
                   1159:        el->el_state.thisch = r->ch;
1.37      christos 1160:        return (*el->el_map.func[r->cmd])(el, r->ch);
1.1       cgd      1161: }

CVSweb <webmaster@jp.NetBSD.org>