Vim 入门-终端记事本

了解 Vim 的基本操作, 能进行 NotePad.exe 所能进行的操作.

概览

本文记录以下功能的实现方法:

  • 打开 保存 另存为
  • 移动光标
  • 输入文本
  • 删除文本
  • 选择文本
  • 复制
  • 剪切
  • 粘贴
  • 搜索
  • 替换
  • 撤销, 重做动作

我刚开始用 Vim 的时候有一个误区, 认为 Vim 在普通模式下的按下的键就是按键. 但实际上是向 Vim 输入了对应字符, 只是这输入被解释为指令罢了. 所以, 不要纳闷一些 “特殊符号” 的键怎么按, 两个符号明明在同一个键位上怎么区分等问题了…

先说说 Vim 的四种模式

Vim 有四种模式:

  1. 普通模式
  2. 输入模式
  3. 命令模式
  4. 可视模式(翻译为选择模式更贴切)

普通模式

普通模式下的 Vim 的光标呈现一个方块的形状, 盖在当前字符上, 进入其他模式后会发生变化, 这是区分当前模式的方法之一.

进入 Vim 时, 默认处于普通模式. 这个时候, 用户可以移动光标, 或进入其他模式. 这个模式下的 Vim 可以当作一个文本阅读器.

从任何模式, 都可以按 Esc 键退回该模式. 命令模式除外, 只需要将最开始的冒号 : 删掉即可.

Vim 会将在普通模式下输入的字符记录并在右下角显示, 当输入的字符满足触发指令的时候, 就会执行相关指令. 例如切换模式等.

输入模式

输入模式, 包括 插入, 替换 两种输入方式.

要进入输入模式, 可以通过 i 等按键从普通模式进入. 当前先掌握下表按键:

按键 作用
i 在当前光标前插入
a 在当前光标后插入
o 在下方另起一行插入
O 在上方另起一行插入
r 替换当前字符
R 进入替换模式

进入插入模式后, 左下角会显示提示符 --INSERT-- , 再按下按键就将在光标位置处插入对应文本.

具体说一下 r R 两个键的作用:

输入 r 后, 在右下角会显示一个提示符 r(在普通模式下输入的字符都会被记录在右下角, 试图解释为指令), 这时候输入任意一个字符, 就会将光标下的字符替换, 然后退出.

而输入 R 则会进入替换模式, 在左下角有提示符 --REPLACE--, 此时输入的字符会将光标下的字符覆盖, 直到按下 Ecs 退出.

简单来说, 就是 r 只替换一个字符, R 则进入替换模式.

选择模式

普通模式下输入 v 进入选择模式, 此种选择模式是 流选择, 效果就和在其他文本编辑器中按下 Shift 并移动光标一样.

普通模式下输入 V 进入行选择模式, 会按行选择.

对于两种选择方式, 有 --VISUAL----VISUAL LINE-- 两种提示符.

TODO: 怎么 块选择?

命令模式

在普通模式下输入冒号 : 进入冒号模式, 会在最下方显示一个输入框, 开头就是输入的冒号. 在冒号后面输入要运行的命令并回车, 就会执行.

最常用的命令, 比如 :w :wq :q! 等等. 则会 保存文件 , 保存文件并退出 , 退出, 不保存更改 .

打开 保存 另存为

在终端中输入

1
vim filename

则会以文本模式打开一个文件. 而加上 -b 参数, 则会以二进制模式打开. 因为二进制没怎么用过, 暂且不表.

编辑完文件后, 在 Vim 的普通模式下输入 : 进入命令模式.

  • :wq, 保存并退出.
  • :q!, 退出且不保存.
  • :w, 保存, 不退出
  • :w new_file_path, 将文件另存为到指定文件中. (可使用相对路径或绝对路径).

移动光标

在任何模式下, 都可以通过键盘方向键移动光标, 而在普通模式和选择模式下, 可以用kjhl 移动光标, 效果和方向键相同.

1
2
  上             k
左下右 h j l

还有另一些功能特殊的键:

输入 作用
w 移动到下一个单词头部
e 移动到下一个单词尾部
b 移动到上一个单词头部
ge 移动到上一个单词尾部
^ 移动到行首
$ 移动到行尾
gg 移动到文件头部
G 移动到文件尾部

