光标移动
在出现软换行时,一个实际行可以被换行成了多个屏幕行。
基础命令
1 | k <上> |
| 按键 | 动作 |
|---|---|
| gj | 下移一个屏幕行 |
| gk | 上移一个屏幕行 |
| 0 | 移动到实际行的行首 |
| g0 | 移动到屏幕行的行首 |
| ^ | 移动到实际行的第一个非空白字符 |
| g^ | 移动到屏幕行的第一个非空白字符 |
| $ | 移动到实际行的行尾 |
| g$ | 移动到屏幕行的行尾 |
基于单词移动
w和b最常用,要记住

| 按键 | 动作 |
|---|---|
| w | 移动到下一单词的开头 |
| b | 移动到当前/上一单词的开头 |
| e | 移动到当前/下一单词的结尾 |
| ge | 移动到上一单词的结尾 |
| W | 移动到下一字符串的开头 |
| B | 移动到当前/上一字符串的开头 |
| E | 移动到当前/下一字符串的结尾 |
| gE | 移动到上一字符串的结尾 |
| H | 移动光标到屏幕上方 |
| M | 移动光标到屏幕中间 |
| L | 移动光标到屏幕底部 |
| zt | 当前行滚动到屏幕顶部 |
| zz | 当前行滚动到屏幕中间 |
| zb | 当前行滚动到屏幕底部 |
单词和字符串区别就记住:字符串比单词长
ea命令连在一起可以被用作在当前单词结尾添加, 输入ea后接着输入要追加的字符
插入
插入文本
| 命令 | 动作 |
|---|---|
| a | 在光标后插入 |
| A | 在光标所在行尾插入 |
| i | 在光标前插入 |
| I | 在光标所在行头插入 |
| o | 在光标下新起一行开始编辑 |
| O | 在光标上新起一行开始编辑 |
插入文件
| 命令 | 动作 |
|---|---|
| :r[ead] filename | 读取并插入文件内容到当前光标下, 如: :r sys.log |
| :r[ead] !{cmd} | 执行命令并将命令输出插入到当前光标下, 如: :r !date |
查找与替换
| 命令 | 动作 |
|---|---|
| r{char} | 用{char}替换光标下的字符 |
| R | 进入插入模式, 如: 按R后输入1234, 则原来的位置的4个字符都被替换, 按esc退出 |
| ~ | 切换光标所在字符的大小写, 并且光标向右移动 |
| g~{范围文本对象} | 替换范围内的文本大小写 如: g~aw替换光标所在单词大小写 |
| 可视 ~ | 先按v进入可视模式, 选中文件后按~切换大小写 |
| 可视 U | 先按v进入可视模式, 选中文件后按U切换到大写 |
| % | 跳转到光标所在字符的匹配字符, 如: 光标在{上, 按%则跳转到} |
| * | 搜索光标所在单词并高亮 |
替换范围
语法: :[range]s/{pattern}/{string}/[c][e][g][p][r][i][I] [count]
c替换前确认, 可以输入如下命令y替换n跳过a替换剩余所有CRTL E向上滚动屏幕CRTL Y向下滚动屏幕
g替换行中出现的所有项i忽略匹配时的大小写
示例:
:s/old/new/g替换当前行old为new:7s/old/new/g替换第7行old为new:$/old/new/g替换最后一行:%s/old/new/g替换所有行:.,$s/old/new/g替换当前行到最后一行:.,+7s/old/new/g替换当前行以及后面7行
f命令
| 命令 | 动作 |
|---|---|
| f* | 光标移动到下一个字符*,如:fa |
| F* | 光标移动到上一个字符* |
| t* | 光标移动到下一个字符*的前一个字符,如:fa |
| T* | 光标移动到上一个字符*的前一个字符 |
| ; | 重复上一次字符查找命令 |
| , | 反向查找上一次的字符查找命令 |
f*会在光标与当前行行尾之间查找指定的字符*,比如:输入fa会在当前行查找光标后第一个字符a。结合;命令,就可以一直往后查找字符a,而不用一遍遍的输入fa。如果;命令按多了,可以输入,命令往回跳。
假如有这么一段字符串:I’m Tom, welcome. 输入f,,定位到逗号,输入dt.就会删除到末尾,但保留句号。结果就是:I’m Tom.
/查找
f命令一次只能查找一个字符,并且只能在本行内查找,为了提高效率,因此我们还需要查找命令。/foo查找字符串foo,使用n命令可以查找下一个foo字符串了,N可以向上查找。
自动位置标记
| 位置标记 | 跳转到 |
|---|---|
|
当前文件中上次跳转动作之前的位置 |
| `. | 上次修改的位置 |
| `^ | 上次插入的位置 |
| `[ | 上次修改或复制的起始位置 |
| `] | 上次修改或复制的结束位置 |
| `< | 上次高亮选区的起始位置 |
| `> | 上次高亮选区的结束位置 |
删除与复制
| 命令 | 动作 |
|---|---|
| x | 删除光标之后的字符 |
| X | 删除光标之前的字符 |
| d{范围文本对象} | 删除范围内的文本 dw daw d$ d0 |
| [count]dd | 删除从光标开始往下count行, dd 3dd |
| D | 从光标删除到行尾 相当于 d$ |
| :[range]d | :2d 删除第2行 :2,3d 删除第2到第3行 |
| :[range]d {count} | :2d 10 从第二行开始删除10行 |
bdw 删除当前单词
cw 删除从光标到单词结尾并进入插入模式
ciw 删除从光标所在单词并进入插入模式
daw 删除光标所在单词及空格 优先使用 配合.可以一直往下删除单个词
d2w 删除2个单词 2dw也可以
d0 或 d^ 从光标删除到行首
d$ 从光标删除到行尾
范围文本对象
| 文本对象 | 选择范围 |
|---|---|
| iw | 当前单词 |
| aw | 当前单词及一个空格 |
| iW | 当前字符串 |
| aW | 当前字符串及一个空格 |
| is | 当前句子 |
| as | 当前句子及一个空格 |
| ip | 当前段落 |
| ap | 当前段落及一个空格 |
删除长字符串
字符串:I’m Tom, nice to meet you. 假设光标定位在Tom上,输入v进入可视模式,输入/yo定位到字符串you,输入h先取消选中y,输入d,删除从Tom到meet,结果就是:I’m you. 更高效的做法是输入d/you。
插入模式下删除
| 命令 | 动作 |
|---|---|
| CTRL h | 删除前一个字符, 等同于退格键 |
| CTRL w | 删除前一个单词 |
| CTRL u | 删除至行首 |
撤销 重做 重复
| 命令 | 动作 |
|---|---|
| [count]u | 撤销前count个修改 |
| :u | 撤销上一次操作 |
| [count]CRTL R | 重做count个撤销操作, 即恢复 |
| :red[o] | 重做上个撤销操作 |
| U | 恢复当前行 |
| . | 重复上一个命令 |
可视模式
| 命令 | 动作 |
|---|---|
| v | 进入面向字符的可视模式, 上下左右类似鼠标拖选 |
| V | 进入面向行的可视模式, 上下选中整行 |
| CTRL v | 进入面向块的可视模式 |
| gv | 重选上次的高亮选区 |
切换选取的起始位置
当定义选区时, 如果发现开始位置选的不对, 可以按下o更改选区编辑, 更改好了再按下o
vww 选择2个单词 -> o调整起始位置 -> b向前选中 -> o确定起始位置, 切换到结尾位置
在长短不一的高亮块后添加文本
为长短不一的代码行尾添加分号: CTRL v 进入块模式 -> jj$ 向下选择2行并选择到行尾 -> A; 追加分号 -> esc
多窗口
| 命令 | 动作 |
|---|---|
| :e filename | 编辑另一个文件 |
| :split filename | 水平拆分窗口并打开另一个文件 |
| :vsplit filename | 垂直拆分并打开另一个文件 |
| :sview file | split的readonly模式 |
| CTRL W v | 垂直拆分窗口 |
| CTRL W s | 水平拆分窗口 |
| CTRL W 上箭头 | 移动光标到上一个窗口 |
| CTRL W CTRL W | 循环切换窗口 |
| CTRL W _ | 最大化当前窗口 |
| CTRL W = | 所有窗口一样大 |
| 10 CTRL W+ | 将当前窗口增加10行高度 |
| :hide | 关闭当前窗口 |
| :only | 仅保持当前窗口打开 |
| :ls | 展示当前缓冲区列表(文件列表) |
| :b 2 | 打开缓冲区中编号2的文件 |
插入-普通模式 CTRL o
当前在插入模式, 但是想向下滚动一屏幕看到更多内容, 然后离开返回插入模式, 可以执行CTRL o tt
命令行模式
输入: 进入命令行模式, 由于历史原因, 在命令行中执行的命令又被称为Ex命令. 可以使用Ex命令读写文件(:edit), 创建标签页(:tabnew), 分隔窗口(:split), 完整命令见: :h ex-cmd-index
| 命令 | 动作 |
|---|---|
| :[range]delete [x] | 删除指定范围内的行[到寄存器x], :10,15delete 删除10到15行 |
| :[range]yank [x] | 复制指定范围的行[到寄存器x] |
| :[line]put [x] | 在指定行后粘贴寄存器x中的内容, :10put a 在第10行粘贴寄存器a中的内容 |
| :[range]copy {address} | 把指定范围内的行拷贝到{address}所指定的行之下, :3,5t. 把第3行到第5行复制到当前行下方, :t5复制当前行到第5行下 copy命令的简写形式为t |
| :[range]move {address} | 把指定范围的行移动到{address}所指定的行下, :3,5m.把第3行到第5行复制到当前行下方, move命令的简写形式为m |
| :[range]join | 连接指定范围内的行 :3,+2join 第3行以及后面2行连接 |
| :[range]normal {commands} | 对指定范围内的每一行执行普通模式命令{commands} |
| :[range]substitute/{pattern}/ {string}/[flags] | 指定范围内的文本进行替换 |
调用外部程序
:!{command} 执行外部查询, 如: :!ls 查看当前目录内容, 这种方式适合执行一次性命令
:shell 启动一个交互的shell会话, 可以执行多条命令了