0%

按模式匹配还是按原义匹配

Tip 72 Tune the Case Sensitivity of Search Patterns

调整搜索大小写敏感度

全局区分大小写

通过设置 :set ignorecase 选项即可开启忽略大小写。需要注意的是, 此设置会对 Vim 关键词补全有一定的影响。

每次搜索区分大小写

可以使用以下选项来覆盖默认的是否忽略大小写:

  • \c - 忽略大小写

  • \C - 区分大小写

每次搜索的时候都可以强制指定是否区分大小写。注意:在替换时\c标志位为手工确认。

启用智能大小写

Vim 提供了预测我们大小写敏感意图的 smartcase 选项, :set smartcase

启用此选项后进行搜索时,

  • 如果输入的全部是小写字母, 那么就不区分大小写;

  • 但只要包含大写字母, 那么就是大小写敏感的

Tip 73 Use the \v Pattern Switch for Regex Searches

按正则表达式查找时,使用 \v 模式开关 (开启字符的特殊含义)

我们可以使用 \v 模式(very magic search)开关规范所有的特殊符号, 启用之后, 除了下划线 _, 大小写字母, 和数字外, 所有的字符都具有特殊含义。

Tip 74 Use the \V Literal Switch for Verbatim Searches

按原义查找文本时,使用 \V 原义开关 (开启字符的特殊含义)

在正则表达式中使用的特殊字符,在按模式查找时用起来很顺手,但如果我们想

按原义查找文本时,它们就变成了阻碍。使用 very nomagic 原义开关,可以消除附

加在 .、 * 以及 ? 等大多数字符上的特殊含义。

使用原义开关 \V,即可激活 very nomagic 搜索模式

例如:搜索匹配“a.k.a.”字符串

/ \Va.k.a.

我们也可以使用转义的方式来消除字符的特殊含义。例如:

/ a.k.a.

使用 “\V” 会使得其后的模式中只有反斜杠有特殊的意义,显然更方便。

Tip 76 Stake the Boundaries of a Ward

界定单词的边界

定义一个搜索模型时, 指定单词的开始和结束位置可能很有用, Vim 给我们提供了单词分隔的选项。

例如执行搜索 /the 的时候, 是会把 these they their 等单词一起搜索出来的。

如果我们想只搜索 the 完整的单词, 而不需要包含 the 片段的词, 那么我们需要指定 词的边界。

在 \v 模式下(开启字符特殊含义), < 和 > 即代表词边界的符号. 所以我们可以使用 /\v 来达到我们的预期。

需要注意的是, 如果我们在 \v 模式下需要匹配 <> 字符, 那么就得加反斜杠来进行转义了。

Tip 78 Escape Problem Characters

转义问题字符

在 /V 纯文本模式下可以很容易的来进行纯文本的搜索匹配, 因为绝大部分的字符(如:. + *等)的特殊含义都被禁用了, 但是仍然有极少字符仍然有特殊的含义。

这时要用 \ 进行转义。

正向搜索转义斜杠 ‘/ ’

正向搜索时, 斜杠 / 字符被解释为终止符, 所有在此字符之后的内容都会被忽略,替换模式下在 \ 字符后添加标志位。

在 \v 和 \V 模式下, 如果要匹配 / 字符, 那么需要进行转义。

反向搜索转义问号 ‘ ? ’

当使用反向搜索的时候, 问号 ? 就是搜索的终止符。如果要匹配 ?号,需要转义 ?

每次都转义反斜杠 ‘ \ ’

\ 是需要进行转义的. 通常情况下, 反斜杠 \ 之后的那个字符表示被转义的特殊含义. 所以要匹配反斜杠字符的话就需要加转义, 也就是: \

而且,不管正向还是反向搜索,要匹配 \ 都是需要转义的。

终止符( / 或 ? )

Vim 允许在搜索字段终止符后面追加某些标志来调整搜索命令的行为

例如 /vim/e 将把光标放到高亮匹配位置的最后而不是前面

替换

Tip 87 Meet the Substitute Command

结识替换命令,:substitute 命令。其允许我们查找和替换一个文本块,语法如下:

1
:[range]s[ubstitute]/{pattern}/{string}/[flags]

​ 命令很复杂.,除了要提供搜索模式和替换文本之外, 还需要指定执行的范围。另外, 还可以提供额外的标识符来调整其行为。

[range] 的使用和其他 Ex 命令一样,以逗号分隔

{pattern} 指代要查找的部分

Flags,标志位调整替换行为

几种常用的 flag 标志符:

  • g - 让替换命令应用到全局,可修改一行内的匹配项, 而不是仅改变第一个匹配项.

  • c -替换前手工确认或拒绝每一处修改,

  • n - 禁止替换行为, 此功能可用于统计匹配文本的数量

  • e - 忽略错误信息. 例如搜索没有匹配项时, 替换命令会提示一个错误信息 “E486: Pattern not found.”

  • & - 告知 Vim 重用上一次替换命令中的相同标志.

替换域中的特殊字符

查找模式时某些字符是有特殊意义的. 而替换字段也是有一些特殊字符的

Symbol Represents
\r 插入回车(而不是\n)
\t 插入 tab 键
\ 插入反斜杠 \
\1 插入第一个子匹配
\2 插入第二个只匹配 (依次到 \9)
\0 插入整个匹配的文本
& 插入整个匹配的文本
~ 使用上次的 {string} 替换文本
={Vim script} 执行 {Vim脚本} 表达式, 把结果结果作为 {string} 替换文本

Tip 88 Find and Replace Every Match in a File

在文件范围内查找并替换每一处匹配

  • 标志位 g 处理横轴字符,当前行所有匹配

  • 地址符 % 处理纵轴的文本行,可理解为处理整个文件的匹配项

语法如下:

1
:%s/content/copy/g

Tip 89 Eyeball Each Substitution

手动控制每一次替换操作

标志位 c 手工确认每一处修改

语法如下:

1
:%s/content/copy/gc

​ 引入标志位 c 后,Vim 会在每处匹配体贴地为我们提示所有的选项y/n/a/q/l/^E/^Y。下表展示了每种答案的含义:

Keystrokes Buffer Contents
y yes 替换本次修改
n no 放弃本次修改
q quit 退出替换
l last 本次为最后一次替换, 然后退出
a all 替换本次和剩下的所有项
向上滚动屏幕
向下滚动屏幕

不同于以往的是,在 Vim 的替换-确认模式下,键盘上的大多数按键都将失效。尽

键可以让我们像往常一样回到普通模式,但除此之外,周围的一切都使我们

感到陌生。

Tip 90 Reuse the Last Search Pattern

重用上次的查找模式

如果你觉得将来会以完整形式来调用历史记录中的 substitute 命令, 就要养成在查

找域中填充内容的习惯。你只需在命令行中输入 <C-r>/,即可把上次的查找内容粘贴进来。