输入文本

参阅 插入与替换.

删除文本

  • 在普通模式下, 输入 x 删除光标所在字符.
  • 在普通模式下, 输入 X 删除光标前一个字符.
  • 在选择模式下, 输入 x 或 输入 X 都会删除选中部分, 如果输入 X, 会删除选中部分所在行(如果选择部分只是某行的一部分, 也会删除整行).
  • 在普通模式下, 输入 dd 删除光标所在行.
  • 在选择模式下, 输入 d 删除选中部分.

被删除的文本都会被存储在寄存器中.

选择文本

选择模式 下移动光标即可选择文本.

复制与粘贴

复制:

  • 在普通模式下, 输入 yy 复制光标所在行.
  • 在选择模式下, 输入 y 复制选中部分.

粘贴:

普通模式下:

  • p (小写), 粘贴到下一行.
  • P (大写), 粘贴到上一行.
  • gp 粘贴到光标之后.
  • gP 粘贴到光标之前.

更多关于复制与粘贴的内容,参见 寄存器

剪切

被删除的文本会被保存到默认寄存器中, 如果再粘贴出来, 就是 “剪切+粘贴” 的效果.

搜索

Vim 的搜索功能通过命令来实现.

要使用搜索命令, 在命令模式下输入 / 接着输入需要搜索的字符串, 就能跳转到指针后的第 1 个匹配的字符串. 可以通过 n 跳转到下一个, 输入 N 跳转到上一个.

例如 :/search.

如果要向上搜索的话, 使用 ?. 例如 :?search

如果输入 // 则意味着重复上一次搜索.

如果要搜索某个单独的单词, 而非单词之中的某一段字符串, 可以使用 \<\> 标记单词头尾.

例如 :/\<look\> 就只会搜索到单独的 look, 而不会搜索到 somebody@outlook 中的 look.

也可以直接按下 /,进入搜索模式。

用正则表达式搜索

实际上, Vim 的搜索功能一直使用的是正则表达式, 只需要在 :/ 后输入合法的表达式即可.

需要注意的是, 正则表达式中的元字符有一部分需要使用 \ 转义, 否则 Vim 会将其当作普通字符处理, 这与其他使用正则的情况不同.

目前已知的需要转义的字符:

  • + , 限定符, 不转义会作为普通字符.
  • * , 限定符, 不转义会作为通配符.
  • ? , 限定符, 不转义会作为普通字符.
  • 各种括号, 限定符, 子表达式等; 不转义会作为普通字符.
  • | , 或逻辑, 不转义会作为普通字符.

TODO: 随时补充新的发现.

替换

除了输入模式里介绍过的 rR 之外, Vim 还可以用命令替换指定字符串.

:s/<from>/<to> 即是最简单的替换命令. 它将搜索到的 <from> 字符串或正则表达式替换为 <to> 字符串. 和用 :/<from> 搜索到的位置一致.

这个命令只生效一次, 如果要重复替换行为, 可以使用 ., 此符号意味着 “重复上一次操作”.

使用替换操作时需要指定操作范围:

1
:[range]s/<form>/<to>/[flags]

range 参数表示操作范围, 常用的有

  • % 表示整个文档
  • 2, 15 表示第 2 行到第 15 行
  • ., +15 表示从当前行到 15 行后

flags 参数设置替换策略. 常用的有

  • g 全局替换, 将会一次性替换操作范围内所有目标.
  • c 表示确认选项, 每次替换前会确认一次.
  • I, i, 搜索时是否大小写敏感, i 为不敏感, I 为敏感.

撤销动作

在普通模式下输入 u 撤销一次修改. 可以一直回退, 虽然修改记录的数量应该会有一个极限, 但大多数时候我都能回退到打开文件最开始时的状态.

如果回退过度, 可以通过 control+r 重做. 按下 Ctrl + r 键, 此键实际上向 Vim 输入了控制字符.

参考资料

参考资料来源未整理, 无法提供.

推荐:

  • Vim 中文社区

Vim 其他用法

