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. 16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 3184260Sobrien * 32237448Spfg * $NetBSD: vi.c,v 1.30 2009/02/21 23:31:56 christos Exp $ 331573Srgrimes */ 341573Srgrimes 351573Srgrimes#if !defined(lint) && !defined(SCCSID) 361573Srgrimesstatic char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; 371573Srgrimes#endif /* not lint && not SCCSID */ 3884260Sobrien#include <sys/cdefs.h> 3984260Sobrien__FBSDID("$FreeBSD$"); 401573Srgrimes 411573Srgrimes/* 421573Srgrimes * vi.c: Vi mode commands. 431573Srgrimes */ 44148834Sstefanf#include <sys/wait.h> 451573Srgrimes#include "sys.h" 461573Srgrimes#include "el.h" 471573Srgrimes 4884260Sobrienprivate el_action_t cv_action(EditLine *, int); 4984260Sobrienprivate el_action_t cv_paste(EditLine *, int); 501573Srgrimes 511573Srgrimes/* cv_action(): 521573Srgrimes * Handle vi actions. 531573Srgrimes */ 541573Srgrimesprivate el_action_t 5584260Sobriencv_action(EditLine *el, int c) 561573Srgrimes{ 571573Srgrimes 58148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 59148834Sstefanf /* 'cc', 'dd' and (possibly) friends */ 60148834Sstefanf if (c != el->el_chared.c_vcmd.action) 61148834Sstefanf return CC_ERROR; 62148834Sstefanf 63148834Sstefanf if (!(c & YANK)) 64148834Sstefanf cv_undo(el); 65148834Sstefanf cv_yank(el, el->el_line.buffer, 66237448Spfg (int)(el->el_line.lastchar - el->el_line.buffer)); 6784260Sobrien el->el_chared.c_vcmd.action = NOP; 6884260Sobrien el->el_chared.c_vcmd.pos = 0; 69148923Sstefanf if (!(c & YANK)) { 70148923Sstefanf el->el_line.lastchar = el->el_line.buffer; 71148923Sstefanf el->el_line.cursor = el->el_line.buffer; 72148923Sstefanf } 7384260Sobrien if (c & INSERT) 7484260Sobrien el->el_map.current = el->el_map.key; 758870Srgrimes 7684260Sobrien return (CC_REFRESH); 7784260Sobrien } 7884260Sobrien el->el_chared.c_vcmd.pos = el->el_line.cursor; 7984260Sobrien el->el_chared.c_vcmd.action = c; 8084260Sobrien return (CC_ARGHACK); 811573Srgrimes} 821573Srgrimes 831573Srgrimes/* cv_paste(): 841573Srgrimes * Paste previous deletion before or after the cursor 851573Srgrimes */ 8684260Sobrienprivate el_action_t 8784260Sobriencv_paste(EditLine *el, int c) 881573Srgrimes{ 89148834Sstefanf c_kill_t *k = &el->el_chared.c_kill; 90237448Spfg size_t len = (size_t)(k->last - k->buf); 9184260Sobrien 92148834Sstefanf if (k->buf == NULL || len == 0) 93148834Sstefanf return (CC_ERROR); 941573Srgrimes#ifdef DEBUG_PASTE 95237448Spfg (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf); 961573Srgrimes#endif 971573Srgrimes 98148834Sstefanf cv_undo(el); 99148834Sstefanf 10084260Sobrien if (!c && el->el_line.cursor < el->el_line.lastchar) 10184260Sobrien el->el_line.cursor++; 1028870Srgrimes 103237448Spfg c_insert(el, (int)len); 104148834Sstefanf if (el->el_line.cursor + len > el->el_line.lastchar) 10584260Sobrien return (CC_ERROR); 106237448Spfg (void) memcpy(el->el_line.cursor, k->buf, len); 107148923Sstefanf 10884260Sobrien return (CC_REFRESH); 1091573Srgrimes} 1101573Srgrimes 1111573Srgrimes 1128870Srgrimes/* vi_paste_next(): 1131573Srgrimes * Vi paste previous deletion to the right of the cursor 1141573Srgrimes * [p] 1151573Srgrimes */ 1161573Srgrimesprotected el_action_t 1171573Srgrimes/*ARGSUSED*/ 118148834Sstefanfvi_paste_next(EditLine *el, int c __unused) 1191573Srgrimes{ 12084260Sobrien 12184260Sobrien return (cv_paste(el, 0)); 1221573Srgrimes} 1231573Srgrimes 1241573Srgrimes 1258870Srgrimes/* vi_paste_prev(): 1261573Srgrimes * Vi paste previous deletion to the left of the cursor 1271573Srgrimes * [P] 1281573Srgrimes */ 1291573Srgrimesprotected el_action_t 1301573Srgrimes/*ARGSUSED*/ 131148834Sstefanfvi_paste_prev(EditLine *el, int c __unused) 1321573Srgrimes{ 13384260Sobrien 13484260Sobrien return (cv_paste(el, 1)); 1351573Srgrimes} 1361573Srgrimes 1371573Srgrimes 138148834Sstefanf/* vi_prev_big_word(): 1391573Srgrimes * Vi move to the previous space delimited word 1401573Srgrimes * [B] 1411573Srgrimes */ 1421573Srgrimesprotected el_action_t 1431573Srgrimes/*ARGSUSED*/ 144148834Sstefanfvi_prev_big_word(EditLine *el, int c) 1451573Srgrimes{ 1461573Srgrimes 14784260Sobrien if (el->el_line.cursor == el->el_line.buffer) 14884260Sobrien return (CC_ERROR); 1491573Srgrimes 150148834Sstefanf el->el_line.cursor = cv_prev_word(el->el_line.cursor, 15184260Sobrien el->el_line.buffer, 15284260Sobrien el->el_state.argument, 153148834Sstefanf cv__isWord); 1541573Srgrimes 155148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 15684260Sobrien cv_delfini(el); 15784260Sobrien return (CC_REFRESH); 15884260Sobrien } 15984260Sobrien return (CC_CURSOR); 1601573Srgrimes} 1611573Srgrimes 1621573Srgrimes 1638870Srgrimes/* vi_prev_word(): 1641573Srgrimes * Vi move to the previous word 16537199Sbrian * [b] 1661573Srgrimes */ 1671573Srgrimesprotected el_action_t 1681573Srgrimes/*ARGSUSED*/ 169148834Sstefanfvi_prev_word(EditLine *el, int c __unused) 1701573Srgrimes{ 1711573Srgrimes 17284260Sobrien if (el->el_line.cursor == el->el_line.buffer) 17384260Sobrien return (CC_ERROR); 1741573Srgrimes 175148834Sstefanf el->el_line.cursor = cv_prev_word(el->el_line.cursor, 17684260Sobrien el->el_line.buffer, 17784260Sobrien el->el_state.argument, 17884260Sobrien cv__isword); 1791573Srgrimes 180148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 18184260Sobrien cv_delfini(el); 18284260Sobrien return (CC_REFRESH); 18384260Sobrien } 18484260Sobrien return (CC_CURSOR); 1851573Srgrimes} 1861573Srgrimes 1871573Srgrimes 188148834Sstefanf/* vi_next_big_word(): 1891573Srgrimes * Vi move to the next space delimited word 1901573Srgrimes * [W] 1911573Srgrimes */ 1921573Srgrimesprotected el_action_t 1931573Srgrimes/*ARGSUSED*/ 194148834Sstefanfvi_next_big_word(EditLine *el, int c) 1951573Srgrimes{ 1961573Srgrimes 197148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar - 1) 19884260Sobrien return (CC_ERROR); 1991573Srgrimes 20084260Sobrien el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 201148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isWord); 2021573Srgrimes 20384260Sobrien if (el->el_map.type == MAP_VI) 204148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 20584260Sobrien cv_delfini(el); 20684260Sobrien return (CC_REFRESH); 20784260Sobrien } 20884260Sobrien return (CC_CURSOR); 2091573Srgrimes} 2101573Srgrimes 21184260Sobrien 2128870Srgrimes/* vi_next_word(): 2131573Srgrimes * Vi move to the next word 2141573Srgrimes * [w] 2151573Srgrimes */ 2161573Srgrimesprotected el_action_t 2171573Srgrimes/*ARGSUSED*/ 218148834Sstefanfvi_next_word(EditLine *el, int c __unused) 2191573Srgrimes{ 2201573Srgrimes 221148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar - 1) 22284260Sobrien return (CC_ERROR); 2231573Srgrimes 22484260Sobrien el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 225148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isword); 2261573Srgrimes 22784260Sobrien if (el->el_map.type == MAP_VI) 228148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 22984260Sobrien cv_delfini(el); 23084260Sobrien return (CC_REFRESH); 23184260Sobrien } 23284260Sobrien return (CC_CURSOR); 2331573Srgrimes} 2341573Srgrimes 2351573Srgrimes 2368870Srgrimes/* vi_change_case(): 2371573Srgrimes * Vi change case of character under the cursor and advance one character 2381573Srgrimes * [~] 2391573Srgrimes */ 2401573Srgrimesprotected el_action_t 24184260Sobrienvi_change_case(EditLine *el, int c) 2421573Srgrimes{ 243148834Sstefanf int i; 24484260Sobrien 245148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar) 246148834Sstefanf return (CC_ERROR); 247148834Sstefanf cv_undo(el); 248148834Sstefanf for (i = 0; i < el->el_state.argument; i++) { 249148834Sstefanf 250148834Sstefanf c = *(unsigned char *)el->el_line.cursor; 25184260Sobrien if (isupper(c)) 252148834Sstefanf *el->el_line.cursor = tolower(c); 25384260Sobrien else if (islower(c)) 254148834Sstefanf *el->el_line.cursor = toupper(c); 255148834Sstefanf 256148834Sstefanf if (++el->el_line.cursor >= el->el_line.lastchar) { 257148834Sstefanf el->el_line.cursor--; 258148834Sstefanf re_fastaddc(el); 259148834Sstefanf break; 260148834Sstefanf } 26184260Sobrien re_fastaddc(el); 26284260Sobrien } 263148834Sstefanf return CC_NORM; 2641573Srgrimes} 2651573Srgrimes 2661573Srgrimes 2678870Srgrimes/* vi_change_meta(): 2681573Srgrimes * Vi change prefix command 2691573Srgrimes * [c] 2701573Srgrimes */ 2711573Srgrimesprotected el_action_t 2721573Srgrimes/*ARGSUSED*/ 273148834Sstefanfvi_change_meta(EditLine *el, int c __unused) 2741573Srgrimes{ 27584260Sobrien 27684260Sobrien /* 27784260Sobrien * Delete with insert == change: first we delete and then we leave in 27884260Sobrien * insert mode. 27984260Sobrien */ 28084260Sobrien return (cv_action(el, DELETE | INSERT)); 2811573Srgrimes} 2821573Srgrimes 2831573Srgrimes 2848870Srgrimes/* vi_insert_at_bol(): 2851573Srgrimes * Vi enter insert mode at the beginning of line 2861573Srgrimes * [I] 2871573Srgrimes */ 2881573Srgrimesprotected el_action_t 2891573Srgrimes/*ARGSUSED*/ 290148834Sstefanfvi_insert_at_bol(EditLine *el, int c __unused) 2911573Srgrimes{ 2921573Srgrimes 29384260Sobrien el->el_line.cursor = el->el_line.buffer; 294148834Sstefanf cv_undo(el); 29584260Sobrien el->el_map.current = el->el_map.key; 29684260Sobrien return (CC_CURSOR); 2971573Srgrimes} 2981573Srgrimes 2991573Srgrimes 3008870Srgrimes/* vi_replace_char(): 3011573Srgrimes * Vi replace character under the cursor with the next character typed 3021573Srgrimes * [r] 3031573Srgrimes */ 3041573Srgrimesprotected el_action_t 3051573Srgrimes/*ARGSUSED*/ 306148834Sstefanfvi_replace_char(EditLine *el, int c __unused) 3071573Srgrimes{ 30884260Sobrien 309148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar) 310148834Sstefanf return CC_ERROR; 311148834Sstefanf 31284260Sobrien el->el_map.current = el->el_map.key; 31384260Sobrien el->el_state.inputmode = MODE_REPLACE_1; 314148834Sstefanf cv_undo(el); 31584260Sobrien return (CC_ARGHACK); 3161573Srgrimes} 3171573Srgrimes 3181573Srgrimes 3198870Srgrimes/* vi_replace_mode(): 3201573Srgrimes * Vi enter replace mode 3211573Srgrimes * [R] 3221573Srgrimes */ 3231573Srgrimesprotected el_action_t 3241573Srgrimes/*ARGSUSED*/ 325148834Sstefanfvi_replace_mode(EditLine *el, int c __unused) 3261573Srgrimes{ 32784260Sobrien 32884260Sobrien el->el_map.current = el->el_map.key; 32984260Sobrien el->el_state.inputmode = MODE_REPLACE; 330148834Sstefanf cv_undo(el); 331148834Sstefanf return (CC_NORM); 3321573Srgrimes} 3331573Srgrimes 3341573Srgrimes 3358870Srgrimes/* vi_substitute_char(): 3361573Srgrimes * Vi replace character under the cursor and enter insert mode 33737199Sbrian * [s] 3381573Srgrimes */ 3391573Srgrimesprotected el_action_t 3401573Srgrimes/*ARGSUSED*/ 341148834Sstefanfvi_substitute_char(EditLine *el, int c __unused) 3421573Srgrimes{ 34384260Sobrien 34484260Sobrien c_delafter(el, el->el_state.argument); 34584260Sobrien el->el_map.current = el->el_map.key; 34684260Sobrien return (CC_REFRESH); 3471573Srgrimes} 3481573Srgrimes 3491573Srgrimes 3508870Srgrimes/* vi_substitute_line(): 3511573Srgrimes * Vi substitute entire line 3521573Srgrimes * [S] 3531573Srgrimes */ 3541573Srgrimesprotected el_action_t 3551573Srgrimes/*ARGSUSED*/ 356148834Sstefanfvi_substitute_line(EditLine *el, int c __unused) 3571573Srgrimes{ 35884260Sobrien 359148834Sstefanf cv_undo(el); 360148834Sstefanf cv_yank(el, el->el_line.buffer, 361237448Spfg (int)(el->el_line.lastchar - el->el_line.buffer)); 36284260Sobrien (void) em_kill_line(el, 0); 36384260Sobrien el->el_map.current = el->el_map.key; 36484260Sobrien return (CC_REFRESH); 3651573Srgrimes} 3661573Srgrimes 3671573Srgrimes 3688870Srgrimes/* vi_change_to_eol(): 3691573Srgrimes * Vi change to end of line 3701573Srgrimes * [C] 3711573Srgrimes */ 3721573Srgrimesprotected el_action_t 3731573Srgrimes/*ARGSUSED*/ 374148834Sstefanfvi_change_to_eol(EditLine *el, int c __unused) 3751573Srgrimes{ 37684260Sobrien 377148834Sstefanf cv_undo(el); 378148834Sstefanf cv_yank(el, el->el_line.cursor, 379237448Spfg (int)(el->el_line.lastchar - el->el_line.cursor)); 38084260Sobrien (void) ed_kill_line(el, 0); 38184260Sobrien el->el_map.current = el->el_map.key; 38284260Sobrien return (CC_REFRESH); 3831573Srgrimes} 3841573Srgrimes 3851573Srgrimes 3861573Srgrimes/* vi_insert(): 3871573Srgrimes * Vi enter insert mode 3881573Srgrimes * [i] 3891573Srgrimes */ 3901573Srgrimesprotected el_action_t 3911573Srgrimes/*ARGSUSED*/ 392148834Sstefanfvi_insert(EditLine *el, int c __unused) 3931573Srgrimes{ 3941573Srgrimes 39584260Sobrien el->el_map.current = el->el_map.key; 396148834Sstefanf cv_undo(el); 39784260Sobrien return (CC_NORM); 3981573Srgrimes} 3991573Srgrimes 4001573Srgrimes 4011573Srgrimes/* vi_add(): 4028870Srgrimes * Vi enter insert mode after the cursor 4031573Srgrimes * [a] 4041573Srgrimes */ 4051573Srgrimesprotected el_action_t 4061573Srgrimes/*ARGSUSED*/ 407148834Sstefanfvi_add(EditLine *el, int c __unused) 4081573Srgrimes{ 409148834Sstefanf int ret; 41037199Sbrian 41184260Sobrien el->el_map.current = el->el_map.key; 41284260Sobrien if (el->el_line.cursor < el->el_line.lastchar) { 41384260Sobrien el->el_line.cursor++; 41484260Sobrien if (el->el_line.cursor > el->el_line.lastchar) 41584260Sobrien el->el_line.cursor = el->el_line.lastchar; 41684260Sobrien ret = CC_CURSOR; 41784260Sobrien } else 41884260Sobrien ret = CC_NORM; 4191573Srgrimes 420148834Sstefanf cv_undo(el); 4211573Srgrimes 42284260Sobrien return (ret); 4231573Srgrimes} 4241573Srgrimes 4251573Srgrimes 4261573Srgrimes/* vi_add_at_eol(): 4271573Srgrimes * Vi enter insert mode at end of line 4281573Srgrimes * [A] 4291573Srgrimes */ 4301573Srgrimesprotected el_action_t 4311573Srgrimes/*ARGSUSED*/ 432148834Sstefanfvi_add_at_eol(EditLine *el, int c __unused) 4331573Srgrimes{ 4341573Srgrimes 43584260Sobrien el->el_map.current = el->el_map.key; 43684260Sobrien el->el_line.cursor = el->el_line.lastchar; 437148834Sstefanf cv_undo(el); 43884260Sobrien return (CC_CURSOR); 4391573Srgrimes} 4401573Srgrimes 4411573Srgrimes 4421573Srgrimes/* vi_delete_meta(): 4438870Srgrimes * Vi delete prefix command 4441573Srgrimes * [d] 4451573Srgrimes */ 4461573Srgrimesprotected el_action_t 4471573Srgrimes/*ARGSUSED*/ 448148834Sstefanfvi_delete_meta(EditLine *el, int c __unused) 4491573Srgrimes{ 45084260Sobrien 45184260Sobrien return (cv_action(el, DELETE)); 4521573Srgrimes} 4531573Srgrimes 4541573Srgrimes 455148834Sstefanf/* vi_end_big_word(): 4568870Srgrimes * Vi move to the end of the current space delimited word 4578870Srgrimes * [E] 4581573Srgrimes */ 4591573Srgrimesprotected el_action_t 4601573Srgrimes/*ARGSUSED*/ 461148834Sstefanfvi_end_big_word(EditLine *el, int c) 4621573Srgrimes{ 4631573Srgrimes 46484260Sobrien if (el->el_line.cursor == el->el_line.lastchar) 46584260Sobrien return (CC_ERROR); 4661573Srgrimes 46784260Sobrien el->el_line.cursor = cv__endword(el->el_line.cursor, 468148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isWord); 4691573Srgrimes 470148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 47184260Sobrien el->el_line.cursor++; 47284260Sobrien cv_delfini(el); 47384260Sobrien return (CC_REFRESH); 47484260Sobrien } 47584260Sobrien return (CC_CURSOR); 4761573Srgrimes} 4771573Srgrimes 4781573Srgrimes 479148834Sstefanf/* vi_end_word(): 4801573Srgrimes * Vi move to the end of the current word 4811573Srgrimes * [e] 4821573Srgrimes */ 4831573Srgrimesprotected el_action_t 4841573Srgrimes/*ARGSUSED*/ 485148834Sstefanfvi_end_word(EditLine *el, int c __unused) 4861573Srgrimes{ 4871573Srgrimes 48884260Sobrien if (el->el_line.cursor == el->el_line.lastchar) 48984260Sobrien return (CC_ERROR); 4901573Srgrimes 49184260Sobrien el->el_line.cursor = cv__endword(el->el_line.cursor, 492148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isword); 4931573Srgrimes 494148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 49584260Sobrien el->el_line.cursor++; 49684260Sobrien cv_delfini(el); 49784260Sobrien return (CC_REFRESH); 49884260Sobrien } 49984260Sobrien return (CC_CURSOR); 5001573Srgrimes} 5011573Srgrimes 5021573Srgrimes 5031573Srgrimes/* vi_undo(): 5041573Srgrimes * Vi undo last change 5051573Srgrimes * [u] 5061573Srgrimes */ 5071573Srgrimesprotected el_action_t 5081573Srgrimes/*ARGSUSED*/ 509148834Sstefanfvi_undo(EditLine *el, int c __unused) 5101573Srgrimes{ 511148834Sstefanf c_undo_t un = el->el_chared.c_undo; 5121573Srgrimes 513148834Sstefanf if (un.len == -1) 514148834Sstefanf return CC_ERROR; 5151573Srgrimes 516148834Sstefanf /* switch line buffer and undo buffer */ 517148834Sstefanf el->el_chared.c_undo.buf = el->el_line.buffer; 518148834Sstefanf el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; 519237448Spfg el->el_chared.c_undo.cursor = 520237448Spfg (int)(el->el_line.cursor - el->el_line.buffer); 521148834Sstefanf el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); 522148834Sstefanf el->el_line.buffer = un.buf; 523148834Sstefanf el->el_line.cursor = un.buf + un.cursor; 524148834Sstefanf el->el_line.lastchar = un.buf + un.len; 5251573Srgrimes 52684260Sobrien return (CC_REFRESH); 5271573Srgrimes} 5281573Srgrimes 5291573Srgrimes 5301573Srgrimes/* vi_command_mode(): 5311573Srgrimes * Vi enter command mode (use alternative key bindings) 5321573Srgrimes * [<ESC>] 5331573Srgrimes */ 5341573Srgrimesprotected el_action_t 5351573Srgrimes/*ARGSUSED*/ 536148834Sstefanfvi_command_mode(EditLine *el, int c __unused) 5371573Srgrimes{ 5381573Srgrimes 53984260Sobrien /* [Esc] cancels pending action */ 54084260Sobrien el->el_chared.c_vcmd.action = NOP; 54184260Sobrien el->el_chared.c_vcmd.pos = 0; 5421573Srgrimes 54384260Sobrien el->el_state.doingarg = 0; 54484260Sobrien 54584260Sobrien el->el_state.inputmode = MODE_INSERT; 54684260Sobrien el->el_map.current = el->el_map.alt; 5471573Srgrimes#ifdef VI_MOVE 54884260Sobrien if (el->el_line.cursor > el->el_line.buffer) 54984260Sobrien el->el_line.cursor--; 5501573Srgrimes#endif 55184260Sobrien return (CC_CURSOR); 5521573Srgrimes} 5531573Srgrimes 55484260Sobrien 5551573Srgrimes/* vi_zero(): 5568870Srgrimes * Vi move to the beginning of line 5571573Srgrimes * [0] 5581573Srgrimes */ 5591573Srgrimesprotected el_action_t 56084260Sobrienvi_zero(EditLine *el, int c) 5611573Srgrimes{ 56284260Sobrien 563148834Sstefanf if (el->el_state.doingarg) 564148834Sstefanf return ed_argument_digit(el, c); 565148834Sstefanf 566148834Sstefanf el->el_line.cursor = el->el_line.buffer; 567148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 568148834Sstefanf cv_delfini(el); 569148834Sstefanf return (CC_REFRESH); 57084260Sobrien } 571148834Sstefanf return (CC_CURSOR); 5721573Srgrimes} 5731573Srgrimes 5741573Srgrimes 5751573Srgrimes/* vi_delete_prev_char(): 5768870Srgrimes * Vi move to previous character (backspace) 577148834Sstefanf * [^H] in insert mode only 5788870Srgrimes */ 5791573Srgrimesprotected el_action_t 5801573Srgrimes/*ARGSUSED*/ 581148834Sstefanfvi_delete_prev_char(EditLine *el, int c __unused) 5821573Srgrimes{ 5831573Srgrimes 584148834Sstefanf if (el->el_line.cursor <= el->el_line.buffer) 58584260Sobrien return (CC_ERROR); 5861573Srgrimes 587148834Sstefanf c_delbefore1(el); 588148834Sstefanf el->el_line.cursor--; 58984260Sobrien return (CC_REFRESH); 59084260Sobrien} 5911573Srgrimes 59284260Sobrien 5931573Srgrimes/* vi_list_or_eof(): 5941573Srgrimes * Vi list choices for completion or indicate end of file if empty line 5951573Srgrimes * [^D] 5961573Srgrimes */ 5971573Srgrimesprotected el_action_t 5981573Srgrimes/*ARGSUSED*/ 599167457Sstefanfvi_list_or_eof(EditLine *el, int c) 6001573Srgrimes{ 60184260Sobrien 602148834Sstefanf if (el->el_line.cursor == el->el_line.lastchar) { 603148834Sstefanf if (el->el_line.cursor == el->el_line.buffer) { 604167457Sstefanf term_writec(el, c); /* then do a EOF */ 605148834Sstefanf return (CC_EOF); 606148834Sstefanf } else { 607148834Sstefanf /* 608148834Sstefanf * Here we could list completions, but it is an 609148834Sstefanf * error right now 610148834Sstefanf */ 611148834Sstefanf term_beep(el); 612148834Sstefanf return (CC_ERROR); 613148834Sstefanf } 614148834Sstefanf } else { 6151573Srgrimes#ifdef notyet 61684260Sobrien re_goto_bottom(el); 61784260Sobrien *el->el_line.lastchar = '\0'; /* just in case */ 61884260Sobrien return (CC_LIST_CHOICES); 619148834Sstefanf#else 620148834Sstefanf /* 621148834Sstefanf * Just complain for now. 622148834Sstefanf */ 623148834Sstefanf term_beep(el); 624148834Sstefanf return (CC_ERROR); 625148834Sstefanf#endif 62684260Sobrien } 6271573Srgrimes} 6281573Srgrimes 6291573Srgrimes 6301573Srgrimes/* vi_kill_line_prev(): 6318870Srgrimes * Vi cut from beginning of line to cursor 6321573Srgrimes * [^U] 6331573Srgrimes */ 6341573Srgrimesprotected el_action_t 6351573Srgrimes/*ARGSUSED*/ 636148834Sstefanfvi_kill_line_prev(EditLine *el, int c __unused) 6371573Srgrimes{ 63884260Sobrien char *kp, *cp; 6391573Srgrimes 64084260Sobrien cp = el->el_line.buffer; 64184260Sobrien kp = el->el_chared.c_kill.buf; 64284260Sobrien while (cp < el->el_line.cursor) 64384260Sobrien *kp++ = *cp++; /* copy it */ 64484260Sobrien el->el_chared.c_kill.last = kp; 645237448Spfg c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); 64684260Sobrien el->el_line.cursor = el->el_line.buffer; /* zap! */ 64784260Sobrien return (CC_REFRESH); 6481573Srgrimes} 6491573Srgrimes 6501573Srgrimes 6511573Srgrimes/* vi_search_prev(): 6521573Srgrimes * Vi search history previous 6531573Srgrimes * [?] 6541573Srgrimes */ 6551573Srgrimesprotected el_action_t 6561573Srgrimes/*ARGSUSED*/ 657148834Sstefanfvi_search_prev(EditLine *el, int c __unused) 6581573Srgrimes{ 65984260Sobrien 66084260Sobrien return (cv_search(el, ED_SEARCH_PREV_HISTORY)); 6611573Srgrimes} 6621573Srgrimes 6631573Srgrimes 6641573Srgrimes/* vi_search_next(): 6651573Srgrimes * Vi search history next 6661573Srgrimes * [/] 6671573Srgrimes */ 6681573Srgrimesprotected el_action_t 6691573Srgrimes/*ARGSUSED*/ 670148834Sstefanfvi_search_next(EditLine *el, int c __unused) 6711573Srgrimes{ 67284260Sobrien 67384260Sobrien return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); 6741573Srgrimes} 6751573Srgrimes 6761573Srgrimes 6771573Srgrimes/* vi_repeat_search_next(): 6781573Srgrimes * Vi repeat current search in the same search direction 6791573Srgrimes * [n] 6801573Srgrimes */ 6811573Srgrimesprotected el_action_t 6821573Srgrimes/*ARGSUSED*/ 683148834Sstefanfvi_repeat_search_next(EditLine *el, int c __unused) 6841573Srgrimes{ 68584260Sobrien 68684260Sobrien if (el->el_search.patlen == 0) 68784260Sobrien return (CC_ERROR); 68884260Sobrien else 68984260Sobrien return (cv_repeat_srch(el, el->el_search.patdir)); 6901573Srgrimes} 6911573Srgrimes 6921573Srgrimes 6931573Srgrimes/* vi_repeat_search_prev(): 6941573Srgrimes * Vi repeat current search in the opposite search direction 6951573Srgrimes * [N] 6961573Srgrimes */ 6971573Srgrimes/*ARGSUSED*/ 6981573Srgrimesprotected el_action_t 699148834Sstefanfvi_repeat_search_prev(EditLine *el, int c __unused) 7001573Srgrimes{ 70184260Sobrien 70284260Sobrien if (el->el_search.patlen == 0) 70384260Sobrien return (CC_ERROR); 70484260Sobrien else 70584260Sobrien return (cv_repeat_srch(el, 70684260Sobrien el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? 70784260Sobrien ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY)); 7081573Srgrimes} 7091573Srgrimes 7101573Srgrimes 7111573Srgrimes/* vi_next_char(): 7121573Srgrimes * Vi move to the character specified next 7131573Srgrimes * [f] 7141573Srgrimes */ 7151573Srgrimesprotected el_action_t 7161573Srgrimes/*ARGSUSED*/ 717148834Sstefanfvi_next_char(EditLine *el, int c __unused) 7181573Srgrimes{ 719148834Sstefanf return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); 7201573Srgrimes} 7211573Srgrimes 7221573Srgrimes 7231573Srgrimes/* vi_prev_char(): 7241573Srgrimes * Vi move to the character specified previous 7251573Srgrimes * [F] 7261573Srgrimes */ 7271573Srgrimesprotected el_action_t 7281573Srgrimes/*ARGSUSED*/ 729148834Sstefanfvi_prev_char(EditLine *el, int c __unused) 7301573Srgrimes{ 731148834Sstefanf return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); 7321573Srgrimes} 7331573Srgrimes 7341573Srgrimes 7351573Srgrimes/* vi_to_next_char(): 7361573Srgrimes * Vi move up to the character specified next 7371573Srgrimes * [t] 7381573Srgrimes */ 7391573Srgrimesprotected el_action_t 7401573Srgrimes/*ARGSUSED*/ 741148834Sstefanfvi_to_next_char(EditLine *el, int c __unused) 7421573Srgrimes{ 743148834Sstefanf return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); 7441573Srgrimes} 7451573Srgrimes 7461573Srgrimes 7471573Srgrimes/* vi_to_prev_char(): 7481573Srgrimes * Vi move up to the character specified previous 7491573Srgrimes * [T] 7501573Srgrimes */ 7511573Srgrimesprotected el_action_t 7521573Srgrimes/*ARGSUSED*/ 753148834Sstefanfvi_to_prev_char(EditLine *el, int c __unused) 7541573Srgrimes{ 755148834Sstefanf return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); 7561573Srgrimes} 7571573Srgrimes 7581573Srgrimes 7591573Srgrimes/* vi_repeat_next_char(): 7601573Srgrimes * Vi repeat current character search in the same search direction 7611573Srgrimes * [;] 7621573Srgrimes */ 7631573Srgrimesprotected el_action_t 7641573Srgrimes/*ARGSUSED*/ 765148834Sstefanfvi_repeat_next_char(EditLine *el, int c __unused) 7661573Srgrimes{ 7671573Srgrimes 768148834Sstefanf return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, 769148834Sstefanf el->el_state.argument, el->el_search.chatflg); 7701573Srgrimes} 7711573Srgrimes 7721573Srgrimes 7731573Srgrimes/* vi_repeat_prev_char(): 7741573Srgrimes * Vi repeat current character search in the opposite search direction 7751573Srgrimes * [,] 7761573Srgrimes */ 7771573Srgrimesprotected el_action_t 7781573Srgrimes/*ARGSUSED*/ 779148834Sstefanfvi_repeat_prev_char(EditLine *el, int c __unused) 7801573Srgrimes{ 781148834Sstefanf el_action_t r; 782148834Sstefanf int dir = el->el_search.chadir; 7831573Srgrimes 784148834Sstefanf r = cv_csearch(el, -dir, el->el_search.chacha, 785148834Sstefanf el->el_state.argument, el->el_search.chatflg); 786148834Sstefanf el->el_search.chadir = dir; 787148834Sstefanf return r; 788148834Sstefanf} 78984260Sobrien 790148834Sstefanf 791148834Sstefanf/* vi_match(): 792148834Sstefanf * Vi go to matching () {} or [] 793148834Sstefanf * [%] 794148834Sstefanf */ 795148834Sstefanfprotected el_action_t 796148834Sstefanf/*ARGSUSED*/ 797148834Sstefanfvi_match(EditLine *el, int c) 798148834Sstefanf{ 799148834Sstefanf const char match_chars[] = "()[]{}"; 800148834Sstefanf char *cp; 801237448Spfg size_t delta, i, count; 802148834Sstefanf char o_ch, c_ch; 803148834Sstefanf 804148834Sstefanf *el->el_line.lastchar = '\0'; /* just in case */ 805148834Sstefanf 806148834Sstefanf i = strcspn(el->el_line.cursor, match_chars); 807148834Sstefanf o_ch = el->el_line.cursor[i]; 808148834Sstefanf if (o_ch == 0) 809148834Sstefanf return CC_ERROR; 810148834Sstefanf delta = strchr(match_chars, o_ch) - match_chars; 811148834Sstefanf c_ch = match_chars[delta ^ 1]; 812148834Sstefanf count = 1; 813148834Sstefanf delta = 1 - (delta & 1) * 2; 814148834Sstefanf 815148834Sstefanf for (cp = &el->el_line.cursor[i]; count; ) { 816148834Sstefanf cp += delta; 817148834Sstefanf if (cp < el->el_line.buffer || cp >= el->el_line.lastchar) 818148834Sstefanf return CC_ERROR; 819148834Sstefanf if (*cp == o_ch) 820148834Sstefanf count++; 821148834Sstefanf else if (*cp == c_ch) 822148834Sstefanf count--; 823148834Sstefanf } 824148834Sstefanf 825148834Sstefanf el->el_line.cursor = cp; 826148834Sstefanf 827148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 828148834Sstefanf /* NB posix says char under cursor should NOT be deleted 829148834Sstefanf for -ve delta - this is different to netbsd vi. */ 830148834Sstefanf if (delta > 0) 831148834Sstefanf el->el_line.cursor++; 832148834Sstefanf cv_delfini(el); 833148834Sstefanf return (CC_REFRESH); 834148834Sstefanf } 835148834Sstefanf return (CC_CURSOR); 8361573Srgrimes} 837148834Sstefanf 838148834Sstefanf/* vi_undo_line(): 839148834Sstefanf * Vi undo all changes to line 840148834Sstefanf * [U] 841148834Sstefanf */ 842148834Sstefanfprotected el_action_t 843148834Sstefanf/*ARGSUSED*/ 844148834Sstefanfvi_undo_line(EditLine *el, int c) 845148834Sstefanf{ 846148834Sstefanf 847148834Sstefanf cv_undo(el); 848148834Sstefanf return hist_get(el); 849148834Sstefanf} 850148834Sstefanf 851148834Sstefanf/* vi_to_column(): 852148834Sstefanf * Vi go to specified column 853148834Sstefanf * [|] 854148834Sstefanf * NB netbsd vi goes to screen column 'n', posix says nth character 855148834Sstefanf */ 856148834Sstefanfprotected el_action_t 857148834Sstefanf/*ARGSUSED*/ 858148834Sstefanfvi_to_column(EditLine *el, int c) 859148834Sstefanf{ 860148834Sstefanf 861148834Sstefanf el->el_line.cursor = el->el_line.buffer; 862148834Sstefanf el->el_state.argument--; 863148834Sstefanf return ed_next_char(el, 0); 864148834Sstefanf} 865148834Sstefanf 866148834Sstefanf/* vi_yank_end(): 867148834Sstefanf * Vi yank to end of line 868148834Sstefanf * [Y] 869148834Sstefanf */ 870148834Sstefanfprotected el_action_t 871148834Sstefanf/*ARGSUSED*/ 872148834Sstefanfvi_yank_end(EditLine *el, int c) 873148834Sstefanf{ 874148834Sstefanf 875148834Sstefanf cv_yank(el, el->el_line.cursor, 876237448Spfg (int)(el->el_line.lastchar - el->el_line.cursor)); 877148834Sstefanf return CC_REFRESH; 878148834Sstefanf} 879148834Sstefanf 880148834Sstefanf/* vi_yank(): 881148834Sstefanf * Vi yank 882148834Sstefanf * [y] 883148834Sstefanf */ 884148834Sstefanfprotected el_action_t 885148834Sstefanf/*ARGSUSED*/ 886148834Sstefanfvi_yank(EditLine *el, int c) 887148834Sstefanf{ 888148834Sstefanf 889148834Sstefanf return cv_action(el, YANK); 890148834Sstefanf} 891148834Sstefanf 892148834Sstefanf/* vi_comment_out(): 893148834Sstefanf * Vi comment out current command 894148848Sstefanf * [#] 895148834Sstefanf */ 896148834Sstefanfprotected el_action_t 897148834Sstefanf/*ARGSUSED*/ 898148834Sstefanfvi_comment_out(EditLine *el, int c) 899148834Sstefanf{ 900148834Sstefanf 901148834Sstefanf el->el_line.cursor = el->el_line.buffer; 902148834Sstefanf c_insert(el, 1); 903148834Sstefanf *el->el_line.cursor = '#'; 904148834Sstefanf re_refresh(el); 905148834Sstefanf return ed_newline(el, 0); 906148834Sstefanf} 907148834Sstefanf 908148834Sstefanf/* vi_alias(): 909148834Sstefanf * Vi include shell alias 910148834Sstefanf * [@] 911148848Sstefanf * NB: posix implies that we should enter insert mode, however 912148834Sstefanf * this is against historical precedent... 913148834Sstefanf */ 914148834Sstefanfprotected el_action_t 915148834Sstefanf/*ARGSUSED*/ 916148834Sstefanfvi_alias(EditLine *el, int c) 917148834Sstefanf{ 918148834Sstefanf#ifdef __weak_extern 919148834Sstefanf char alias_name[3]; 920148834Sstefanf char *alias_text; 921148834Sstefanf extern char *get_alias_text(const char *); 922148834Sstefanf __weak_extern(get_alias_text); 923148834Sstefanf 924148834Sstefanf if (get_alias_text == 0) { 925148834Sstefanf return CC_ERROR; 926148834Sstefanf } 927148834Sstefanf 928148834Sstefanf alias_name[0] = '_'; 929148834Sstefanf alias_name[2] = 0; 930148834Sstefanf if (el_getc(el, &alias_name[1]) != 1) 931148834Sstefanf return CC_ERROR; 932148834Sstefanf 933148834Sstefanf alias_text = get_alias_text(alias_name); 934148834Sstefanf if (alias_text != NULL) 935148834Sstefanf el_push(el, alias_text); 936148834Sstefanf return CC_NORM; 937148834Sstefanf#else 938148834Sstefanf return CC_ERROR; 939148834Sstefanf#endif 940148834Sstefanf} 941148834Sstefanf 942148834Sstefanf/* vi_to_history_line(): 943148834Sstefanf * Vi go to specified history file line. 944148834Sstefanf * [G] 945148834Sstefanf */ 946148834Sstefanfprotected el_action_t 947148834Sstefanf/*ARGSUSED*/ 948148834Sstefanfvi_to_history_line(EditLine *el, int c) 949148834Sstefanf{ 950148834Sstefanf int sv_event_no = el->el_history.eventno; 951148834Sstefanf el_action_t rval; 952148834Sstefanf 953148834Sstefanf 954148834Sstefanf if (el->el_history.eventno == 0) { 955148834Sstefanf (void) strncpy(el->el_history.buf, el->el_line.buffer, 956148834Sstefanf EL_BUFSIZ); 957148834Sstefanf el->el_history.last = el->el_history.buf + 958148834Sstefanf (el->el_line.lastchar - el->el_line.buffer); 959148834Sstefanf } 960148834Sstefanf 961148834Sstefanf /* Lack of a 'count' means oldest, not 1 */ 962148834Sstefanf if (!el->el_state.doingarg) { 963148834Sstefanf el->el_history.eventno = 0x7fffffff; 964148834Sstefanf hist_get(el); 965148834Sstefanf } else { 966148834Sstefanf /* This is brain dead, all the rest of this code counts 967148834Sstefanf * upwards going into the past. Here we need count in the 968148834Sstefanf * other direction (to match the output of fc -l). 969148834Sstefanf * I could change the world, but this seems to suffice. 970148834Sstefanf */ 971148834Sstefanf el->el_history.eventno = 1; 972148834Sstefanf if (hist_get(el) == CC_ERROR) 973148834Sstefanf return CC_ERROR; 974148834Sstefanf el->el_history.eventno = 1 + el->el_history.ev.num 975148834Sstefanf - el->el_state.argument; 976148834Sstefanf if (el->el_history.eventno < 0) { 977148834Sstefanf el->el_history.eventno = sv_event_no; 978148834Sstefanf return CC_ERROR; 979148834Sstefanf } 980148834Sstefanf } 981148834Sstefanf rval = hist_get(el); 982148834Sstefanf if (rval == CC_ERROR) 983148834Sstefanf el->el_history.eventno = sv_event_no; 984148834Sstefanf return rval; 985148834Sstefanf} 986148834Sstefanf 987148834Sstefanf/* vi_histedit(): 988148834Sstefanf * Vi edit history line with vi 989148834Sstefanf * [v] 990148834Sstefanf */ 991148834Sstefanfprotected el_action_t 992148834Sstefanf/*ARGSUSED*/ 993148834Sstefanfvi_histedit(EditLine *el, int c) 994148834Sstefanf{ 995148834Sstefanf int fd; 996148834Sstefanf pid_t pid; 997237448Spfg ssize_t st; 998237448Spfg int status; 999148834Sstefanf char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; 1000148834Sstefanf char *cp; 1001148834Sstefanf 1002148834Sstefanf if (el->el_state.doingarg) { 1003148834Sstefanf if (vi_to_history_line(el, 0) == CC_ERROR) 1004148834Sstefanf return CC_ERROR; 1005148834Sstefanf } 1006148834Sstefanf 1007148834Sstefanf fd = mkstemp(tempfile); 1008148834Sstefanf if (fd < 0) 1009148834Sstefanf return CC_ERROR; 1010148834Sstefanf cp = el->el_line.buffer; 1011237448Spfg write(fd, cp, (size_t)(el->el_line.lastchar - cp)); 1012148834Sstefanf write(fd, "\n", 1); 1013148834Sstefanf pid = fork(); 1014148834Sstefanf switch (pid) { 1015148834Sstefanf case -1: 1016148834Sstefanf close(fd); 1017148834Sstefanf unlink(tempfile); 1018148834Sstefanf return CC_ERROR; 1019148834Sstefanf case 0: 1020148834Sstefanf close(fd); 1021237448Spfg execlp("vi", "vi", tempfile, (char *)NULL); 1022148834Sstefanf exit(0); 1023148834Sstefanf /*NOTREACHED*/ 1024148834Sstefanf default: 1025237448Spfg while (waitpid(pid, &status, 0) != pid) 1026148834Sstefanf continue; 1027237448Spfg lseek(fd, (off_t)0, SEEK_SET); 1028237448Spfg st = read(fd, cp, (size_t)(el->el_line.limit - cp)); 1029148834Sstefanf if (st > 0 && cp[st - 1] == '\n') 1030148834Sstefanf st--; 1031148834Sstefanf el->el_line.cursor = cp; 1032148834Sstefanf el->el_line.lastchar = cp + st; 1033148834Sstefanf break; 1034148834Sstefanf } 1035148834Sstefanf 1036148834Sstefanf close(fd); 1037148834Sstefanf unlink(tempfile); 1038148834Sstefanf /* return CC_REFRESH; */ 1039148834Sstefanf return ed_newline(el, 0); 1040148834Sstefanf} 1041148834Sstefanf 1042148834Sstefanf/* vi_history_word(): 1043148834Sstefanf * Vi append word from previous input line 1044148834Sstefanf * [_] 1045148834Sstefanf * Who knows where this one came from! 1046148834Sstefanf * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' 1047148834Sstefanf */ 1048148834Sstefanfprotected el_action_t 1049148834Sstefanf/*ARGSUSED*/ 1050148834Sstefanfvi_history_word(EditLine *el, int c) 1051148834Sstefanf{ 1052148834Sstefanf const char *wp = HIST_FIRST(el); 1053148834Sstefanf const char *wep, *wsp; 1054148834Sstefanf int len; 1055148834Sstefanf char *cp; 1056148834Sstefanf const char *lim; 1057148834Sstefanf 1058148834Sstefanf if (wp == NULL) 1059148834Sstefanf return CC_ERROR; 1060148834Sstefanf 1061148834Sstefanf wep = wsp = 0; 1062148834Sstefanf do { 1063148834Sstefanf while (isspace((unsigned char)*wp)) 1064148834Sstefanf wp++; 1065148834Sstefanf if (*wp == 0) 1066148834Sstefanf break; 1067148834Sstefanf wsp = wp; 1068148834Sstefanf while (*wp && !isspace((unsigned char)*wp)) 1069148834Sstefanf wp++; 1070148834Sstefanf wep = wp; 1071148834Sstefanf } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0); 1072148834Sstefanf 1073148834Sstefanf if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) 1074148834Sstefanf return CC_ERROR; 1075148834Sstefanf 1076148834Sstefanf cv_undo(el); 1077237448Spfg len = (int)(wep - wsp); 1078148834Sstefanf if (el->el_line.cursor < el->el_line.lastchar) 1079148834Sstefanf el->el_line.cursor++; 1080148834Sstefanf c_insert(el, len + 1); 1081148834Sstefanf cp = el->el_line.cursor; 1082148834Sstefanf lim = el->el_line.limit; 1083148834Sstefanf if (cp < lim) 1084148834Sstefanf *cp++ = ' '; 1085148834Sstefanf while (wsp < wep && cp < lim) 1086148834Sstefanf *cp++ = *wsp++; 1087148834Sstefanf el->el_line.cursor = cp; 1088148834Sstefanf 1089148834Sstefanf el->el_map.current = el->el_map.key; 1090148834Sstefanf return CC_REFRESH; 1091148834Sstefanf} 1092148834Sstefanf 1093148834Sstefanf/* vi_redo(): 1094148834Sstefanf * Vi redo last non-motion command 1095148834Sstefanf * [.] 1096148834Sstefanf */ 1097148834Sstefanfprotected el_action_t 1098148834Sstefanf/*ARGSUSED*/ 1099148834Sstefanfvi_redo(EditLine *el, int c) 1100148834Sstefanf{ 1101148834Sstefanf c_redo_t *r = &el->el_chared.c_redo; 1102148834Sstefanf 1103148834Sstefanf if (!el->el_state.doingarg && r->count) { 1104148834Sstefanf el->el_state.doingarg = 1; 1105148834Sstefanf el->el_state.argument = r->count; 1106148834Sstefanf } 1107148834Sstefanf 1108148834Sstefanf el->el_chared.c_vcmd.pos = el->el_line.cursor; 1109148834Sstefanf el->el_chared.c_vcmd.action = r->action; 1110148834Sstefanf if (r->pos != r->buf) { 1111148834Sstefanf if (r->pos + 1 > r->lim) 1112148834Sstefanf /* sanity */ 1113148834Sstefanf r->pos = r->lim - 1; 1114148834Sstefanf r->pos[0] = 0; 1115148834Sstefanf el_push(el, r->buf); 1116148834Sstefanf } 1117148834Sstefanf 1118148834Sstefanf el->el_state.thiscmd = r->cmd; 1119148834Sstefanf el->el_state.thisch = r->ch; 1120148834Sstefanf return (*el->el_map.func[r->cmd])(el, r->ch); 1121148834Sstefanf} 1122