即留空查找域,使用<C-r>/替代

Tip 91 Replace with the Contents of a Register

用寄存器的内容替换

通过输入 <C-r>{register}, 我们可以将寄存器的内容插入到命令行

Tip 92 Repeat the Previous Substitute Command

重复上一次 substitute 命令

假设我们刚刚执行完以下命令(其作用范围为当前行):s/target/replacement/g

但我们失误,应该加上前缀 % 才对,接下来,我们只需输入 g&,即可在整个文件的范围内重复这条命令。

某条 substitute 命令除了没加 % 前缀之外,其余都正确的时候,不妨试一试 g&

​ gv 命令会激活可视模式,并重新将上次被选中的文本高亮起来(详情参考Tip 21 )进入命令行模式,此时命令行会提示为 :’<,’> 键入 &&, 第一个 :& 组合为 Ex 命令, 功能为重复最后一次替(:substitute)换命令(参考 :h :&), 而第二个 & 则表示使用前一个替换命令的标志符。

查找

Tip 79 Meet the Search Command

结识查找命令

Command Effect
/ 向后搜索
? 向前搜索
n 跳转到下一个匹配位置(next match), 保持搜索方向和偏移
N 调整到上一个匹配位置, 保持搜索方向和偏移
/ 搜索模式不变, 向后跳转到下一个匹配位置
? 搜索模式不变, 向前调整到上一个匹配位置
gn 启用可视化模式, 选中下一次的匹配文本
gN 启用可视化模式, 选中上一次的匹配文本

回溯之前的查找

Vim 会一直记录我们执行过的查找模式,因此可以方便地重用它们。当查找提示

符出现时,我们可以通过 键,滚动浏览之前的查找记录。

Tip 80 Highlight Search Matches

高亮查找匹配

通过启用hlsearch选项,在配置文件中设置set hlsearch 可以高亮显示查找匹配。

禁用高亮查找功能

高亮查找有时会使得工作区内到处充斥高亮色调,Vim 提供了一种优雅的解决方案, 即通过 :nohlsearch 命令暂时关闭查找高亮功能(简写 :noh )。此命令使得高亮功能一直处于关闭状态,直到执行新的或重复的查找命令为止。

创建用于关闭高亮功能的快捷键

:noh <CR> 虽然可以禁用查找高亮功能,但我们在键盘操作上也花费了不少功夫。

通过创建映射项,可以让我们加速操作,例如:

1
nnoremap <silent> <C-l> :<C-u>nohlsearch<CR><C-l>

通常用于清除并重绘显示屏(参见 :h CTRL-L )。而新的映射项,是在原有基础之上增加了暂时关闭查找高亮的功能。

Tip 81 Preview the First Match Before Execution

在执行查找前预览第一处匹配

缺省情况下, 我们在输入查找模式时, Vim 不会进行查找, 只有当我们按下 后,它才会立即展开行动。启用‘incsearch’选项,set incsearch , 会让 Vim 根据已在查找域中输入的文本,预览第一处匹配。每当我们新输入一个字符时, Vim 会即时更新预览内容。

