vim从入门到精通

安装 下载windows安装包, 最新版在这里
下载中文帮助安装包, 最新版在这里
安装vim-plug插件, 原文件在这里, 下载plug.vim,然后把它放到vim安装路径的autoload目录下
VIM简介 VIM是一种信仰。

对我来说vi是禅, 使用vi就是使用禅。每个命令都是心印,这对用户来说是深奥的,对未入门者来说是无法了解的。每次使用它你都能发现真理。 --Satish Reddy
商业化产品可能是有用的, 但最好的东西往往是免费的, 空气, 水, vim
高效编辑的原则 形成过程
  • 自省, 找出重复/低效的部分
  • 寻找solution
  • 使之成为习惯
  • 7 Habits
    • 他们能做事主动。 (“积极主动”)
    • 他们能关注目标。 (“以终为始”)
    • 他们能确定要务。 (“要事第一”)
    • 他们能与人共赢。 (“双赢思维”)
    • 他们能与人沟通交流。 (“知彼解己”)
    • 他们能与人合作。 (“统合综效”)
    • 他们能反省自己并弥补不足。 (“自我更新”)
区分学习和使用
  • 学习是投入,使用是产出
  • 学习是投资,使用是收益
  • 不要第二次寻找同一问题的解决方案(DRY)
拿来主义
  • 选择性收集技巧, 有用的 VS 对你有用的
  • 避免收集对自己无用的高度特殊化的技巧
  • 不要为用不到的功能买单
    • 不要提前买单
    • 技能的投入产出比
    • 遗忘曲线
    • 打磨技艺持续前进
不断提高
  • 理解而非记忆
  • 培植而非收藏
  • 精心经营个人化功能子集
  • 全面了解,不要浅尝辄止
态度
  • 学而不用,积而不发
  • 了解工具实际被设计能做的事, 而不是你希望它能做的事.
  • 高效与否, 操之在你
    • 工具只会跟使用者一样好
  • 开放态度, 不要拒绝其它工具
    • 手持锤子,满世界都是钉子
第一课 学会自己搜索答案
vim从入门到精通
文章图片

第二课 完成vimtutor
vimtutor位于vim安装目录里,一个可执行程序(脚本)
它大约需要20分钟
第三课 Motion 通用
  • h/l/k/j
  • G/{num}G/gg/:{num}
  • %
  • gk/gj
  • 0/^/$
  • f{char}/F{char}/t{char}/T{char}/; /, : t=till=find-1
  • -/+/_
练习
To err is human.To really foul up you need a computer. <-------------------------> Thtn

单词级移动
key action
wW 移动到下一单词的开头
bB 移动到上一单词的开头
eE 移动到光标所在单词的末尾
gebwe <-<---->---> This is-a line, with special/separated/words (and some more). <----- <------------------------->-----> gEBWE gebwe

