vi.c revision 148848
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 * 32148834Sstefanf * $NetBSD: vi.c,v 1.21 2005/04/25 01:06:03 matt 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: head/lib/libedit/vi.c 148848 2005-08-08 07:08:35Z stefanf $"); 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, 66148834Sstefanf el->el_line.lastchar - el->el_line.buffer); 6784260Sobrien el->el_chared.c_vcmd.action = NOP; 6884260Sobrien el->el_chared.c_vcmd.pos = 0; 6984260Sobrien el->el_line.lastchar = el->el_line.buffer; 7084260Sobrien el->el_line.cursor = el->el_line.buffer; 7184260Sobrien if (c & INSERT) 7284260Sobrien el->el_map.current = el->el_map.key; 738870Srgrimes 7484260Sobrien return (CC_REFRESH); 7584260Sobrien } 7684260Sobrien el->el_chared.c_vcmd.pos = el->el_line.cursor; 7784260Sobrien el->el_chared.c_vcmd.action = c; 7884260Sobrien return (CC_ARGHACK); 791573Srgrimes} 801573Srgrimes 811573Srgrimes/* cv_paste(): 821573Srgrimes * Paste previous deletion before or after the cursor 831573Srgrimes */ 8484260Sobrienprivate el_action_t 8584260Sobriencv_paste(EditLine *el, int c) 861573Srgrimes{ 8784260Sobrien char *ptr; 88148834Sstefanf c_kill_t *k = &el->el_chared.c_kill; 89148834Sstefanf int len = k->last - k->buf; 9084260Sobrien 91148834Sstefanf if (k->buf == NULL || len == 0) 92148834Sstefanf return (CC_ERROR); 931573Srgrimes#ifdef DEBUG_PASTE 94148834Sstefanf (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf); 951573Srgrimes#endif 961573Srgrimes 97148834Sstefanf cv_undo(el); 98148834Sstefanf 9984260Sobrien if (!c && el->el_line.cursor < el->el_line.lastchar) 10084260Sobrien el->el_line.cursor++; 10184260Sobrien ptr = el->el_line.cursor; 1028870Srgrimes 103148834Sstefanf c_insert(el, len); 104148834Sstefanf if (el->el_line.cursor + len > el->el_line.lastchar) 10584260Sobrien return (CC_ERROR); 106148834Sstefanf (void) memcpy(ptr, k->buf, len +0u); 10784260Sobrien return (CC_REFRESH); 1081573Srgrimes} 1091573Srgrimes 1101573Srgrimes 1118870Srgrimes/* vi_paste_next(): 1121573Srgrimes * Vi paste previous deletion to the right of the cursor 1131573Srgrimes * [p] 1141573Srgrimes */ 1151573Srgrimesprotected el_action_t 1161573Srgrimes/*ARGSUSED*/ 117148834Sstefanfvi_paste_next(EditLine *el, int c __unused) 1181573Srgrimes{ 11984260Sobrien 12084260Sobrien return (cv_paste(el, 0)); 1211573Srgrimes} 1221573Srgrimes 1231573Srgrimes 1248870Srgrimes/* vi_paste_prev(): 1251573Srgrimes * Vi paste previous deletion to the left of the cursor 1261573Srgrimes * [P] 1271573Srgrimes */ 1281573Srgrimesprotected el_action_t 1291573Srgrimes/*ARGSUSED*/ 130148834Sstefanfvi_paste_prev(EditLine *el, int c __unused) 1311573Srgrimes{ 13284260Sobrien 13384260Sobrien return (cv_paste(el, 1)); 1341573Srgrimes} 1351573Srgrimes 1361573Srgrimes 137148834Sstefanf/* vi_prev_big_word(): 1381573Srgrimes * Vi move to the previous space delimited word 1391573Srgrimes * [B] 1401573Srgrimes */ 1411573Srgrimesprotected el_action_t 1421573Srgrimes/*ARGSUSED*/ 143148834Sstefanfvi_prev_big_word(EditLine *el, int c) 1441573Srgrimes{ 1451573Srgrimes 14684260Sobrien if (el->el_line.cursor == el->el_line.buffer) 14784260Sobrien return (CC_ERROR); 1481573Srgrimes 149148834Sstefanf el->el_line.cursor = cv_prev_word(el->el_line.cursor, 15084260Sobrien el->el_line.buffer, 15184260Sobrien el->el_state.argument, 152148834Sstefanf cv__isWord); 1531573Srgrimes 154148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 15584260Sobrien cv_delfini(el); 15684260Sobrien return (CC_REFRESH); 15784260Sobrien } 15884260Sobrien return (CC_CURSOR); 1591573Srgrimes} 1601573Srgrimes 1611573Srgrimes 1628870Srgrimes/* vi_prev_word(): 1631573Srgrimes * Vi move to the previous word 16437199Sbrian * [b] 1651573Srgrimes */ 1661573Srgrimesprotected el_action_t 1671573Srgrimes/*ARGSUSED*/ 168148834Sstefanfvi_prev_word(EditLine *el, int c __unused) 1691573Srgrimes{ 1701573Srgrimes 17184260Sobrien if (el->el_line.cursor == el->el_line.buffer) 17284260Sobrien return (CC_ERROR); 1731573Srgrimes 174148834Sstefanf el->el_line.cursor = cv_prev_word(el->el_line.cursor, 17584260Sobrien el->el_line.buffer, 17684260Sobrien el->el_state.argument, 17784260Sobrien cv__isword); 1781573Srgrimes 179148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 18084260Sobrien cv_delfini(el); 18184260Sobrien return (CC_REFRESH); 18284260Sobrien } 18384260Sobrien return (CC_CURSOR); 1841573Srgrimes} 1851573Srgrimes 1861573Srgrimes 187148834Sstefanf/* vi_next_big_word(): 1881573Srgrimes * Vi move to the next space delimited word 1891573Srgrimes * [W] 1901573Srgrimes */ 1911573Srgrimesprotected el_action_t 1921573Srgrimes/*ARGSUSED*/ 193148834Sstefanfvi_next_big_word(EditLine *el, int c) 1941573Srgrimes{ 1951573Srgrimes 196148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar - 1) 19784260Sobrien return (CC_ERROR); 1981573Srgrimes 19984260Sobrien el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 200148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isWord); 2011573Srgrimes 20284260Sobrien if (el->el_map.type == MAP_VI) 203148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 20484260Sobrien cv_delfini(el); 20584260Sobrien return (CC_REFRESH); 20684260Sobrien } 20784260Sobrien return (CC_CURSOR); 2081573Srgrimes} 2091573Srgrimes 21084260Sobrien 2118870Srgrimes/* vi_next_word(): 2121573Srgrimes * Vi move to the next word 2131573Srgrimes * [w] 2141573Srgrimes */ 2151573Srgrimesprotected el_action_t 2161573Srgrimes/*ARGSUSED*/ 217148834Sstefanfvi_next_word(EditLine *el, int c __unused) 2181573Srgrimes{ 2191573Srgrimes 220148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar - 1) 22184260Sobrien return (CC_ERROR); 2221573Srgrimes 22384260Sobrien el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 224148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isword); 2251573Srgrimes 22684260Sobrien if (el->el_map.type == MAP_VI) 227148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 22884260Sobrien cv_delfini(el); 22984260Sobrien return (CC_REFRESH); 23084260Sobrien } 23184260Sobrien return (CC_CURSOR); 2321573Srgrimes} 2331573Srgrimes 2341573Srgrimes 2358870Srgrimes/* vi_change_case(): 2361573Srgrimes * Vi change case of character under the cursor and advance one character 2371573Srgrimes * [~] 2381573Srgrimes */ 2391573Srgrimesprotected el_action_t 24084260Sobrienvi_change_case(EditLine *el, int c) 2411573Srgrimes{ 242148834Sstefanf int i; 24384260Sobrien 244148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar) 245148834Sstefanf return (CC_ERROR); 246148834Sstefanf cv_undo(el); 247148834Sstefanf for (i = 0; i < el->el_state.argument; i++) { 248148834Sstefanf 249148834Sstefanf c = *(unsigned char *)el->el_line.cursor; 25084260Sobrien if (isupper(c)) 251148834Sstefanf *el->el_line.cursor = tolower(c); 25284260Sobrien else if (islower(c)) 253148834Sstefanf *el->el_line.cursor = toupper(c); 254148834Sstefanf 255148834Sstefanf if (++el->el_line.cursor >= el->el_line.lastchar) { 256148834Sstefanf el->el_line.cursor--; 257148834Sstefanf re_fastaddc(el); 258148834Sstefanf break; 259148834Sstefanf } 26084260Sobrien re_fastaddc(el); 26184260Sobrien } 262148834Sstefanf return CC_NORM; 2631573Srgrimes} 2641573Srgrimes 2651573Srgrimes 2668870Srgrimes/* vi_change_meta(): 2671573Srgrimes * Vi change prefix command 2681573Srgrimes * [c] 2691573Srgrimes */ 2701573Srgrimesprotected el_action_t 2711573Srgrimes/*ARGSUSED*/ 272148834Sstefanfvi_change_meta(EditLine *el, int c __unused) 2731573Srgrimes{ 27484260Sobrien 27584260Sobrien /* 27684260Sobrien * Delete with insert == change: first we delete and then we leave in 27784260Sobrien * insert mode. 27884260Sobrien */ 27984260Sobrien return (cv_action(el, DELETE | INSERT)); 2801573Srgrimes} 2811573Srgrimes 2821573Srgrimes 2838870Srgrimes/* vi_insert_at_bol(): 2841573Srgrimes * Vi enter insert mode at the beginning of line 2851573Srgrimes * [I] 2861573Srgrimes */ 2871573Srgrimesprotected el_action_t 2881573Srgrimes/*ARGSUSED*/ 289148834Sstefanfvi_insert_at_bol(EditLine *el, int c __unused) 2901573Srgrimes{ 2911573Srgrimes 29284260Sobrien el->el_line.cursor = el->el_line.buffer; 293148834Sstefanf cv_undo(el); 29484260Sobrien el->el_map.current = el->el_map.key; 29584260Sobrien return (CC_CURSOR); 2961573Srgrimes} 2971573Srgrimes 2981573Srgrimes 2998870Srgrimes/* vi_replace_char(): 3001573Srgrimes * Vi replace character under the cursor with the next character typed 3011573Srgrimes * [r] 3021573Srgrimes */ 3031573Srgrimesprotected el_action_t 3041573Srgrimes/*ARGSUSED*/ 305148834Sstefanfvi_replace_char(EditLine *el, int c __unused) 3061573Srgrimes{ 30784260Sobrien 308148834Sstefanf if (el->el_line.cursor >= el->el_line.lastchar) 309148834Sstefanf return CC_ERROR; 310148834Sstefanf 31184260Sobrien el->el_map.current = el->el_map.key; 31284260Sobrien el->el_state.inputmode = MODE_REPLACE_1; 313148834Sstefanf cv_undo(el); 31484260Sobrien return (CC_ARGHACK); 3151573Srgrimes} 3161573Srgrimes 3171573Srgrimes 3188870Srgrimes/* vi_replace_mode(): 3191573Srgrimes * Vi enter replace mode 3201573Srgrimes * [R] 3211573Srgrimes */ 3221573Srgrimesprotected el_action_t 3231573Srgrimes/*ARGSUSED*/ 324148834Sstefanfvi_replace_mode(EditLine *el, int c __unused) 3251573Srgrimes{ 32684260Sobrien 32784260Sobrien el->el_map.current = el->el_map.key; 32884260Sobrien el->el_state.inputmode = MODE_REPLACE; 329148834Sstefanf cv_undo(el); 330148834Sstefanf return (CC_NORM); 3311573Srgrimes} 3321573Srgrimes 3331573Srgrimes 3348870Srgrimes/* vi_substitute_char(): 3351573Srgrimes * Vi replace character under the cursor and enter insert mode 33637199Sbrian * [s] 3371573Srgrimes */ 3381573Srgrimesprotected el_action_t 3391573Srgrimes/*ARGSUSED*/ 340148834Sstefanfvi_substitute_char(EditLine *el, int c __unused) 3411573Srgrimes{ 34284260Sobrien 34384260Sobrien c_delafter(el, el->el_state.argument); 34484260Sobrien el->el_map.current = el->el_map.key; 34584260Sobrien return (CC_REFRESH); 3461573Srgrimes} 3471573Srgrimes 3481573Srgrimes 3498870Srgrimes/* vi_substitute_line(): 3501573Srgrimes * Vi substitute entire line 3511573Srgrimes * [S] 3521573Srgrimes */ 3531573Srgrimesprotected el_action_t 3541573Srgrimes/*ARGSUSED*/ 355148834Sstefanfvi_substitute_line(EditLine *el, int c __unused) 3561573Srgrimes{ 35784260Sobrien 358148834Sstefanf cv_undo(el); 359148834Sstefanf cv_yank(el, el->el_line.buffer, 360148834Sstefanf el->el_line.lastchar - el->el_line.buffer); 36184260Sobrien (void) em_kill_line(el, 0); 36284260Sobrien el->el_map.current = el->el_map.key; 36384260Sobrien return (CC_REFRESH); 3641573Srgrimes} 3651573Srgrimes 3661573Srgrimes 3678870Srgrimes/* vi_change_to_eol(): 3681573Srgrimes * Vi change to end of line 3691573Srgrimes * [C] 3701573Srgrimes */ 3711573Srgrimesprotected el_action_t 3721573Srgrimes/*ARGSUSED*/ 373148834Sstefanfvi_change_to_eol(EditLine *el, int c __unused) 3741573Srgrimes{ 37584260Sobrien 376148834Sstefanf cv_undo(el); 377148834Sstefanf cv_yank(el, el->el_line.cursor, 378148834Sstefanf el->el_line.lastchar - el->el_line.cursor); 37984260Sobrien (void) ed_kill_line(el, 0); 38084260Sobrien el->el_map.current = el->el_map.key; 38184260Sobrien return (CC_REFRESH); 3821573Srgrimes} 3831573Srgrimes 3841573Srgrimes 3851573Srgrimes/* vi_insert(): 3861573Srgrimes * Vi enter insert mode 3871573Srgrimes * [i] 3881573Srgrimes */ 3891573Srgrimesprotected el_action_t 3901573Srgrimes/*ARGSUSED*/ 391148834Sstefanfvi_insert(EditLine *el, int c __unused) 3921573Srgrimes{ 3931573Srgrimes 39484260Sobrien el->el_map.current = el->el_map.key; 395148834Sstefanf cv_undo(el); 39684260Sobrien return (CC_NORM); 3971573Srgrimes} 3981573Srgrimes 3991573Srgrimes 4001573Srgrimes/* vi_add(): 4018870Srgrimes * Vi enter insert mode after the cursor 4021573Srgrimes * [a] 4031573Srgrimes */ 4041573Srgrimesprotected el_action_t 4051573Srgrimes/*ARGSUSED*/ 406148834Sstefanfvi_add(EditLine *el, int c __unused) 4071573Srgrimes{ 408148834Sstefanf int ret; 40937199Sbrian 41084260Sobrien el->el_map.current = el->el_map.key; 41184260Sobrien if (el->el_line.cursor < el->el_line.lastchar) { 41284260Sobrien el->el_line.cursor++; 41384260Sobrien if (el->el_line.cursor > el->el_line.lastchar) 41484260Sobrien el->el_line.cursor = el->el_line.lastchar; 41584260Sobrien ret = CC_CURSOR; 41684260Sobrien } else 41784260Sobrien ret = CC_NORM; 4181573Srgrimes 419148834Sstefanf cv_undo(el); 4201573Srgrimes 42184260Sobrien return (ret); 4221573Srgrimes} 4231573Srgrimes 4241573Srgrimes 4251573Srgrimes/* vi_add_at_eol(): 4261573Srgrimes * Vi enter insert mode at end of line 4271573Srgrimes * [A] 4281573Srgrimes */ 4291573Srgrimesprotected el_action_t 4301573Srgrimes/*ARGSUSED*/ 431148834Sstefanfvi_add_at_eol(EditLine *el, int c __unused) 4321573Srgrimes{ 4331573Srgrimes 43484260Sobrien el->el_map.current = el->el_map.key; 43584260Sobrien el->el_line.cursor = el->el_line.lastchar; 436148834Sstefanf cv_undo(el); 43784260Sobrien return (CC_CURSOR); 4381573Srgrimes} 4391573Srgrimes 4401573Srgrimes 4411573Srgrimes/* vi_delete_meta(): 4428870Srgrimes * Vi delete prefix command 4431573Srgrimes * [d] 4441573Srgrimes */ 4451573Srgrimesprotected el_action_t 4461573Srgrimes/*ARGSUSED*/ 447148834Sstefanfvi_delete_meta(EditLine *el, int c __unused) 4481573Srgrimes{ 44984260Sobrien 45084260Sobrien return (cv_action(el, DELETE)); 4511573Srgrimes} 4521573Srgrimes 4531573Srgrimes 454148834Sstefanf/* vi_end_big_word(): 4558870Srgrimes * Vi move to the end of the current space delimited word 4568870Srgrimes * [E] 4571573Srgrimes */ 4581573Srgrimesprotected el_action_t 4591573Srgrimes/*ARGSUSED*/ 460148834Sstefanfvi_end_big_word(EditLine *el, int c) 4611573Srgrimes{ 4621573Srgrimes 46384260Sobrien if (el->el_line.cursor == el->el_line.lastchar) 46484260Sobrien return (CC_ERROR); 4651573Srgrimes 46684260Sobrien el->el_line.cursor = cv__endword(el->el_line.cursor, 467148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isWord); 4681573Srgrimes 469148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 47084260Sobrien el->el_line.cursor++; 47184260Sobrien cv_delfini(el); 47284260Sobrien return (CC_REFRESH); 47384260Sobrien } 47484260Sobrien return (CC_CURSOR); 4751573Srgrimes} 4761573Srgrimes 4771573Srgrimes 478148834Sstefanf/* vi_end_word(): 4791573Srgrimes * Vi move to the end of the current word 4801573Srgrimes * [e] 4811573Srgrimes */ 4821573Srgrimesprotected el_action_t 4831573Srgrimes/*ARGSUSED*/ 484148834Sstefanfvi_end_word(EditLine *el, int c __unused) 4851573Srgrimes{ 4861573Srgrimes 48784260Sobrien if (el->el_line.cursor == el->el_line.lastchar) 48884260Sobrien return (CC_ERROR); 4891573Srgrimes 49084260Sobrien el->el_line.cursor = cv__endword(el->el_line.cursor, 491148834Sstefanf el->el_line.lastchar, el->el_state.argument, cv__isword); 4921573Srgrimes 493148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 49484260Sobrien el->el_line.cursor++; 49584260Sobrien cv_delfini(el); 49684260Sobrien return (CC_REFRESH); 49784260Sobrien } 49884260Sobrien return (CC_CURSOR); 4991573Srgrimes} 5001573Srgrimes 5011573Srgrimes 5021573Srgrimes/* vi_undo(): 5031573Srgrimes * Vi undo last change 5041573Srgrimes * [u] 5051573Srgrimes */ 5061573Srgrimesprotected el_action_t 5071573Srgrimes/*ARGSUSED*/ 508148834Sstefanfvi_undo(EditLine *el, int c __unused) 5091573Srgrimes{ 510148834Sstefanf c_undo_t un = el->el_chared.c_undo; 5111573Srgrimes 512148834Sstefanf if (un.len == -1) 513148834Sstefanf return CC_ERROR; 5141573Srgrimes 515148834Sstefanf /* switch line buffer and undo buffer */ 516148834Sstefanf el->el_chared.c_undo.buf = el->el_line.buffer; 517148834Sstefanf el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; 518148834Sstefanf el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer; 519148834Sstefanf el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); 520148834Sstefanf el->el_line.buffer = un.buf; 521148834Sstefanf el->el_line.cursor = un.buf + un.cursor; 522148834Sstefanf el->el_line.lastchar = un.buf + un.len; 5231573Srgrimes 52484260Sobrien return (CC_REFRESH); 5251573Srgrimes} 5261573Srgrimes 5271573Srgrimes 5281573Srgrimes/* vi_command_mode(): 5291573Srgrimes * Vi enter command mode (use alternative key bindings) 5301573Srgrimes * [<ESC>] 5311573Srgrimes */ 5321573Srgrimesprotected el_action_t 5331573Srgrimes/*ARGSUSED*/ 534148834Sstefanfvi_command_mode(EditLine *el, int c __unused) 5351573Srgrimes{ 5361573Srgrimes 53784260Sobrien /* [Esc] cancels pending action */ 53884260Sobrien el->el_chared.c_vcmd.action = NOP; 53984260Sobrien el->el_chared.c_vcmd.pos = 0; 5401573Srgrimes 54184260Sobrien el->el_state.doingarg = 0; 54284260Sobrien 54384260Sobrien el->el_state.inputmode = MODE_INSERT; 54484260Sobrien el->el_map.current = el->el_map.alt; 5451573Srgrimes#ifdef VI_MOVE 54684260Sobrien if (el->el_line.cursor > el->el_line.buffer) 54784260Sobrien el->el_line.cursor--; 5481573Srgrimes#endif 54984260Sobrien return (CC_CURSOR); 5501573Srgrimes} 5511573Srgrimes 55284260Sobrien 5531573Srgrimes/* vi_zero(): 5548870Srgrimes * Vi move to the beginning of line 5551573Srgrimes * [0] 5561573Srgrimes */ 5571573Srgrimesprotected el_action_t 55884260Sobrienvi_zero(EditLine *el, int c) 5591573Srgrimes{ 56084260Sobrien 561148834Sstefanf if (el->el_state.doingarg) 562148834Sstefanf return ed_argument_digit(el, c); 563148834Sstefanf 564148834Sstefanf el->el_line.cursor = el->el_line.buffer; 565148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 566148834Sstefanf cv_delfini(el); 567148834Sstefanf return (CC_REFRESH); 56884260Sobrien } 569148834Sstefanf return (CC_CURSOR); 5701573Srgrimes} 5711573Srgrimes 5721573Srgrimes 5731573Srgrimes/* vi_delete_prev_char(): 5748870Srgrimes * Vi move to previous character (backspace) 575148834Sstefanf * [^H] in insert mode only 5768870Srgrimes */ 5771573Srgrimesprotected el_action_t 5781573Srgrimes/*ARGSUSED*/ 579148834Sstefanfvi_delete_prev_char(EditLine *el, int c __unused) 5801573Srgrimes{ 5811573Srgrimes 582148834Sstefanf if (el->el_line.cursor <= el->el_line.buffer) 58384260Sobrien return (CC_ERROR); 5841573Srgrimes 585148834Sstefanf c_delbefore1(el); 586148834Sstefanf el->el_line.cursor--; 58784260Sobrien return (CC_REFRESH); 58884260Sobrien} 5891573Srgrimes 59084260Sobrien 5911573Srgrimes/* vi_list_or_eof(): 5921573Srgrimes * Vi list choices for completion or indicate end of file if empty line 5931573Srgrimes * [^D] 5941573Srgrimes */ 5951573Srgrimesprotected el_action_t 5961573Srgrimes/*ARGSUSED*/ 597148834Sstefanfvi_list_or_eof(EditLine *el, int c __unused) 5981573Srgrimes{ 59984260Sobrien 600148834Sstefanf if (el->el_line.cursor == el->el_line.lastchar) { 601148834Sstefanf if (el->el_line.cursor == el->el_line.buffer) { 602148834Sstefanf term_overwrite(el, STReof, 4); /* then do a EOF */ 603148834Sstefanf term__flush(); 604148834Sstefanf return (CC_EOF); 605148834Sstefanf } else { 606148834Sstefanf /* 607148834Sstefanf * Here we could list completions, but it is an 608148834Sstefanf * error right now 609148834Sstefanf */ 610148834Sstefanf term_beep(el); 611148834Sstefanf return (CC_ERROR); 612148834Sstefanf } 613148834Sstefanf } else { 6141573Srgrimes#ifdef notyet 61584260Sobrien re_goto_bottom(el); 61684260Sobrien *el->el_line.lastchar = '\0'; /* just in case */ 61784260Sobrien return (CC_LIST_CHOICES); 618148834Sstefanf#else 619148834Sstefanf /* 620148834Sstefanf * Just complain for now. 621148834Sstefanf */ 622148834Sstefanf term_beep(el); 623148834Sstefanf return (CC_ERROR); 624148834Sstefanf#endif 62584260Sobrien } 6261573Srgrimes} 6271573Srgrimes 6281573Srgrimes 6291573Srgrimes/* vi_kill_line_prev(): 6308870Srgrimes * Vi cut from beginning of line to cursor 6311573Srgrimes * [^U] 6321573Srgrimes */ 6331573Srgrimesprotected el_action_t 6341573Srgrimes/*ARGSUSED*/ 635148834Sstefanfvi_kill_line_prev(EditLine *el, int c __unused) 6361573Srgrimes{ 63784260Sobrien char *kp, *cp; 6381573Srgrimes 63984260Sobrien cp = el->el_line.buffer; 64084260Sobrien kp = el->el_chared.c_kill.buf; 64184260Sobrien while (cp < el->el_line.cursor) 64284260Sobrien *kp++ = *cp++; /* copy it */ 64384260Sobrien el->el_chared.c_kill.last = kp; 64484260Sobrien c_delbefore(el, el->el_line.cursor - el->el_line.buffer); 64584260Sobrien el->el_line.cursor = el->el_line.buffer; /* zap! */ 64684260Sobrien return (CC_REFRESH); 6471573Srgrimes} 6481573Srgrimes 6491573Srgrimes 6501573Srgrimes/* vi_search_prev(): 6511573Srgrimes * Vi search history previous 6521573Srgrimes * [?] 6531573Srgrimes */ 6541573Srgrimesprotected el_action_t 6551573Srgrimes/*ARGSUSED*/ 656148834Sstefanfvi_search_prev(EditLine *el, int c __unused) 6571573Srgrimes{ 65884260Sobrien 65984260Sobrien return (cv_search(el, ED_SEARCH_PREV_HISTORY)); 6601573Srgrimes} 6611573Srgrimes 6621573Srgrimes 6631573Srgrimes/* vi_search_next(): 6641573Srgrimes * Vi search history next 6651573Srgrimes * [/] 6661573Srgrimes */ 6671573Srgrimesprotected el_action_t 6681573Srgrimes/*ARGSUSED*/ 669148834Sstefanfvi_search_next(EditLine *el, int c __unused) 6701573Srgrimes{ 67184260Sobrien 67284260Sobrien return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); 6731573Srgrimes} 6741573Srgrimes 6751573Srgrimes 6761573Srgrimes/* vi_repeat_search_next(): 6771573Srgrimes * Vi repeat current search in the same search direction 6781573Srgrimes * [n] 6791573Srgrimes */ 6801573Srgrimesprotected el_action_t 6811573Srgrimes/*ARGSUSED*/ 682148834Sstefanfvi_repeat_search_next(EditLine *el, int c __unused) 6831573Srgrimes{ 68484260Sobrien 68584260Sobrien if (el->el_search.patlen == 0) 68684260Sobrien return (CC_ERROR); 68784260Sobrien else 68884260Sobrien return (cv_repeat_srch(el, el->el_search.patdir)); 6891573Srgrimes} 6901573Srgrimes 6911573Srgrimes 6921573Srgrimes/* vi_repeat_search_prev(): 6931573Srgrimes * Vi repeat current search in the opposite search direction 6941573Srgrimes * [N] 6951573Srgrimes */ 6961573Srgrimes/*ARGSUSED*/ 6971573Srgrimesprotected el_action_t 698148834Sstefanfvi_repeat_search_prev(EditLine *el, int c __unused) 6991573Srgrimes{ 70084260Sobrien 70184260Sobrien if (el->el_search.patlen == 0) 70284260Sobrien return (CC_ERROR); 70384260Sobrien else 70484260Sobrien return (cv_repeat_srch(el, 70584260Sobrien el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? 70684260Sobrien ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY)); 7071573Srgrimes} 7081573Srgrimes 7091573Srgrimes 7101573Srgrimes/* vi_next_char(): 7111573Srgrimes * Vi move to the character specified next 7121573Srgrimes * [f] 7131573Srgrimes */ 7141573Srgrimesprotected el_action_t 7151573Srgrimes/*ARGSUSED*/ 716148834Sstefanfvi_next_char(EditLine *el, int c __unused) 7171573Srgrimes{ 718148834Sstefanf return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); 7191573Srgrimes} 7201573Srgrimes 7211573Srgrimes 7221573Srgrimes/* vi_prev_char(): 7231573Srgrimes * Vi move to the character specified previous 7241573Srgrimes * [F] 7251573Srgrimes */ 7261573Srgrimesprotected el_action_t 7271573Srgrimes/*ARGSUSED*/ 728148834Sstefanfvi_prev_char(EditLine *el, int c __unused) 7291573Srgrimes{ 730148834Sstefanf return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); 7311573Srgrimes} 7321573Srgrimes 7331573Srgrimes 7341573Srgrimes/* vi_to_next_char(): 7351573Srgrimes * Vi move up to the character specified next 7361573Srgrimes * [t] 7371573Srgrimes */ 7381573Srgrimesprotected el_action_t 7391573Srgrimes/*ARGSUSED*/ 740148834Sstefanfvi_to_next_char(EditLine *el, int c __unused) 7411573Srgrimes{ 742148834Sstefanf return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); 7431573Srgrimes} 7441573Srgrimes 7451573Srgrimes 7461573Srgrimes/* vi_to_prev_char(): 7471573Srgrimes * Vi move up to the character specified previous 7481573Srgrimes * [T] 7491573Srgrimes */ 7501573Srgrimesprotected el_action_t 7511573Srgrimes/*ARGSUSED*/ 752148834Sstefanfvi_to_prev_char(EditLine *el, int c __unused) 7531573Srgrimes{ 754148834Sstefanf return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); 7551573Srgrimes} 7561573Srgrimes 7571573Srgrimes 7581573Srgrimes/* vi_repeat_next_char(): 7591573Srgrimes * Vi repeat current character search in the same search direction 7601573Srgrimes * [;] 7611573Srgrimes */ 7621573Srgrimesprotected el_action_t 7631573Srgrimes/*ARGSUSED*/ 764148834Sstefanfvi_repeat_next_char(EditLine *el, int c __unused) 7651573Srgrimes{ 7661573Srgrimes 767148834Sstefanf return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, 768148834Sstefanf el->el_state.argument, el->el_search.chatflg); 7691573Srgrimes} 7701573Srgrimes 7711573Srgrimes 7721573Srgrimes/* vi_repeat_prev_char(): 7731573Srgrimes * Vi repeat current character search in the opposite search direction 7741573Srgrimes * [,] 7751573Srgrimes */ 7761573Srgrimesprotected el_action_t 7771573Srgrimes/*ARGSUSED*/ 778148834Sstefanfvi_repeat_prev_char(EditLine *el, int c __unused) 7791573Srgrimes{ 780148834Sstefanf el_action_t r; 781148834Sstefanf int dir = el->el_search.chadir; 7821573Srgrimes 783148834Sstefanf r = cv_csearch(el, -dir, el->el_search.chacha, 784148834Sstefanf el->el_state.argument, el->el_search.chatflg); 785148834Sstefanf el->el_search.chadir = dir; 786148834Sstefanf return r; 787148834Sstefanf} 78884260Sobrien 789148834Sstefanf 790148834Sstefanf/* vi_match(): 791148834Sstefanf * Vi go to matching () {} or [] 792148834Sstefanf * [%] 793148834Sstefanf */ 794148834Sstefanfprotected el_action_t 795148834Sstefanf/*ARGSUSED*/ 796148834Sstefanfvi_match(EditLine *el, int c) 797148834Sstefanf{ 798148834Sstefanf const char match_chars[] = "()[]{}"; 799148834Sstefanf char *cp; 800148834Sstefanf int delta, i, count; 801148834Sstefanf char o_ch, c_ch; 802148834Sstefanf 803148834Sstefanf *el->el_line.lastchar = '\0'; /* just in case */ 804148834Sstefanf 805148834Sstefanf i = strcspn(el->el_line.cursor, match_chars); 806148834Sstefanf o_ch = el->el_line.cursor[i]; 807148834Sstefanf if (o_ch == 0) 808148834Sstefanf return CC_ERROR; 809148834Sstefanf delta = strchr(match_chars, o_ch) - match_chars; 810148834Sstefanf c_ch = match_chars[delta ^ 1]; 811148834Sstefanf count = 1; 812148834Sstefanf delta = 1 - (delta & 1) * 2; 813148834Sstefanf 814148834Sstefanf for (cp = &el->el_line.cursor[i]; count; ) { 815148834Sstefanf cp += delta; 816148834Sstefanf if (cp < el->el_line.buffer || cp >= el->el_line.lastchar) 817148834Sstefanf return CC_ERROR; 818148834Sstefanf if (*cp == o_ch) 819148834Sstefanf count++; 820148834Sstefanf else if (*cp == c_ch) 821148834Sstefanf count--; 822148834Sstefanf } 823148834Sstefanf 824148834Sstefanf el->el_line.cursor = cp; 825148834Sstefanf 826148834Sstefanf if (el->el_chared.c_vcmd.action != NOP) { 827148834Sstefanf /* NB posix says char under cursor should NOT be deleted 828148834Sstefanf for -ve delta - this is different to netbsd vi. */ 829148834Sstefanf if (delta > 0) 830148834Sstefanf el->el_line.cursor++; 831148834Sstefanf cv_delfini(el); 832148834Sstefanf return (CC_REFRESH); 833148834Sstefanf } 834148834Sstefanf return (CC_CURSOR); 8351573Srgrimes} 836148834Sstefanf 837148834Sstefanf/* vi_undo_line(): 838148834Sstefanf * Vi undo all changes to line 839148834Sstefanf * [U] 840148834Sstefanf */ 841148834Sstefanfprotected el_action_t 842148834Sstefanf/*ARGSUSED*/ 843148834Sstefanfvi_undo_line(EditLine *el, int c) 844148834Sstefanf{ 845148834Sstefanf 846148834Sstefanf cv_undo(el); 847148834Sstefanf return hist_get(el); 848148834Sstefanf} 849148834Sstefanf 850148834Sstefanf/* vi_to_column(): 851148834Sstefanf * Vi go to specified column 852148834Sstefanf * [|] 853148834Sstefanf * NB netbsd vi goes to screen column 'n', posix says nth character 854148834Sstefanf */ 855148834Sstefanfprotected el_action_t 856148834Sstefanf/*ARGSUSED*/ 857148834Sstefanfvi_to_column(EditLine *el, int c) 858148834Sstefanf{ 859148834Sstefanf 860148834Sstefanf el->el_line.cursor = el->el_line.buffer; 861148834Sstefanf el->el_state.argument--; 862148834Sstefanf return ed_next_char(el, 0); 863148834Sstefanf} 864148834Sstefanf 865148834Sstefanf/* vi_yank_end(): 866148834Sstefanf * Vi yank to end of line 867148834Sstefanf * [Y] 868148834Sstefanf */ 869148834Sstefanfprotected el_action_t 870148834Sstefanf/*ARGSUSED*/ 871148834Sstefanfvi_yank_end(EditLine *el, int c) 872148834Sstefanf{ 873148834Sstefanf 874148834Sstefanf cv_yank(el, el->el_line.cursor, 875148834Sstefanf el->el_line.lastchar - el->el_line.cursor); 876148834Sstefanf return CC_REFRESH; 877148834Sstefanf} 878148834Sstefanf 879148834Sstefanf/* vi_yank(): 880148834Sstefanf * Vi yank 881148834Sstefanf * [y] 882148834Sstefanf */ 883148834Sstefanfprotected el_action_t 884148834Sstefanf/*ARGSUSED*/ 885148834Sstefanfvi_yank(EditLine *el, int c) 886148834Sstefanf{ 887148834Sstefanf 888148834Sstefanf return cv_action(el, YANK); 889148834Sstefanf} 890148834Sstefanf 891148834Sstefanf/* vi_comment_out(): 892148834Sstefanf * Vi comment out current command 893148848Sstefanf * [#] 894148834Sstefanf */ 895148834Sstefanfprotected el_action_t 896148834Sstefanf/*ARGSUSED*/ 897148834Sstefanfvi_comment_out(EditLine *el, int c) 898148834Sstefanf{ 899148834Sstefanf 900148834Sstefanf el->el_line.cursor = el->el_line.buffer; 901148834Sstefanf c_insert(el, 1); 902148834Sstefanf *el->el_line.cursor = '#'; 903148834Sstefanf re_refresh(el); 904148834Sstefanf return ed_newline(el, 0); 905148834Sstefanf} 906148834Sstefanf 907148834Sstefanf/* vi_alias(): 908148834Sstefanf * Vi include shell alias 909148834Sstefanf * [@] 910148848Sstefanf * NB: posix implies that we should enter insert mode, however 911148834Sstefanf * this is against historical precedent... 912148834Sstefanf */ 913148834Sstefanfprotected el_action_t 914148834Sstefanf/*ARGSUSED*/ 915148834Sstefanfvi_alias(EditLine *el, int c) 916148834Sstefanf{ 917148834Sstefanf#ifdef __weak_extern 918148834Sstefanf char alias_name[3]; 919148834Sstefanf char *alias_text; 920148834Sstefanf extern char *get_alias_text(const char *); 921148834Sstefanf __weak_extern(get_alias_text); 922148834Sstefanf 923148834Sstefanf if (get_alias_text == 0) { 924148834Sstefanf return CC_ERROR; 925148834Sstefanf } 926148834Sstefanf 927148834Sstefanf alias_name[0] = '_'; 928148834Sstefanf alias_name[2] = 0; 929148834Sstefanf if (el_getc(el, &alias_name[1]) != 1) 930148834Sstefanf return CC_ERROR; 931148834Sstefanf 932148834Sstefanf alias_text = get_alias_text(alias_name); 933148834Sstefanf if (alias_text != NULL) 934148834Sstefanf el_push(el, alias_text); 935148834Sstefanf return CC_NORM; 936148834Sstefanf#else 937148834Sstefanf return CC_ERROR; 938148834Sstefanf#endif 939148834Sstefanf} 940148834Sstefanf 941148834Sstefanf/* vi_to_history_line(): 942148834Sstefanf * Vi go to specified history file line. 943148834Sstefanf * [G] 944148834Sstefanf */ 945148834Sstefanfprotected el_action_t 946148834Sstefanf/*ARGSUSED*/ 947148834Sstefanfvi_to_history_line(EditLine *el, int c) 948148834Sstefanf{ 949148834Sstefanf int sv_event_no = el->el_history.eventno; 950148834Sstefanf el_action_t rval; 951148834Sstefanf 952148834Sstefanf 953148834Sstefanf if (el->el_history.eventno == 0) { 954148834Sstefanf (void) strncpy(el->el_history.buf, el->el_line.buffer, 955148834Sstefanf EL_BUFSIZ); 956148834Sstefanf el->el_history.last = el->el_history.buf + 957148834Sstefanf (el->el_line.lastchar - el->el_line.buffer); 958148834Sstefanf } 959148834Sstefanf 960148834Sstefanf /* Lack of a 'count' means oldest, not 1 */ 961148834Sstefanf if (!el->el_state.doingarg) { 962148834Sstefanf el->el_history.eventno = 0x7fffffff; 963148834Sstefanf hist_get(el); 964148834Sstefanf } else { 965148834Sstefanf /* This is brain dead, all the rest of this code counts 966148834Sstefanf * upwards going into the past. Here we need count in the 967148834Sstefanf * other direction (to match the output of fc -l). 968148834Sstefanf * I could change the world, but this seems to suffice. 969148834Sstefanf */ 970148834Sstefanf el->el_history.eventno = 1; 971148834Sstefanf if (hist_get(el) == CC_ERROR) 972148834Sstefanf return CC_ERROR; 973148834Sstefanf el->el_history.eventno = 1 + el->el_history.ev.num 974148834Sstefanf - el->el_state.argument; 975148834Sstefanf if (el->el_history.eventno < 0) { 976148834Sstefanf el->el_history.eventno = sv_event_no; 977148834Sstefanf return CC_ERROR; 978148834Sstefanf } 979148834Sstefanf } 980148834Sstefanf rval = hist_get(el); 981148834Sstefanf if (rval == CC_ERROR) 982148834Sstefanf el->el_history.eventno = sv_event_no; 983148834Sstefanf return rval; 984148834Sstefanf} 985148834Sstefanf 986148834Sstefanf/* vi_histedit(): 987148834Sstefanf * Vi edit history line with vi 988148834Sstefanf * [v] 989148834Sstefanf */ 990148834Sstefanfprotected el_action_t 991148834Sstefanf/*ARGSUSED*/ 992148834Sstefanfvi_histedit(EditLine *el, int c) 993148834Sstefanf{ 994148834Sstefanf int fd; 995148834Sstefanf pid_t pid; 996148834Sstefanf int st; 997148834Sstefanf char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; 998148834Sstefanf char *cp; 999148834Sstefanf 1000148834Sstefanf if (el->el_state.doingarg) { 1001148834Sstefanf if (vi_to_history_line(el, 0) == CC_ERROR) 1002148834Sstefanf return CC_ERROR; 1003148834Sstefanf } 1004148834Sstefanf 1005148834Sstefanf fd = mkstemp(tempfile); 1006148834Sstefanf if (fd < 0) 1007148834Sstefanf return CC_ERROR; 1008148834Sstefanf cp = el->el_line.buffer; 1009148834Sstefanf write(fd, cp, el->el_line.lastchar - cp +0u); 1010148834Sstefanf write(fd, "\n", 1); 1011148834Sstefanf pid = fork(); 1012148834Sstefanf switch (pid) { 1013148834Sstefanf case -1: 1014148834Sstefanf close(fd); 1015148834Sstefanf unlink(tempfile); 1016148834Sstefanf return CC_ERROR; 1017148834Sstefanf case 0: 1018148834Sstefanf close(fd); 1019148834Sstefanf execlp("vi", "vi", tempfile, NULL); 1020148834Sstefanf exit(0); 1021148834Sstefanf /*NOTREACHED*/ 1022148834Sstefanf default: 1023148834Sstefanf while (waitpid(pid, &st, 0) != pid) 1024148834Sstefanf continue; 1025148834Sstefanf lseek(fd, 0ll, SEEK_SET); 1026148834Sstefanf st = read(fd, cp, el->el_line.limit - cp +0u); 1027148834Sstefanf if (st > 0 && cp[st - 1] == '\n') 1028148834Sstefanf st--; 1029148834Sstefanf el->el_line.cursor = cp; 1030148834Sstefanf el->el_line.lastchar = cp + st; 1031148834Sstefanf break; 1032148834Sstefanf } 1033148834Sstefanf 1034148834Sstefanf close(fd); 1035148834Sstefanf unlink(tempfile); 1036148834Sstefanf /* return CC_REFRESH; */ 1037148834Sstefanf return ed_newline(el, 0); 1038148834Sstefanf} 1039148834Sstefanf 1040148834Sstefanf/* vi_history_word(): 1041148834Sstefanf * Vi append word from previous input line 1042148834Sstefanf * [_] 1043148834Sstefanf * Who knows where this one came from! 1044148834Sstefanf * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' 1045148834Sstefanf */ 1046148834Sstefanfprotected el_action_t 1047148834Sstefanf/*ARGSUSED*/ 1048148834Sstefanfvi_history_word(EditLine *el, int c) 1049148834Sstefanf{ 1050148834Sstefanf const char *wp = HIST_FIRST(el); 1051148834Sstefanf const char *wep, *wsp; 1052148834Sstefanf int len; 1053148834Sstefanf char *cp; 1054148834Sstefanf const char *lim; 1055148834Sstefanf 1056148834Sstefanf if (wp == NULL) 1057148834Sstefanf return CC_ERROR; 1058148834Sstefanf 1059148834Sstefanf wep = wsp = 0; 1060148834Sstefanf do { 1061148834Sstefanf while (isspace((unsigned char)*wp)) 1062148834Sstefanf wp++; 1063148834Sstefanf if (*wp == 0) 1064148834Sstefanf break; 1065148834Sstefanf wsp = wp; 1066148834Sstefanf while (*wp && !isspace((unsigned char)*wp)) 1067148834Sstefanf wp++; 1068148834Sstefanf wep = wp; 1069148834Sstefanf } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0); 1070148834Sstefanf 1071148834Sstefanf if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) 1072148834Sstefanf return CC_ERROR; 1073148834Sstefanf 1074148834Sstefanf cv_undo(el); 1075148834Sstefanf len = wep - wsp; 1076148834Sstefanf if (el->el_line.cursor < el->el_line.lastchar) 1077148834Sstefanf el->el_line.cursor++; 1078148834Sstefanf c_insert(el, len + 1); 1079148834Sstefanf cp = el->el_line.cursor; 1080148834Sstefanf lim = el->el_line.limit; 1081148834Sstefanf if (cp < lim) 1082148834Sstefanf *cp++ = ' '; 1083148834Sstefanf while (wsp < wep && cp < lim) 1084148834Sstefanf *cp++ = *wsp++; 1085148834Sstefanf el->el_line.cursor = cp; 1086148834Sstefanf 1087148834Sstefanf el->el_map.current = el->el_map.key; 1088148834Sstefanf return CC_REFRESH; 1089148834Sstefanf} 1090148834Sstefanf 1091148834Sstefanf/* vi_redo(): 1092148834Sstefanf * Vi redo last non-motion command 1093148834Sstefanf * [.] 1094148834Sstefanf */ 1095148834Sstefanfprotected el_action_t 1096148834Sstefanf/*ARGSUSED*/ 1097148834Sstefanfvi_redo(EditLine *el, int c) 1098148834Sstefanf{ 1099148834Sstefanf c_redo_t *r = &el->el_chared.c_redo; 1100148834Sstefanf 1101148834Sstefanf if (!el->el_state.doingarg && r->count) { 1102148834Sstefanf el->el_state.doingarg = 1; 1103148834Sstefanf el->el_state.argument = r->count; 1104148834Sstefanf } 1105148834Sstefanf 1106148834Sstefanf el->el_chared.c_vcmd.pos = el->el_line.cursor; 1107148834Sstefanf el->el_chared.c_vcmd.action = r->action; 1108148834Sstefanf if (r->pos != r->buf) { 1109148834Sstefanf if (r->pos + 1 > r->lim) 1110148834Sstefanf /* sanity */ 1111148834Sstefanf r->pos = r->lim - 1; 1112148834Sstefanf r->pos[0] = 0; 1113148834Sstefanf el_push(el, r->buf); 1114148834Sstefanf } 1115148834Sstefanf 1116148834Sstefanf el->el_state.thiscmd = r->cmd; 1117148834Sstefanf el->el_state.thisch = r->ch; 1118148834Sstefanf return (*el->el_map.func[r->cmd])(el, r->ch); 1119148834Sstefanf} 1120