根据预览结果对查找域自动补全 (

例子:我们搜索输入 carr 就直接定位到 carrot 单词了. 假如我们需要匹配整个的 carrot 单词, 用来做替换之类的呢?

​ 简单的方式就是手动全部敲完整个单词 carrot, 不过有快捷键可以完成此任务: <C-r><C-w>. 此快捷键可以把当前预览匹配的词自动补全到搜索字段, 比较长的单词就很好用了。

需要注意的是 自动补全比较脆弱。

例如在使用 \v 正则模式下搜索时, 将会补全光标处的整个单词 (那么 /\vcarr 将会得到 /\vcarrcarrot 结果)。

因此,只要你找的不是模式,而是单词或词组,基于增量查找的自动补全功能真地能节省一点时间。

Tip 82 统计当前模式的匹配个数

虽然没有任何方法可以让查找命令统计当前文档中的匹配个数,但是用下面这条命令就可以做到这一点

1
2
➾:%s///gn
《 117 matches on 65 lines

​ 实际上,我们调用的是 :substitute 命令,替换命令,但标志位 n 会抑制正常的替换动作。该命令不会对每处匹配进行替换,而是简单地统计匹配的次数,并将结果显示到命令

行上。

不管怎样,不要省略任何 / 字符。如果少加了一个/ ,即 :%s//gn,将致使

“gn”替换每一处匹配。

Tip 83 Offset the Cursor to the End of a Search Match

将光标偏移到查找匹配的结尾

​ 每当我们执行查找命令时,光标总会被定位于匹配的首字母上。虽然这种缺省操

作看起来比较合理,但我们可能有时更倾向于将光标定位于查找匹配的结尾。Vim 的

查找偏移功能,可以将此想法变为现实。

标志位e

加入标志位e会把光标移到匹配项结尾

例如: /vim/e

Tip 85 Create Complex Patterns by Iterating upon Search History

利用查找历史,迭代完成复杂的模式

写一个正则表达式并不简单. 通常都不是一次就能写对的, 所以如果能在上一次的基础上进行改进就显得很必要. 那么重新调用和编辑搜索历史就是必备的技巧 。

在查找提示符 \ 出现后,键入 会显示之前的搜索记录

在文件中跳转

Tip 55 Traverse the Jump List

遍历跳转列表

Vim 在跳转之前和之后记录我们的位置,并提供一些命令来回溯我们的步骤,类似于Web浏览器中的前进和后退。对vim来说:

  • < C - o > - 后退, 跳转到上一个位置

  • < C - i > - 前进, 后退之后就可以往前了

:jumps命令可以查看跳转列表,效果类似于 :ls

跳转位置的定义:Any command that changes the active file for the current window can be described as a jump.

任何更改当前窗口的活动文件的命令都可以描述为跳转。Vim 会把执行跳转命令之前和之后的光标位置,记录到跳转列表中。例如:

如果我们运行:edit命令打开了一个新文件,那么就可以用 <C-o> 和 <C-i> 命令在这个新文件以及原本的文件之间来回跳转。

[count]G命令直接跳到指定的行号也会被当成一次跳转,但每次向上或向下移动一行则不算。面向句子的动作及面向段落的动作都算跳转,但面向字符及面向单词的动作则不算。用一句话来概括,我们可以说大范围的动作命令可能会被当成跳转,但小范围的动作命令则只能算移动。

下表节选了一些跳转动作:

[count]G 行跳转
/pattern 或 ?pattern 跳转到 下一个/上一个 匹配的 pattern 位置
n / N 同上
% 跳转到 配对的括号位置 () [] {} <>
( / ) 跳转到 前/后 一句内容
{ / } 跳转到 前/后 一段内容
H / M / L 跳转到 上/中/下 屏幕
gf 跳转到 光标处的文件
<C-]> 跳转到 光标处关键词定义的地方
`{mark} / ‘{mark} 跳转到 标记 / 标记非空白行首 位置

命令本身不会被当成动作命令。也就是说,我们既不能用它们扩大可视模式的选区,也不能在操作符待决模式中使用它们。

​ Vim 可以同时维护多份跳转列表。实际上,每个单独的窗口都拥有一份自己的跳转列表。如果你正在使用分割窗口或多标签页,那么 命令会始终在当前活动窗口的跳转列表范围内进行跳转

注意:试着在插入模式中按一下 < C- i >,你会发现这和按 键的效果是一样的,

因为 Vim 本来就把 当成同一个东西。如果重新映射 键的话,那么也应该意识到,当你按下 时,该映射项也会被触发(反之亦然)。跳转的缺省行为将会被改变,只能单向遍历。

Tip 56 Traverse the Change List

遍历改变列表

每当对文档做出修改后, Vim 都会记录当时光标所在的位置。遍历改变列表的方法很简单,并且这大概是跳到你要去的地方的最快方式。

撤销/重做 命令:

  • u - 撤销变更 (相当于 win <C - z>)

  • - 撤销之前的撤销 (相当于 win <C - y>)

Vim 会在编辑会话期间维护一张表,里面记载我们对每个缓冲区所做的修改,此表就是所谓的改变列表,使用 :change 命令可以查看其内容。

Vim 为每次修改都记录了行号与列号,我们可以用 g; 和 g,命令反向或正向遍历改变列表。可以拿; 和 ,命令当参考,来帮你记忆 g; 与 g, 命令。前两条命令分别用来正向及反向重复 f{char} 命令,加上g前缀

标识上次修改方位的位置标记,Vim 会自动创建一些位置标记,它们是对改变列表的一个有用补充。

  • `. 标记总是指向上次修改的位置

  • `^ 标记则会指向上次退出插入模式时光标所在的位置 ( gi 命令)

Vim 会为编辑会话中的每个单独缓冲区维护一个改变列表,而与之不同的是,每个窗口都会创建一个单独的跳转列表。

在大多数场景下,跳转到 `` . 的效果与使用 g; 命令相同。不过位置标记只指向最后修改的位置,而改变列表中则保存了多组位置。我们可以多次按 g; 命令,每次它都会把我们带到改变列表中较早的一个位置,而 . 则总是把我们带到改变列表的最后一项。

​ ``^ 标记指向上次插入的位置,它比上次修改的位置更具体一点。如果我们先退出插入模式,接着又在文档中四处移动,然后,当我们又想快速回到退出的地方继续编辑时,用 **gi (g前缀 i插入**)命令就行了。此命令会用 ^ 标记恢复光标位置,并切换到插入模式,这真是省时省力的好办法!

Tip 57 Jump to the Filename Under the Cursor

跳转到光标下的文件

Vim 将文档中的文件名视为一种超链接。如果配置正确, 我们可以使用 gf 命令转到光标下的文件名。

指定文件的扩展名

suffixesadd 选项允许我们指定一个或多个文件扩展名,当 Vim 用 gf 命令搜寻文件名时,会尝试使用这些扩展名。

1
:set suffixesadd+=.rb      //添加.rb的文件扩展名

每次用 gf 命令时, Vim 都会在跳转列表中增添一条记录,因此我们总是可以用** 命令返回原处**。

指定要搜寻的目录

​ 引用的文件不位于工作目录的相对路径中,要引用第三方库的时候,需添加路径path。我们可以把它配置成一个以逗号分隔的目录列表。 当使用 gf 命令时, Vim 会检查path列表中的每一个目录,看看该目录中是否包含一个匹配光标下文本的文件名。path设置也会作用域 :find 命令

1
2
3
4
5
6
7
8
9
10
11
:set path+=app/**   //添加路径

:set path? //查看路径

❮ path=.,/usr/include, ,

. : 表示 当前文件所在目录

/usr/include : 这个很明显了

空 : 两个 , , 中间的空 就表示当前工作目录 (注意,一个文件所在,一个当前工作)

Tip 58 Snap Between Files Using Global Marks

用全局位置标记在文件间快速跳转

标记语法 m{letter}

  • m[a-z] - 小写字母的, 创建一个可以在当前文件(缓冲区)进行跳转的标签
  • m[A-Z] - 大写字母的, 创建一个可以全局的标签, 可以在多个文件之前跳转

跳转语法 `{letter}

编码之前设置全局标记,全局标记在多个文件切换时非常有用。

用动作命令在文档中移动

命令 用途 命令 用途
( 前移一句 后移一句
{ 前移一段(以空格行分辨) } 后移一段(以空格行分辨)

Tip 47 Distinguish Between Real Lines and Display Lines

区分实际行与屏幕行

除 Vim 以外,其他大多数文本编辑器都没有实际行的概念,它们只提供操作屏幕行的手段。

vim的 j、 k、 0 和 $ 都用于操作实际行,而如果在这些键前加上 g 前缀的话,就会让 Vim 对屏幕行进行操作。

img

以截图为例,假设我们想把光标向上移一行( k ),光标会移到单词“ac”上去,这既是所谓的实际行

我们按 gk 就会移到单词“vehicula”上,目标单词位于光标之上的一个屏幕行,这就是屏幕行

Vim 也提供了直接跳到行首及行尾的命令

命令 移动
0 移动到实际行的行首
g0 移动到屏幕行的行首
^ 移动到实际行的第一个非空白字符
g^ 移动到屏幕行的第一个非空白字符
$ 移动到实际行的行尾
g$ 移动到屏幕行的行尾

Tip 48 Move Word-Wise

基于单词的移动

img

w b命令,可以把它们想作“word”及“back-word”。

e ge 命令是对此命令集的补充

vim有“单词” word 和“字串” WORD 的区分,以空白字符为间隔识别字串每个面向单词的动作命令,都有一个面向字串的命令与其对应,这当中包括 W、 B、 E 和 gE

  • “单词”(word):由 字母+数字+下划线 组成。

  • “字串”(WORD):由 一串非空白字符的字符串组成,以空格为间隔识别字串

空白字符 包括: 空格, 制表符(Tab), 换行

Tip 49 Find by Character

对字符进行查找

最常用语法 f{char}

vim 里最快的移动技能之一; 行内按字符往后搜索, 如果匹配到, 那么光标直接定位到匹配的字符上, 没匹配就保持原状。但仅能在行内查找

移动到下一个匹配项(正向查找) 移动到前一个匹配项(反向查找)

查找字符时,可以包含或是排除目标字符,下表列出了其中的所有命令:

命令 用途
f{char} 正向移动到下一个{char}所在之处
F{char} 反向移动到下一个{char}所在之处
t{char} 正向移动到下一个{char}所在之处的前一个字符上
T{char} 反向移动到下一个{char}所在之处的前一个字符上
重复上一次的查找命令
反向查找上一次的字符查找命令

Tip 50 Search to Navigate

通过查找进行移动

1
语法 /{chars} 或 /{patterns}

普通模式下,按下 / 启用搜索命令,

键入字符后, 可以看到有多处匹配的结果, <CR> 回车定位到了第一次匹配的地方; 可以按 n 跳转到下一个匹配地方, 也可以按 N 反向跳转

匹配到了唯一的结果时, 回车定位直接到匹配的地方

取消高亮选区,命令模式下,输入:nohlsearch 也可以:set nohlsearch; 当然,可以简写,:noh或者set noh

在vim配置文件中加入如下配置会非常实用: ~/.vimrc

set hlsearch “ 搜索高亮

set incsearch “增量显示部分匹配

set ignorecase “忽略大小写

Tip 51 Trace Your Selection with Precision Text Objects

用精确的文本对象选择选区

文本对象允许我们操作括号、 被引用的文本、 XML 标签以及其他文本中的常见结构。

文本对象 选择区域 文本对象 选择区域
a) or ab 一对圆括号(parentheses) i) or ib 一对圆括号(parentheses)内部的内容
a} or aB 一对花括号{braces} i} or iB 一对花括号{braces}内部的内容
a] 一对方括号[brackets] i] 一对方括号[brackets]里的内容
a> 尖括号 i> 尖括号的内容
a’ 单引号 i’ 单引号的内容
a” 双引号 i” 双引号的内容
a` 反引号 i` 反引号的内容
at 标签 it 标签的内容

为了便于记忆,可以把i想成inside,而把a想成aroundall

用文本对象执行操作

文本对象并不仅仅局限于可视化选择,每当在vim命令语法里出现{motion} 时,都可以在这个地方使用文本对象,常见的例子包括 d{motion}、c{motion}和 y{motion}

Tip 52 Delete Around, or Change Inside

删除周边,修改内部

Vim 的文本对象分为两类:

  • 一类是操作分隔符的文本对象,如 i)、 i” 和 it;另

  • 一类用于操作文本块,如单词、句子和段落。

  • Tip 51总结前者,Tip 52总结后者。

文本对象 匹配区域 文本对象 匹配区域
iw 一个词 word aw 一个词 word 含后面的一个空格
iW 一个词 WORD aW 一个词 WORD 含空格
is 一句话 as 一句话含后面的一个空格
ip 一段话 ap 一段话 含空行

一般来讲:

  • d{motion} 更适合于: aw as ap 场景
  • c{motion} 更适合于: iw is ip 场景

Tip 53 Mark Your Place and Snap Back to It

位置标记和返回标记

vim 标记可以使我们在文档内快速的进行跳转, 我们可以手动设置标记, vim 也会自动记录我们感兴趣的位置。

1
标记语法 m[a-z / A-Z]
  • [a-z] 小写字母 仅在当前缓冲区可访问

  • [A-Z] 大写字母 全局生效, 多个缓冲区可访问

跳转语法

  • `{mark} - 跳转到标记为 {mark} 的精确位置

  • ‘{mark} - 跳转到标记为 {mark} 行的行首非空白字符处

mm 和 ``m `命令是一对便于使用的命令,它们分别设置位置标记 m,以及跳转到该标记

如果你只想记一条命令,那就记住``{mark} `好了。不论你是想恢复到准确的光标位置,还是只想回到正确的行,这条命令都能做到。

自动位置标记

Vim 会自动帮我们设置一些位置标记,这些标记用起来非常方便

Keystrokes Buffer Contents
`` 当前文件中最后一次跳转前的位置
`. 最后修改的位置
`^ 最后插入的位置
`[ 最后一次修改/拷贝的起始位置
`] 最后一次修改/拷贝的结束位置
`< 最后一次可视化块的起始位置
`> 最后一次可视化块的结束位置

Tip 54 Jump Between Matching Parentheses

在匹配括号之间跳转

% 可以再匹配的括号间进行跳转; 比如: () {} [] <>

File

Tip 36 Track Open File with the Buffer List

用缓冲区列表管理打开的文件

文件与缓冲区的区别:文件是存储在磁盘上的,而缓冲区则存在于内存中。当 Vim 打开一个文件时,该文件的内容被读入一个具有相同名字的缓冲区。刚开始,缓冲区的内容和文件的内容完全相同,但当我们对缓冲区做出修改时,二者的内容就会出现差别。如果我们决定保留这些修改,就可以再把缓冲区的内容写回到文件里。

Vim允许我们同时在多个缓冲区(buffer)上工作,它会显示一个窗口,但窗口内仅会显示第一个buffer,一个窗口对应一个buffer。另外的buffer在当前窗口不可见,但其内容已经被载入到一个后台的缓冲区了,通过:ls命令可以查看。

:ls命令会列出所有被载入到内存中的缓冲区的列表,例如:

img

% 符号指明哪个缓冲区在当前窗口中可见, 而#符号则代表轮换文件。 按 <C-^>可以在当前文件和轮换文件间快速切换。

使用缓冲区列表 ( :buffer 命令简写形式为 :b )

​ 可以用 4 条命令来遍历缓冲区列表。

  • :bprev ( :bp ):bnext ( :bn ) 在列表中反向或正向移动,每次移动一项;
  • :bfirst ( :bf ):blast ( :bl ) 则分别跳到列表的开头和结尾。

:ls列表的开头有一个数字,它是在缓冲区创建时由 Vim 自动分配的编号。我们可以用 :buffer N 命令直接凭编号跳转到一个缓冲区:bn

删除缓冲区

​ 每次打开一个文件时, Vim 就会创建一个新的缓冲区。如果想删除缓冲区,可以用 :bdelete 命令 :bd ,命令格式如下:

1
2
3
:bdelete N1 N2 N3

:N,M bdelete

如果我们想删除编号 5~ 10(包含 5 和 10)的缓冲区,可以执行 :5,10bd 。然而, 如果想要保留编号为 8 的缓冲区的话, 那么就只能用:bd5 6 7 9 10了。

注意:缓冲区的编号由 Vim 自动分配,没有办法手动改变此编号。因此,如果想删除一个或多个缓冲区,先得进行一番查找以便找出它们的编号。

​ Vim 内置的缓冲区管理功能缺乏灵活性。如果我们想对缓冲区进行组织,使其满足工作过程的需要,使用缓冲区列表并不是最佳选择。建议最好是把工作区划分成多个分割窗口、标签页,或是使用参数列表

Tip 37 Group Buffers into a Collection with the Argument List

用参数列表将缓冲区分组

参数列表易于管理,适用于对一批文件进行分组,使其更容易访问。 首先用 Vim 打开一些文件 ,使用 :args命令后再查看参数列表:

img

输出中的“[]”字符则指明了参数列表中的哪个文件是活动文件。

如果只是想在列表里增加几个文件,用这种方式就行了。它的好处是可以指定文件的次序,但它也有一个缺点,那就是手动增加文件的工作量比较大。如果想往参数列表中加入大量文件,那么使用通配符会快得多。

参数列表比缓冲区列表更容易管理,这使其成为对缓冲区进行分组的理想方式。

当不带参数运行 :args 命令时,它会打印当前参数列表的内容。也可以用下列格式来设置参数列表的内容

1
:args {arglist} 

{arglist} 可以包括文件名、通配符,甚至是一条 shell 命令的输出结果 。

接着就可以用 :next :prev 命令遍历参数列表中的文件,或是用 :argdo 命令在列表中的每个缓冲区上执行同一条命令。

缓冲区列表就像是计算机桌面(desktop),它永远是乱七八糟的;而参数列表则像一个整洁的独立工作区(workspace),只有在需要扩展空间时才会用到它。

Tip 38 Manage Hidden Files

管理隐藏文件,即隐藏的缓冲区

Vim 对被修改过的缓冲区会给予特殊对待,以防未加保存就意外退出。此技巧将介绍如何隐藏一个被修改过的缓冲区,以及如何在退出 Vim 时处理隐藏缓冲区。

img

缓冲区 a.txt 前有一个 + 号,表示这个缓冲区被修改过了。如果现在保存文件的话, 缓冲区的内容就会被写入磁盘里, 而 + 号也会消失了。但如果尝试切换一下缓冲区:bn,Vim 会报错。我们需要命令的结尾加一个叹号!,表该命令强制执行。

在退出时处理隐藏缓冲区

当一个缓冲区被隐藏后, Vim 允许我们像往常一样工作。我们可以打开其他缓冲区,对其进行修改、保存等,没有任何不同。然而,当我们想关闭编辑会话时, Vim 就会提醒我们某个缓冲区中有未保存的修改。

Vim 会把第一个有改动的隐藏缓冲区载入当前窗口,这样我们就可以决定如何处理它。

  • 如果要保留修改,可以执行 :write ( :w ) 命令把缓冲区保存到文件
  • 如果想摒弃此修改,可以执行 :edit!,重新从磁盘读取此文件,这会用文件的内容覆盖缓冲区中的内容
  • 当缓冲区内容与磁盘文件一致后,我们就可以再次尝试执行 :quit 命令了

如果会话里有不止一个被修改过的隐藏缓冲区,那么每次执行:quit命令时,Vim 都会激活下一个未保存的缓冲区。同样的,我们可以用:write:edit! 来保存或摒弃此修改。当没有其他窗口和隐藏缓冲区时,:q 命令就会关闭 Vim。

  • 如果想退出 Vim 而不想对未保存的修改进行检查,可以执行 :qall! 命令

  • 如果想保存所有有改动的缓冲区而无需逐个检查,可以用:wall命令。

在退出时,处理隐藏缓冲区的方式

命令 用途
:w[rite] 把缓冲区内容写入磁盘
:e[dit]! 把磁盘文件内容读入缓冲区(即回滚所做修改)
:qa[ll]! 关闭所有窗口,摒弃修改而无需警告
:wa[ll]! 把所有改变的缓冲区写入磁盘

启用 ‘hidden’ 设置

缺省情况下, Vim 不会让我们从一个改动过的缓冲区切换到其他缓冲区,将设置写入vim配置文件,

1
set hidden  " 允许在有未保存的修改时切换缓冲区,此时的修改由 vim 负责保存

Tip 39 Divide Your Workspace into Split Windows

将工作区切分成窗口

vim对窗口操作的快捷键前缀 :<C-w> ( window )

在Vim的术语中, 窗口window指是 缓冲区 的可视化窗口viewport。一个缓冲区buffer对应一个窗口。

Vim 允许我们切分工作区来展示多个缓冲区。

  • <C-w>s 命令可以水平切分此窗口,使之成为两个高度相同的窗口

  • <C-w>v 命令对窗口进行垂直切分。

窗口切分可任意重复多次,可把工作区一次次 地切分为更小的窗口,就像细胞分裂那样

img

工作区切分窗口方式

命令 用途
< C - w >s 水平切分当前窗口,新窗口仍显示当前缓冲区
< C - w >v 垂直切分当前窗口,新窗口仍显示当前缓冲区
:sp[list] { file } 水平切分当前窗口,并在新窗口中载入{ file }
:vsp[list] { file } 垂直切分当前窗口,并在新窗口中载入{ file }

在窗口间切换

  • < C - w > 配上 h j k l 在窗口间方向移动

  • < C - w >w 在窗口间循环切换。

实际上, <C-w><C-w> 完成的功能和<C-w>w 相同,也就是说可以一直按住<Ctrl> 键,然后再输入 ww (或 wj ,或上表中的其他命令)来切换活动窗口。

关闭窗口

Ex命令 普通模式下命令 用途
:clo[se] c 关闭活动窗口
:on[ly] o 只保留活动窗口,关闭其他窗口

改变窗口大小及重新排列窗口(建议,直接上鼠标)

命令 用途
= 使所有窗口等宽、等高
_ 最大化活动窗口高度
| 最大化活动窗口宽度
[N]_ 把活动窗口的高度设为 N 行
[N]| 把活动窗口的宽度设为 N 行

Tip 40 Organize Your Window Layouts with Tab Pages

用标签页将窗口分组

在 Vim 中,标签页是可以容纳一系列窗口的容器。

Vim中,一个窗口显示一个bufffer,一个标签页有可以有多个窗口,标签页为这些窗口提供排版,而标签栏显示当前标签页的活动窗口。窗口与buffer的关系是一对一,标签页于窗口的关系是一对多

在 Vim 中,当我们用:edit命令打开一个文件时, Vim 却不会自动创建一个新标签页,而是会创建一个新缓冲区,并把该缓冲区显示到当前窗口。

假设我们正在处理某个工程中的文件,并且已经把工作区分成了几个窗口。然后,突然接到一项紧急任务,我们不得不马上切换工作内容。我们不想在当前标签页里打开新文件,因为这会把我们精心布置的工作区弄乱。此时,我们可以新创建一个标签页,并在此标签页中工作。当我们准备继续做原来的工作时,只需切回原来的标签页即可,所有的窗口都保持着我们离开时的模样。

:lcd {path} 命令让我们可以设置当前窗口的本地工作目录。如果我们创建了一个新标签页,并用 :lcd 命令切换到另一个目录,那么就可以把每个标签页限制在不同的工程范围内。

注意: :lcd 只影响当前窗口,而非当前标签页。

如果一个标签页包含了两个或更多的窗口,我们可以用:windo lcd {path}命令为所有这些窗口设置本地工作目录。

打开及关闭标签页

命令 用途
:tabe[dit] { filename } 在新标签页中打开 { filename }
< C - w >T 把当前窗口移到一个新标签页
:tabc[lose] 关闭当前标签页以及其中所有窗口
:tabo[nly] 只保留活动标签页,关闭其他标签页

实际上也可使用:tabnew来创建标签页

在标签页间切换

Ex命令 普通模式命令 用途
:tabn[ext] { N } { N }gt 切换到编号为N的标签页
:tabn[ext] gt 切换到下一标签页
:tabp[revious] gT 切换到上一标签页

重排标签页

:tabmove [N] 命令可以重新排列标签页。

  • [N] 为 0 时,当前标签页会被移到开头;
  • 如果省略了 [N],当前标签页会被移到结尾。
  • 如果终端支持鼠标,或是正在使用 GVim,可通过鼠标拖曳来进行重排操作。

Command-Line Mode

命令行模式

Vim 的先祖是 vi,正是 vi 开创了区分模式编辑的范例。而 vi 则奉一个名为 ex的行编辑器为先祖,这就是为什么称在命令行模式输入为Ex命令。

Tip 27 Meet Command-Line Mode

结识命令行模式

命令行模式会提示我们输入

  1. 一条 Ex 命令
  2. 一个查找模式
  3. 一个表达式。

按下键进入命令行模式,输入一条命令按< CR >执行它。

常用Ex命令: 读写文件 :edit 和 :write,创建新标签页:tabnew及分割窗口 :split, 或是操作参数列表:prev/:next及缓冲区列表 :bprev/:bnext。事实上, Vim 为几乎所有功能都提供了相应的 Ex 命令。

操作缓冲区文本的 Ex 命令

Command Effect
:[range]delete [x] 行区间删除 [内容存入寄存器 x]
:[range]yank [x] 行区间拷贝 [内容存入寄存器 x]
:[line]put [x] 指定行追加寄存器 x 的内容
:[range]copy {address} 行区间拷贝后并张贴到指定的位置
:[range]move {address} 行区间移动到指定的位置
:[range]join 合并行,连接指定范围内的行
:[range]normal {commands} 区间内执行常规模式的命令
:[range]substitute/{pattern}/{string}/[flags] 区间内按匹配的替换
:[range]global/{pattern}/[cmd] 区间内匹配的行里执行 Ex 命令: cmd

在命令行模式中,文本出现在命令行上。命令行模式中也可以用组合键触发命令。

有些命令在插入模式和命令行模式中通用。例如,可以用<C-w><C-u>分别删除至上个单词的开头及行首,也可以用 <C-v><C-k>来插入键盘上找不到的字符,还可以用 <C-r>{register} 命令把任意寄存器的内容插入到命令行。

Tip 28 Execute a Command on One or More Consececutive Lines

在一行或多行上执行Ex命令

很多Ex命令可以用 [range] 指定要操作的范围。我们可以用行号、位置标记或是查找模式来指定范围的开始位置及结束位置。

Ex 命令的优点之一是它们可以在某一范围内的所有行上执行。

通常,一个范围具有如下的形式:

1
:{ start } , { end }

定义范围的语法非常灵活,既可以混合搭配行号、位置标记以及查找模式,也可以对它们加以偏移。

偏移地址的一半形式如下:

1
:{ address } + n

如果n被省略,那么缺省的偏移量为1。例如:

.p p : print ( 打印简写 ) ,打印当前行
.+p 打印当前行的下一行

特殊符号

符号 地址
1 文件第一行
$ 文件最后一行
0 虚拟行,文件第0行,位于第一行上方
. 文件当前行
‘m 包含位置标记m的行
‘< 高亮选区的起始行
‘> 高亮选区的结束行
% 当前文件中的所有行,相当于 : 1 , $

Tip 29 Duplicate or Move Lines Using ‘:t’ and ‘:m’ Commands

使用 :t :m 命令来复制或移动行

:copy 命令(及其简写形式 :co 以及 :t)让我们可以把一行或多行从文档的一部分复制到另一部分。

:move(简写形式 :m)命令则可以让我们把文档移动到其他地方。

为了更好地记忆,可以把:t命令想成“复制到 copy TO

下表展示了:t 命令的一些应用实例:

命令 用途
:6t. 把第6行复制到当前行下方
:t6 把当前行复制到第6行下方
:t. 为当前行创建一个副本,类似于普通模式下 yyp
:t$ 把当前行复制到文件末尾
:’<,’>t0 把高亮选中的行复制到文件开头

:t. yyp 的区别:yyp会使用寄存器,而 :t. 不会

在复制距离较远的行时,:t命令通常更加高效。

:move 命令看上去和:copy 命令很相似,只是他是移动文本。

重复上次的 Ex 命令非常简单,只需按 @: 即可

Tip 30 Run Normal Mode Command Across a Range

在指定范围上执行普通模式命令

如果想在一系列连续行上执行一条普通模式命令,我们可以用 :normal 命令。此命令在与 . 命令或宏结合使用时,我们只需花费很少的努力就能完成大量重复性任务。

语法如下:

1
:[range]normal {commands}

Tip 31 Repeat the Last Ex Command

重复上一次Ex命令

.命令可重复上次的修改。但是,.命令不会重复由 Vim 命令行中做出的修改。

作为替代, 我们可以用 @: 来重复上次的 Ex 命令

Tip 32 Tab-Complete Your Ex Commands

Tab 自动补全Ex命令

如同在 shell 中一样,在命令行上也可以用<Tab>键自动补全命令。

Vim 在选取Tab 补全的补全项时非常智能,它会检查命令行上已经输入的上下文,然后再构建合适的补全列表。例如,可以这样输入:

img

<C-d> 命令会让 Vim 显示可用的补全列表,我们多次按<Tab>键的话,命令行上会依次显示 colder、 colorscheme,然后再回到最初的 col,如此循环往复。要想反向遍历补全列表,可以按 <S-Tab>

假设我们想改配色方案,但是不太记得要用的配色方案的名称,这时可以用<C-d> 命令列出所有的可用选项。

不过在neovim中貌似以及封装好了

Tip 33 Insert the Current Word at the Command Prompt

将当前单词插入命令行

即使是在命令行模式下, Vim 也始终知道光标位于何处以及哪个分割窗口处于活动状态。为节省时间,我们可以把活动窗口中的当前单词(或字串)插入到命令行中。

在 Vim 的命令行下, <C-r><C-w> (word)映射项会复制光标下的单词并把它插入到命令行中。我们可以利用这一功能减少击键的次数。

<C-r><C-a>(WORD)把当前字串插入到命令行

Tip 34 Recall Commands from history

回溯历史命令

我们先按:键切换到命令行模式,在保持提示符为空的情况下按<Up>键,此时最后执行的那条Ex命令就会被填充到命令行上。再接着按 <Up> 键的话,就可以回到更早的 Ex 历史命令;按 <Down> 键的话,则会沿相反方向滚动。上下方向键也是可以。

结识命令行窗口

在命令行模式下按 <Ctrl-f> 从命令行模式切换到命令行窗口。

​ Vim 会打开一个新的窗口,当命令行窗口处于打开状态时,它会始终拥有焦点。这意味着,除非关闭命令行窗口,否则我们无法切换到其他窗口。要想关闭命令行窗口,我们可以执行 :q 命令(就像关闭普通 Vim 窗口那样),或是按 <CR>

下表总结了打开命令行窗口的几种方式

命令 动作
q/ 打开查找命令历史的命令行窗口(注意是查找命令)
q: 打开Ex命令历史的命令行窗口
< C - f > 从命令行模式切换到命令行窗口

q: 命令和 :q 命令很容易被搞混。

Tip 35 Run Command in the shell

运行shell命令

在 Vim 的命令行模式中,给命令加一个叹号! 前缀就可以调用外部程序。

注意区分:!ls:ls的不同之处。前者调用的是 shell 中的 ls 命令,而 :ls调用的是 Vim 的内置命令,用来显示缓冲区列表的内容。

:!{cmd}这种语法适用于执行一次性命令,而:shell命令会启动一个交互的 shell 会话,可在 shell 中执行数条命令,用 exit 命令可以退出此 shell 并返回 Vim界面。

Vim挂起,即Vim 后台执行: 此方式比 :shell 方式要方便一点。<C-z> 会把 vim 挂起, 然后切换到终端。

在 Vim 中操作时,我们能很方便地调用 shell 命令 。

  • :shell 启动一个 shell (输入 exit 返回 Vim)
  • :!{cmd} 在 shell 中执行 {cmd}

使用缓冲区的内容进行标准输入或输出:

  • :read !{cmd} - 把 cmd 执行的结果(标准输出)写入当前文件(缓冲区) 如: :read !ls

  • :write !{cmd} - 和上面相反, 把当前文件(缓冲区)内容当做标准输入传给了 cmd 命令

! 符号的位置不同有不同的含义:

  • :[range]write ! sh - 把缓冲区当做标准输入传给了 sh 命令

  • :[range]write! filename - 表示把 filename 内容强制覆盖掉; 相当于内容另存为一个文件

Visual Mode

可视化模式

Vim 的可视模式允许我们选中一块文本区域并在其上进行操作,并具有 3 种不同的可视模式,分别用于操作字符文本、行文本或块文本。

可视化模式批量编辑或者纵向编辑模式时,可以极大的提高工作效率

Tip 20 Grok Visual Mode

深入了解可视化模式

Select Mode 选择模式

在一个典型的文本编辑器环境中,当选中一段文本后,再输入任意可见字符时,这些选中的文本将会被删除。Vim中的Select Mode类似于这样的模式。

使用 < C - g >,可以在可视化模式与选择模式中进行切换。不同点在于最后一行显示的是 Visual 以及 Select

Tip 21 Define a Visual Selection

定义高亮选区

Command Effect
v 激活面向字符的可视模式
V 激活面向行的可视模式
< C - v > 激活面向块的可视模式
gv 重选上次的高亮选区
o 切换高亮选区的活动端

Tip 22 Repeat Line-wise Visual Command

重复执行面向行的可视化命令

还是 .命令,甚至不需要进行gv命令重选上次的高亮选区

Tip 23 Prefer Operation to Visual Command Where Possible

只要可能,最好用操作符命令,而不是可视命令

可视模式可能比 Vim 的普通模式操作起来更自然一些,但是它有一个缺点:

  • 在这个模式下 . 命令有时会有一些异常的表现。

我们可以用普通模式下的操作符命令来规避此缺点。

Tip 24 Edit Tabular Data with Visual-Block Mode

用面向列块的可视化模式编辑表格数据

以在列间增加分隔竖线 为例:

img

Tip 25 Change Columns of Text

修改列文本

用列块可视模式可以同时往若干行中插入文本。列块可视模式不仅仅对表格数据有用,在编程时我们也时常受惠于此功能。

使用 < C – v > 模式选中块,可同时修改多行中同一列的数据。

Tip 26 Append After a Ragged Visual Block

长短不一的高亮块后添加文本。

以在块可视化模式中为多行添加分号为例:

img

处于插入模式期间,任何输入的内容只出现在顶行,然而一旦返回到普通模式,这些修改就会被扩散到其余选中的行上。

Tip13 Make Corrections Instantly from Insert Mode

插入模式下进行更正

在插入模式下更正错误首先想到退格键,它删除光标前的字符。另外还有使用以下组合键:

按键操作 用途
< C – h > 删除前一个字符(同退格键)
< C - w > 删除前一个单词
< C - u > 删至行首

​ 注:这些快捷键不是插入模式独有的,甚至不是vim独有的,在vim命令行模式,以及bash shell , cmd, powershell 中也可以使用他们。

Tip14 Get Back to Normal Mode

返回普通模式

插入模式只专注于一件事,就是输入文字普通模式才是我们大部分时间所用的模式

切换会普通模式的经典方式是 <Esc> 键,我们也可以用< C – [ >替代,效果完全一样。

按键操作 用途
< Esc > 切换回普通模式
< C – [ > 切换回普通模式
< C - o > 切换至插入 - 普通模式

插入 - 普通模式:普通模式的一个特例,它能让我们执行一次普通模式命令,执行完毕之后,马上有回到插入模式。

例:使用zz命令使光标重新位于屏幕中间。键入< C - o > zz ,在普通模式下触发命令,重绘屏幕,此操作完成后会直接回到插入模式,因此可以不中断打字。

Tip15 Paste from a Register Without Leaving Insert Mode

不离开插入模式,粘贴寄存器中的文本

Keystrokes Buffer Contents
yt, Practical Vim, by Drew Neil Read Drew Neil’s
jA␣ Practical Vim, by Drew Neil Read Drew Neil’s
< C – r >0 Practical Vim, by Drew Neil Read Drew Neil’s Practical Vim
. Practical Vim, by Drew Neil Read Drew Neil’s Practical Vim.

yt, - 光标到第一个 “,” 之间的文本放入寄存器

jA␣ - 光标移动到下一行, 然后定位到行末并切换为插入模式, 再输入一个空格

0 - 插入寄存器 0 里的内容, 即刚刚放到寄存器的内容 (:h i_CTRL-R)

. - 句号结尾后退出插入模式

Tip 16 Do Back-of-the-Envelope Calculations in Place

数学计算

Keystrokes Buffer Contents
A 6 chairs, each costing $35, totals $
=6*35 6 chairs, each costing $35, totals $210.

Tip 17 Insert Unusual Characters by Character Code

用字符编码插入非常用字符。插入一些无法通过键盘输入的字符(目前需求不大)

Tip 18 Insert Unusual Characters by Digraph

用二合字母插入非常用字符。插入一些无法通过键盘输入的字符(目前需求不大)

Tip 19 Overwrite Existing Text with Replace Mode

覆盖模式

普通模式下按 R 即可开启覆盖模式; r / gr 仅覆盖一个字符

用虚拟替换模式替换制表符:

一些字符使替换模式变得复杂化。以制表符为例,在文件中它以单个字符表示,但在屏幕上它却会占据若干列的宽度,此宽度由 ‘tabstop’ 设置决定。如果把光标移到制表符上,然后进入替换模式,那么我们所输入的下一个字符将会替换制表符。假设 ‘tabstop’ 选项设置为 8(这是缺省值),那么该操作的结果就是把 8 个字符替换成了一个字符,这将大幅缩短当前行的长度。

Vim 还有另外一种替换模式,称为虚拟替换模式(Virtual Replace mode)。该模式可由 gR 命令触发,它会把制表符当成一组空格进行处理。假设我们把光标移到一个占屏幕 8 列宽的制表符上,然后切换到虚拟替换模式,在输入前 7 个字符时,每个字符都会被插入到制表符之前;最后,当输入了第 8 个字符时,该字符将会替换制表符。

在虚拟替换模式中,我们是按屏幕上实际显示的宽度来替换字符的,而不是按文件中所保存的字符进行替换。这会减少意外情况的发生,因此建议在可能的情况下尽量使用虚拟替换模式。

Tip1:Meet the Dot Command

结识 . 命令

. 命令可以重复上次的修改, Vim 中最为强大的多面手。

每次我们进入插入模式时,就会形成一次修改。从进入插入模式的那一刻起,直到返回普通模式, Vim 会记录每一个按键操作。做出这样一个修改后再用 . 命令的话,它将会重新执行所有这些按键操作 。

Tip2: Don’t Repeat Yourself

不要自我重复,不少vim命令是两个甚至多个命令的组合

例如:

行移动:

  • $: 将光标移动到当前行的行尾

  • 0: 将光标移动到当前行的行首

  • ^: 将光标移动到当前行的第一个非空字符(行首和当前行非空字符不是一个位置)

文本操作:

  • i: 在当前光标的前面插入字符

  • a: 在当前光标的后面追加字符

  • o: 在当前光标的下一行行首插入字符

  • I: 在一行的开头添加文本

  • A: 在一行的结尾处添加文本

  • O: 在光标当前行的上一行插入文本

  • s: 删除当前光标处的字符并进入到插入模式

  • S: 删除光标所在处的行,并进入到插入模式

  • u: 撤销修改

  • c or C : 表示修改当前行上光标后面的部分. 进入编辑状态.

Tip4 Act, Repeat, Reverse

执行、重复、回退

在面对重复性工作时,我们需要让移动动作和修改都能够重复,这样就可以达到 一个最佳编辑模式。 Vim会记住我们的操作,使最常见的操作触手可及。

​ . 命令会重复上次修改。@: 可以用来重复任意 Ex 命令,或者我们也可以输入 &来重复上次的:substitute命令(它本身也是一条 Ex 命令)。

​ 当 Vim 让一个操作或移动可以很方便地重复时,它总是会提供某种方式,让我们在不小心做过头时能回退回来。

对 . 命令而言,我们永远可以按 u 键撤销上次的修改。如果在使用 f{char} 命令后,不小心按了太多次 ; 键,就会偏离我们的目标。不过我们可以再按 , 键跳回去,这个命令会反方向查找上次 f{char}所查找的字符。

目的 操作 重复 回退
做出一个修改 {edit} . u
在行内查找下一个指定字符 f{char}/t{char} ; ,
在行内查找上一个指定字符 F{char}/T{char} ; ,
在文档中查找下一个匹配项 /pattern n N
在文档中查找上一个匹配项 ?pattern n N
执行替换 :/s/target/replacement & u
执行一系列修改 qx{changes}q @x u

Tip5 Find and Replace by Hand

查找并手动替换

一般的查找替换命令:%s/content/copy/g(以copy替换所有行中的content)。

偷懒方法:无需输入就可进行查找。* 命令。

把光标移动到content单词上,然后用 * 命令对他进行查找。

这会产生两个结果:

  • 一是光标会跳到下一个匹配项
  • 二是所有出现这个词的地方都会被高亮显示。

执行一次查找后,只需按 n 键就可以跳转到下一个匹配项。使修改可重复

Tip7 Pause with Your Brush Off the Page

停顿时请移开画笔

​ 插入模式专注于文本修改,停顿时进入普通模式。

Tip8 Chunk Your Undos

大步撤销,把撤销单元切成块

u键会撤销最新的修改。一次修改可以是改变文档内文本的任意操作,其中包括在普通模式、可视模式以及命令行模式中触发的命令。

在vim中,可以控制撤销的力度。从进入插入模式开始到返回普通模式,在期间插入或删除任何内容都会被当成一次修改。因此,只要控制对<Esc>键的使用就可以使撤销作用于句子、段落或单词。

注:在插入模式中,使用<up> <Down> <Left> <Right>移动光标会重置修改状态,将会产生一个新的撤销块。

Tip9 Compose Repeatable Changes

构造可重复的修改

配合 . 命令选择最优的方案

以删除一个单词为例:

  • 反向删除 dbx

  • 正向删除 bdw

  • 删除整个单词 daw

命令有助于 . 命令发挥最大威力。反向删除 . == x ; 正向删除 . == dx; 删除整个单词 . == daw

Tip11 Don’t Count If You Can Repeat

能重复,就不要用数数

以删除5个单词为例,有两种风格:

  • 次数风格(d5w)
  • 重复风格(dw….)

对于两种风格的使用存在争议,各有优缺,作者鼓励重复风格,数完估计都操作完了。应用过程中由程序员自由选。

Tip12 Combine and Conquer

动作组合

在Vim 中,操作符 + 动作命令 = 操作

d{motion} 命令可以对一个字符 dl、一个完整单词 daw或一整个段落 dap 进行删除操作,它作用的范围由动作命令决定。 c{motion}y{motion}以及其他一些命令 也类似,它们被统称为操作符operator

g~、 gu 和 gU 命令要用两次按键来调用,我们可以把上述命令中的 g 当做一个 前缀字符,用以改变其后面的按键行为。

学习新的动作命令及操作符,就像是在学习 Vim 的词汇一样。如果掌握了这一简单的语法规则,在词汇量增长时,就能表达更多的想法。用 daw 删除一个单词,然后又学到 gU 命令。它也是个操作符,所以我们可以用 gUaw 把当前单词转换成大写形式。进一步扩充,学会了作用于段落的 ap 动作命令,就会发现我们可以进行两个新的操作:用 dap 删除整个段落,或者用 gUap 把整段文字转换为大写。

常见VIM操作符命令

命令 用途
c 修改
d 删除
y 复制到寄存器
g~ 反转大小写
gu 转换为小写
gU 转换为大写
> 增加缩进
< 减小缩进
= 自动缩进
! 使用外部程序过滤{motion}所跨越的行