Vim 打开模式

  • 打开模式
    • -b 二进制模式
    • -o 多文件模式

Vim 多窗口编辑

Vim 在打开一组文件的使用可以使用 -o-O 参数来进行多窗口的打开:

1
2
3
# 垂直划分
vim -o file1 file2
# 水平划分

所谓的垂直与水平, 是指窗口见分界线的分布, 例如:

1
2
3
4
5
6
7
8
9
10
11
12
# 垂直
+-----+-----+
| | |
| | |
+-----+-----+

# 水平
+-----------+
| |
+-----------+
| |
+-----------+

也可以在进入 Vim 编辑器中后进行窗口的打开操作:

  • :split <filename> 打开新文件并水平划分窗口
  • :vsplit <filename> 打开新文件并竖直划分窗口

在有多个窗口后, 可以通过这些操作来进行调整

目标 操作 备注
移动窗口焦点 `C-w h j k l` 先按下 Ctrl+W 组合键, 然后通过 hjkl 移动窗口焦点
改变窗口布局 `C-w = - + < > \ ` 调整当前窗口的大小: = 均分所有窗口, -+ 调整高度, <> 调整宽度, ` ` 则将当前窗口调到最大

Vim 调用外部命令

  • :!cmd 执行 Shell 命令 cmd, 例如 :!echo Hello 将会 跳出 编辑器通过系统 Shell 而显示 Hello. Windows 系统下 Shell 环境为 Cmd. 要使用 PowerShell, 需要 :!powershell echo Hello.
    • % 表示此文件.
    • xxd.exe 用于将文件在文本模式与十六进制模式之间转换. :%!xxd 转化为十六进制, :%!xxd -r 由十六进制转化为文本.

当使用 :%! cmd 时,Vim 会将全文内容发送给调用命令的 stdin,然后将 stdout 内容替换当前文件。 最前方的 % 其实是一个 Range 参数,表示全文,它还可以为以下值:

  • '<, '> 表示可视模式下选中的内容
  • 1,30 表示从第一行到第三十行

等等。

折叠相关

添加折叠 za 打开折叠 zo 关闭折叠 zc

date:2018-08-27 00:22:28

寄存器

在 Vim 中,你可以访问系统剪贴板:

剪切: "+y 粘贴: "+p

这其实就是使用了 Vim 的寄存器功能。 Vim 有多个寄存器:" 是默认寄存器;0 ~ 9 作为多级缓存;a ~ z 作为命名寄存器;_ 是黑洞寄存器,功能类似于 Linux 中的特殊文件 /dev/null+* 访问系统剪贴板。还有三个特殊的寄存器 :, /, %,用来存储上次执行的命令和搜索关键词以及所编辑的文件路径(相对路径)。" 同时也是操作寄存器的前缀指令。

当在 Vim 中不带前缀地剪切(剪切和删除是一个概念)和粘贴时,内容将被存储到 " 寄存器以及 0 寄存器。 而在多次进行编辑时,缓存寄存器中的内容将会逐级移动, 0 中的内容将会移动到 11223 … 直到 9 被删除。

当要永久保存某些内容时,可以使用 a~z 之间的字母寄存器,它们是明明寄存器,除非主动覆盖,内部内容不会变化。

+* 与系统剪贴板相联通,对于 Windows 系统,这两者是一样的,而对于 Unix 系统,这两者存在不同。 + 访问的是 X11 系统的 cut buffer, 而 * 访问 selection。要使用此功能需要确保 Vim 特性列表中包含 +clipboard

要操作某个寄存器,使用指令 "<寄存器名>y 复制,"<寄存器名>p 粘贴。(注意 " 前缀!) 也可以通过命令 :reg 来查看寄存器的状态。

关于自动缩进

在复制粘贴具有缩进的代码,例如 Python 时,Vim 的自动缩进功能可能会导致内容变得更混乱,有两个方法来规避:

  1. 总是新起一行粘贴内容,之后再通过 S-> 来调整缩进。
  2. 设置 :set pastetoggle 来切换为粘贴模式,将会禁用 autoindent 等干扰内容的功能,之后用同样的命令切换回来。

我的 Vim 配置文件