# Vim 参考手册

2024年8月08日16分钟阅读

- FormalSciences/ComputerScience
- GettingStarted/CommandLineTools
- Vim

## Vim Cheat Sheet

## 全局

    :h[elp] 关键字      - 打开关键字帮助
    :sav[eas] 文件名    - 另存为
    :clo[se]           - 关闭当前窗口
    :ter[minal]        - 打开一个shell窗口
    K                  - 打开光标所在单词的man页面

Tip 在终端中运行 vimtutor 以学习最基础的 Vim 命令。

## 移动光标

    h     - 左移光标
    j     - 下移光标
    k     - 上移光标
    l     - 右移光标
    gj    - 下移光标(折行文本)
    gk    - 下移光标(折行文本)
    H     - 移动到当前页面顶部
    M     - 移动到当前页面中间
    L     - 移动到当前页面底部
    w     - 移动到下个单词开头
    W     - 移动到下个单词开头(单词含标点)
    e     - 移动到下个单词结尾
    E     - 移动到下个单词结尾(单词含标点)
    b     - 移动到上个单词开头
    B     - 移动到上个单词开头(单词含标点)
    ge    - 移动到上个单词结尾
    gE    - 移动到上个单词结尾(单词含标点)
    %     - 跳转到配对的符号(默认支持的配对符号组:: '()', '{}', '[]' -
            在vim中使用 :h matchpairs 获得更多信息)
    0     - 移动到行首
    ^     - 移动到行首的非空白符
    $     - 移动到行尾
    g_    - 移动到行内最后一个非空白符
    gg    - 移动到文件第一行
    G     - 移动到文件最后一行
    5gg or 5G  - 移动到第五行
    gd         - 跳转到局部定义
    gD         - 跳转到全局定义
    fx         - 移动到字符 x 下次出现的位置
    tx         - 移动到字符 x 下次出现的位置的前一个字符
    Fx         - 移动到字符 x 上次出现的位置
    Tx         - 移动到字符 x 上次出现的位置的后一个字符
    ;          - 重复之前的f、t、F、T操作
    ,          - 反向重复之前的f、t、F、T操作
    }          - 移动到下一个段落 (当编辑代码时则为函数／代码块)
    {          - 移动到上一个段落 (当编辑代码时则为函数／代码块)
    zz         - 移动屏幕使光标居中
    Ctrl + e   - 向下移动屏幕一行(保持光标不动)
    Ctrl + y   - 向上移动屏幕一行(保持光标不动)
    Ctrl + b   - 向上滚动一屏
    Ctrl + f   - 向下滚动一屏
    Ctrl + d   - 向下滚动半屏
    Ctrl + u   - 向上滚动半屏

## 插入模式 - 插入/追加文本

    i          - 从光标前开始插入字符
    I          - 从行首开始插入字符
    a          - 从光标后开始插入字符
    A          - 从行尾开始插入字符
    o          - 在当前行之下另起一行, 开始插入字符
    O          - 在当前行之上另起一行, 开始插入字符
    ea         - 从当前单词末尾开始插入
    Ctrl + h   - 在插入模式下，删除光标前的字符
    Ctrl + w   - 在插入模式下，删除光标前的单词
    Ctrl + j   - 在插入模式下，另起一行
    Ctrl + t   - 在插入模式下，向右缩进，宽度由 shiftwidth 控制
    Ctrl + d   - 在插入模式下，向左缩进，宽度由 shiftwidth 控制
    Ctrl + n   - 在插入模式下，在光标之前插入自动补全的下一个匹配项
    Ctrl + p   - 在插入模式下，在光标之前插入自动补全的上一个匹配项
    Ctrl + rx  - 插入寄存器 x 的内容
    Ctrl + ox  - 暂时进入正常模式以发出一个正常模式命令 x。
    Esc        - 退出插入模式

## 编辑文本

    r         - 替换当前字符
    R         - 在 ESC 按下之前，替换多个字符
    J         - 将下一行合并到当前行, 并在两部分文本之间插入一个空格
    gJ        - 将下一行合并到当前行, 两部分文本之间不含空格
    gwip      - 重新调整段落
    g~        - 大小写转换操作修饰符
    gu        - 小写操作修饰符
    gU        - 大写操作修饰符
    cc        - 将光标所在的行删除, 然后进入插入模式
    c$ or C   - 将光标处到行尾删除, 然后进入插入模式
    ciw       - 将光标所在的单词删除, 然后进入插入模式
    cw or ce  - 从光标位置开始, 修改单词
    s         - 删除当前字符, 然后进入插入模式
    S         - 清空当前行, 然后进入插入模式 (同cc)
    xp        - 当前字符后移
    u         - 撤销
    U         - 撤销上一次的改动行的操作
    Ctrl + r  - 重做（取消撤销）
    .         - 再次执行上个命令

## 选择文本（可视化模式）

    v         - 进入可视化模式, 移动光标高亮选择, 然后可以对选择的文本执行命令(比 y - 复制)
    V         - 进入可视化模式(行粒度选择)
    o         - 切换光标到选择区开头/结尾
    Ctrl + v  - 进入可视化模式(矩阵选择)
    O         - 切换光标到选择区的角
    aw        - 选择当前单词
    ab        - 选择被 () 包裹的区域(含括号)
    aB        - 选择被 {} 包裹的区域(含花括号)
    at        - 选择被 <> 标签包裹的区域(含<>标签)
    ib        - 选择被 () 包裹的区域(不含括号)
    iB        - 选择被 {} 包裹的区域(不含花括号)
    it        - 选择被 <> 标签包裹的区域(不含<>标签)
    Esc       - 退出可视化模式

Tip 也可以使用 ( 和 { 分别代替 b 和 B

## 可视化模式命令

    >  - 向右缩进
    <  - 向左缩进
    y  - 复制
    d  - 剪切
    ~  - 大小写切换
    u  - 将选中文本转换为小写
    U  - 将选中文本转换为大写

## 寄存器

寄存器被存储在 ~/.viminfo 中, 在下次重启 vim 时仍会加载

    :reg[isters]  - 显示寄存器内容
    "xy    - 复制内容到寄存器 x
    "xp    - 粘贴寄存器 x 中的内容
    "+y    - 复制内容到系统剪贴板寄存器
    "+p    - 粘贴系统剪贴板寄存器的内容

特殊寄存器：

    0 - 上次复制
    " - 未命名寄存器，上次复制或删除
    % - 当前文件名
    # - 轮换文件名
    * - 剪贴板内容 (X11 primary)
    + - 剪贴板内容 (X11 clipboard)
    / - 上次搜索的pattern
    : - 上次执行的命令
    . - 上次插入的文本
    - - 上次剪切的短于一行的文本
    = - 表达式寄存器
    _ - 黑洞寄存器

## 标记

    :marks    - 标记列表
    ma        - 设置当前位置为标记 a
    `a        - 跳转到标记 a 的位置
    y`a       - 复制当前位置到标记 a 的内容
    `0        - 跳转到上次 Vim 退出时的位置
    `"        - 跳转到上次编辑该文件时的位置
    `.        - 跳转到上次修改的位置
    ``        - 跳转回上次跳转前的位置
    :ju[mps]  - 列出跳转历史记录
    Ctrl + i  - 跳转至跳转历史中较晚的位置
    Ctrl + o  - 跳转回跳转历史中较早的位置
    :changes  - 列出修改历史记录
    g,        - 跳转至修改历史中较晚修改的位置
    g;        - 跳转至修改历史中较早修改的位置
    Ctrl + ]  - 跳转到当前光标位置对应的 tag

Tip 可以使用反引号 (`) 或单引号 (’) 跳转至标记位置。使用单引号会跳转至该标记所在行行首 (首个非空白字符)。

## 宏

    qa  - 录制宏 a
    q   - 停止录制宏
    @a  - 执行宏 a
    @@  - 重新执行上次执行的宏

## 剪切, 复制, 粘贴

    yy       - 复制当前行
    2yy      - 复制 2 行
    yw       - 复制当前单词
    yiw      - 复制光标处的单词
    yaw      - 复制光标处的单词及其前后的空格
    y$ or Y  - 复制, 从光标位置到行末
    p        - 在光标后粘贴
    P        - 在光标前粘贴
    gp       - 在光标后粘贴并把光标定位于粘贴的文本之后
    gP       - 在光标前粘贴并把光标定位于粘贴的文本之后
    dd       - 剪切当前行
    2dd      - 剪切 2 行
    dw       - 剪切当前单词
    diw      - 删除光标处的单词
    daw      - 删除光标处的单词及其前后的空格
    d$ or D  - 剪切, 从光标位置到行末 (同 D )
    x        - 剪切当前字符

## 文字缩进

    >>   - 将当前行向右缩进，宽度由 shiftwidth 控制
    <<   - 将当前行向左缩进，宽度由 shiftwidth 控制
    >%   - 向右缩进 () 或 {} 内的区域 (光标需置于括号上)
    >ib  - 向右缩进 () 内的区域
    >at  - 向右缩进 <> 标签内的区域
    3==  - 自动缩进 3 行
    =%   - 自动缩进 () 或 {} 内的区域 (光标需置于括号上)
    =iB  - 自动缩进 {} 内的区域 (光标需置于括号上)
    gg=G - 自动缩进整个缓冲区
    ]p   - 粘贴并调整缩进至当前行

## 退出

    :w               - 保存
    :w !sudo tee %   - 使用 sudo 保存当前文件
    :wq or :x or ZZ  - 保存并退出
    :q               - 退出(修改未保存时警告)
    :q! or ZQ        - 不保存强制退出
    :wqa             - 保存所有标签页并全部退出

## 查找/替换

    /pattern        - 查找 pattern
    ?pattern        - 向上查找 pattern
    \vpattern       - pattern 中的非字母数字字符被视为正则表达式特殊字符 (不需转义字符)
    n               - 查找下一个
    N               - 查找上一个
    :%s/old/new/g   - 替换全部
    :%s/old/new/gc  - (逐个)替换
    :noh[lsearch]   - 移除搜索结果的高亮显示

## 多文件搜索

    :vim[grep] /pattern/ {`{file}`}   - 在多个文件中搜索 pattern
    e.g. :vim[grep] /foo/ **/*
    :cn[ext]       - 移动至下一个
    :cp[revious]   - 移动至上一个
    :cope[n]       - 打开搜索结果列表
    :ccl[ose]      - 关闭 quickfix 窗口

## 标签

    :tabnew or :tabnew {page.words.file}  - 在新标签中打开文件
    Ctrl + wT              - 将窗口变成标签
    gt or :tabn[ext]       - 切换到下一个标签
    gT or :tabp[revious]   - 切换到上一个标签
    #gt                    - 切换到第 # 个标签
    :tabm[ove] #           - 移动标签到第 # 位(下标从 0 开始)
    :tabc[lose]            - 关闭当前标签
    :tabo[nly]             - 关闭其他标签
    :tabdo command         - 在所有标签中执行命令 (例如 :tabdo q 关闭所有标签)

## 多文件编辑

    :e[dit] 文件名        - 新建缓冲区打开 filename
    :bn[ext]             - 切换到下个缓冲区
    :bp[revious]         - 切换到上个缓冲区
    :bd[elete]           - 关闭缓冲区
    :b[uffer]#           - 切换到第 # 个缓冲区
    :b[uffer] file       - 用文件名切换缓冲区
    :ls or :buffers      - 列出所有打开的缓冲区
    :sp[lit] 文件名       - 新建缓冲区打开 filename 并水平分割窗口
    :vs[plit] 文件名      - 新缓冲区打开 filename 并垂直分割窗口
    :vert[ical] ba[ll]   - 垂直分割窗口编辑所有缓冲区
    :tab ba[ll]          - 标签页编辑所有缓冲区
    Ctrl + ws     - 水平分割窗口
    Ctrl + wv     - 垂直分割窗口
    Ctrl + ww     - 在窗口间切换
    Ctrl + wq     - 关闭窗口
    Ctrl + wx     - 当前窗口与下一个窗口交换位置
    Ctrl + w=     - 令所有窗口高 & 宽一致
    Ctrl + wh     - 切换到左侧窗口
    Ctrl + wl     - 切换到右侧窗口
    Ctrl + wj     - 切换到下侧窗口
    Ctrl + wk     - 切换到上侧窗口
    Ctrl + wH     - 使游标所在视窗全高并移至最左 (最左垂直视窗)
    Ctrl + wL     - 使游标所在视窗全高并移至最右 (最右垂直视窗)
    Ctrl + wJ     - 使游标所在视窗全宽并移至最下 (最下水平视窗)
    Ctrl + wK     - 使游标所在视窗全宽并移至最上 (最上水平视窗)

## Diff

    zf      - 定义折叠修饰符
    zd      - 删除光标位置的折叠
    za      - 展开 & 关闭光标位置的折叠
    zo      - 展开光标位置的折叠
    zc      - 关闭光标位置的折叠
    zr      - 展开同级的所有折叠
    zm      - 关闭同级的所有折叠
    zi      - 开启 & 关闭折叠功能
    ]c      - 光标移至下一处差异
    [c      - 光标移至上一处差异
    do or :diffg[et]  - 将另一缓冲区中的差异合并至当前缓冲区
    dp or :diffpu[t]  - 将当前缓冲区中的差异推送至另一缓冲区
    :diffthis         - 令当前窗口成为 diff 模式的窗口之一
    :dif[fupdate]     - 强制刷新 diff 的高亮与折叠
    :diffo[ff]        - 令当前窗口退出 diff 模式

折叠命令 (e.g. za) 只作用于当前级别。使用大写字母 (e.g. zA) 令命令作用于全部级别。

可以直接在终端运行 vimdiff 查看文件间的不同。也可以将该程序设为 git difftool 的选项之一。