📄 vi.c
字号:
/* $NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $ *//*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Christos Zoulas of Cornell University. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "config.h"#if !defined(lint) && !defined(SCCSID)#if 0static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";#else__RCSID("$NetBSD: vi.c,v 1.9 2002/03/18 16:01:01 christos Exp $");#endif#endif /* not lint && not SCCSID *//* * vi.c: Vi mode commands. */#include "el.h"private el_action_t cv_action(EditLine *, int);private el_action_t cv_paste(EditLine *, int);/* cv_action(): * Handle vi actions. */private el_action_tcv_action(EditLine *el, int c){ char *cp, *kp; if (el->el_chared.c_vcmd.action & DELETE) { el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; el->el_chared.c_undo.isize = 0; el->el_chared.c_undo.dsize = 0; kp = el->el_chared.c_undo.buf; for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { *kp++ = *cp; el->el_chared.c_undo.dsize++; } el->el_chared.c_undo.action = INSERT; el->el_chared.c_undo.ptr = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer; if (c & INSERT) el->el_map.current = el->el_map.key; return (CC_REFRESH); } el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.action = c; return (CC_ARGHACK);#ifdef notdef /* * I don't think that this is needed. But we keep it for now */ else if (el_chared.c_vcmd.action == NOP) { el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.action = c; return (CC_ARGHACK); } else { el->el_chared.c_vcmd.action = 0; el->el_chared.c_vcmd.pos = 0; return (CC_ERROR); }#endif}/* cv_paste(): * Paste previous deletion before or after the cursor */private el_action_tcv_paste(EditLine *el, int c){ char *ptr; c_undo_t *un = &el->el_chared.c_undo;#ifdef DEBUG_PASTE (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", un->action, un->buf, un->isize, un->dsize);#endif if (un->isize == 0) return (CC_ERROR); if (!c && el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; ptr = el->el_line.cursor; c_insert(el, (int) un->isize); if (el->el_line.cursor + un->isize > el->el_line.lastchar) return (CC_ERROR); (void) memcpy(ptr, un->buf, un->isize); return (CC_REFRESH);}/* vi_paste_next(): * Vi paste previous deletion to the right of the cursor * [p] */protected el_action_t/*ARGSUSED*/vi_paste_next(EditLine *el, int c){ return (cv_paste(el, 0));}/* vi_paste_prev(): * Vi paste previous deletion to the left of the cursor * [P] */protected el_action_t/*ARGSUSED*/vi_paste_prev(EditLine *el, int c){ return (cv_paste(el, 1));}/* vi_prev_space_word(): * Vi move to the previous space delimited word * [B] */protected el_action_t/*ARGSUSED*/vi_prev_space_word(EditLine *el, int c){ if (el->el_line.cursor == el->el_line.buffer) return (CC_ERROR); el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, el->el_line.buffer, el->el_state.argument, cv__isword); if (el->el_chared.c_vcmd.action & DELETE) { cv_delfini(el); return (CC_REFRESH); } return (CC_CURSOR);}/* vi_prev_word(): * Vi move to the previous word * [B] */protected el_action_t/*ARGSUSED*/vi_prev_word(EditLine *el, int c){ if (el->el_line.cursor == el->el_line.buffer) return (CC_ERROR); el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); if (el->el_chared.c_vcmd.action & DELETE) { cv_delfini(el); return (CC_REFRESH); } return (CC_CURSOR);}/* vi_next_space_word(): * Vi move to the next space delimited word * [W] */protected el_action_t/*ARGSUSED*/vi_next_space_word(EditLine *el, int c){ if (el->el_line.cursor == el->el_line.lastchar) return (CC_ERROR); el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isword); if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action & DELETE) { cv_delfini(el); return (CC_REFRESH); } return (CC_CURSOR);}/* vi_next_word(): * Vi move to the next word * [w] */protected el_action_t/*ARGSUSED*/vi_next_word(EditLine *el, int c){ if (el->el_line.cursor == el->el_line.lastchar) return (CC_ERROR); el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action & DELETE) { cv_delfini(el); return (CC_REFRESH); } return (CC_CURSOR);}/* vi_change_case(): * Vi change case of character under the cursor and advance one character * [~] */protected el_action_tvi_change_case(EditLine *el, int c){ if (el->el_line.cursor < el->el_line.lastchar) { c = *el->el_line.cursor; if (isupper(c)) *el->el_line.cursor++ = tolower(c); else if (islower(c)) *el->el_line.cursor++ = toupper(c); else el->el_line.cursor++; re_fastaddc(el); return (CC_NORM); } return (CC_ERROR);}/* vi_change_meta(): * Vi change prefix command * [c] */protected el_action_t/*ARGSUSED*/vi_change_meta(EditLine *el, int c){ /* * Delete with insert == change: first we delete and then we leave in * insert mode. */ return (cv_action(el, DELETE | INSERT));}/* vi_insert_at_bol(): * Vi enter insert mode at the beginning of line * [I] */protected el_action_t/*ARGSUSED*/vi_insert_at_bol(EditLine *el, int c){ el->el_line.cursor = el->el_line.buffer; el->el_chared.c_vcmd.ins = el->el_line.cursor; el->el_chared.c_undo.ptr = el->el_line.cursor; el->el_chared.c_undo.action = DELETE; el->el_map.current = el->el_map.key; return (CC_CURSOR);}/* vi_replace_char(): * Vi replace character under the cursor with the next character typed * [r] */protected el_action_t/*ARGSUSED*/vi_replace_char(EditLine *el, int c){ el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE_1; el->el_chared.c_undo.action = CHANGE; el->el_chared.c_undo.ptr = el->el_line.cursor; el->el_chared.c_undo.isize = 0; el->el_chared.c_undo.dsize = 0; return (CC_NORM);}/* vi_replace_mode(): * Vi enter replace mode * [R] */protected el_action_t/*ARGSUSED*/vi_replace_mode(EditLine *el, int c){ el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE; el->el_chared.c_undo.action = CHANGE; el->el_chared.c_undo.ptr = el->el_line.cursor; el->el_chared.c_undo.isize = 0; el->el_chared.c_undo.dsize = 0; return (CC_NORM);}/* vi_substitute_char(): * Vi replace character under the cursor and enter insert mode * [r] */protected el_action_t/*ARGSUSED*/vi_substitute_char(EditLine *el, int c){ c_delafter(el, el->el_state.argument); el->el_map.current = el->el_map.key; return (CC_REFRESH);}/* vi_substitute_line(): * Vi substitute entire line * [S] */protected el_action_t/*ARGSUSED*/vi_substitute_line(EditLine *el, int c){ (void) em_kill_line(el, 0); el->el_map.current = el->el_map.key; return (CC_REFRESH);}/* vi_change_to_eol(): * Vi change to end of line * [C] */protected el_action_t/*ARGSUSED*/vi_change_to_eol(EditLine *el, int c){ (void) ed_kill_line(el, 0); el->el_map.current = el->el_map.key; return (CC_REFRESH);}/* vi_insert(): * Vi enter insert mode * [i] */protected el_action_t/*ARGSUSED*/vi_insert(EditLine *el, int c){ el->el_map.current = el->el_map.key; el->el_chared.c_vcmd.ins = el->el_line.cursor; el->el_chared.c_undo.ptr = el->el_line.cursor; el->el_chared.c_undo.action = DELETE; return (CC_NORM);}/* vi_add(): * Vi enter insert mode after the cursor * [a] */protected el_action_t/*ARGSUSED*/vi_add(EditLine *el, int c){ int ret; el->el_map.current = el->el_map.key; if (el->el_line.cursor < el->el_line.lastchar) { el->el_line.cursor++; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; ret = CC_CURSOR; } else ret = CC_NORM; el->el_chared.c_vcmd.ins = el->el_line.cursor; el->el_chared.c_undo.ptr = el->el_line.cursor; el->el_chared.c_undo.action = DELETE; return (ret);}/* vi_add_at_eol(): * Vi enter insert mode at end of line * [A] */protected el_action_t/*ARGSUSED*/vi_add_at_eol(EditLine *el, int c){ el->el_map.current = el->el_map.key; el->el_line.cursor = el->el_line.lastchar; /* Mark where insertion begins */ el->el_chared.c_vcmd.ins = el->el_line.lastchar; el->el_chared.c_undo.ptr = el->el_line.lastchar; el->el_chared.c_undo.action = DELETE; return (CC_CURSOR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -