📄 vcmd.c
字号:
/*- * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. * * 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. */#ifndef lintstatic char sccsid[] = "@(#)vcmd.c 8.28 (Berkeley) 4/18/94";#endif /* not lint */#include <sys/types.h>#include <sys/queue.h>#include <sys/time.h>#include <bitstring.h>#include <limits.h>#include <signal.h>#include <stdio.h>#include <termios.h>#include "compat.h"#include <db.h>#include <regex.h>#include "vi.h"#include "vcmd.h"/* * This array maps keystrokes to vi command functions. It is known * in ex/ex_usage.c that it takes four columns to name a vi character. */VIKEYS const vikeys [MAXVIKEY + 1] = {/* 000 NUL -- The code in vi.c expects key 0 to be undefined. */ {NULL},/* 001 ^A */ {v_searchw, V_ABS|V_CNT|V_MOVE|V_KEYW|VM_RCM_SET, "[count]^A", "^A search forward for cursor word"},/* 002 ^B */ {v_pageup, V_ABS|V_CNT|VM_RCM_SETLFNB, "[count]^B", "^B scroll up by screens"},/* 003 ^C */ {NULL, 0, "^C", "^C interrupt an operation (e.g. read, write, search)"},/* 004 ^D */ {v_hpagedown, V_ABS|V_CNT|VM_RCM_SETLFNB, "[count]^D", "^D scroll down by half screens (setting count)"},/* 005 ^E */ {v_linedown, V_CNT, "[count]^E", "^E scroll down by lines"},/* 006 ^F */ {v_pagedown, V_ABS|V_CNT|VM_RCM_SETLFNB, "[count]^F", "^F scroll down by screens"},/* 007 ^G */ {v_status, 0, "^G", "^G file status"},/* 010 ^H */ {v_left, V_CNT|V_MOVE|VM_RCM_SET, "[count]^H", "^H move left by characters"},/* 011 ^I */ {NULL},/* 012 ^J */ {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM, "[count]^J", "^J move down by lines"},/* 013 ^K */ {NULL},/* 014 ^L */ {v_redraw, 0, "^L", "^L redraw screen"},/* 015 ^M */ {v_cr, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB, "[count]^M", "^M move down by lines (to first non-blank)"},/* 016 ^N */ {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM, "[count]^N", "^N move down by lines"},/* 017 ^O */ {NULL},/* 020 ^P */ {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM, "[count]^P", "^P move up by lines"},/* 021 ^Q -- not available, used for hardware flow control. */ {NULL},/* 022 ^R */ {v_redraw, 0, "^R", "^R redraw screen"},/* 023 ^S -- not available, used for hardware flow control. */ {NULL},/* 024 ^T */ {v_tagpop, VM_RCM_SET, "^T", "^T tag pop"},/* 025 ^U */ {v_hpageup, V_ABS|V_CNT|VM_RCM_SETLFNB, "[count]^U", "^U half page up (set count)"},/* 026 ^V */ {NULL, 0, "^V", "^V input a literal character"},/* 027 ^W */ {v_screen, 0, "^W", "^W move to next screen"},/* 030 ^X */ {NULL},/* 031 ^Y */ {v_lineup, V_CNT, "[count]^Y", "^Y page up by lines"},/* 032 ^Z */ {v_stop, 0, "^Z", "^Z suspend editor"},/* 033 ^[ */ {NULL, 0, "^[ <escape>", "^[ <escape> leave input mode, return to command mode"},/* 034 ^\ */ {NULL},/* 035 ^] */ {v_tagpush, V_KEYW|VM_RCM_SET, "^]", "^] tag push cursor word"},/* 036 ^^ */ {v_switch, 0, "^^", "^^ switch to previous file"},/* 037 ^_ */ {NULL},/* 040 ' ' */ {v_right, V_CNT|V_MOVE|VM_RCM_SET, "[count]' '", " <space> move right by columns"},/* 041 ! */ {v_filter, V_CNT|V_DOT|V_MOTION|VM_RCM_SET, "[count]![count]motion command(s)", " ! filter through command(s) to motion"},/* 042 " */ {NULL},/* 043 # */ {v_increment, V_CHAR|V_CNT|V_DOT|V_KEYNUM|VM_RCM_SET, "[count]#[#+-]", " # number increment/decrement"},/* 044 $ */ {v_dollar, V_CNT|V_MOVE|VM_RCM_SETLAST, " [count]$", " $ move to last column"},/* 045 % */ {v_match, V_ABS|V_MOVE|VM_RCM_SET, "%", " % move to match"},/* 046 & */ {v_again, 0, "&", " & repeat substitution"},/* 047 ' */ {v_fmark, V_ABS|V_CHAR|V_MOVE|VM_LMODE, "'['a-z]", " ' move to mark (to first non-blank)"},/* 050 ( */ {v_sentenceb, V_CNT|V_MOVE|VM_RCM_SET, "[count](", " ( move back sentence"},/* 051 ) */ {v_sentencef, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "[count])", " ) move forward sentence"},/* 052 * */ {NULL},/* 053 + */ {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB, "[count]+", " + move down by lines (to first non-blank)"},/* 054 , */ {v_chrrepeat, V_CNT|V_MOVE|VM_RCM_SET, "[count],", " , reverse last F, f, T or t search"},/* 055 - */ {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB, "[count]-", " - move up by lines (to first non-blank)"},/* 056 . */ {NULL, 0, ".", " . repeat the last command"},/* 057 / */ {v_searchf, V_ABS|V_MOVE|VM_RCM_SET, "/RE[/ offset]", " / search forward"},/* 060 0 */ {v_zero, V_MOVE|VM_RCM_SET, "0", " 0 move to first character"},/* 061 1 */ {NULL},/* 062 2 */ {NULL},/* 063 3 */ {NULL},/* 064 4 */ {NULL},/* 065 5 */ {NULL},/* 066 6 */ {NULL},/* 067 7 */ {NULL},/* 070 8 */ {NULL},/* 071 9 */ {NULL},/* 072 : */ {v_ex, 0, ":command [| command] ...", " : ex command"},/* 073 ; */ {v_chrepeat, V_CNT|V_MOVE|VM_RCM_SET, "[count];", " ; repeat last F, f, T or t search"},/* 074 < */ {v_shiftl, V_CNT|V_DOT|V_MOTION|VC_S|VM_RCM_SET, "[count]<[count]motion", " < shift lines left to motion"},/* 075 = */ {NULL},/* 076 > */ {v_shiftr, V_CNT|V_DOT|V_MOTION|VC_S|VM_RCM_SET, "[count]>[count]motion", " > shift lines right to motion"},/* 077 ? */ {v_searchb, V_ABS|V_MOVE|VM_RCM_SET, "?RE[? offset]", " ? search backward"},/* 100 @ */ {v_at, V_RBUF|VM_RCM_SET, "@buffer", " @ execute buffer"},/* 101 A */ {v_iA, V_CNT|V_DOT|VM_RCM_SET, "[count]A", " A append to the line"},/* 102 B */ {v_wordB, V_CNT|V_MOVE|VM_RCM_SET, "[count]B", " B move back bigword"},/* 103 C */ {v_Change, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer][count]C", " C change to end-of-line"},/* 104 D */ {v_Delete, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer][count]D", " D delete to end-of-line"},/* 105 E */ {v_wordE, V_CNT|V_MOVE|VM_RCM_SET, "[count]E", " E move to end of bigword"},/* 106 F */ {v_chF, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET, "[count]F character", " F character in line backward search"},/* 107 G */ {v_lgoto, V_ABS|V_CNT|V_MOVE|VM_LMODE, "[count]G", " G move to line"},/* 110 H */ {v_home, V_ABS|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB, "[count]H", " H move to count lines from screen top"},/* 111 I */ {v_iI, V_CNT|V_DOT|VM_RCM_SET, "[count]I", " I insert at line beginning"},/* 112 J */ {v_join, V_CNT|V_DOT|VM_RCM_SET, "[count]J", " J join lines"},/* 113 K */ {NULL},/* 114 L */ {v_bottom, V_ABS|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB, "[count]L", " L move to screen bottom"},/* 115 M */ {v_middle, V_ABS|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB, "M", " M move to screen middle"},/* 116 N */ {v_searchN, V_ABS|V_MOVE|VM_RCM_SET, "n", " N reverse last search"},/* 117 O */ {v_iO, V_CNT|V_DOT|VM_RCM_SET, "[count]O", " O insert above line"},/* 120 P */ {v_Put, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer]P", " P insert before cursor from buffer"},/* 121 Q */ {v_exmode, 0, "Q", " Q switch to ex mode"},/* 122 R */ {v_Replace, V_CNT|V_DOT|VM_RCM_SET, "[count]R", " R replace characters"},/* 123 S */ {v_Subst, V_CNT|V_DOT|V_OBUF|VM_LMODE|VM_RCM_SET, "[buffer][count]S", " S substitute for the line(s)"},/* 124 T */ {v_chT, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET, "[count]T character", " T before character in line backward search"},/* 125 U */ {v_Undo, VM_RCM_SET, "U", " U Restore the current line"},/* 126 V */ {NULL},/* 127 W */ {v_wordW, V_CNT|V_MOVE|VM_RCM_SET, "[count]W", " W move to next bigword"},/* 130 X */ {v_Xchar, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer][count]X", " X delete character before cursor"},/* 131 Y */ {v_yank, V_CNT|VM_LMODE|V_OBUF, "[buffer][count]Y", " Y copy line"},/* 132 Z */ {v_zexit, 0, "ZZ", "ZZ save file and exit"},/* 133 [ */ {v_sectionb, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "[[", "[[ move back section"},/* 134 \ */ {NULL},/* 135 ] */ {v_sectionf, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "]]", "]] move forward section"},/* 136 ^ */ /* * DON'T set the VM_RCM_SETFNB flag, the function has to do the work * anyway, in case it's a motion component. DO set VM_RCM_SET, so * that any motion that's part of a command is preserved. */ {v_first, V_CNT|V_MOVE|VM_RCM_SET, "^", " ^ move to first non-blank"},/* 137 _ */ /* * Needs both to set the VM_RCM_SETFNB flag, and to do the work * in the function, in case it's a delete. */ {v_cfirst, V_CNT|V_MOVE|VM_RCM_SETFNB, "_", " _ move to first non-blank"},/* 140 ` */ {v_bmark, V_ABS|V_CHAR|V_MOVE|VM_RCM_SET, "`[`a-z]", " ` move to mark"},/* 141 a */ {v_ia, V_CNT|V_DOT|VM_RCM_SET, "[count]a", " a append after cursor"},/* 142 b */ {v_wordb, V_CNT|V_MOVE|VM_RCM_SET, "[count]b", " b move back word"},/* 143 c */ {v_change, V_CNT|V_DOT|V_MOTION|V_OBUF|VC_C|VM_RCM_SET, "[buffer][count]c[count]motion", " c change to motion"},/* 144 d */ {v_delete, V_CNT|V_DOT|V_MOTION|V_OBUF|VC_D|VM_RCM_SET, "[buffer][count]d[count]motion", " d delete to motion"},/* 145 e */ {v_worde, V_CNT|V_MOVE|VM_RCM_SET, "[count]e", " e move to end of word"},/* 146 f */ {v_chf, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET, "[count]f character", " f character in line forward search"},/* 147 g */ {NULL},/* 150 h */ {v_left, V_CNT|V_MOVE|VM_RCM_SET, "[count]h", " h move left by columns"},/* 151 i */ {v_ii, V_CNT|V_DOT|VM_RCM_SET, "[count]i", " i insert before cursor"},/* 152 j */ {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM, "[count]j", " j move down by lines"},/* 153 k */ {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM, "[count]k", " k move up by lines"},/* 154 l */ {v_right, V_CNT|V_MOVE|VM_RCM_SET, "[count]l", " l move right by columns"},/* 155 m */ {v_mark, V_CHAR, "m[a-z]", " m set mark"},/* 156 n */ {v_searchn, V_ABS|V_MOVE|VM_RCM_SET, "n", " n repeat last search"},/* 157 o */ {v_io, V_CNT|V_DOT|VM_RCM_SET, "[count]o", " o append after line"},/* 160 p */ {v_put, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer]p", " p insert after cursor from buffer"},/* 161 q */ {NULL},/* 162 r */ {v_replace, V_CNT|V_DOT|VM_RCM_SET, "[count]r character", " r replace character"},/* 163 s */ {v_subst, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer][count]s", " s substitute character"},/* 164 t */ {v_cht, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET, "[count]t character", " t before character in line forward search"},/* 165 u */ /* * DON'T set the V_DOT flag, it' more complicated than that. * See vi/vi.c for details. */ {v_undo, VM_RCM_SET, "u", " u undo last change"},/* 166 v */ {NULL},/* 167 w */ {v_wordw, V_CNT|V_MOVE|VM_RCM_SET, "[count]w", " w move to next word"},/* 170 x */ {v_xchar, V_CNT|V_DOT|V_OBUF|VM_RCM_SET, "[buffer][count]x", " x delete character"},/* 171 y */ {v_yank, V_CNT|V_MOTION|V_OBUF|VC_Y|VM_RCM_SET, "[buffer][count]y[count]motion", " y copy text to motion into a cut buffer"},/* 172 z */ /* * DON'T set the V_CHAR flag, the char isn't required, * so it's handled specially in getcmd(). */ {v_z, V_CNT|VM_RCM_SETFNB, "[line]z[window_size][-|.|+|^|<CR>]", " z redraw window"},/* 173 { */ {v_paragraphb, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "[count]{", " { move back paragraph"},/* 174 | */ {v_ncol, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "[count]|", " | move to column"},/* 175 } */ {v_paragraphf, V_ABS|V_CNT|V_MOVE|VM_RCM_SET, "[count]}", " } move forward paragraph"},/* 176 ~ */ {v_ulcase, V_CNT|V_DOT|VM_RCM_SET, "[count]~", " ~ reverse case"},};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -