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

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

CVSweb <webmaster@jp.NetBSD.org>