大范围移动
key action
% 移动光标到括号左半部分( 包括(、{、[ )对应右半匹配部分( )、}、] )
} 移动光标到当前段落的末尾
{ 移到光标到当前段落的开头
H 移动光标到屏幕的第一行
M 移动光标到屏幕的中间一行
L 移动光标到屏幕的最后一行
Ctrl + f 向前滚动一页
Ctrl + b 向后滚动一页
Ctrl + u 向前滚动半页
Ctrl + d 向后滚动半页
/ 向前查找, 结合n/N可以重复向前向后查找同一字符
? 向后查找, 可以结合n/N
关于查找
  • .*[]^%/\?~$有特殊含义,如果要查找它们,在在前面加上\.
  • 可以用:set ic:set noic来忽略或不忽略大小写
  • 输入/?后可以用来查找历史记录。
  • 可以在单词上用*#来向前或向后查找光标下单词
  • 如果要精确匹配, 用\<\>来精确匹配开头或结尾,两者可以同时使用,如/\,这样three不会被匹配
位置标记
key desciption
m{a-zA-Z} 把位置标记 {a-zA-Z} 设在当前光标位置 (不移动光标,这不是动作命令)。
g'{mark} 跳转到指定的位置标记 {mark},但在当前缓冲区内跳转时,不改变跳转表。
:marks 列出所有的位置标记 (这不是动作命令),第一列的编号为零。
标志说明
mark description
'a - 'z 小写位置标记,在每个文件内有效。
'A - 'Z 大写位置标记,也叫做文件标记,在文件间都有效。
'0 - '9 数字位置标记,在 .viminfo 文件里设置。
跳转
key action
CTRL-O 转到跳转表里第 [count] 个较旧的光标位置 (不是动作命令)。
CTRL-I 转到跳转表里第 [count] 个较新的光标位置 (不是动作命令)。
:ju[mps] 打出跳转表 (不是动作命令)。
:cle[arjumps] 清除当前窗口的跳转表。
编辑命令
<次数> <操作符> <文本对象或移动命令>

操作符
key action
c 修改 (change)
d 删除 (delete)
y 抽出 (yank) 到寄存器 (不改变文本)
~ 变换大小写 (只有当 'tildeop' 置位时有效)
g~ 变换大小写
gu 变为小写
gU 变为大写
! 通过外部程序过滤
= 通过 'equalprg' (若为空,C-indenting) 过滤
gq 文本排版
gw 文本排版,不移动光标
> 右移
< 左移
zf 定义折叠
高级技巧: 可以用":"命令定义一个动作, 例如d:call search("f"), 如果该命令多于一行,则不能用"."重复。
面向对象类型
一共三种: 字符/行/列
key type
v 在操作符后和动作命令之前应用: 即使该动作是面向行的,也强制该操作面向字符。
V 在操作符后和动作命令之前应用: 即使该动作是面向字符的,也强制该操作面向行。
CTRL-V 在操作符后和动作命令之前应用: 强制该动作面向列块。
练习: dj, dvj, dj
对象定义
  • word: 一个单词由字符、数字和下划线序列或者其他的非空白字符的序列组成。单词间可以空白
    字符 (空格、制表、换行) 分隔。这一规则可以用 'iskeyword' 选项改变。空行也被认
    作单词。
  • WORD: 一个字串由非空白字符序列组成。字串以空白分隔。空行也被认作字串。
  • sentence: 一个句子以 '.'、'!' 或者 '?' 结尾并紧随着一个换行符、空格或者制表符。标点和空
    白字符之间可以出现任何数量的闭括号和引号: ')'、']'、'"' 和 '''。另,段落和小节
    的边界也视为句子的边界。
  • paragraph: 一个段落从空行或某一个段落宏命令开始,段落宏由 'paragraphs' 选项里成对出现的字
    符所定义。它的缺省值为 "IPLPPPQPP TPHPLIPpLpItpplpipbp",也就是宏 ".IP"、".LP"
    等 (这些是 nroff 宏,所以句号一定要出现在第一列)。小节边界也被视为段落边界。
    注意 空白行 (只包含空白) 不是 段落边界。
  • section: 一个小节从首列出现的换页符 () 或某一个小节宏命令开始。小节宏由 'sections'
    选项里成对出现的字符所定义。它的缺省值是 "SHNHH HUnhsh",也就是说小节可以从如
    下的 nroff 宏开始: ".SH"、".NH"、".H"、".HU"、".nh" 和 ".sh"。
文本对象
key description
aw "一个单词",选择 [count] 个单词 (见 word )。包括开头或拖尾的空白,但不单独计算。在可视面向行的模式下,"aw" 切换到可视面向字符的模式。
iw "内含单词",选择 [count] 个单词 (见 word )。单词之间的空白也被算为一个单词。在可视面向行的模式下,"iw" 切换到可视面向字符的模式。
aW "一个字串",选择 [count] 个字串 (见 WORD )。包括开头或拖尾的空白,但不单独计算。在可视面向行的模式下,"aW" 切换到可视面向字符的模式。
iW "内含字串",选择 [count] 个字串 (见 WORD )。字串之间的空白也被算为一个字串。在可视面向行的模式下,"iW" 切换到可视面向字符的模式。
as "一个句子",选择 [count] 个句子 (见 sentence )。可视模式下它切换为面向字符的模式。
is "内含句子",选择 [count] 个句子 (见 sentence )。可视模式下它切换为面向字符的模式。
ap "一个段落",选择 [count] 个段落 (见 paragraph )。特例: 空白行 (只包含空白的行) 也被视为段落边界。可视模式下它切换为面向行的模式。
ip "内含段落",选择 [count] 个段落 (见 paragraph )。特例: 空白行 (只包含空白的行) 也被视为段落边界。可视模式下它切换为面向行的模式。
a(ab "一个()块",包括'(' 和 ')'
i(ib "一个()块",不包括'(' 和 ')'
a{a{ "一个{}块",包括'{' 和 '}'
i{i{ "一个{}块",不包括'{' 和 '}'
a"a'a\` "一个引号字符串", 包括引号
i"i'i\` "一个引号字符串", 不包括引号
常见命令
key actions
x 删除光标下的字符 ("dl" 的缩写)
X 删除光标前的字符 ("dh" 的缩写)
D 从当前位置删除到行尾 ("d$" 的缩写)
dw 从当前位置删除到下一个单词开头
db 从当前位置删除到前一个单词的开头
diw 删除光标上的单词 (不包括空白字符)
daw 删除光标上的单词 (包括空白字符)
dG 删除到文件末
dgg 删除到文件首
上面的d可以改成c或y
插入和替换 插入模式命令
key action
a 在光标后附加文本 [count] 次。如果光标在空行的第一列,启动插入模式。但在置位了 'virtualedit' 以后就不是!
A 在行尾附加文本 [count] 次。
i 在光标前插入文本 [count] 次。在插入模式里使用 CTRL-O 的时候,i_CTRL-O 不支持计数。
I 在本行第一个非空白字符之前插入文本 [count] 次。如果 'cpoptions' 里有 'H' 标志位而本行只有空白,在最后一个空白前插入。
gI 在第一列插入文本 [count] 次。
gi 在当前缓冲区最近一次插入模式停止的位置继续插入文本。该位置记在 '^ 位置标记里。如果标记在行末之后,和 "^i" 有所差异。该位置在插入/删除行时会自动修正。但_不_在插入/删除字符时被修正。使用 :keepjumps 命令修饰符时,不改变 '^` 位置标记。
o 在光标下方开启新行,并插入文本,重复 [count] 次。如果 'cpoptions' 里有 '#' 标志位,忽略计数。
O 在光标上方开启新行,并插入文本,重复 [count] 次。如果 'cpoptions' 里有 '#' 标志位,忽略计数。
退出插入模式
Ex插入命令
key Actions
:{range}a[ppend][!] 在指定行下方添加若干行。如果没有给出 {range},文本会在当前行之后插入。加入 [!] 切换此命令执行时的 'autoindent'。
:{range}i[nsert][!] 在指定行上方添加若干行。如果没有给出 {range},文本会在当前行之前插入。加入 [!] 切换此命令执行时的 'autoindent'。
这两个命令会继续要求行,直到你输入了只包含 "." 的一行。小心反斜杠开始的行,见 line-continuation
Ex 模式 (见 -e) 下,行尾的反斜杠可用来插入 NUL 字符。所以要使一行以反斜杠结尾,用两个反斜杠。也就是说仅在行尾情况下,反斜杠数目减半。
注意: 这些命令不能和 :global:vglobal 一起使用。":append" 和 ":insert" 在 ":if" 和 ":endif"、":for" 和 ":endfor" 还有 ":while" 和 ":endwhile" 之间不能很好的工作。
插入文件
key action
:r[ead] [++opt] [name] 在光标下方插入文件 [name] (缺省: 当前文件)。
:{range}r[ead] [++opt] [name] 在指定行下方插入文件 [name] (缺省: 当前文件)。
:[range]r[ead] [++opt] !{cmd} 执行 {cmd} 并把它的标准输出插入到光标下方。临时文件会建立来保存命令输出的结果,并被读到缓冲区里。'shellredir' 用来保存命令的输出结果,它可以设置是否包含标准错误的输出。
插入模式下的一些快捷键
key action
CTRL-[ 结束插入或替换模式,回到普通模式。结束缩写。
CTRL-C 退出插入模式,回到普通模式。不检查缩写。不激活 InsertLeave 自动命令事件。
CTRL-@ 插入最近插入的文本,并停止插入。
CTRL-A 插入最近插入的文本。
CTRL-H 删除光标前的字符 。
删除光标下的字符。如果光标在行尾,并且 'backspace' 选项包括 "eol",删除 ;下一行就此附加于当前行之后。如果你的 键不正确,见 :fixdel。
CTRL-W 删除光标前的单词
CTRL-U 删除当前行上光标前的所有输入字符。
CTRL-I 插入制表。如果打开 'expandtab' 选项,等价数目的空格被插入 也可使用 CTRL-Q
CTRL-J 开始新行。
CTRL-M 开始新行。
CTRL-K {char1} [char2] 输入二合字母 (见digraphs)。当 {char1} 为特殊字符时,该键的键码以 <> 形式插入。例如字符串 可以这样输入: (两个键)。两个键都不考虑映射。
CTRL-N 查找下一个关键字 (见 i_CTRL-N)。
CTRL-P 查找上一个关键字 (见 i_CTRL-P)。
CTRL-T 在当前行开始处插入一个 shiftwidth 的缩进。缩进总是取整到 'shiftwidth' 的倍数 (这是 vi 兼容的)。
CTRL-D 在当前行开始处删除一个 shiftwidth 的缩进。缩进总是取整到 'shiftwidth' 的倍数 (这是 vi 兼容的)。
0 CTRL-D 删除所有当前行的缩进。
^ CTRL-D 删除当前行的所有缩进。缩进在下一行上恢复。这可以用于插入卷标。
CTRL-V 如果下一个是非数字,按本义插入。对特殊键而言,插入其终端代码。CTRL-V 之后紧接着输入的字符不经过映射。注意: 当 CTRL-V 被映射时 (例如,用来粘贴文本),你可能经常需要使用 CTRL-Q 来代替
CTRL-SHIFT-V 与 CTRL-V 类似,除非激活了 modifyOtherKeys,此时插入带修饰符的键的转义序列。
CTRL-Q 等同于 CTRL-V。
CTRL-X 进入 CTRL-X 模式,一个子模式。那里你可以给出命令来补全单词或者滚动窗口。见 i_CTRL-Xins-completion
CTRL-E 插入光标下面的字符。
CTRL-Y 插入光标上面的字符。注意 CTRL-E 和 CTRL-Y 不使用 'textwidth',从而可以从长行里复制字符。
CTRL-] 切换缩写,不插入字符。
切换插入和替换模式。
插入寄存器内容
CTRL-R {register} 用于插入寄存器内容,在输入CTRL-R之后会有"显示出来,这时你需要输入寄存器名字
register Usage
" 无名寄存器,包含最近删除或抽出的文本
% 当前文件名
# 轮换文件名
* 剪贴板内容 (X11: 主选择)
+ 剪贴板内容
/ 最近的搜索模式
: 最近的命令行
. 最近插入的文本
- 最近的行内 (少于一行) 删除
= 表达式寄存器;你会被提示输入一个表达式 (见expression)
CTRL-R {register}还有几个变种:
  • CTRL-R CTRL-R {register} : 文本按本义插入,这意味着如果寄存器包含 这样的字符,结果会不同。例如,如果寄存器包含 "ab^Hc": CTRL-R a 产生 "ac"。CTRL-R CTRL-R a产生 "ab^Hc"。
  • CTRL-R CTRL-O {register} : 按本义插入寄存器内容,并且不进行自动缩进。
  • CTRL-R CTRL-P {register} : 按本义插入寄存器内容,修正缩进
复制并移动
keys Usage
"{a-zA-Z0-9.%#:-"} 指定下次的删除、抽出和放置命令使用的寄存器 {a-zA-Z0-9.%#:-"} (大写字符使得删除和抽出命令附加到该寄存器) ({.%#:} 只能用于放置命令)。
["x]y{motion} 抽出 {motion} 跨越的文本 [到寄存器 x]。如果没有字符被抽出 (例如,在第一列执行 "y0") 并且 'cpoptions' 里包括 'E' 标志位,这是一个错误。
["x]yy 抽出 [count] 行 [到寄存器 x] linewise 行动作。
["x]Y 抽出 [count] 行 [到寄存器 x] (等同于 yy, linewise 行动作)。如果你想要 "Y" 执行从光标到行尾的操作 (更合乎逻辑,但是与 Vi 不兼容),用 ":map Y y$"。
{Visual}["x]y 抽出高亮文本 [到寄存器 x] (关于 {Visual} 见 Visual-mode )。
{Visual}["x]Y 抽出高亮行 [到寄存器 x] (关于 {Visual} 见 Visual-mode )。
["x]p 放置文本 [从寄存器 x] 在光标之后 [count] 次。
["x] 从一个寄存器放置文本在光标之前 [count] 次。除非另外指定,否则用 "* 寄存器。光标停留在新文本的尾部。
["x]gp 如同 "p",但光标停留在新文本之后。
["x]gP 如同 "P",但光标停留在新文本之后。
Ex Command Usage
:reg[isters] 显示所有编号和命名寄存器的类型和内容。但不列出用于 :redir 目的地的寄存器。类型可以是以下之一: "c" 用于 characterwise 文本; "l" 用于 linewise 文本; "b" 用于 blockwise-visual 文本
:reg[isters] {arg} 显示 {arg} 里提到的编号和命名寄存器的内容。例如: :reg 1a
:di[splay] [arg] 和 :registers 相同。
:[range]y[ank] [x] 抽出 [range] 所指定的行 [到寄存器 x]。仅当包含 +clipboard 特性时才可以抽出到 "* 或 "+ 寄存器。
:[range]y[ank] [x] {count} 从 [range] 的最后一行开始 (缺省: 当前行 cmdline-ranges ) 抽出 {count} 行 [到寄存器 x]。
:[line]pu[t] [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之后。
:[line]pu[t]! [x] 放置文本 [从寄存器 x] 在行号 [line] (缺省为当前行) 之前。
:[range]co[py] {address} 把 [range] 指定的行复制到 {address} 给出的行之下。
:[range]m[ove] {address} 把 [range] 指定的行移动到 {address} 给出的行之下。
put总是 linewise 行动作,因而这个命令可以用来把抽出的块放置在新行上。寄存器也可以是 '=',跟随一个可选的表达式。表达式继续到该命令结束为止。你需要在 '|' 和 '"' 字符前加上反斜杠不让它们终止你的命令行。例如: :put ='path' . \",/test\" ; 如果 '=' 之后没有表达式,Vim 使用前一个表达式。用 :dis = 你可以看到它。
上面这些命令也可以用于global命令, 详细列表查看help ex-cmd-index
寄存器类型:
  1. 无名寄存器 ""
    用 "d"、"c"、"s"、"x" 等命令删除或者用 "y" 等抽出命令复制的文本都被 Vim 用来填
    充该寄存器
  2. 10 个编号寄存器 "0 到 "9
    Vim 把抽出和删除命令的文本保存在这些寄存器里。
  3. 行内删除寄存器 "-
    该寄存器保存删除不到一行内容的命令的文本
  4. 26 个命名的寄存器 "a 到 "z 或者 "A 到 "Z
    Vim 只有在你指定的时候才使用这些寄存器。指定为小写字母时替换原来的内容,指定为大写字母时附加到原来的内容。
  5. 三个只读寄存器 ":、". 和 "%
    ". 包含最近插入的文本
    "% 包含当前文件名
    “: 包含最近执行过的命令行。
  6. 轮换缓冲区寄存器 "#
    包含当前窗口buf文件名
  7. 表达式寄存器 "=
    其实并没有这么一个寄存器,这是可读写的
  8. 选择和拖放寄存器 "*、"+ 和 "~
    用这些寄存器来保存和取得 GUI 界面选择的文本。 只读的 "~ 寄存器保存最近一次拖放操作放下的文本
  9. 黑洞寄存器寄存器 "_
  10. 最近搜索模式寄存器 "/
常用选项
选项 描述
用法 :set all 显示所有选项和设置;
:set 显示当前设置的所有选项;
:set num? 显示num选项的当前设置;num可以换成其他选项;
:set num 打开选项与关闭选项;
:set nonum num可以换成其他选项;
num/nonum 是/否显示行号;
wrap/nowrap 是(默认)/否自动换行;
wrapmargin=n 设置右边界的值,当输入时到达右边界,并遇到空格时,会自动插入换行;
aw/noaw 临时转入shell或使用":n"编辑其他文件时,是/否自动保存当前文件已做的修改;
flash/noflash 在出错处使用闪烁提醒/使用呜叫提醒;
缩进 ai/noai autoindent是/否使用自动缩进方式,新行与前面的行保持—致的缩进;
smartindent smartindent/nosmartindent:是否使用能识别类C语法的智能缩进方式;
cindent cindent/nocindent:是/否使用cindent缩进方式;
indentexpr indentexpr/noindentexpr:是/否使用indentexpr缩进方式;
indenttype= 缩进方式:autoindent、smartindent、cindent、indentexpr(同上);
shiftwidth=n 自动缩进字符数;
tabstop=n 将TAB键的宽度设置为n个宁符宽度,默认为8;
编码 encoding= 设置vim内部使用的编码字符集;如:prc;
fileencoding= 设置当前编辑的文件的字符编码方式;如:utf-8;
fileencodings= 设置vim自动探测fileencoding的顺序列表;如:"ucs-bom,utf-8,latin1";
termencoding= vim工作的终端的编码方式;如:utf-8;
ambiwidth= 设置汉字所占字符宽度;如:double;
搜索 ic/noic 搜索时忽赂大小写/不忽略大小写(默认);
wrapscan 在搜索时到达文件尾后是/否跳文件头继续搜索;
incsearch incsearch/noincsearch:输入搜索关键字时,是/否(默认)自动高亮匹配的字符;
hlsearch hlsearch/nohlsearch:搜索后,是/否(默认)保留匹配字符的高亮显示
编程 syntax= on/off:是/否显示语法高亮;
保存 ro/noro 是/否只读模式,只读模式写只能通过强制方式":w!"写入,否则无法写入;
history=n history记录的行数,默认100个历史记录;
file filetype on 侦测文件类型;
filetype plugin on 载入文件类型插件;
filetype indent on 为特定文件类型载入相关缩进文件;
report=n 复制或者删除了多少行时显示提示信息,默认为2;
laststatus=0,1,2 是否显示状态栏,0:不显示,1:需要时间显示,2:总是显示;
list/nolist 是/否将tab、换行符使用替代字符显示(^I、$);
shell=path 设置vim执行外部命令时使用的shell路径,如:/bin/bash;
showmatch 设置输入右半边括号时,是/否(默认)提示所对应的左半边括号;
showmode 设置是(默认)/否在窗口左下角显示当前的模式:插入、替换等模式;
compatible 除非.vimrc文件存在,默认vim会尝试采用vi兼容的模式;
正则表达式
  1. 表示目标字符的元字符
元字符 说明
. 匹配任意字符
[abc] 匹配方括号中的任意一个字符,可用-表示字符范围。如[a-z0-9]匹配小写字母和数字
[^abc] 匹配除方括号中字符之外的任意字符
\d 匹配阿拉伯数字,等同于[0-9]
\D 匹配阿拉伯数字之外的任意字符,等同于1
\x 匹配十六进制数字,等同于[0-9A-Fa-f]
\X 匹配十六进制数字之外的任意字符,等同于2
\l 匹配[a-z]
\L 匹配3
\u 匹配[A-Z]
\U 匹配4
\w 匹配单词字母,等同于[0-9A-Za-z_]
\W 匹配单词字母之外的任意字符,等同于5
\t 匹配字符
\s 匹配空白字符,等同于[\t]
\S 匹配非空白字符,等同于6
  1. 需要转义的字符
元字符 说明
\* 匹配* 字符
. 匹配. 字符
\/ 匹配 / 字符
\ 匹配 \ 字符
\[ 匹配 [ 字符
\] 匹配 ] 字符
  1. 表示数量的元字符
元字符 说明
* 匹配0-任意个
\+ 匹配1-任意个
\? 匹配0-1个
\{n,m} 匹配n-m个
\{n} 匹配n个
\{n,} 匹配n-任意个
\{,m} 匹配0-m个
  1. 表示位置的元字符
元字符 说明
$ 匹配行尾
^ 匹配行首
\< 匹配单词词首
\> 匹配单词词尾
  1. 表示子模式的元字符
\()括起来的正则表达式,在后面使用时可以依次用\1, \2等变量来表示括号里的内容
  1. 表示非打印字符的元字符
元字符 说明
\n 表示匹配 一个换行符。
\r 表示匹配 一个回车符。
\t 表示匹配 一个制表符 ( Tab 键)。
\s 表示匹配 任意一个空白字符,包括空格、制表符、换页符等。
\S 表示匹配 任意一个非空白字符。
替换 substitue的缩写是s, 基本语法是: [range]substitue/search/replace/[flags] [count]
对 [range] 指定的行把 {pattern} 的匹配替代成 {string}。关于 {pattern},参见 |pattern|。{string} 可以是按本义出现的字符串,也可包含特殊字符。参见 |sub-replace-special|。如果不指定 [range] 和 [count],仅在当前行进行替代。如果指定 [count],在 [range] 最后一行开始的 [count] 行进行替代。如果不指定 [range] ,则从当前行开始。[count] 必须为正数。另见 |cmdline-ranges|。

  1. range
range是同一个或多个被,; 分割的行限定符组成。当用; 时, 光标位置会被设置为前一个行限定符确定的行值。
如果行限定符个数多于命令需要的数量,那么前面的限定符被忽略。
行号可以用下列符号:
符号 行号
{number} 行号
. 当前行
$ 文件的最后一行
% 相当于 1,$ (整个文件)
't 标记 t 的位置 (小写)
'T 标记 T 的位置 (大写);如果标记存在于另一个文件中,则不能在范围里应用。
/{pattern}[/] 下一个 匹配 {pattern} 的行
?{pattern}[?] 前一个 匹配 {pattern} 的行
\/ 下一个 与前次搜索模式匹配的行
\? 前一个 与前次搜索模式匹配的行
\& 下一个 与前次替代模式匹配的行
这些符号后面可以跟一个或多个+-和一个可靠数字,如果数字省略,则认为是1
/?前面可能有另一个地址,那么查找就从那里开始。如果使用; , 那么光标会移动
/pat1//pat2/ :不移动光标
7; /pat2/ : 光标留在第7行
例子:
.+3
/that/+1
.,$
0; /that
1; /tath
  1. replace中的特殊字符
nomagic 动作
\& 替代为完整的匹配
& 替代为 &
\0 替代为完整的匹配
\1 替代为匹配的第一个 () 里面的内容
\2 替代为匹配的第二个 () 里面的内容
.. ..
\9 替代为匹配的第九个 () 里面的内容
\~ 替代为前一个 substitute 的替代字符串
~ 替代为 ~
\u 下一个字符成为大写
\U 其后字符成为大写,直到 \E 出现
\l 下一个字符成为小写
\L 其后字符成为小写,直到 \E 出现
\e 结束 \u、\U、\l 和 \L (注意: 不是 !)
\E 结束 \u、\U、\l 和 \L
把该行在此位置一分为二 ( 以 CTRL-V 方式输入)
\r 同上
\ 插入一个回车 (CTRL-M) ( 以 CTRL-V 方式输入)
\n 插入一个 (文件里的 ) (此处并不是换行)
\b 插入一个
\t 插入一个
\\ 插入单个反斜杠
\x 其中 x 是上面没提到的任何一个字符: 保留作将来的扩展
\1\2 等里的数字是基于模式里 \( 出现的顺序 (从左到右)。如果一个括号组匹配多次,最后一次的匹配被使用在 \1\2 等里。例如:
:s/\(\(a[a-d] \)*\)/\2/# 修改 "aa ab x" 为 "ab x"

\2 对应 \(a[a-d] \)。第一次匹配 "aa ",第二次匹配 "ab ", 最后一次匹配"ab "被用于\2
  1. Flags
Flags Usage
`& 必须是首个使用的标志位,保留和上次substitue相同的标志位 `
`c ` 确认每个替代
`e ` 如果搜索不成功,不给出错误信息
`g ` 对行内所有匹配进行替代
`i ` 忽略模式的大小写
`I ` 不忽略模式大小写
`n ` 只报告匹配次数,不实际进行替代
`p ` 显示包含最后一次替代的行
`# ` 类似p, 且在前面加上行号
`l ` 类似p,但显示方式类似:list
`r ` 如果匹配模式为空,优先使用上一次使用的搜索模式,之后再是上一次substitute或global使用的模式
  1. 示例
:s/a\|b/xxx\0xxx/g# 修改 "a b"为 "xxxaxxx xxxbxxx" :s/\([abc]\)\([efg]\)/\2\1/g# 修改 "af fa bg" 为 "fa fa gb" :s/abcde/abc^Mde/# 修改 "abcde"为 "abc"、"de" (两行) :s/$/\^M/# 修改 "abcde"为 "abcde^M" :s/\w\+/\u\0/g# 修改 "bla bla"为 "Bla Bla" :s/\w\+/\L\u\0/g# 修改 "BLA bla"为 "Bla Bla" :s/aa/a^Ma/# 修改 "aa"为 aa :s/aa/a\^Ma/# 修改 "aa" 为a^Ma :s/aa/a\\^Ma/# 修改 "aa" 为 a\a

多文件编辑
  1. 已经打开一个文件
    • 打开一个新文件
      edit[!] foo.txt
    • 保存
      write
  2. 打开多个文件
    vim one.c two.c three.c
    然后可以用:[num]next, :wnext:[num]previous, :wprevious, :last, :first来切换
  3. 多文件跳转
    可以用args one.c two.c three.c来添加多个文件
    然后可以用CTRL-^来切换到上一个文件
    有两个标记非常重要:
    `'"`: 你上次离开这个文件的位置 `'.`: 你最后一次修改文件的位置

    可以用m[a-zA-Z]来标记文件, 然后用'[mark]来跳转
    还可以用CTRL-OCTRL-I来在整个跳转序列中前后跳转
多窗口 分割窗口
可以直接用vim -O one.c two.c来直接以分割方式打开多个文件
-O : 垂直分割
-o : 水平分割
如果已经打开文件,可以使用命令来打开/关闭窗口
:sp[lit] {file}水平分屏 :new {file}水平分屏 :sv[iew] {file}水平分屏,以只读方式打开 :vs[plit] {file}垂直分屏 :clo[se]关闭当前窗口 :only只显示当前窗口

上述命令都有快捷键, 共同前缀是: CTRL-W
Ctrl+w s水平分割当前窗口 Ctrl+w v垂直分割当前窗口 Ctrl+w q关闭当前窗口 Ctrl+w n打开一个新窗口(空文件) Ctrl+w o关闭除当前窗口之外的所有窗口 Ctrl+w T移动当前窗口到新标签页

切换窗口
Ctrl+w h切换到左边窗口 Ctrl+w j切换到下边窗口 Ctrl+w k切换到上边窗口 Ctrl+w l切换到右边窗口 Ctrl+w w遍历切换窗口

移动窗口
Ctrl+w H向左移动当前窗口 Ctrl+w J向下移动当前窗口 Ctrl+w K向上移动当前窗口 Ctrl+w L向右移动当前窗口

调整窗口大小
Ctrl+w +增加窗口高度 Ctrl+w -减小窗口高度 Ctrl+w =统一窗口高度

映射 【vim从入门到精通】$$ {lhs} {rhs} $$
command
Command Normal Visual Operator Pending Insert Only Command Line
命令 常规模式 可视化模式 运算符模式 插入模式 命令行模式
:map noremap y y y
:nmap nnoremap y
:vmap vnoremap y
:omap onoremap y
:map! noremap! y y
:imap inoremap y
:cmap cnoremap y
Operator-pending模式,是指当你输入操作符(比如d)时,然后继续输入的移动步长和文本对象(dw)的状态
nore的含义是, 禁止对{rhs}再进行映射扫描,以防止嵌套和递归,通常用于重定义一个命令
args
可以按任意顺序使用。它们必须紧跟在命令的后边,而在其它任何参数的前边。
: 只作用于当前buffer
: 不回显命令
: 只能使用开关的脚本来映射{rhs}
: 如果映射或缩写的命令已存在,只命令失败
: 那个{rhs}是一个表达式,会用计算后的返回值代替{rhs}
强大的gv :global 命令是 Vim 中一个更强大的命令 (之一)。它允许你找到一个匹配点并且在那里执行一个命令。它的一般形式是:
:[range]g/{pattern}/{command}

在每一匹配行上执行命令command. 这个命令只能是冒号命令, 普通模式命令不能在这里使用。如果需要,可以使用:normal命令。
如果要查看可以使用的命令,可以help ex-cmd-index。 如果要查看详细解释, 查看help 10.4help multi-repeat
vglobal相当于global!, 两者可以组合使用, 如:g/found/v/notfound/{cmd}
利用global我们可以把我们之前学的很多东西都串连起来,以完全一些非常奇妙的动作。
简单示例,
  • 要删除所有空行: :g/^$/d
  • 要在含有always..begin的行后加上:label: :g/always.*begin/s/$/ :label
exec和normal execute命令用来把一个字符串当作Vimscript命令执行。比如: :execute "rightbelow vsplit " . bufname("#")
normal命令把我们的脚本跟日常的文本编辑按键结合起来, 比如: :normal ggdd。 为了防止递归解析, 建议永远使用normal!
利用exec和normal的组合可以将动作变成可重复的命令, 并消除转义字符问题。比如: :execute "normal! mqA; \'q"
  1. 0-9 ?
  2. 0-9A-Fa-f ?
  3. a-z ?
  4. A-Z ?
  5. 0-9A-Za-z_ ?
  6. \t ?

    推荐阅读