1*84b940c1SJohn Marino /* $NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $ */ 232fe07f8SJohn Marino 332fe07f8SJohn Marino /*- 432fe07f8SJohn Marino * Copyright (c) 1992, 1993 532fe07f8SJohn Marino * The Regents of the University of California. All rights reserved. 632fe07f8SJohn Marino * 732fe07f8SJohn Marino * This code is derived from software contributed to Berkeley by 832fe07f8SJohn Marino * Christos Zoulas of Cornell University. 932fe07f8SJohn Marino * 1032fe07f8SJohn Marino * Redistribution and use in source and binary forms, with or without 1132fe07f8SJohn Marino * modification, are permitted provided that the following conditions 1232fe07f8SJohn Marino * are met: 1332fe07f8SJohn Marino * 1. Redistributions of source code must retain the above copyright 1432fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer. 1532fe07f8SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 1632fe07f8SJohn Marino * notice, this list of conditions and the following disclaimer in the 1732fe07f8SJohn Marino * documentation and/or other materials provided with the distribution. 1832fe07f8SJohn Marino * 3. Neither the name of the University nor the names of its contributors 1932fe07f8SJohn Marino * may be used to endorse or promote products derived from this software 2032fe07f8SJohn Marino * without specific prior written permission. 2132fe07f8SJohn Marino * 2232fe07f8SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2332fe07f8SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2432fe07f8SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2532fe07f8SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2632fe07f8SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2732fe07f8SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2832fe07f8SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2932fe07f8SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3032fe07f8SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3132fe07f8SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3232fe07f8SJohn Marino * SUCH DAMAGE. 3332fe07f8SJohn Marino */ 3432fe07f8SJohn Marino 3532fe07f8SJohn Marino #include "config.h" 3632fe07f8SJohn Marino #include <stdlib.h> 3732fe07f8SJohn Marino #include <unistd.h> 3832fe07f8SJohn Marino #include <limits.h> 3932fe07f8SJohn Marino #include <sys/wait.h> 4032fe07f8SJohn Marino 4132fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID) 4232fe07f8SJohn Marino #if 0 4332fe07f8SJohn Marino static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; 4432fe07f8SJohn Marino #else 45*84b940c1SJohn Marino __RCSID("$NetBSD: vi.c,v 1.45 2014/06/18 18:12:28 christos Exp $"); 4632fe07f8SJohn Marino #endif 4732fe07f8SJohn Marino #endif /* not lint && not SCCSID */ 4832fe07f8SJohn Marino 4932fe07f8SJohn Marino /* 5032fe07f8SJohn Marino * vi.c: Vi mode commands. 5132fe07f8SJohn Marino */ 5232fe07f8SJohn Marino #include "el.h" 5332fe07f8SJohn Marino 5432fe07f8SJohn Marino private el_action_t cv_action(EditLine *, Int); 5532fe07f8SJohn Marino private el_action_t cv_paste(EditLine *, Int); 5632fe07f8SJohn Marino 5732fe07f8SJohn Marino /* cv_action(): 5832fe07f8SJohn Marino * Handle vi actions. 5932fe07f8SJohn Marino */ 6032fe07f8SJohn Marino private el_action_t 6132fe07f8SJohn Marino cv_action(EditLine *el, Int c) 6232fe07f8SJohn Marino { 6332fe07f8SJohn Marino 6432fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 6532fe07f8SJohn Marino /* 'cc', 'dd' and (possibly) friends */ 6632fe07f8SJohn Marino if (c != (Int)el->el_chared.c_vcmd.action) 6732fe07f8SJohn Marino return CC_ERROR; 6832fe07f8SJohn Marino 6932fe07f8SJohn Marino if (!(c & YANK)) 7032fe07f8SJohn Marino cv_undo(el); 7132fe07f8SJohn Marino cv_yank(el, el->el_line.buffer, 7232fe07f8SJohn Marino (int)(el->el_line.lastchar - el->el_line.buffer)); 7332fe07f8SJohn Marino el->el_chared.c_vcmd.action = NOP; 7432fe07f8SJohn Marino el->el_chared.c_vcmd.pos = 0; 7532fe07f8SJohn Marino if (!(c & YANK)) { 7632fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer; 7732fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 7832fe07f8SJohn Marino } 7932fe07f8SJohn Marino if (c & INSERT) 8032fe07f8SJohn Marino el->el_map.current = el->el_map.key; 8132fe07f8SJohn Marino 8232fe07f8SJohn Marino return CC_REFRESH; 8332fe07f8SJohn Marino } 8432fe07f8SJohn Marino el->el_chared.c_vcmd.pos = el->el_line.cursor; 8532fe07f8SJohn Marino el->el_chared.c_vcmd.action = c; 8632fe07f8SJohn Marino return CC_ARGHACK; 8732fe07f8SJohn Marino } 8832fe07f8SJohn Marino 8932fe07f8SJohn Marino /* cv_paste(): 9032fe07f8SJohn Marino * Paste previous deletion before or after the cursor 9132fe07f8SJohn Marino */ 9232fe07f8SJohn Marino private el_action_t 9332fe07f8SJohn Marino cv_paste(EditLine *el, Int c) 9432fe07f8SJohn Marino { 9532fe07f8SJohn Marino c_kill_t *k = &el->el_chared.c_kill; 9632fe07f8SJohn Marino size_t len = (size_t)(k->last - k->buf); 9732fe07f8SJohn Marino 9832fe07f8SJohn Marino if (k->buf == NULL || len == 0) 9932fe07f8SJohn Marino return CC_ERROR; 10032fe07f8SJohn Marino #ifdef DEBUG_PASTE 10132fe07f8SJohn Marino (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf); 10232fe07f8SJohn Marino #endif 10332fe07f8SJohn Marino 10432fe07f8SJohn Marino cv_undo(el); 10532fe07f8SJohn Marino 10632fe07f8SJohn Marino if (!c && el->el_line.cursor < el->el_line.lastchar) 10732fe07f8SJohn Marino el->el_line.cursor++; 10832fe07f8SJohn Marino 10932fe07f8SJohn Marino c_insert(el, (int)len); 11032fe07f8SJohn Marino if (el->el_line.cursor + len > el->el_line.lastchar) 11132fe07f8SJohn Marino return CC_ERROR; 11232fe07f8SJohn Marino (void) memcpy(el->el_line.cursor, k->buf, len * 11332fe07f8SJohn Marino sizeof(*el->el_line.cursor)); 11432fe07f8SJohn Marino 11532fe07f8SJohn Marino return CC_REFRESH; 11632fe07f8SJohn Marino } 11732fe07f8SJohn Marino 11832fe07f8SJohn Marino 11932fe07f8SJohn Marino /* vi_paste_next(): 12032fe07f8SJohn Marino * Vi paste previous deletion to the right of the cursor 12132fe07f8SJohn Marino * [p] 12232fe07f8SJohn Marino */ 12332fe07f8SJohn Marino protected el_action_t 12432fe07f8SJohn Marino /*ARGSUSED*/ 12532fe07f8SJohn Marino vi_paste_next(EditLine *el, Int c __attribute__((__unused__))) 12632fe07f8SJohn Marino { 12732fe07f8SJohn Marino 12832fe07f8SJohn Marino return cv_paste(el, 0); 12932fe07f8SJohn Marino } 13032fe07f8SJohn Marino 13132fe07f8SJohn Marino 13232fe07f8SJohn Marino /* vi_paste_prev(): 13332fe07f8SJohn Marino * Vi paste previous deletion to the left of the cursor 13432fe07f8SJohn Marino * [P] 13532fe07f8SJohn Marino */ 13632fe07f8SJohn Marino protected el_action_t 13732fe07f8SJohn Marino /*ARGSUSED*/ 13832fe07f8SJohn Marino vi_paste_prev(EditLine *el, Int c __attribute__((__unused__))) 13932fe07f8SJohn Marino { 14032fe07f8SJohn Marino 14132fe07f8SJohn Marino return cv_paste(el, 1); 14232fe07f8SJohn Marino } 14332fe07f8SJohn Marino 14432fe07f8SJohn Marino 14532fe07f8SJohn Marino /* vi_prev_big_word(): 14632fe07f8SJohn Marino * Vi move to the previous space delimited word 14732fe07f8SJohn Marino * [B] 14832fe07f8SJohn Marino */ 14932fe07f8SJohn Marino protected el_action_t 15032fe07f8SJohn Marino /*ARGSUSED*/ 15132fe07f8SJohn Marino vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) 15232fe07f8SJohn Marino { 15332fe07f8SJohn Marino 15432fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer) 15532fe07f8SJohn Marino return CC_ERROR; 15632fe07f8SJohn Marino 15732fe07f8SJohn Marino el->el_line.cursor = cv_prev_word(el->el_line.cursor, 15832fe07f8SJohn Marino el->el_line.buffer, 15932fe07f8SJohn Marino el->el_state.argument, 16032fe07f8SJohn Marino cv__isWord); 16132fe07f8SJohn Marino 16232fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 16332fe07f8SJohn Marino cv_delfini(el); 16432fe07f8SJohn Marino return CC_REFRESH; 16532fe07f8SJohn Marino } 16632fe07f8SJohn Marino return CC_CURSOR; 16732fe07f8SJohn Marino } 16832fe07f8SJohn Marino 16932fe07f8SJohn Marino 17032fe07f8SJohn Marino /* vi_prev_word(): 17132fe07f8SJohn Marino * Vi move to the previous word 17232fe07f8SJohn Marino * [b] 17332fe07f8SJohn Marino */ 17432fe07f8SJohn Marino protected el_action_t 17532fe07f8SJohn Marino /*ARGSUSED*/ 17632fe07f8SJohn Marino vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) 17732fe07f8SJohn Marino { 17832fe07f8SJohn Marino 17932fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer) 18032fe07f8SJohn Marino return CC_ERROR; 18132fe07f8SJohn Marino 18232fe07f8SJohn Marino el->el_line.cursor = cv_prev_word(el->el_line.cursor, 18332fe07f8SJohn Marino el->el_line.buffer, 18432fe07f8SJohn Marino el->el_state.argument, 18532fe07f8SJohn Marino cv__isword); 18632fe07f8SJohn Marino 18732fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 18832fe07f8SJohn Marino cv_delfini(el); 18932fe07f8SJohn Marino return CC_REFRESH; 19032fe07f8SJohn Marino } 19132fe07f8SJohn Marino return CC_CURSOR; 19232fe07f8SJohn Marino } 19332fe07f8SJohn Marino 19432fe07f8SJohn Marino 19532fe07f8SJohn Marino /* vi_next_big_word(): 19632fe07f8SJohn Marino * Vi move to the next space delimited word 19732fe07f8SJohn Marino * [W] 19832fe07f8SJohn Marino */ 19932fe07f8SJohn Marino protected el_action_t 20032fe07f8SJohn Marino /*ARGSUSED*/ 20132fe07f8SJohn Marino vi_next_big_word(EditLine *el, Int c __attribute__((__unused__))) 20232fe07f8SJohn Marino { 20332fe07f8SJohn Marino 20432fe07f8SJohn Marino if (el->el_line.cursor >= el->el_line.lastchar - 1) 20532fe07f8SJohn Marino return CC_ERROR; 20632fe07f8SJohn Marino 20732fe07f8SJohn Marino el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 20832fe07f8SJohn Marino el->el_line.lastchar, el->el_state.argument, cv__isWord); 20932fe07f8SJohn Marino 21032fe07f8SJohn Marino if (el->el_map.type == MAP_VI) 21132fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 21232fe07f8SJohn Marino cv_delfini(el); 21332fe07f8SJohn Marino return CC_REFRESH; 21432fe07f8SJohn Marino } 21532fe07f8SJohn Marino return CC_CURSOR; 21632fe07f8SJohn Marino } 21732fe07f8SJohn Marino 21832fe07f8SJohn Marino 21932fe07f8SJohn Marino /* vi_next_word(): 22032fe07f8SJohn Marino * Vi move to the next word 22132fe07f8SJohn Marino * [w] 22232fe07f8SJohn Marino */ 22332fe07f8SJohn Marino protected el_action_t 22432fe07f8SJohn Marino /*ARGSUSED*/ 22532fe07f8SJohn Marino vi_next_word(EditLine *el, Int c __attribute__((__unused__))) 22632fe07f8SJohn Marino { 22732fe07f8SJohn Marino 22832fe07f8SJohn Marino if (el->el_line.cursor >= el->el_line.lastchar - 1) 22932fe07f8SJohn Marino return CC_ERROR; 23032fe07f8SJohn Marino 23132fe07f8SJohn Marino el->el_line.cursor = cv_next_word(el, el->el_line.cursor, 23232fe07f8SJohn Marino el->el_line.lastchar, el->el_state.argument, cv__isword); 23332fe07f8SJohn Marino 23432fe07f8SJohn Marino if (el->el_map.type == MAP_VI) 23532fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 23632fe07f8SJohn Marino cv_delfini(el); 23732fe07f8SJohn Marino return CC_REFRESH; 23832fe07f8SJohn Marino } 23932fe07f8SJohn Marino return CC_CURSOR; 24032fe07f8SJohn Marino } 24132fe07f8SJohn Marino 24232fe07f8SJohn Marino 24332fe07f8SJohn Marino /* vi_change_case(): 24432fe07f8SJohn Marino * Vi change case of character under the cursor and advance one character 24532fe07f8SJohn Marino * [~] 24632fe07f8SJohn Marino */ 24732fe07f8SJohn Marino protected el_action_t 24832fe07f8SJohn Marino vi_change_case(EditLine *el, Int c) 24932fe07f8SJohn Marino { 25032fe07f8SJohn Marino int i; 25132fe07f8SJohn Marino 25232fe07f8SJohn Marino if (el->el_line.cursor >= el->el_line.lastchar) 25332fe07f8SJohn Marino return CC_ERROR; 25432fe07f8SJohn Marino cv_undo(el); 25532fe07f8SJohn Marino for (i = 0; i < el->el_state.argument; i++) { 25632fe07f8SJohn Marino 25732fe07f8SJohn Marino c = *el->el_line.cursor; 25832fe07f8SJohn Marino if (Isupper(c)) 25932fe07f8SJohn Marino *el->el_line.cursor = Tolower(c); 26032fe07f8SJohn Marino else if (Islower(c)) 26132fe07f8SJohn Marino *el->el_line.cursor = Toupper(c); 26232fe07f8SJohn Marino 26332fe07f8SJohn Marino if (++el->el_line.cursor >= el->el_line.lastchar) { 26432fe07f8SJohn Marino el->el_line.cursor--; 26532fe07f8SJohn Marino re_fastaddc(el); 26632fe07f8SJohn Marino break; 26732fe07f8SJohn Marino } 26832fe07f8SJohn Marino re_fastaddc(el); 26932fe07f8SJohn Marino } 27032fe07f8SJohn Marino return CC_NORM; 27132fe07f8SJohn Marino } 27232fe07f8SJohn Marino 27332fe07f8SJohn Marino 27432fe07f8SJohn Marino /* vi_change_meta(): 27532fe07f8SJohn Marino * Vi change prefix command 27632fe07f8SJohn Marino * [c] 27732fe07f8SJohn Marino */ 27832fe07f8SJohn Marino protected el_action_t 27932fe07f8SJohn Marino /*ARGSUSED*/ 28032fe07f8SJohn Marino vi_change_meta(EditLine *el, Int c __attribute__((__unused__))) 28132fe07f8SJohn Marino { 28232fe07f8SJohn Marino 28332fe07f8SJohn Marino /* 28432fe07f8SJohn Marino * Delete with insert == change: first we delete and then we leave in 28532fe07f8SJohn Marino * insert mode. 28632fe07f8SJohn Marino */ 28732fe07f8SJohn Marino return cv_action(el, DELETE | INSERT); 28832fe07f8SJohn Marino } 28932fe07f8SJohn Marino 29032fe07f8SJohn Marino 29132fe07f8SJohn Marino /* vi_insert_at_bol(): 29232fe07f8SJohn Marino * Vi enter insert mode at the beginning of line 29332fe07f8SJohn Marino * [I] 29432fe07f8SJohn Marino */ 29532fe07f8SJohn Marino protected el_action_t 29632fe07f8SJohn Marino /*ARGSUSED*/ 29732fe07f8SJohn Marino vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__))) 29832fe07f8SJohn Marino { 29932fe07f8SJohn Marino 30032fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 30132fe07f8SJohn Marino cv_undo(el); 30232fe07f8SJohn Marino el->el_map.current = el->el_map.key; 30332fe07f8SJohn Marino return CC_CURSOR; 30432fe07f8SJohn Marino } 30532fe07f8SJohn Marino 30632fe07f8SJohn Marino 30732fe07f8SJohn Marino /* vi_replace_char(): 30832fe07f8SJohn Marino * Vi replace character under the cursor with the next character typed 30932fe07f8SJohn Marino * [r] 31032fe07f8SJohn Marino */ 31132fe07f8SJohn Marino protected el_action_t 31232fe07f8SJohn Marino /*ARGSUSED*/ 31332fe07f8SJohn Marino vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) 31432fe07f8SJohn Marino { 31532fe07f8SJohn Marino 31632fe07f8SJohn Marino if (el->el_line.cursor >= el->el_line.lastchar) 31732fe07f8SJohn Marino return CC_ERROR; 31832fe07f8SJohn Marino 31932fe07f8SJohn Marino el->el_map.current = el->el_map.key; 32032fe07f8SJohn Marino el->el_state.inputmode = MODE_REPLACE_1; 32132fe07f8SJohn Marino cv_undo(el); 32232fe07f8SJohn Marino return CC_ARGHACK; 32332fe07f8SJohn Marino } 32432fe07f8SJohn Marino 32532fe07f8SJohn Marino 32632fe07f8SJohn Marino /* vi_replace_mode(): 32732fe07f8SJohn Marino * Vi enter replace mode 32832fe07f8SJohn Marino * [R] 32932fe07f8SJohn Marino */ 33032fe07f8SJohn Marino protected el_action_t 33132fe07f8SJohn Marino /*ARGSUSED*/ 33232fe07f8SJohn Marino vi_replace_mode(EditLine *el, Int c __attribute__((__unused__))) 33332fe07f8SJohn Marino { 33432fe07f8SJohn Marino 33532fe07f8SJohn Marino el->el_map.current = el->el_map.key; 33632fe07f8SJohn Marino el->el_state.inputmode = MODE_REPLACE; 33732fe07f8SJohn Marino cv_undo(el); 33832fe07f8SJohn Marino return CC_NORM; 33932fe07f8SJohn Marino } 34032fe07f8SJohn Marino 34132fe07f8SJohn Marino 34232fe07f8SJohn Marino /* vi_substitute_char(): 34332fe07f8SJohn Marino * Vi replace character under the cursor and enter insert mode 34432fe07f8SJohn Marino * [s] 34532fe07f8SJohn Marino */ 34632fe07f8SJohn Marino protected el_action_t 34732fe07f8SJohn Marino /*ARGSUSED*/ 34832fe07f8SJohn Marino vi_substitute_char(EditLine *el, Int c __attribute__((__unused__))) 34932fe07f8SJohn Marino { 35032fe07f8SJohn Marino 35132fe07f8SJohn Marino c_delafter(el, el->el_state.argument); 35232fe07f8SJohn Marino el->el_map.current = el->el_map.key; 35332fe07f8SJohn Marino return CC_REFRESH; 35432fe07f8SJohn Marino } 35532fe07f8SJohn Marino 35632fe07f8SJohn Marino 35732fe07f8SJohn Marino /* vi_substitute_line(): 35832fe07f8SJohn Marino * Vi substitute entire line 35932fe07f8SJohn Marino * [S] 36032fe07f8SJohn Marino */ 36132fe07f8SJohn Marino protected el_action_t 36232fe07f8SJohn Marino /*ARGSUSED*/ 36332fe07f8SJohn Marino vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) 36432fe07f8SJohn Marino { 36532fe07f8SJohn Marino 36632fe07f8SJohn Marino cv_undo(el); 36732fe07f8SJohn Marino cv_yank(el, el->el_line.buffer, 36832fe07f8SJohn Marino (int)(el->el_line.lastchar - el->el_line.buffer)); 36932fe07f8SJohn Marino (void) em_kill_line(el, 0); 37032fe07f8SJohn Marino el->el_map.current = el->el_map.key; 37132fe07f8SJohn Marino return CC_REFRESH; 37232fe07f8SJohn Marino } 37332fe07f8SJohn Marino 37432fe07f8SJohn Marino 37532fe07f8SJohn Marino /* vi_change_to_eol(): 37632fe07f8SJohn Marino * Vi change to end of line 37732fe07f8SJohn Marino * [C] 37832fe07f8SJohn Marino */ 37932fe07f8SJohn Marino protected el_action_t 38032fe07f8SJohn Marino /*ARGSUSED*/ 38132fe07f8SJohn Marino vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) 38232fe07f8SJohn Marino { 38332fe07f8SJohn Marino 38432fe07f8SJohn Marino cv_undo(el); 38532fe07f8SJohn Marino cv_yank(el, el->el_line.cursor, 38632fe07f8SJohn Marino (int)(el->el_line.lastchar - el->el_line.cursor)); 38732fe07f8SJohn Marino (void) ed_kill_line(el, 0); 38832fe07f8SJohn Marino el->el_map.current = el->el_map.key; 38932fe07f8SJohn Marino return CC_REFRESH; 39032fe07f8SJohn Marino } 39132fe07f8SJohn Marino 39232fe07f8SJohn Marino 39332fe07f8SJohn Marino /* vi_insert(): 39432fe07f8SJohn Marino * Vi enter insert mode 39532fe07f8SJohn Marino * [i] 39632fe07f8SJohn Marino */ 39732fe07f8SJohn Marino protected el_action_t 39832fe07f8SJohn Marino /*ARGSUSED*/ 39932fe07f8SJohn Marino vi_insert(EditLine *el, Int c __attribute__((__unused__))) 40032fe07f8SJohn Marino { 40132fe07f8SJohn Marino 40232fe07f8SJohn Marino el->el_map.current = el->el_map.key; 40332fe07f8SJohn Marino cv_undo(el); 40432fe07f8SJohn Marino return CC_NORM; 40532fe07f8SJohn Marino } 40632fe07f8SJohn Marino 40732fe07f8SJohn Marino 40832fe07f8SJohn Marino /* vi_add(): 40932fe07f8SJohn Marino * Vi enter insert mode after the cursor 41032fe07f8SJohn Marino * [a] 41132fe07f8SJohn Marino */ 41232fe07f8SJohn Marino protected el_action_t 41332fe07f8SJohn Marino /*ARGSUSED*/ 41432fe07f8SJohn Marino vi_add(EditLine *el, Int c __attribute__((__unused__))) 41532fe07f8SJohn Marino { 41632fe07f8SJohn Marino int ret; 41732fe07f8SJohn Marino 41832fe07f8SJohn Marino el->el_map.current = el->el_map.key; 41932fe07f8SJohn Marino if (el->el_line.cursor < el->el_line.lastchar) { 42032fe07f8SJohn Marino el->el_line.cursor++; 42132fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.lastchar) 42232fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar; 42332fe07f8SJohn Marino ret = CC_CURSOR; 42432fe07f8SJohn Marino } else 42532fe07f8SJohn Marino ret = CC_NORM; 42632fe07f8SJohn Marino 42732fe07f8SJohn Marino cv_undo(el); 42832fe07f8SJohn Marino 42932fe07f8SJohn Marino return (el_action_t)ret; 43032fe07f8SJohn Marino } 43132fe07f8SJohn Marino 43232fe07f8SJohn Marino 43332fe07f8SJohn Marino /* vi_add_at_eol(): 43432fe07f8SJohn Marino * Vi enter insert mode at end of line 43532fe07f8SJohn Marino * [A] 43632fe07f8SJohn Marino */ 43732fe07f8SJohn Marino protected el_action_t 43832fe07f8SJohn Marino /*ARGSUSED*/ 43932fe07f8SJohn Marino vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__))) 44032fe07f8SJohn Marino { 44132fe07f8SJohn Marino 44232fe07f8SJohn Marino el->el_map.current = el->el_map.key; 44332fe07f8SJohn Marino el->el_line.cursor = el->el_line.lastchar; 44432fe07f8SJohn Marino cv_undo(el); 44532fe07f8SJohn Marino return CC_CURSOR; 44632fe07f8SJohn Marino } 44732fe07f8SJohn Marino 44832fe07f8SJohn Marino 44932fe07f8SJohn Marino /* vi_delete_meta(): 45032fe07f8SJohn Marino * Vi delete prefix command 45132fe07f8SJohn Marino * [d] 45232fe07f8SJohn Marino */ 45332fe07f8SJohn Marino protected el_action_t 45432fe07f8SJohn Marino /*ARGSUSED*/ 45532fe07f8SJohn Marino vi_delete_meta(EditLine *el, Int c __attribute__((__unused__))) 45632fe07f8SJohn Marino { 45732fe07f8SJohn Marino 45832fe07f8SJohn Marino return cv_action(el, DELETE); 45932fe07f8SJohn Marino } 46032fe07f8SJohn Marino 46132fe07f8SJohn Marino 46232fe07f8SJohn Marino /* vi_end_big_word(): 46332fe07f8SJohn Marino * Vi move to the end of the current space delimited word 46432fe07f8SJohn Marino * [E] 46532fe07f8SJohn Marino */ 46632fe07f8SJohn Marino protected el_action_t 46732fe07f8SJohn Marino /*ARGSUSED*/ 46832fe07f8SJohn Marino vi_end_big_word(EditLine *el, Int c __attribute__((__unused__))) 46932fe07f8SJohn Marino { 47032fe07f8SJohn Marino 47132fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar) 47232fe07f8SJohn Marino return CC_ERROR; 47332fe07f8SJohn Marino 47432fe07f8SJohn Marino el->el_line.cursor = cv__endword(el->el_line.cursor, 47532fe07f8SJohn Marino el->el_line.lastchar, el->el_state.argument, cv__isWord); 47632fe07f8SJohn Marino 47732fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 47832fe07f8SJohn Marino el->el_line.cursor++; 47932fe07f8SJohn Marino cv_delfini(el); 48032fe07f8SJohn Marino return CC_REFRESH; 48132fe07f8SJohn Marino } 48232fe07f8SJohn Marino return CC_CURSOR; 48332fe07f8SJohn Marino } 48432fe07f8SJohn Marino 48532fe07f8SJohn Marino 48632fe07f8SJohn Marino /* vi_end_word(): 48732fe07f8SJohn Marino * Vi move to the end of the current word 48832fe07f8SJohn Marino * [e] 48932fe07f8SJohn Marino */ 49032fe07f8SJohn Marino protected el_action_t 49132fe07f8SJohn Marino /*ARGSUSED*/ 49232fe07f8SJohn Marino vi_end_word(EditLine *el, Int c __attribute__((__unused__))) 49332fe07f8SJohn Marino { 49432fe07f8SJohn Marino 49532fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar) 49632fe07f8SJohn Marino return CC_ERROR; 49732fe07f8SJohn Marino 49832fe07f8SJohn Marino el->el_line.cursor = cv__endword(el->el_line.cursor, 49932fe07f8SJohn Marino el->el_line.lastchar, el->el_state.argument, cv__isword); 50032fe07f8SJohn Marino 50132fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 50232fe07f8SJohn Marino el->el_line.cursor++; 50332fe07f8SJohn Marino cv_delfini(el); 50432fe07f8SJohn Marino return CC_REFRESH; 50532fe07f8SJohn Marino } 50632fe07f8SJohn Marino return CC_CURSOR; 50732fe07f8SJohn Marino } 50832fe07f8SJohn Marino 50932fe07f8SJohn Marino 51032fe07f8SJohn Marino /* vi_undo(): 51132fe07f8SJohn Marino * Vi undo last change 51232fe07f8SJohn Marino * [u] 51332fe07f8SJohn Marino */ 51432fe07f8SJohn Marino protected el_action_t 51532fe07f8SJohn Marino /*ARGSUSED*/ 51632fe07f8SJohn Marino vi_undo(EditLine *el, Int c __attribute__((__unused__))) 51732fe07f8SJohn Marino { 51832fe07f8SJohn Marino c_undo_t un = el->el_chared.c_undo; 51932fe07f8SJohn Marino 52032fe07f8SJohn Marino if (un.len == -1) 52132fe07f8SJohn Marino return CC_ERROR; 52232fe07f8SJohn Marino 52332fe07f8SJohn Marino /* switch line buffer and undo buffer */ 52432fe07f8SJohn Marino el->el_chared.c_undo.buf = el->el_line.buffer; 52532fe07f8SJohn Marino el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; 52632fe07f8SJohn Marino el->el_chared.c_undo.cursor = 52732fe07f8SJohn Marino (int)(el->el_line.cursor - el->el_line.buffer); 52832fe07f8SJohn Marino el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); 52932fe07f8SJohn Marino el->el_line.buffer = un.buf; 53032fe07f8SJohn Marino el->el_line.cursor = un.buf + un.cursor; 53132fe07f8SJohn Marino el->el_line.lastchar = un.buf + un.len; 53232fe07f8SJohn Marino 53332fe07f8SJohn Marino return CC_REFRESH; 53432fe07f8SJohn Marino } 53532fe07f8SJohn Marino 53632fe07f8SJohn Marino 53732fe07f8SJohn Marino /* vi_command_mode(): 53832fe07f8SJohn Marino * Vi enter command mode (use alternative key bindings) 53932fe07f8SJohn Marino * [<ESC>] 54032fe07f8SJohn Marino */ 54132fe07f8SJohn Marino protected el_action_t 54232fe07f8SJohn Marino /*ARGSUSED*/ 54332fe07f8SJohn Marino vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) 54432fe07f8SJohn Marino { 54532fe07f8SJohn Marino 54632fe07f8SJohn Marino /* [Esc] cancels pending action */ 54732fe07f8SJohn Marino el->el_chared.c_vcmd.action = NOP; 54832fe07f8SJohn Marino el->el_chared.c_vcmd.pos = 0; 54932fe07f8SJohn Marino 55032fe07f8SJohn Marino el->el_state.doingarg = 0; 55132fe07f8SJohn Marino 55232fe07f8SJohn Marino el->el_state.inputmode = MODE_INSERT; 55332fe07f8SJohn Marino el->el_map.current = el->el_map.alt; 55432fe07f8SJohn Marino #ifdef VI_MOVE 55532fe07f8SJohn Marino if (el->el_line.cursor > el->el_line.buffer) 55632fe07f8SJohn Marino el->el_line.cursor--; 55732fe07f8SJohn Marino #endif 55832fe07f8SJohn Marino return CC_CURSOR; 55932fe07f8SJohn Marino } 56032fe07f8SJohn Marino 56132fe07f8SJohn Marino 56232fe07f8SJohn Marino /* vi_zero(): 56332fe07f8SJohn Marino * Vi move to the beginning of line 56432fe07f8SJohn Marino * [0] 56532fe07f8SJohn Marino */ 56632fe07f8SJohn Marino protected el_action_t 56732fe07f8SJohn Marino vi_zero(EditLine *el, Int c) 56832fe07f8SJohn Marino { 56932fe07f8SJohn Marino 57032fe07f8SJohn Marino if (el->el_state.doingarg) 57132fe07f8SJohn Marino return ed_argument_digit(el, c); 57232fe07f8SJohn Marino 57332fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 57432fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 57532fe07f8SJohn Marino cv_delfini(el); 57632fe07f8SJohn Marino return CC_REFRESH; 57732fe07f8SJohn Marino } 57832fe07f8SJohn Marino return CC_CURSOR; 57932fe07f8SJohn Marino } 58032fe07f8SJohn Marino 58132fe07f8SJohn Marino 58232fe07f8SJohn Marino /* vi_delete_prev_char(): 58332fe07f8SJohn Marino * Vi move to previous character (backspace) 58432fe07f8SJohn Marino * [^H] in insert mode only 58532fe07f8SJohn Marino */ 58632fe07f8SJohn Marino protected el_action_t 58732fe07f8SJohn Marino /*ARGSUSED*/ 58832fe07f8SJohn Marino vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) 58932fe07f8SJohn Marino { 59032fe07f8SJohn Marino 59132fe07f8SJohn Marino if (el->el_line.cursor <= el->el_line.buffer) 59232fe07f8SJohn Marino return CC_ERROR; 59332fe07f8SJohn Marino 59432fe07f8SJohn Marino c_delbefore1(el); 59532fe07f8SJohn Marino el->el_line.cursor--; 59632fe07f8SJohn Marino return CC_REFRESH; 59732fe07f8SJohn Marino } 59832fe07f8SJohn Marino 59932fe07f8SJohn Marino 60032fe07f8SJohn Marino /* vi_list_or_eof(): 60132fe07f8SJohn Marino * Vi list choices for completion or indicate end of file if empty line 60232fe07f8SJohn Marino * [^D] 60332fe07f8SJohn Marino */ 60432fe07f8SJohn Marino protected el_action_t 60532fe07f8SJohn Marino /*ARGSUSED*/ 60632fe07f8SJohn Marino vi_list_or_eof(EditLine *el, Int c) 60732fe07f8SJohn Marino { 60832fe07f8SJohn Marino 60932fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.lastchar) { 61032fe07f8SJohn Marino if (el->el_line.cursor == el->el_line.buffer) { 61132fe07f8SJohn Marino terminal_writec(el, c); /* then do a EOF */ 61232fe07f8SJohn Marino return CC_EOF; 61332fe07f8SJohn Marino } else { 61432fe07f8SJohn Marino /* 61532fe07f8SJohn Marino * Here we could list completions, but it is an 61632fe07f8SJohn Marino * error right now 61732fe07f8SJohn Marino */ 61832fe07f8SJohn Marino terminal_beep(el); 61932fe07f8SJohn Marino return CC_ERROR; 62032fe07f8SJohn Marino } 62132fe07f8SJohn Marino } else { 62232fe07f8SJohn Marino #ifdef notyet 62332fe07f8SJohn Marino re_goto_bottom(el); 62432fe07f8SJohn Marino *el->el_line.lastchar = '\0'; /* just in case */ 62532fe07f8SJohn Marino return CC_LIST_CHOICES; 62632fe07f8SJohn Marino #else 62732fe07f8SJohn Marino /* 62832fe07f8SJohn Marino * Just complain for now. 62932fe07f8SJohn Marino */ 63032fe07f8SJohn Marino terminal_beep(el); 63132fe07f8SJohn Marino return CC_ERROR; 63232fe07f8SJohn Marino #endif 63332fe07f8SJohn Marino } 63432fe07f8SJohn Marino } 63532fe07f8SJohn Marino 63632fe07f8SJohn Marino 63732fe07f8SJohn Marino /* vi_kill_line_prev(): 63832fe07f8SJohn Marino * Vi cut from beginning of line to cursor 63932fe07f8SJohn Marino * [^U] 64032fe07f8SJohn Marino */ 64132fe07f8SJohn Marino protected el_action_t 64232fe07f8SJohn Marino /*ARGSUSED*/ 64332fe07f8SJohn Marino vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) 64432fe07f8SJohn Marino { 64532fe07f8SJohn Marino Char *kp, *cp; 64632fe07f8SJohn Marino 64732fe07f8SJohn Marino cp = el->el_line.buffer; 64832fe07f8SJohn Marino kp = el->el_chared.c_kill.buf; 64932fe07f8SJohn Marino while (cp < el->el_line.cursor) 65032fe07f8SJohn Marino *kp++ = *cp++; /* copy it */ 65132fe07f8SJohn Marino el->el_chared.c_kill.last = kp; 65232fe07f8SJohn Marino c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); 65332fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; /* zap! */ 65432fe07f8SJohn Marino return CC_REFRESH; 65532fe07f8SJohn Marino } 65632fe07f8SJohn Marino 65732fe07f8SJohn Marino 65832fe07f8SJohn Marino /* vi_search_prev(): 65932fe07f8SJohn Marino * Vi search history previous 66032fe07f8SJohn Marino * [?] 66132fe07f8SJohn Marino */ 66232fe07f8SJohn Marino protected el_action_t 66332fe07f8SJohn Marino /*ARGSUSED*/ 66432fe07f8SJohn Marino vi_search_prev(EditLine *el, Int c __attribute__((__unused__))) 66532fe07f8SJohn Marino { 66632fe07f8SJohn Marino 66732fe07f8SJohn Marino return cv_search(el, ED_SEARCH_PREV_HISTORY); 66832fe07f8SJohn Marino } 66932fe07f8SJohn Marino 67032fe07f8SJohn Marino 67132fe07f8SJohn Marino /* vi_search_next(): 67232fe07f8SJohn Marino * Vi search history next 67332fe07f8SJohn Marino * [/] 67432fe07f8SJohn Marino */ 67532fe07f8SJohn Marino protected el_action_t 67632fe07f8SJohn Marino /*ARGSUSED*/ 67732fe07f8SJohn Marino vi_search_next(EditLine *el, Int c __attribute__((__unused__))) 67832fe07f8SJohn Marino { 67932fe07f8SJohn Marino 68032fe07f8SJohn Marino return cv_search(el, ED_SEARCH_NEXT_HISTORY); 68132fe07f8SJohn Marino } 68232fe07f8SJohn Marino 68332fe07f8SJohn Marino 68432fe07f8SJohn Marino /* vi_repeat_search_next(): 68532fe07f8SJohn Marino * Vi repeat current search in the same search direction 68632fe07f8SJohn Marino * [n] 68732fe07f8SJohn Marino */ 68832fe07f8SJohn Marino protected el_action_t 68932fe07f8SJohn Marino /*ARGSUSED*/ 69032fe07f8SJohn Marino vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__))) 69132fe07f8SJohn Marino { 69232fe07f8SJohn Marino 69332fe07f8SJohn Marino if (el->el_search.patlen == 0) 69432fe07f8SJohn Marino return CC_ERROR; 69532fe07f8SJohn Marino else 69632fe07f8SJohn Marino return cv_repeat_srch(el, el->el_search.patdir); 69732fe07f8SJohn Marino } 69832fe07f8SJohn Marino 69932fe07f8SJohn Marino 70032fe07f8SJohn Marino /* vi_repeat_search_prev(): 70132fe07f8SJohn Marino * Vi repeat current search in the opposite search direction 70232fe07f8SJohn Marino * [N] 70332fe07f8SJohn Marino */ 70432fe07f8SJohn Marino /*ARGSUSED*/ 70532fe07f8SJohn Marino protected el_action_t 70632fe07f8SJohn Marino vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__))) 70732fe07f8SJohn Marino { 70832fe07f8SJohn Marino 70932fe07f8SJohn Marino if (el->el_search.patlen == 0) 71032fe07f8SJohn Marino return CC_ERROR; 71132fe07f8SJohn Marino else 71232fe07f8SJohn Marino return (cv_repeat_srch(el, 71332fe07f8SJohn Marino el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? 71432fe07f8SJohn Marino ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY)); 71532fe07f8SJohn Marino } 71632fe07f8SJohn Marino 71732fe07f8SJohn Marino 71832fe07f8SJohn Marino /* vi_next_char(): 71932fe07f8SJohn Marino * Vi move to the character specified next 72032fe07f8SJohn Marino * [f] 72132fe07f8SJohn Marino */ 72232fe07f8SJohn Marino protected el_action_t 72332fe07f8SJohn Marino /*ARGSUSED*/ 72432fe07f8SJohn Marino vi_next_char(EditLine *el, Int c __attribute__((__unused__))) 72532fe07f8SJohn Marino { 72632fe07f8SJohn Marino return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); 72732fe07f8SJohn Marino } 72832fe07f8SJohn Marino 72932fe07f8SJohn Marino 73032fe07f8SJohn Marino /* vi_prev_char(): 73132fe07f8SJohn Marino * Vi move to the character specified previous 73232fe07f8SJohn Marino * [F] 73332fe07f8SJohn Marino */ 73432fe07f8SJohn Marino protected el_action_t 73532fe07f8SJohn Marino /*ARGSUSED*/ 73632fe07f8SJohn Marino vi_prev_char(EditLine *el, Int c __attribute__((__unused__))) 73732fe07f8SJohn Marino { 73832fe07f8SJohn Marino return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); 73932fe07f8SJohn Marino } 74032fe07f8SJohn Marino 74132fe07f8SJohn Marino 74232fe07f8SJohn Marino /* vi_to_next_char(): 74332fe07f8SJohn Marino * Vi move up to the character specified next 74432fe07f8SJohn Marino * [t] 74532fe07f8SJohn Marino */ 74632fe07f8SJohn Marino protected el_action_t 74732fe07f8SJohn Marino /*ARGSUSED*/ 74832fe07f8SJohn Marino vi_to_next_char(EditLine *el, Int c __attribute__((__unused__))) 74932fe07f8SJohn Marino { 75032fe07f8SJohn Marino return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); 75132fe07f8SJohn Marino } 75232fe07f8SJohn Marino 75332fe07f8SJohn Marino 75432fe07f8SJohn Marino /* vi_to_prev_char(): 75532fe07f8SJohn Marino * Vi move up to the character specified previous 75632fe07f8SJohn Marino * [T] 75732fe07f8SJohn Marino */ 75832fe07f8SJohn Marino protected el_action_t 75932fe07f8SJohn Marino /*ARGSUSED*/ 76032fe07f8SJohn Marino vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__))) 76132fe07f8SJohn Marino { 76232fe07f8SJohn Marino return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); 76332fe07f8SJohn Marino } 76432fe07f8SJohn Marino 76532fe07f8SJohn Marino 76632fe07f8SJohn Marino /* vi_repeat_next_char(): 76732fe07f8SJohn Marino * Vi repeat current character search in the same search direction 76832fe07f8SJohn Marino * [;] 76932fe07f8SJohn Marino */ 77032fe07f8SJohn Marino protected el_action_t 77132fe07f8SJohn Marino /*ARGSUSED*/ 77232fe07f8SJohn Marino vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__))) 77332fe07f8SJohn Marino { 77432fe07f8SJohn Marino 77532fe07f8SJohn Marino return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, 77632fe07f8SJohn Marino el->el_state.argument, el->el_search.chatflg); 77732fe07f8SJohn Marino } 77832fe07f8SJohn Marino 77932fe07f8SJohn Marino 78032fe07f8SJohn Marino /* vi_repeat_prev_char(): 78132fe07f8SJohn Marino * Vi repeat current character search in the opposite search direction 78232fe07f8SJohn Marino * [,] 78332fe07f8SJohn Marino */ 78432fe07f8SJohn Marino protected el_action_t 78532fe07f8SJohn Marino /*ARGSUSED*/ 78632fe07f8SJohn Marino vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__))) 78732fe07f8SJohn Marino { 78832fe07f8SJohn Marino el_action_t r; 78932fe07f8SJohn Marino int dir = el->el_search.chadir; 79032fe07f8SJohn Marino 79132fe07f8SJohn Marino r = cv_csearch(el, -dir, el->el_search.chacha, 79232fe07f8SJohn Marino el->el_state.argument, el->el_search.chatflg); 79332fe07f8SJohn Marino el->el_search.chadir = dir; 79432fe07f8SJohn Marino return r; 79532fe07f8SJohn Marino } 79632fe07f8SJohn Marino 79732fe07f8SJohn Marino 79832fe07f8SJohn Marino /* vi_match(): 79932fe07f8SJohn Marino * Vi go to matching () {} or [] 80032fe07f8SJohn Marino * [%] 80132fe07f8SJohn Marino */ 80232fe07f8SJohn Marino protected el_action_t 80332fe07f8SJohn Marino /*ARGSUSED*/ 80432fe07f8SJohn Marino vi_match(EditLine *el, Int c __attribute__((__unused__))) 80532fe07f8SJohn Marino { 80632fe07f8SJohn Marino const Char match_chars[] = STR("()[]{}"); 80732fe07f8SJohn Marino Char *cp; 80832fe07f8SJohn Marino size_t delta, i, count; 80932fe07f8SJohn Marino Char o_ch, c_ch; 81032fe07f8SJohn Marino 81132fe07f8SJohn Marino *el->el_line.lastchar = '\0'; /* just in case */ 81232fe07f8SJohn Marino 81332fe07f8SJohn Marino i = Strcspn(el->el_line.cursor, match_chars); 81432fe07f8SJohn Marino o_ch = el->el_line.cursor[i]; 81532fe07f8SJohn Marino if (o_ch == 0) 81632fe07f8SJohn Marino return CC_ERROR; 81732fe07f8SJohn Marino delta = (size_t)(Strchr(match_chars, o_ch) - match_chars); 81832fe07f8SJohn Marino c_ch = match_chars[delta ^ 1]; 81932fe07f8SJohn Marino count = 1; 82032fe07f8SJohn Marino delta = 1 - (delta & 1) * 2; 82132fe07f8SJohn Marino 82232fe07f8SJohn Marino for (cp = &el->el_line.cursor[i]; count; ) { 82332fe07f8SJohn Marino cp += delta; 82432fe07f8SJohn Marino if (cp < el->el_line.buffer || cp >= el->el_line.lastchar) 82532fe07f8SJohn Marino return CC_ERROR; 82632fe07f8SJohn Marino if (*cp == o_ch) 82732fe07f8SJohn Marino count++; 82832fe07f8SJohn Marino else if (*cp == c_ch) 82932fe07f8SJohn Marino count--; 83032fe07f8SJohn Marino } 83132fe07f8SJohn Marino 83232fe07f8SJohn Marino el->el_line.cursor = cp; 83332fe07f8SJohn Marino 83432fe07f8SJohn Marino if (el->el_chared.c_vcmd.action != NOP) { 83532fe07f8SJohn Marino /* NB posix says char under cursor should NOT be deleted 83632fe07f8SJohn Marino for -ve delta - this is different to netbsd vi. */ 83732fe07f8SJohn Marino if (delta > 0) 83832fe07f8SJohn Marino el->el_line.cursor++; 83932fe07f8SJohn Marino cv_delfini(el); 84032fe07f8SJohn Marino return CC_REFRESH; 84132fe07f8SJohn Marino } 84232fe07f8SJohn Marino return CC_CURSOR; 84332fe07f8SJohn Marino } 84432fe07f8SJohn Marino 84532fe07f8SJohn Marino /* vi_undo_line(): 84632fe07f8SJohn Marino * Vi undo all changes to line 84732fe07f8SJohn Marino * [U] 84832fe07f8SJohn Marino */ 84932fe07f8SJohn Marino protected el_action_t 85032fe07f8SJohn Marino /*ARGSUSED*/ 85132fe07f8SJohn Marino vi_undo_line(EditLine *el, Int c __attribute__((__unused__))) 85232fe07f8SJohn Marino { 85332fe07f8SJohn Marino 85432fe07f8SJohn Marino cv_undo(el); 85532fe07f8SJohn Marino return hist_get(el); 85632fe07f8SJohn Marino } 85732fe07f8SJohn Marino 85832fe07f8SJohn Marino /* vi_to_column(): 85932fe07f8SJohn Marino * Vi go to specified column 86032fe07f8SJohn Marino * [|] 86132fe07f8SJohn Marino * NB netbsd vi goes to screen column 'n', posix says nth character 86232fe07f8SJohn Marino */ 86332fe07f8SJohn Marino protected el_action_t 86432fe07f8SJohn Marino /*ARGSUSED*/ 86532fe07f8SJohn Marino vi_to_column(EditLine *el, Int c __attribute__((__unused__))) 86632fe07f8SJohn Marino { 86732fe07f8SJohn Marino 86832fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 86932fe07f8SJohn Marino el->el_state.argument--; 87032fe07f8SJohn Marino return ed_next_char(el, 0); 87132fe07f8SJohn Marino } 87232fe07f8SJohn Marino 87332fe07f8SJohn Marino /* vi_yank_end(): 87432fe07f8SJohn Marino * Vi yank to end of line 87532fe07f8SJohn Marino * [Y] 87632fe07f8SJohn Marino */ 87732fe07f8SJohn Marino protected el_action_t 87832fe07f8SJohn Marino /*ARGSUSED*/ 87932fe07f8SJohn Marino vi_yank_end(EditLine *el, Int c __attribute__((__unused__))) 88032fe07f8SJohn Marino { 88132fe07f8SJohn Marino 88232fe07f8SJohn Marino cv_yank(el, el->el_line.cursor, 88332fe07f8SJohn Marino (int)(el->el_line.lastchar - el->el_line.cursor)); 88432fe07f8SJohn Marino return CC_REFRESH; 88532fe07f8SJohn Marino } 88632fe07f8SJohn Marino 88732fe07f8SJohn Marino /* vi_yank(): 88832fe07f8SJohn Marino * Vi yank 88932fe07f8SJohn Marino * [y] 89032fe07f8SJohn Marino */ 89132fe07f8SJohn Marino protected el_action_t 89232fe07f8SJohn Marino /*ARGSUSED*/ 89332fe07f8SJohn Marino vi_yank(EditLine *el, Int c __attribute__((__unused__))) 89432fe07f8SJohn Marino { 89532fe07f8SJohn Marino 89632fe07f8SJohn Marino return cv_action(el, YANK); 89732fe07f8SJohn Marino } 89832fe07f8SJohn Marino 89932fe07f8SJohn Marino /* vi_comment_out(): 90032fe07f8SJohn Marino * Vi comment out current command 90132fe07f8SJohn Marino * [#] 90232fe07f8SJohn Marino */ 90332fe07f8SJohn Marino protected el_action_t 90432fe07f8SJohn Marino /*ARGSUSED*/ 90532fe07f8SJohn Marino vi_comment_out(EditLine *el, Int c __attribute__((__unused__))) 90632fe07f8SJohn Marino { 90732fe07f8SJohn Marino 90832fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 90932fe07f8SJohn Marino c_insert(el, 1); 91032fe07f8SJohn Marino *el->el_line.cursor = '#'; 91132fe07f8SJohn Marino re_refresh(el); 91232fe07f8SJohn Marino return ed_newline(el, 0); 91332fe07f8SJohn Marino } 91432fe07f8SJohn Marino 91532fe07f8SJohn Marino /* vi_alias(): 91632fe07f8SJohn Marino * Vi include shell alias 91732fe07f8SJohn Marino * [@] 91832fe07f8SJohn Marino * NB: posix implies that we should enter insert mode, however 91932fe07f8SJohn Marino * this is against historical precedent... 92032fe07f8SJohn Marino */ 92132fe07f8SJohn Marino protected el_action_t 92232fe07f8SJohn Marino /*ARGSUSED*/ 923*84b940c1SJohn Marino vi_alias(EditLine *el __attribute__((__unused__)), Int c __attribute__((__unused__))) 92432fe07f8SJohn Marino { 92532fe07f8SJohn Marino char alias_name[3]; 926*84b940c1SJohn Marino const char *alias_text; 92732fe07f8SJohn Marino 928*84b940c1SJohn Marino if (el->el_chared.c_aliasfun == NULL) 92932fe07f8SJohn Marino return CC_ERROR; 93032fe07f8SJohn Marino 93132fe07f8SJohn Marino alias_name[0] = '_'; 93232fe07f8SJohn Marino alias_name[2] = 0; 93332fe07f8SJohn Marino if (el_getc(el, &alias_name[1]) != 1) 93432fe07f8SJohn Marino return CC_ERROR; 93532fe07f8SJohn Marino 936*84b940c1SJohn Marino alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg, 937*84b940c1SJohn Marino alias_name); 93832fe07f8SJohn Marino if (alias_text != NULL) 93932fe07f8SJohn Marino FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch)); 94032fe07f8SJohn Marino return CC_NORM; 94132fe07f8SJohn Marino } 94232fe07f8SJohn Marino 94332fe07f8SJohn Marino /* vi_to_history_line(): 94432fe07f8SJohn Marino * Vi go to specified history file line. 94532fe07f8SJohn Marino * [G] 94632fe07f8SJohn Marino */ 94732fe07f8SJohn Marino protected el_action_t 94832fe07f8SJohn Marino /*ARGSUSED*/ 94932fe07f8SJohn Marino vi_to_history_line(EditLine *el, Int c __attribute__((__unused__))) 95032fe07f8SJohn Marino { 95132fe07f8SJohn Marino int sv_event_no = el->el_history.eventno; 95232fe07f8SJohn Marino el_action_t rval; 95332fe07f8SJohn Marino 95432fe07f8SJohn Marino 95532fe07f8SJohn Marino if (el->el_history.eventno == 0) { 95632fe07f8SJohn Marino (void) Strncpy(el->el_history.buf, el->el_line.buffer, 95732fe07f8SJohn Marino EL_BUFSIZ); 95832fe07f8SJohn Marino el->el_history.last = el->el_history.buf + 95932fe07f8SJohn Marino (el->el_line.lastchar - el->el_line.buffer); 96032fe07f8SJohn Marino } 96132fe07f8SJohn Marino 96232fe07f8SJohn Marino /* Lack of a 'count' means oldest, not 1 */ 96332fe07f8SJohn Marino if (!el->el_state.doingarg) { 96432fe07f8SJohn Marino el->el_history.eventno = 0x7fffffff; 96532fe07f8SJohn Marino hist_get(el); 96632fe07f8SJohn Marino } else { 96732fe07f8SJohn Marino /* This is brain dead, all the rest of this code counts 96832fe07f8SJohn Marino * upwards going into the past. Here we need count in the 96932fe07f8SJohn Marino * other direction (to match the output of fc -l). 97032fe07f8SJohn Marino * I could change the world, but this seems to suffice. 97132fe07f8SJohn Marino */ 97232fe07f8SJohn Marino el->el_history.eventno = 1; 97332fe07f8SJohn Marino if (hist_get(el) == CC_ERROR) 97432fe07f8SJohn Marino return CC_ERROR; 97532fe07f8SJohn Marino el->el_history.eventno = 1 + el->el_history.ev.num 97632fe07f8SJohn Marino - el->el_state.argument; 97732fe07f8SJohn Marino if (el->el_history.eventno < 0) { 97832fe07f8SJohn Marino el->el_history.eventno = sv_event_no; 97932fe07f8SJohn Marino return CC_ERROR; 98032fe07f8SJohn Marino } 98132fe07f8SJohn Marino } 98232fe07f8SJohn Marino rval = hist_get(el); 98332fe07f8SJohn Marino if (rval == CC_ERROR) 98432fe07f8SJohn Marino el->el_history.eventno = sv_event_no; 98532fe07f8SJohn Marino return rval; 98632fe07f8SJohn Marino } 98732fe07f8SJohn Marino 98832fe07f8SJohn Marino /* vi_histedit(): 98932fe07f8SJohn Marino * Vi edit history line with vi 99032fe07f8SJohn Marino * [v] 99132fe07f8SJohn Marino */ 99232fe07f8SJohn Marino protected el_action_t 99332fe07f8SJohn Marino /*ARGSUSED*/ 99432fe07f8SJohn Marino vi_histedit(EditLine *el, Int c __attribute__((__unused__))) 99532fe07f8SJohn Marino { 99632fe07f8SJohn Marino int fd; 99732fe07f8SJohn Marino pid_t pid; 99832fe07f8SJohn Marino ssize_t st; 99932fe07f8SJohn Marino int status; 100032fe07f8SJohn Marino char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; 100132fe07f8SJohn Marino char *cp = NULL; 100232fe07f8SJohn Marino size_t len; 100332fe07f8SJohn Marino Char *line = NULL; 100432fe07f8SJohn Marino 100532fe07f8SJohn Marino if (el->el_state.doingarg) { 100632fe07f8SJohn Marino if (vi_to_history_line(el, 0) == CC_ERROR) 100732fe07f8SJohn Marino return CC_ERROR; 100832fe07f8SJohn Marino } 100932fe07f8SJohn Marino 101032fe07f8SJohn Marino fd = mkstemp(tempfile); 101132fe07f8SJohn Marino if (fd < 0) 101232fe07f8SJohn Marino return CC_ERROR; 101332fe07f8SJohn Marino len = (size_t)(el->el_line.lastchar - el->el_line.buffer); 101432fe07f8SJohn Marino #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX) 101532fe07f8SJohn Marino cp = el_malloc(TMP_BUFSIZ * sizeof(*cp)); 101632fe07f8SJohn Marino if (cp == NULL) 101732fe07f8SJohn Marino goto error; 101832fe07f8SJohn Marino line = el_malloc(len * sizeof(*line) + 1); 101932fe07f8SJohn Marino if (line == NULL) 102032fe07f8SJohn Marino goto error; 102132fe07f8SJohn Marino Strncpy(line, el->el_line.buffer, len); 102232fe07f8SJohn Marino line[len] = '\0'; 102332fe07f8SJohn Marino ct_wcstombs(cp, line, TMP_BUFSIZ - 1); 102432fe07f8SJohn Marino cp[TMP_BUFSIZ - 1] = '\0'; 102532fe07f8SJohn Marino len = strlen(cp); 102632fe07f8SJohn Marino write(fd, cp, len); 102732fe07f8SJohn Marino write(fd, "\n", (size_t)1); 102832fe07f8SJohn Marino pid = fork(); 102932fe07f8SJohn Marino switch (pid) { 103032fe07f8SJohn Marino case -1: 103132fe07f8SJohn Marino goto error; 103232fe07f8SJohn Marino case 0: 103332fe07f8SJohn Marino close(fd); 103432fe07f8SJohn Marino execlp("vi", "vi", tempfile, (char *)NULL); 103532fe07f8SJohn Marino exit(0); 103632fe07f8SJohn Marino /*NOTREACHED*/ 103732fe07f8SJohn Marino default: 103832fe07f8SJohn Marino while (waitpid(pid, &status, 0) != pid) 103932fe07f8SJohn Marino continue; 104032fe07f8SJohn Marino lseek(fd, (off_t)0, SEEK_SET); 104132fe07f8SJohn Marino st = read(fd, cp, TMP_BUFSIZ); 104232fe07f8SJohn Marino if (st > 0) { 104332fe07f8SJohn Marino len = (size_t)(el->el_line.lastchar - 104432fe07f8SJohn Marino el->el_line.buffer); 104532fe07f8SJohn Marino len = ct_mbstowcs(el->el_line.buffer, cp, len); 104632fe07f8SJohn Marino if (len > 0 && el->el_line.buffer[len -1] == '\n') 104732fe07f8SJohn Marino --len; 104832fe07f8SJohn Marino } 104932fe07f8SJohn Marino else 105032fe07f8SJohn Marino len = 0; 105132fe07f8SJohn Marino el->el_line.cursor = el->el_line.buffer; 105232fe07f8SJohn Marino el->el_line.lastchar = el->el_line.buffer + len; 105332fe07f8SJohn Marino el_free(cp); 105432fe07f8SJohn Marino el_free(line); 105532fe07f8SJohn Marino break; 105632fe07f8SJohn Marino } 105732fe07f8SJohn Marino 105832fe07f8SJohn Marino close(fd); 105932fe07f8SJohn Marino unlink(tempfile); 106032fe07f8SJohn Marino /* return CC_REFRESH; */ 106132fe07f8SJohn Marino return ed_newline(el, 0); 106232fe07f8SJohn Marino error: 106332fe07f8SJohn Marino el_free(line); 106432fe07f8SJohn Marino el_free(cp); 106532fe07f8SJohn Marino close(fd); 106632fe07f8SJohn Marino unlink(tempfile); 106732fe07f8SJohn Marino return CC_ERROR; 106832fe07f8SJohn Marino } 106932fe07f8SJohn Marino 107032fe07f8SJohn Marino /* vi_history_word(): 107132fe07f8SJohn Marino * Vi append word from previous input line 107232fe07f8SJohn Marino * [_] 107332fe07f8SJohn Marino * Who knows where this one came from! 107432fe07f8SJohn Marino * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' 107532fe07f8SJohn Marino */ 107632fe07f8SJohn Marino protected el_action_t 107732fe07f8SJohn Marino /*ARGSUSED*/ 107832fe07f8SJohn Marino vi_history_word(EditLine *el, Int c __attribute__((__unused__))) 107932fe07f8SJohn Marino { 108032fe07f8SJohn Marino const Char *wp = HIST_FIRST(el); 108132fe07f8SJohn Marino const Char *wep, *wsp; 108232fe07f8SJohn Marino int len; 108332fe07f8SJohn Marino Char *cp; 108432fe07f8SJohn Marino const Char *lim; 108532fe07f8SJohn Marino 108632fe07f8SJohn Marino if (wp == NULL) 108732fe07f8SJohn Marino return CC_ERROR; 108832fe07f8SJohn Marino 108932fe07f8SJohn Marino wep = wsp = 0; 109032fe07f8SJohn Marino do { 109132fe07f8SJohn Marino while (Isspace(*wp)) 109232fe07f8SJohn Marino wp++; 109332fe07f8SJohn Marino if (*wp == 0) 109432fe07f8SJohn Marino break; 109532fe07f8SJohn Marino wsp = wp; 109632fe07f8SJohn Marino while (*wp && !Isspace(*wp)) 109732fe07f8SJohn Marino wp++; 109832fe07f8SJohn Marino wep = wp; 109932fe07f8SJohn Marino } while ((!el->el_state.doingarg || --el->el_state.argument > 0) 110032fe07f8SJohn Marino && *wp != 0); 110132fe07f8SJohn Marino 110232fe07f8SJohn Marino if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) 110332fe07f8SJohn Marino return CC_ERROR; 110432fe07f8SJohn Marino 110532fe07f8SJohn Marino cv_undo(el); 110632fe07f8SJohn Marino len = (int)(wep - wsp); 110732fe07f8SJohn Marino if (el->el_line.cursor < el->el_line.lastchar) 110832fe07f8SJohn Marino el->el_line.cursor++; 110932fe07f8SJohn Marino c_insert(el, len + 1); 111032fe07f8SJohn Marino cp = el->el_line.cursor; 111132fe07f8SJohn Marino lim = el->el_line.limit; 111232fe07f8SJohn Marino if (cp < lim) 111332fe07f8SJohn Marino *cp++ = ' '; 111432fe07f8SJohn Marino while (wsp < wep && cp < lim) 111532fe07f8SJohn Marino *cp++ = *wsp++; 111632fe07f8SJohn Marino el->el_line.cursor = cp; 111732fe07f8SJohn Marino 111832fe07f8SJohn Marino el->el_map.current = el->el_map.key; 111932fe07f8SJohn Marino return CC_REFRESH; 112032fe07f8SJohn Marino } 112132fe07f8SJohn Marino 112232fe07f8SJohn Marino /* vi_redo(): 112332fe07f8SJohn Marino * Vi redo last non-motion command 112432fe07f8SJohn Marino * [.] 112532fe07f8SJohn Marino */ 112632fe07f8SJohn Marino protected el_action_t 112732fe07f8SJohn Marino /*ARGSUSED*/ 112832fe07f8SJohn Marino vi_redo(EditLine *el, Int c __attribute__((__unused__))) 112932fe07f8SJohn Marino { 113032fe07f8SJohn Marino c_redo_t *r = &el->el_chared.c_redo; 113132fe07f8SJohn Marino 113232fe07f8SJohn Marino if (!el->el_state.doingarg && r->count) { 113332fe07f8SJohn Marino el->el_state.doingarg = 1; 113432fe07f8SJohn Marino el->el_state.argument = r->count; 113532fe07f8SJohn Marino } 113632fe07f8SJohn Marino 113732fe07f8SJohn Marino el->el_chared.c_vcmd.pos = el->el_line.cursor; 113832fe07f8SJohn Marino el->el_chared.c_vcmd.action = r->action; 113932fe07f8SJohn Marino if (r->pos != r->buf) { 114032fe07f8SJohn Marino if (r->pos + 1 > r->lim) 114132fe07f8SJohn Marino /* sanity */ 114232fe07f8SJohn Marino r->pos = r->lim - 1; 114332fe07f8SJohn Marino r->pos[0] = 0; 114432fe07f8SJohn Marino FUN(el,push)(el, r->buf); 114532fe07f8SJohn Marino } 114632fe07f8SJohn Marino 114732fe07f8SJohn Marino el->el_state.thiscmd = r->cmd; 114832fe07f8SJohn Marino el->el_state.thisch = r->ch; 114932fe07f8SJohn Marino return (*el->el_map.func[r->cmd])(el, r->ch); 115032fe07f8SJohn Marino } 1151