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