vi.c revision 37199
11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Christos Zoulas of Cornell University. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 161573Srgrimes * 3. All advertising materials mentioning features or use of this software 171573Srgrimes * must display the following acknowledgement: 181573Srgrimes * This product includes software developed by the University of 191573Srgrimes * California, Berkeley and its contributors. 201573Srgrimes * 4. Neither the name of the University nor the names of its contributors 211573Srgrimes * may be used to endorse or promote products derived from this software 221573Srgrimes * without specific prior written permission. 231573Srgrimes * 241573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341573Srgrimes * SUCH DAMAGE. 351573Srgrimes */ 361573Srgrimes 371573Srgrimes#if !defined(lint) && !defined(SCCSID) 381573Srgrimesstatic char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; 391573Srgrimes#endif /* not lint && not SCCSID */ 401573Srgrimes 411573Srgrimes/* 421573Srgrimes * vi.c: Vi mode commands. 431573Srgrimes */ 441573Srgrimes#include "sys.h" 451573Srgrimes#include "el.h" 461573Srgrimes 471573Srgrimesprivate el_action_t cv_action __P((EditLine *, int)); 481573Srgrimes 491573Srgrimes/* cv_action(): 501573Srgrimes * Handle vi actions. 511573Srgrimes */ 521573Srgrimesprivate el_action_t 531573Srgrimescv_action(el, c) 541573Srgrimes EditLine *el; 551573Srgrimes int c; 561573Srgrimes{ 571573Srgrimes register char *cp, *kp; 581573Srgrimes 591573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 601573Srgrimes el->el_chared.c_vcmd.action = NOP; 611573Srgrimes el->el_chared.c_vcmd.pos = 0; 628870Srgrimes 631573Srgrimes el->el_chared.c_undo.isize = 0; 641573Srgrimes el->el_chared.c_undo.dsize = 0; 651573Srgrimes kp = el->el_chared.c_undo.buf; 661573Srgrimes for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { 671573Srgrimes *kp++ = *cp; 681573Srgrimes el->el_chared.c_undo.dsize++; 691573Srgrimes } 708870Srgrimes 711573Srgrimes el->el_chared.c_undo.action = INSERT; 721573Srgrimes el->el_chared.c_undo.ptr = el->el_line.buffer; 731573Srgrimes el->el_line.lastchar = el->el_line.buffer; 741573Srgrimes el->el_line.cursor = el->el_line.buffer; 751573Srgrimes if (c & INSERT) 761573Srgrimes el->el_map.current = el->el_map.key; 778870Srgrimes 781573Srgrimes return CC_REFRESH; 791573Srgrimes } 801573Srgrimes 811573Srgrimes el->el_chared.c_vcmd.pos = el->el_line.cursor; 821573Srgrimes el->el_chared.c_vcmd.action = c; 831573Srgrimes return CC_ARGHACK; 841573Srgrimes 851573Srgrimes#ifdef notdef 861573Srgrimes /* 871573Srgrimes * I don't think that this is needed. But we keep it for now 881573Srgrimes */ 891573Srgrimes else if (el_chared.c_vcmd.action == NOP) { 901573Srgrimes el->el_chared.c_vcmd.pos = el->el_line.cursor; 911573Srgrimes el->el_chared.c_vcmd.action = c; 921573Srgrimes return CC_ARGHACK; 931573Srgrimes } 941573Srgrimes else { 951573Srgrimes el->el_chared.c_vcmd.action = 0; 961573Srgrimes el->el_chared.c_vcmd.pos = 0; 971573Srgrimes return CC_ERROR; 981573Srgrimes } 991573Srgrimes#endif 1001573Srgrimes} 1011573Srgrimes 1021573Srgrimes 1031573Srgrimes/* cv_paste(): 1041573Srgrimes * Paste previous deletion before or after the cursor 1051573Srgrimes */ 1061573Srgrimesprotected el_action_t 1071573Srgrimescv_paste(el, c) 1081573Srgrimes EditLine *el; 1091573Srgrimes int c; 1101573Srgrimes{ 1111573Srgrimes char *ptr; 1121573Srgrimes c_undo_t *un = &el->el_chared.c_undo; 1131573Srgrimes#ifdef DEBUG_PASTE 1148870Srgrimes (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", 1151573Srgrimes un->action, un->buf, un->isize, un->dsize); 1161573Srgrimes#endif 1171573Srgrimes if (un->isize == 0) 1181573Srgrimes return CC_ERROR; 1191573Srgrimes 1201573Srgrimes if (!c && el->el_line.cursor < el->el_line.lastchar) 1211573Srgrimes el->el_line.cursor++; 1221573Srgrimes ptr = el->el_line.cursor; 1238870Srgrimes 1241573Srgrimes c_insert(el, un->isize); 1251573Srgrimes if (el->el_line.cursor + un->isize > el->el_line.lastchar) 1261573Srgrimes return CC_ERROR; 1271573Srgrimes (void) memcpy(ptr, un->buf, un->isize); 1281573Srgrimes return CC_REFRESH; 1291573Srgrimes} 1301573Srgrimes 1311573Srgrimes 1328870Srgrimes/* vi_paste_next(): 1331573Srgrimes * Vi paste previous deletion to the right of the cursor 1341573Srgrimes * [p] 1351573Srgrimes */ 1361573Srgrimesprotected el_action_t 1371573Srgrimes/*ARGSUSED*/ 1381573Srgrimesvi_paste_next(el, c) 1391573Srgrimes EditLine *el; 1401573Srgrimes int c; 1411573Srgrimes{ 1421573Srgrimes return cv_paste(el, 0); 1431573Srgrimes} 1441573Srgrimes 1451573Srgrimes 1468870Srgrimes/* vi_paste_prev(): 1471573Srgrimes * Vi paste previous deletion to the left of the cursor 1481573Srgrimes * [P] 1491573Srgrimes */ 1501573Srgrimesprotected el_action_t 1511573Srgrimes/*ARGSUSED*/ 1521573Srgrimesvi_paste_prev(el, c) 1531573Srgrimes EditLine *el; 1541573Srgrimes int c; 1551573Srgrimes{ 1561573Srgrimes return cv_paste(el, 1); 1571573Srgrimes} 1581573Srgrimes 1591573Srgrimes 1608870Srgrimes/* vi_prev_space_word(): 1611573Srgrimes * Vi move to the previous space delimited word 1621573Srgrimes * [B] 1631573Srgrimes */ 1641573Srgrimesprotected el_action_t 1651573Srgrimes/*ARGSUSED*/ 1661573Srgrimesvi_prev_space_word(el, c) 1671573Srgrimes EditLine *el; 1681573Srgrimes int c; 1691573Srgrimes{ 1701573Srgrimes if (el->el_line.cursor == el->el_line.buffer) 1711573Srgrimes return CC_ERROR; 1721573Srgrimes 1738870Srgrimes el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, 1748870Srgrimes el->el_line.buffer, 1758870Srgrimes el->el_state.argument, 17637199Sbrian c___isword); 1771573Srgrimes 1781573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 1791573Srgrimes cv_delfini(el); 1801573Srgrimes return CC_REFRESH; 1811573Srgrimes } 1821573Srgrimes 1831573Srgrimes return CC_CURSOR; 1841573Srgrimes} 1851573Srgrimes 1861573Srgrimes 1878870Srgrimes/* vi_prev_word(): 1881573Srgrimes * Vi move to the previous word 18937199Sbrian * [b] 1901573Srgrimes */ 1911573Srgrimesprotected el_action_t 1921573Srgrimes/*ARGSUSED*/ 1931573Srgrimesvi_prev_word(el, c) 1941573Srgrimes EditLine *el; 1951573Srgrimes int c; 1961573Srgrimes{ 1971573Srgrimes if (el->el_line.cursor == el->el_line.buffer) 1981573Srgrimes return CC_ERROR; 1991573Srgrimes 2008870Srgrimes el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, 2018870Srgrimes el->el_line.buffer, 2028870Srgrimes el->el_state.argument, 20337199Sbrian cv__isword); 2041573Srgrimes 2051573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 2061573Srgrimes cv_delfini(el); 2071573Srgrimes return CC_REFRESH; 2081573Srgrimes } 2091573Srgrimes 2101573Srgrimes return CC_CURSOR; 2111573Srgrimes} 2121573Srgrimes 2131573Srgrimes 2148870Srgrimes/* vi_next_space_word(): 2151573Srgrimes * Vi move to the next space delimited word 2161573Srgrimes * [W] 2171573Srgrimes */ 2181573Srgrimesprotected el_action_t 2191573Srgrimes/*ARGSUSED*/ 2201573Srgrimesvi_next_space_word(el, c) 2211573Srgrimes EditLine *el; 2221573Srgrimes int c; 2231573Srgrimes{ 2241573Srgrimes if (el->el_line.cursor == el->el_line.lastchar) 2251573Srgrimes return CC_ERROR; 2261573Srgrimes 2278870Srgrimes el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 2288870Srgrimes el->el_line.lastchar, 2298870Srgrimes el->el_state.argument, 23037199Sbrian c___isword); 2311573Srgrimes 2321573Srgrimes if (el->el_map.type == MAP_VI) 2331573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 2341573Srgrimes cv_delfini(el); 2351573Srgrimes return CC_REFRESH; 2361573Srgrimes } 2371573Srgrimes 2381573Srgrimes return CC_CURSOR; 2391573Srgrimes} 2401573Srgrimes 2418870Srgrimes/* vi_next_word(): 2421573Srgrimes * Vi move to the next word 2431573Srgrimes * [w] 2441573Srgrimes */ 2451573Srgrimesprotected el_action_t 2461573Srgrimes/*ARGSUSED*/ 2471573Srgrimesvi_next_word(el, c) 2481573Srgrimes EditLine *el; 2491573Srgrimes int c; 2501573Srgrimes{ 2511573Srgrimes if (el->el_line.cursor == el->el_line.lastchar) 2521573Srgrimes return CC_ERROR; 2531573Srgrimes 2548870Srgrimes el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 2558870Srgrimes el->el_line.lastchar, 2561573Srgrimes el->el_state.argument, 25737199Sbrian cv__isword); 2581573Srgrimes 2591573Srgrimes if (el->el_map.type == MAP_VI) 2601573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 2611573Srgrimes cv_delfini(el); 2621573Srgrimes return CC_REFRESH; 2631573Srgrimes } 2641573Srgrimes 2651573Srgrimes return CC_CURSOR; 2661573Srgrimes} 2671573Srgrimes 2681573Srgrimes 2691573Srgrimes 2708870Srgrimes/* vi_change_case(): 2711573Srgrimes * Vi change case of character under the cursor and advance one character 2721573Srgrimes * [~] 2731573Srgrimes */ 2741573Srgrimesprotected el_action_t 2751573Srgrimesvi_change_case(el, c) 2761573Srgrimes EditLine *el; 2771573Srgrimes int c; 2781573Srgrimes{ 2791573Srgrimes if (el->el_line.cursor < el->el_line.lastchar) { 28026982Sache c = (unsigned char)*el->el_line.cursor; 2811573Srgrimes if (isupper(c)) 2821573Srgrimes *el->el_line.cursor++ = tolower(c); 2831573Srgrimes else if (islower(c)) 2841573Srgrimes *el->el_line.cursor++ = toupper(c); 2851573Srgrimes else 2861573Srgrimes el->el_line.cursor++; 2871573Srgrimes re_fastaddc(el); 2881573Srgrimes return CC_NORM; 2891573Srgrimes } 2901573Srgrimes return CC_ERROR; 2911573Srgrimes} 2921573Srgrimes 2931573Srgrimes 2948870Srgrimes/* vi_change_meta(): 2951573Srgrimes * Vi change prefix command 2961573Srgrimes * [c] 2971573Srgrimes */ 2981573Srgrimesprotected el_action_t 2991573Srgrimes/*ARGSUSED*/ 3001573Srgrimesvi_change_meta(el, c) 3011573Srgrimes EditLine *el; 3021573Srgrimes int c; 3031573Srgrimes{ 3041573Srgrimes /* 3051573Srgrimes * Delete with insert == change: first we delete and then we leave in 3061573Srgrimes * insert mode. 3071573Srgrimes */ 3081573Srgrimes return cv_action(el, DELETE|INSERT); 3091573Srgrimes} 3101573Srgrimes 3111573Srgrimes 3128870Srgrimes/* vi_insert_at_bol(): 3131573Srgrimes * Vi enter insert mode at the beginning of line 3141573Srgrimes * [I] 3151573Srgrimes */ 3161573Srgrimesprotected el_action_t 3171573Srgrimes/*ARGSUSED*/ 3181573Srgrimesvi_insert_at_bol(el, c) 3191573Srgrimes EditLine *el; 3201573Srgrimes int c; 3211573Srgrimes{ 3221573Srgrimes el->el_line.cursor = el->el_line.buffer; 3231573Srgrimes el->el_chared.c_vcmd.ins = el->el_line.cursor; 3241573Srgrimes 3251573Srgrimes el->el_chared.c_undo.ptr = el->el_line.cursor; 3261573Srgrimes el->el_chared.c_undo.action = DELETE; 3271573Srgrimes 3281573Srgrimes el->el_map.current = el->el_map.key; 3291573Srgrimes return CC_CURSOR; 3301573Srgrimes} 3311573Srgrimes 3321573Srgrimes 3338870Srgrimes/* vi_replace_char(): 3341573Srgrimes * Vi replace character under the cursor with the next character typed 3351573Srgrimes * [r] 3361573Srgrimes */ 3371573Srgrimesprotected el_action_t 3381573Srgrimes/*ARGSUSED*/ 3391573Srgrimesvi_replace_char(el, c) 3401573Srgrimes EditLine *el; 3411573Srgrimes int c; 3421573Srgrimes{ 3431573Srgrimes el->el_map.current = el->el_map.key; 3441573Srgrimes el->el_state.inputmode = MODE_REPLACE_1; 3451573Srgrimes el->el_chared.c_undo.action = CHANGE; 3461573Srgrimes el->el_chared.c_undo.ptr = el->el_line.cursor; 3471573Srgrimes el->el_chared.c_undo.isize = 0; 3481573Srgrimes el->el_chared.c_undo.dsize = 0; 34937199Sbrian return CC_ARGHACK; 3501573Srgrimes} 3511573Srgrimes 3521573Srgrimes 3538870Srgrimes/* vi_replace_mode(): 3541573Srgrimes * Vi enter replace mode 3551573Srgrimes * [R] 3561573Srgrimes */ 3571573Srgrimesprotected el_action_t 3581573Srgrimes/*ARGSUSED*/ 3591573Srgrimesvi_replace_mode(el, c) 3601573Srgrimes EditLine *el; 3611573Srgrimes int c; 3621573Srgrimes{ 3631573Srgrimes el->el_map.current = el->el_map.key; 3641573Srgrimes el->el_state.inputmode = MODE_REPLACE; 3651573Srgrimes el->el_chared.c_undo.action = CHANGE; 3661573Srgrimes el->el_chared.c_undo.ptr = el->el_line.cursor; 3671573Srgrimes el->el_chared.c_undo.isize = 0; 3681573Srgrimes el->el_chared.c_undo.dsize = 0; 36937199Sbrian return CC_ARGHACK; 3701573Srgrimes} 3711573Srgrimes 3721573Srgrimes 3738870Srgrimes/* vi_substitute_char(): 3741573Srgrimes * Vi replace character under the cursor and enter insert mode 37537199Sbrian * [s] 3761573Srgrimes */ 3771573Srgrimesprotected el_action_t 3781573Srgrimes/*ARGSUSED*/ 3791573Srgrimesvi_substitute_char(el, c) 3801573Srgrimes EditLine *el; 3811573Srgrimes int c; 3821573Srgrimes{ 3831573Srgrimes c_delafter(el, el->el_state.argument); 3841573Srgrimes el->el_map.current = el->el_map.key; 3851573Srgrimes return CC_REFRESH; 3861573Srgrimes} 3871573Srgrimes 3881573Srgrimes 3898870Srgrimes/* vi_substitute_line(): 3901573Srgrimes * Vi substitute entire line 3911573Srgrimes * [S] 3921573Srgrimes */ 3931573Srgrimesprotected el_action_t 3941573Srgrimes/*ARGSUSED*/ 3951573Srgrimesvi_substitute_line(el, c) 3961573Srgrimes EditLine *el; 3971573Srgrimes int c; 3981573Srgrimes{ 3991573Srgrimes (void) em_kill_line(el, 0); 4001573Srgrimes el->el_map.current = el->el_map.key; 4011573Srgrimes return CC_REFRESH; 4021573Srgrimes} 4031573Srgrimes 4041573Srgrimes 4058870Srgrimes/* vi_change_to_eol(): 4061573Srgrimes * Vi change to end of line 4071573Srgrimes * [C] 4081573Srgrimes */ 4091573Srgrimesprotected el_action_t 4101573Srgrimes/*ARGSUSED*/ 4111573Srgrimesvi_change_to_eol(el, c) 4121573Srgrimes EditLine *el; 4131573Srgrimes int c; 4141573Srgrimes{ 4151573Srgrimes (void) ed_kill_line(el, 0); 4161573Srgrimes el->el_map.current = el->el_map.key; 4171573Srgrimes return CC_REFRESH; 4181573Srgrimes} 4191573Srgrimes 4201573Srgrimes 4211573Srgrimes/* vi_insert(): 4221573Srgrimes * Vi enter insert mode 4231573Srgrimes * [i] 4241573Srgrimes */ 4251573Srgrimesprotected el_action_t 4261573Srgrimes/*ARGSUSED*/ 4271573Srgrimesvi_insert(el, c) 4281573Srgrimes EditLine *el; 4291573Srgrimes int c; 4301573Srgrimes{ 4311573Srgrimes el->el_map.current = el->el_map.key; 4321573Srgrimes 4331573Srgrimes el->el_chared.c_vcmd.ins = el->el_line.cursor; 4341573Srgrimes el->el_chared.c_undo.ptr = el->el_line.cursor; 4351573Srgrimes el->el_chared.c_undo.action = DELETE; 4361573Srgrimes 4371573Srgrimes return CC_NORM; 4381573Srgrimes} 4391573Srgrimes 4401573Srgrimes 4411573Srgrimes/* vi_add(): 4428870Srgrimes * Vi enter insert mode after the cursor 4431573Srgrimes * [a] 4441573Srgrimes */ 4451573Srgrimesprotected el_action_t 4461573Srgrimes/*ARGSUSED*/ 4471573Srgrimesvi_add(el, c) 4481573Srgrimes EditLine *el; 4491573Srgrimes int c; 4501573Srgrimes{ 45137199Sbrian el_action_t ret; 45237199Sbrian 4531573Srgrimes el->el_map.current = el->el_map.key; 4541573Srgrimes if (el->el_line.cursor < el->el_line.lastchar) { 4551573Srgrimes el->el_line.cursor++; 4561573Srgrimes if (el->el_line.cursor > el->el_line.lastchar) 4571573Srgrimes el->el_line.cursor = el->el_line.lastchar; 4581573Srgrimes ret = CC_CURSOR; 4591573Srgrimes } 4601573Srgrimes else 4611573Srgrimes ret = CC_NORM; 4621573Srgrimes 4631573Srgrimes el->el_chared.c_vcmd.ins = el->el_line.cursor; 4641573Srgrimes el->el_chared.c_undo.ptr = el->el_line.cursor; 4651573Srgrimes el->el_chared.c_undo.action = DELETE; 4661573Srgrimes 4671573Srgrimes return ret; 4681573Srgrimes} 4691573Srgrimes 4701573Srgrimes 4711573Srgrimes/* vi_add_at_eol(): 4721573Srgrimes * Vi enter insert mode at end of line 4731573Srgrimes * [A] 4741573Srgrimes */ 4751573Srgrimesprotected el_action_t 4761573Srgrimes/*ARGSUSED*/ 4771573Srgrimesvi_add_at_eol(el, c) 4781573Srgrimes EditLine *el; 4791573Srgrimes int c; 4801573Srgrimes{ 4811573Srgrimes el->el_map.current = el->el_map.key; 4821573Srgrimes el->el_line.cursor = el->el_line.lastchar; 4831573Srgrimes 4841573Srgrimes /* Mark where insertion begins */ 4858870Srgrimes el->el_chared.c_vcmd.ins = el->el_line.lastchar; 4861573Srgrimes el->el_chared.c_undo.ptr = el->el_line.lastchar; 4871573Srgrimes el->el_chared.c_undo.action = DELETE; 4881573Srgrimes return CC_CURSOR; 4891573Srgrimes} 4901573Srgrimes 4911573Srgrimes 4921573Srgrimes/* vi_delete_meta(): 4938870Srgrimes * Vi delete prefix command 4941573Srgrimes * [d] 4951573Srgrimes */ 4961573Srgrimesprotected el_action_t 4971573Srgrimes/*ARGSUSED*/ 4981573Srgrimesvi_delete_meta(el, c) 4991573Srgrimes EditLine *el; 5001573Srgrimes int c; 5011573Srgrimes{ 5021573Srgrimes return cv_action(el, DELETE); 5031573Srgrimes} 5041573Srgrimes 5051573Srgrimes 5061573Srgrimes/* vi_end_word(): 5078870Srgrimes * Vi move to the end of the current space delimited word 5088870Srgrimes * [E] 5091573Srgrimes */ 5101573Srgrimesprotected el_action_t 5111573Srgrimes/*ARGSUSED*/ 5121573Srgrimesvi_end_word(el, c) 5131573Srgrimes EditLine *el; 5141573Srgrimes int c; 5151573Srgrimes{ 5161573Srgrimes if (el->el_line.cursor == el->el_line.lastchar) 5171573Srgrimes return CC_ERROR; 5181573Srgrimes 5198870Srgrimes el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, 5201573Srgrimes el->el_state.argument); 5211573Srgrimes 5221573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 5231573Srgrimes el->el_line.cursor++; 5241573Srgrimes cv_delfini(el); 5251573Srgrimes return CC_REFRESH; 5261573Srgrimes } 5271573Srgrimes 5281573Srgrimes return CC_CURSOR; 5291573Srgrimes} 5301573Srgrimes 5311573Srgrimes 5321573Srgrimes/* vi_to_end_word(): 5331573Srgrimes * Vi move to the end of the current word 5341573Srgrimes * [e] 5351573Srgrimes */ 5361573Srgrimesprotected el_action_t 5371573Srgrimes/*ARGSUSED*/ 5381573Srgrimesvi_to_end_word(el, c) 5391573Srgrimes EditLine *el; 5401573Srgrimes int c; 5411573Srgrimes{ 5421573Srgrimes if (el->el_line.cursor == el->el_line.lastchar) 5431573Srgrimes return CC_ERROR; 5441573Srgrimes 5458870Srgrimes el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, 5461573Srgrimes el->el_state.argument); 5471573Srgrimes 5481573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 5491573Srgrimes el->el_line.cursor++; 5501573Srgrimes cv_delfini(el); 5511573Srgrimes return CC_REFRESH; 5521573Srgrimes } 5531573Srgrimes 5541573Srgrimes return CC_CURSOR; 5551573Srgrimes} 5561573Srgrimes 5571573Srgrimes 5581573Srgrimes/* vi_undo(): 5591573Srgrimes * Vi undo last change 5601573Srgrimes * [u] 5611573Srgrimes */ 5621573Srgrimesprotected el_action_t 5631573Srgrimes/*ARGSUSED*/ 5641573Srgrimesvi_undo(el, c) 5651573Srgrimes EditLine *el; 5661573Srgrimes int c; 5671573Srgrimes{ 5681573Srgrimes char *cp, *kp; 5691573Srgrimes char temp; 5701573Srgrimes int i, size; 5711573Srgrimes c_undo_t *un = &el->el_chared.c_undo; 5721573Srgrimes 5731573Srgrimes#ifdef DEBUG_UNDO 5748870Srgrimes (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n", 5751573Srgrimes un->action, un->buf, un->isize, un->dsize); 5761573Srgrimes#endif 5771573Srgrimes switch (un->action) { 5781573Srgrimes case DELETE: 5798870Srgrimes if (un->dsize == 0) 5801573Srgrimes return CC_NORM; 5811573Srgrimes 5821573Srgrimes (void) memcpy(un->buf, un->ptr, un->dsize); 5831573Srgrimes for (cp = un->ptr; cp <= el->el_line.lastchar; cp++) 5841573Srgrimes *cp = cp[un->dsize]; 5851573Srgrimes 5861573Srgrimes el->el_line.lastchar -= un->dsize; 5871573Srgrimes el->el_line.cursor = un->ptr; 5888870Srgrimes 5891573Srgrimes un->action = INSERT; 5901573Srgrimes un->isize = un->dsize; 5911573Srgrimes un->dsize = 0; 5921573Srgrimes break; 5931573Srgrimes 5941573Srgrimes case DELETE|INSERT: 5951573Srgrimes size = un->isize - un->dsize; 5968870Srgrimes if (size > 0) 5971573Srgrimes i = un->dsize; 5988870Srgrimes else 5991573Srgrimes i = un->isize; 6001573Srgrimes cp = un->ptr; 6011573Srgrimes kp = un->buf; 6021573Srgrimes while (i-- > 0) { 6031573Srgrimes temp = *kp; 6041573Srgrimes *kp++ = *cp; 6051573Srgrimes *cp++ = temp; 6061573Srgrimes } 6071573Srgrimes if (size > 0) { 6081573Srgrimes el->el_line.cursor = cp; 6091573Srgrimes c_insert(el, size); 6101573Srgrimes while (size-- > 0 && cp < el->el_line.lastchar) { 6111573Srgrimes temp = *kp; 6121573Srgrimes *kp++ = *cp; 6131573Srgrimes *cp++ = temp; 6141573Srgrimes } 6151573Srgrimes } 6161573Srgrimes else if (size < 0) { 6171573Srgrimes size = -size; 6181573Srgrimes for (; cp <= el->el_line.lastchar; cp++) { 6191573Srgrimes *kp++ = *cp; 6201573Srgrimes *cp = cp[size]; 6211573Srgrimes } 6221573Srgrimes el->el_line.lastchar -= size; 6231573Srgrimes } 6241573Srgrimes el->el_line.cursor = un->ptr; 6251573Srgrimes i = un->dsize; 6261573Srgrimes un->dsize = un->isize; 6271573Srgrimes un->isize = i; 6281573Srgrimes break; 6291573Srgrimes 6301573Srgrimes case INSERT: 6318870Srgrimes if (un->isize == 0) 6321573Srgrimes return CC_NORM; 6331573Srgrimes 6341573Srgrimes el->el_line.cursor = un->ptr; 6351573Srgrimes c_insert(el, un->isize); 6361573Srgrimes memcpy(un->ptr, un->buf, un->isize); 6371573Srgrimes un->action = DELETE; 6381573Srgrimes un->dsize = un->isize; 6391573Srgrimes un->isize = 0; 6401573Srgrimes break; 6411573Srgrimes 6421573Srgrimes case CHANGE: 6438870Srgrimes if (un->isize == 0) 6441573Srgrimes return CC_NORM; 6451573Srgrimes 6461573Srgrimes el->el_line.cursor = un->ptr; 6478870Srgrimes size = (int) (el->el_line.cursor - el->el_line.lastchar); 6481573Srgrimes if (size < un->isize) 6491573Srgrimes size = un->isize; 6501573Srgrimes cp = un->ptr; 6511573Srgrimes kp = un->buf; 6521573Srgrimes for(i = 0; i < size; i++) { 6531573Srgrimes temp = *kp; 6541573Srgrimes *kp++ = *cp; 6551573Srgrimes *cp++ = temp; 6561573Srgrimes } 6571573Srgrimes un->dsize = 0; 6581573Srgrimes break; 6591573Srgrimes 6601573Srgrimes default: 6611573Srgrimes return CC_ERROR; 6621573Srgrimes } 6631573Srgrimes 6641573Srgrimes return CC_REFRESH; 6651573Srgrimes} 6661573Srgrimes 6671573Srgrimes 66837199Sbrian/* vi_undo_line(): 66937199Sbrian * Vi undo all changes 67037199Sbrian * [U] 67137199Sbrian */ 67237199Sbrianprotected el_action_t 67337199Sbrian/*ARGSUSED*/ 67437199Sbrianvi_undo_line(el, c) 67537199Sbrian EditLine *el; 67637199Sbrian int c; 67737199Sbrian{ 67837199Sbrian 67937199Sbrian return hist_get(el); 68037199Sbrian} 68137199Sbrian 68237199Sbrian 6831573Srgrimes/* vi_command_mode(): 6841573Srgrimes * Vi enter command mode (use alternative key bindings) 6851573Srgrimes * [<ESC>] 6861573Srgrimes */ 6871573Srgrimesprotected el_action_t 6881573Srgrimes/*ARGSUSED*/ 6891573Srgrimesvi_command_mode(el, c) 6901573Srgrimes EditLine *el; 6911573Srgrimes int c; 6921573Srgrimes{ 6931573Srgrimes int size; 6941573Srgrimes /* [Esc] cancels pending action */ 6951573Srgrimes el->el_chared.c_vcmd.ins = 0; 6968870Srgrimes el->el_chared.c_vcmd.action = NOP; 6971573Srgrimes el->el_chared.c_vcmd.pos = 0; 6981573Srgrimes 6991573Srgrimes el->el_state.doingarg = 0; 7001573Srgrimes size = el->el_chared.c_undo.ptr - el->el_line.cursor; 7011573Srgrimes if (size < 0) 7021573Srgrimes size = -size; 7031573Srgrimes if (el->el_chared.c_undo.action == (INSERT|DELETE) || 7041573Srgrimes el->el_chared.c_undo.action == DELETE) 7051573Srgrimes el->el_chared.c_undo.dsize = size; 7061573Srgrimes else 7071573Srgrimes el->el_chared.c_undo.isize = size; 7081573Srgrimes 7091573Srgrimes el->el_state.inputmode = MODE_INSERT; 7101573Srgrimes el->el_map.current = el->el_map.alt; 7111573Srgrimes#ifdef VI_MOVE 7121573Srgrimes if (el->el_line.cursor > el->el_line.buffer) 7131573Srgrimes el->el_line.cursor--; 7141573Srgrimes#endif 7151573Srgrimes return CC_CURSOR; 7161573Srgrimes} 7171573Srgrimes 7181573Srgrimes/* vi_zero(): 7198870Srgrimes * Vi move to the beginning of line 7201573Srgrimes * [0] 7211573Srgrimes */ 7221573Srgrimesprotected el_action_t 7231573Srgrimesvi_zero(el, c) 7241573Srgrimes EditLine *el; 7251573Srgrimes int c; 7261573Srgrimes{ 7271573Srgrimes if (el->el_state.doingarg) { 7281573Srgrimes if (el->el_state.argument > 1000000) 7291573Srgrimes return CC_ERROR; 7308870Srgrimes el->el_state.argument = 7311573Srgrimes (el->el_state.argument * 10) + (c - '0'); 7321573Srgrimes return CC_ARGHACK; 7331573Srgrimes } 7341573Srgrimes else { 7351573Srgrimes el->el_line.cursor = el->el_line.buffer; 7361573Srgrimes if (el->el_chared.c_vcmd.action & DELETE) { 7371573Srgrimes cv_delfini(el); 7381573Srgrimes return CC_REFRESH; 7391573Srgrimes } 7401573Srgrimes return CC_CURSOR; 7411573Srgrimes } 7421573Srgrimes} 7431573Srgrimes 7441573Srgrimes 7451573Srgrimes/* vi_delete_prev_char(): 7468870Srgrimes * Vi move to previous character (backspace) 7471573Srgrimes * [^H] 7488870Srgrimes */ 7491573Srgrimesprotected el_action_t 7501573Srgrimes/*ARGSUSED*/ 7511573Srgrimesvi_delete_prev_char(el, c) 7521573Srgrimes EditLine *el; 7531573Srgrimes int c; 7541573Srgrimes{ 7558870Srgrimes if (el->el_chared.c_vcmd.ins == 0) 7561573Srgrimes return CC_ERROR; 7571573Srgrimes 7588870Srgrimes if (el->el_chared.c_vcmd.ins > 7591573Srgrimes el->el_line.cursor - el->el_state.argument) 7601573Srgrimes return CC_ERROR; 7611573Srgrimes 7628870Srgrimes c_delbefore(el, el->el_state.argument); 7631573Srgrimes el->el_line.cursor -= el->el_state.argument; 7641573Srgrimes 7651573Srgrimes return CC_REFRESH; 7661573Srgrimes} /* end v_del_char_prev */ 7671573Srgrimes 7681573Srgrimes 7691573Srgrimes/* vi_list_or_eof(): 7701573Srgrimes * Vi list choices for completion or indicate end of file if empty line 7711573Srgrimes * [^D] 7721573Srgrimes */ 7731573Srgrimesprotected el_action_t 7741573Srgrimes/*ARGSUSED*/ 7751573Srgrimesvi_list_or_eof(el, c) 7761573Srgrimes EditLine *el; 7771573Srgrimes int c; 7781573Srgrimes{ 7791573Srgrimes#ifdef notyet 7808870Srgrimes if (el->el_line.cursor == el->el_line.lastchar && 7811573Srgrimes el->el_line.cursor == el->el_line.buffer) { 7821573Srgrimes#endif 7831573Srgrimes term_overwrite(el, STReof, 4); /* then do a EOF */ 7841573Srgrimes term__flush(); 7851573Srgrimes return CC_EOF; 7861573Srgrimes#ifdef notyet 7871573Srgrimes } 7881573Srgrimes else { 7891573Srgrimes re_goto_bottom(el); 7901573Srgrimes *el->el_line.lastchar = '\0'; /* just in case */ 7911573Srgrimes return CC_LIST_CHOICES; 7921573Srgrimes } 7931573Srgrimes#endif 7941573Srgrimes} 7951573Srgrimes 7961573Srgrimes 7971573Srgrimes/* vi_kill_line_prev(): 7988870Srgrimes * Vi cut from beginning of line to cursor 7991573Srgrimes * [^U] 8001573Srgrimes */ 8011573Srgrimesprotected el_action_t 8021573Srgrimes/*ARGSUSED*/ 8031573Srgrimesvi_kill_line_prev(el, c) 8041573Srgrimes EditLine *el; 8051573Srgrimes int c; 8061573Srgrimes{ 8071573Srgrimes char *kp, *cp; 8081573Srgrimes 8091573Srgrimes cp = el->el_line.buffer; 8101573Srgrimes kp = el->el_chared.c_kill.buf; 8111573Srgrimes while (cp < el->el_line.cursor) 8121573Srgrimes *kp++ = *cp++; /* copy it */ 8131573Srgrimes el->el_chared.c_kill.last = kp; 8141573Srgrimes c_delbefore(el, el->el_line.cursor - el->el_line.buffer); 8151573Srgrimes el->el_line.cursor = el->el_line.buffer; /* zap! */ 8161573Srgrimes return CC_REFRESH; 8171573Srgrimes} 8181573Srgrimes 8191573Srgrimes 8201573Srgrimes/* vi_search_prev(): 8211573Srgrimes * Vi search history previous 8221573Srgrimes * [?] 8231573Srgrimes */ 8241573Srgrimesprotected el_action_t 8251573Srgrimes/*ARGSUSED*/ 8261573Srgrimesvi_search_prev(el, c) 8271573Srgrimes EditLine *el; 8281573Srgrimes int c; 8291573Srgrimes{ 8301573Srgrimes return cv_search(el, ED_SEARCH_PREV_HISTORY); 8311573Srgrimes} 8321573Srgrimes 8331573Srgrimes 8341573Srgrimes/* vi_search_next(): 8351573Srgrimes * Vi search history next 8361573Srgrimes * [/] 8371573Srgrimes */ 8381573Srgrimesprotected el_action_t 8391573Srgrimes/*ARGSUSED*/ 8401573Srgrimesvi_search_next(el, c) 8411573Srgrimes EditLine *el; 8421573Srgrimes int c; 8431573Srgrimes{ 8441573Srgrimes return cv_search(el, ED_SEARCH_NEXT_HISTORY); 8451573Srgrimes} 8461573Srgrimes 8471573Srgrimes 8481573Srgrimes/* vi_repeat_search_next(): 8491573Srgrimes * Vi repeat current search in the same search direction 8501573Srgrimes * [n] 8511573Srgrimes */ 8521573Srgrimesprotected el_action_t 8531573Srgrimes/*ARGSUSED*/ 8541573Srgrimesvi_repeat_search_next(el, c) 8551573Srgrimes EditLine *el; 8561573Srgrimes int c; 8571573Srgrimes{ 8588870Srgrimes if (el->el_search.patlen == 0) 8591573Srgrimes return CC_ERROR; 8601573Srgrimes else 8611573Srgrimes return cv_repeat_srch(el, el->el_search.patdir); 8621573Srgrimes} 8631573Srgrimes 8641573Srgrimes 8651573Srgrimes/* vi_repeat_search_prev(): 8661573Srgrimes * Vi repeat current search in the opposite search direction 8671573Srgrimes * [N] 8681573Srgrimes */ 8691573Srgrimes/*ARGSUSED*/ 8701573Srgrimesprotected el_action_t 8711573Srgrimesvi_repeat_search_prev(el, c) 8721573Srgrimes EditLine *el; 8731573Srgrimes int c; 8741573Srgrimes{ 8758870Srgrimes if (el->el_search.patlen == 0) 8761573Srgrimes return CC_ERROR; 8771573Srgrimes else 8788870Srgrimes return cv_repeat_srch(el, 8791573Srgrimes el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? 8801573Srgrimes ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY); 8811573Srgrimes} 8821573Srgrimes 8831573Srgrimes 8841573Srgrimes/* vi_next_char(): 8851573Srgrimes * Vi move to the character specified next 8861573Srgrimes * [f] 8871573Srgrimes */ 8881573Srgrimesprotected el_action_t 8891573Srgrimes/*ARGSUSED*/ 8901573Srgrimesvi_next_char(el, c) 8911573Srgrimes EditLine *el; 8921573Srgrimes int c; 8931573Srgrimes{ 8941573Srgrimes char ch; 8951573Srgrimes 8961573Srgrimes if (el_getc(el, &ch) != 1) 8971573Srgrimes return ed_end_of_file(el, 0); 8981573Srgrimes 8991573Srgrimes el->el_search.chadir = CHAR_FWD; 9001573Srgrimes el->el_search.chacha = ch; 9011573Srgrimes 9021573Srgrimes return cv_csearch_fwd(el, ch, el->el_state.argument, 0); 9031573Srgrimes 9041573Srgrimes} 9051573Srgrimes 9061573Srgrimes 9071573Srgrimes/* vi_prev_char(): 9081573Srgrimes * Vi move to the character specified previous 9091573Srgrimes * [F] 9101573Srgrimes */ 9111573Srgrimesprotected el_action_t 9121573Srgrimes/*ARGSUSED*/ 9131573Srgrimesvi_prev_char(el, c) 9141573Srgrimes EditLine *el; 9151573Srgrimes int c; 9161573Srgrimes{ 9171573Srgrimes char ch; 9181573Srgrimes 9191573Srgrimes if (el_getc(el, &ch) != 1) 9201573Srgrimes return ed_end_of_file(el, 0); 9211573Srgrimes 9221573Srgrimes el->el_search.chadir = CHAR_BACK; 9231573Srgrimes el->el_search.chacha = ch; 9241573Srgrimes 9251573Srgrimes return cv_csearch_back(el, ch, el->el_state.argument, 0); 9261573Srgrimes} 9271573Srgrimes 9281573Srgrimes 9291573Srgrimes/* vi_to_next_char(): 9301573Srgrimes * Vi move up to the character specified next 9311573Srgrimes * [t] 9321573Srgrimes */ 9331573Srgrimesprotected el_action_t 9341573Srgrimes/*ARGSUSED*/ 9351573Srgrimesvi_to_next_char(el, c) 9361573Srgrimes EditLine *el; 9371573Srgrimes int c; 9381573Srgrimes{ 9391573Srgrimes char ch; 9401573Srgrimes 9411573Srgrimes if (el_getc(el, &ch) != 1) 9421573Srgrimes return ed_end_of_file(el, 0); 9431573Srgrimes 9441573Srgrimes return cv_csearch_fwd(el, ch, el->el_state.argument, 1); 9451573Srgrimes 9461573Srgrimes} 9471573Srgrimes 9481573Srgrimes 9491573Srgrimes/* vi_to_prev_char(): 9501573Srgrimes * Vi move up to the character specified previous 9511573Srgrimes * [T] 9521573Srgrimes */ 9531573Srgrimesprotected el_action_t 9541573Srgrimes/*ARGSUSED*/ 9551573Srgrimesvi_to_prev_char(el, c) 9561573Srgrimes EditLine *el; 9571573Srgrimes int c; 9581573Srgrimes{ 9591573Srgrimes char ch; 9601573Srgrimes if (el_getc(el, &ch) != 1) 9611573Srgrimes return ed_end_of_file(el, 0); 9621573Srgrimes 9631573Srgrimes return cv_csearch_back(el, ch, el->el_state.argument, 1); 9641573Srgrimes} 9651573Srgrimes 9661573Srgrimes 9671573Srgrimes/* vi_repeat_next_char(): 9681573Srgrimes * Vi repeat current character search in the same search direction 9691573Srgrimes * [;] 9701573Srgrimes */ 9711573Srgrimesprotected el_action_t 9721573Srgrimes/*ARGSUSED*/ 9731573Srgrimesvi_repeat_next_char(el, c) 9741573Srgrimes EditLine *el; 9751573Srgrimes int c; 9761573Srgrimes{ 9771573Srgrimes if (el->el_search.chacha == 0) 9781573Srgrimes return CC_ERROR; 9791573Srgrimes 9808870Srgrimes return el->el_search.chadir == CHAR_FWD ? 9818870Srgrimes cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : 9821573Srgrimes cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); 9831573Srgrimes} 9841573Srgrimes 9851573Srgrimes 9861573Srgrimes/* vi_repeat_prev_char(): 9871573Srgrimes * Vi repeat current character search in the opposite search direction 9881573Srgrimes * [,] 9891573Srgrimes */ 9901573Srgrimesprotected el_action_t 9911573Srgrimes/*ARGSUSED*/ 9921573Srgrimesvi_repeat_prev_char(el, c) 9931573Srgrimes EditLine *el; 9941573Srgrimes int c; 9951573Srgrimes{ 9961573Srgrimes if (el->el_search.chacha == 0) 9971573Srgrimes return CC_ERROR; 9981573Srgrimes 9998870Srgrimes return el->el_search.chadir == CHAR_BACK ? 10008870Srgrimes cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : 10011573Srgrimes cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); 10021573Srgrimes} 1003