区块链技术博客
www.b2bchain.cn

神级编辑器 Vim 使用-操作篇求职学习资料

本文介绍了神级编辑器 Vim 使用-操作篇求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

本部分笔记可作为速查 CheatSheet 使用

神级编辑器 Vim 使用-操作篇

<!– more –>

本系列教程共分为以下五个部分:

  1. 神级编辑器 Vim 使用-基础篇
  2. 神级编辑器 Vim 使用-操作篇
  3. 神级编辑器 Vim 使用-插件篇
  4. 神级编辑器 Vim 使用-正则操作篇
  5. 神级编辑器 Vim 使用-最后

基础命令

  • $ vim code.c: 在终端中打开 code.c 文件
  • $ vim ~/.vimrc: 打开根目录下的 .vimrc 文件
  • $ vim -u NONE -N: 以不加载任何插件的方式启动 vim
  • :h [option]: 显示对命令的帮助
  • :source ~/.vimrc: 重载配置文件(可以在不重启 vim 的情况下重载配置文件)
  • :syntax on: 开启语法
  • :set number: 设置行号
  • :set ft=json: 设置的文件格式为json 格式
  • :set ft?: 查看当前文件的 ft 值
  • .: 修改完之后移动至下一个单词出按. 可重复相同操作(厉害!)
  • 5.: 重复 5 次相同动作
  • *: 向下查找光标下的单词
  • #: 向上查找光标下的单词
  • ga: 查看当前光标下字符的 unicode 码及其他详细信息
  • :e.: . 代表 pwd 的结果, 即当前工作路径, 这个命令会进入 netrw 的文件管理界面

保存退出

  • :q: 退出文件
  • q:: 进入命令历史记录, 与:history 等价
  • q/: 进入搜索历史记录
  • :wq: 保存退出
  • :wa: 保存所有缓冲区
  • :wn: 保存当前缓冲区并进入下一个参数列表
  • :qa: 退出所有缓冲区
  • ZZ: 保存退出
  • :sav path/to.txt: 将本缓冲区保存为文件(相当于另存为, 命令全名是 saveas)
  • :w path/to.txt: 保存到某路径
  • :e!: 重载本文件, 即使有未保存的内容也会被丢弃(edit 缩写)
  • :e path/to.txt: 打开指定文件
  • :e .: 进入 netrw 浏览目录

移动

  • hjkl: 左下上右键
  • 10 + hjkl: 向左下上右跳 10 个格
  • gj: 在一段被折为多行时, 将光标向下移动一行(向下移动一个屏幕行)
  • gk: 在一段被折为多行时, 将光标向上移动一行(向上移动一个屏幕行)
  • >>: 整行向右缩进
  • <<: 整行向左缩进
  • :le: 当前行居左对齐
  • :ce: 当前行居中对齐
  • :ri: 当前行居右对齐
  • 0: 移动到行首(非字符)
  • ^: 光标移至行首(字符)
  • g^: 移动到屏幕行的行首
  • $: 光标移至行尾(换行符)
  • g$: 移动到屏幕行的行尾
  • g_: 光标移至最后一个可见字符上
  • 0: 光标移动至行首
  • g;: 跳转到上次修改的位置
  • g,: 跳转到下次修改的位置
  • gi: 跳转到上次退出插入模式的位置并直接进入 Insert Mode
  • %: 在 (), [], {} 之内跳转到包围符号上
  • '', 双反撇号, 跳转到当前文件中最近一次跳转动作发生时的位置
  • '.: 反撇号, 跳转到上次修改的地方
  • w: 跳至下一个词首
  • b: 跳至上一个词首
  • e: 跳至下一个词末端
  • ge: 跳转到上一个词的结尾
  • f: 移动到行内下一个字符, 如 fx 将查找行内出现的下一个 x 字符
  • F: 移动到行内上一个字符, 用法同 f
  • t: 移动到行内下一个字符的前一字符上
  • T: 移动到行内上一个字符的下一字符上
  • ;: 重复查找, 即重复 ft, 非常有用, 可以与 . 想媲美
  • ,: ; 的反面, 当按 ; 过头了可以用 , 退回来
  • <C-b>: 向前滚一页
  • <C-f>: 向后滚一页
  • <C-e>: 向上滚一行
  • <C-y>: 向下滚一行
  • <C-u>: 向上滚半页
  • <C-d>: 向下滚半页
  • gg: 跳至文件顶部
  • G: 跳至文件底部
  • M: 光标移至页中部
  • L: 光标移至页底部
  • H: 光标移至页顶部
  • 88gg: 跳至第 88 行
  • 88G: 跳至第 88 行
  • zz: 将当前行置于视图中央
  • zt: 将当前行置于视图顶部
  • zb: 将当前行置于视图底部
  • gd: 跳转到局部变量定义处
  • gD: 跳转到文件内全局声明(从文件开头开始查找)
  • gf: 跳转到相应的头文件
  • <C-o>: Normal 模式下返回上一个操作的位置, Insert 模式下切换到 Normal 模式, 输入完命令后再次进入 Insert 模式: c-o zz
  • <C-t>: Normal 模式下返回上一个操作的位置
  • <C-i>: Normal 模式下返回下一个操作的位置
  • <C-^>: 在当前文件与上次编辑的文件中快速切换
  • mm: 为当前位置在当前缓冲区内设置标记 m
  • 'm: 反撇号, 跳转到设置的标记 m
  • mM: 为当前位置设置全局标记 M(必须是大写, 可以跨文件使用)
  • 'M: 跳转到全局标记

复制/粘贴/删除

  • c: 删除并进入插入模式 (理解: cert , 会插入)
  • cw: 删除一个单词并进入插入模式
  • C: 删除自游标处到当前行尾, 并进入插入模式
  • c2c: 删除两行并进入插入模式
  • cc: 删除一行并进入插入模式
  • d^: 删除至行首 (理解: delete , 不会插入, 直接删除, 不会复制)
  • D: 从当前光标处删除至行尾
  • dw: 向右删除一个单词
  • d2d: 删除两行
  • dd: 删除一行
  • d121gg: 从当前行删除到 121 行
  • d121j: 从当前行向下删除 121 行
  • x: 删除本字符(等于 delete)
  • X: 向前删除一个字符(等于 backspace)
  • s: 删除右侧并进入插入模式
  • S: 删除整行并进入插入模式
  • yy: 复制一行
  • y$: 从光标当前处复制到结尾, 不会复制到换行符, 但是如果 v$y 则会复制到换行符
  • y: 复制所选(可视模式)
  • y5j: 向下复制 5 行
  • v/d/c/y + [文本对象]
    • 操作分隔符的文本对象: 用于确定范围
      • i(/[/{/"/': 由(/[/{/"/' 包围起来的字符, 不包含 (/[/{/"/'
      • a(/[/{/"/': 由 (/[/{/"/'包围起来的字符及包围符号本身
      • it: 由 tag 包围起来的字符
      • at: 由 tag 包围起来的字符及 tag 本身
    • 操作文本块的文本对象
      • iw: 当前单词
      • aw: 当前单词及一个空格
      • iW: 当前字串
      • aW: 当前字串及一个空格
      • is: 当前句子
      • as: 当前句子及一个空格
      • ip: 当前段落
      • ap: 当前段落记一个空行
    • 一般来说, d{motion} 命令和 aw, asap 配合起来使用比较好,而 c{motion} 命令和 iw 及类似的文本对象一起用效果会更好.
  • p: 如果整行复制, 粘贴在下方一行. 如果选中复制, 粘贴到当前光标后方
  • P: 与 p 方向相反
  • gp: 与p类似, 不过会把光标移动至文本的结尾
  • gP: 与 P类似, 不过会把光标移动到文本的结尾, 在粘贴多行的时候尤其有用

模式切换

  • i: 当前字符之前插入
  • I: 行首插入
  • a: 当前字符之后插入
  • A: 当前字符行尾插入
  • o: 在下方插入一行并进入Insert Mode
  • O: 在上方插入一行并进入Insert Mode
  • <C-v>: 进入列选择模式, 可沿垂直方向选中多行, 然后使用大写的 I 和 A 分别可以实现在前侧和后侧批量添加字符, 使用 > 可以向右缩进, 使用 r 可以替换, 特别好用!
  • v: 进入 visual 模式, 移动光标可进行批量选择删除
  • gv: 重复选择上次选择并操作的区域
  • O: 在 Visual 模式下切换高亮选取的活动端使之可调整

大小写/加减

  • ~: 将当前光标处的大小写翻转
  • g~5j: 将当前行向下 5 行大小写反转
  • gu5j: 将当前行向下 5 行改为小写
  • gU5j: 将当前行向下 5 行改为大写
  • gUit: 将 tag 包围的内容改为大写
  • Vu: 将当前行改为小写
  • VU: 将当前行改为大写
  • veu: 当前光标至尾端的字符改为小写
  • vG~: 将当前光标至文本结尾的字符翻转大小写
  • <C-a>: 对数字进行增加操作, 在列选择模式下批量增加数字, 对 Markdown 的列表排序特别好用
    • <C-v> + select + C-a: 将选择区域数字统一增加 1
    • <C-v> + select + 2 + C-a: 将选择区域数字统一增加 2
    • <C-v> + select + g + C-a: 将选择区域的数字改为递增为 1 的序列
    • <C-v> + select + 2 + g + C-a: 将选择区域的数字改为递增为 2 的序列
  • <C-x>: 对数字进行缩小操作(用法同C-a )

撤销

  • u: 撤销 undo(命令模式, 可多次撤销)
  • U: 无论当前行修改了多少次, 全部撤销操作
  • <C-r>: Normal 模式下反撤销
  • :undolist: 撤销历史(命令模式)
  • :undo 5: 撤销 5 个改变(命令模式)

Folding

  • zc: close, 关闭当前光标下可折叠区域
  • zo: open, 打开当前光标下可折叠区域
  • za: toggle, 打开/关闭当前光标下可折叠区域
  • zC/zO/zA: 与小写不同的是操作对象为全局, 与光标位置无关
  • zr: reduce, 整体减少折叠等级(与光标位置无关)
  • zR: 将所有折叠级别减值最小(直观看来就是缓冲区完全展开了)
  • zm: more, 整体增加折叠级别(与光标位置无关)
  • zM: 增加折叠级别至最高(直观看来就是缓冲区完全折叠了)
  • zd: 删除当前折叠
  • zE: 删除所有折叠
  • zj: 移动至下一个折叠
  • zk: 移动至上一个折叠
  • zn: 禁用折叠
  • zN: 启用折叠

window/tab

  • :tabnew [filename]: 新建一个标签页, 例: tabnew% 以当前文件新建一个标签页, % 表示当前文件
  • :tabclose: 关闭当前标签
  • :tabonly: 关闭所有其他的tab
  • :tabn: 前一个 tab
  • :tabp: 后一个 tab
  • tabdo %s/foo/bar/g: 在所有打开的 tab 上执行替换
  • tab ball: 将所有的缓冲区在 tab 中打开
  • gt: 跳转到下一个 tab
  • gT: 跳转到上一个 tab
  • gt5: 跳转到第 5 个 tab 上
  • :tabn: 移动至下一个标签, 直接使用 gt 也可
  • :tabp: 移动至上一个标签, 直接使用 gT 也可
  • :sp: 上下切割当前文件, 同 <C-w> s
  • :vs: 左右切割当前文件, 同 <C-w> v
  • :sp [filename]: 上下分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • :vs [filename]: 左右分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • <C-w> T: 如果当前 tab 存在多个不同的window, 那么将当前 window 移动到新标签上, 必须是大写
  • <C-w> s: 水平切割当前窗口
  • <C-w> v: 垂直切割当前窗口
  • <C-w> h/j/k/l: 光标向某个方向分屏移动
  • <C-w> w: 在所有窗口间进行切换
  • <C-w> _: 使窗口高度最大化
  • <C-w> |: 使窗口宽度最大化
  • <C-w> =: 使所有窗口等宽等高
  • <C-w> q: quit, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> c: close, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> o: only, 关闭所有除当前屏幕外的所有分屏
  • <C-w> L: 当前分屏向右移动
  • [N]<C-w> +: 分屏增加 N 列高度(可选)
  • [N]<C-w> <: 分屏减少 N 列宽度(可选)
  • :close: 关闭活动窗口
  • :only: 只留下当前活动窗口
  • new abc.txt: 在新窗口中编辑文件

Buffer

  • :ls: 显示当前所有 buffer(缓冲区列表)
  • :ls! : 列出非缓冲区列表文件
  • :bn: buffer next, 下一个 buffer
  • :bp: buffer previous, 上一个 buffer
  • :bf: 打开第一个 buffer
  • :bl: 打开最后一个 buffer
  • :b1: 切换到 buffer1(同理可按照数字切换到不同的 buffer)
  • :bd: 删除 buffer(并没有删除文件本身, 只是 buffer 而已)
  • :bd 1 3: 删除 buffer 编号为 1, 3 的两个 buffer
  • :bw 3 : 将非缓冲区文件全部删除
  • :bufdo [command]: 对所有缓冲区执行操作
  • :1,3 bd: 删除 buffer 编号在 1~3之间的所有 buffer

Tag

  • <C-]>: 跳转到当前光标的定义处
  • g<C-]>: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • g]: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • tag {keyword}: 根据 keyworkd 查找有多少个匹配的 tag
  • tag: 正向遍历标签历史
  • tnext: 跳转到下一处匹配的标签
  • tprev: 跳转到上一处匹配的标签
  • tfist: 跳转到第一处匹配的标签
  • tlast: 跳转到最后一处匹配的标签
  • tselect: 提示用户从标签匹配的列表中选择一项进行跳转

Quick-list

  • :cnext : 显示当前页下一个结果
  • :cpre : 显示当前页上一个结果
  • :copen : 打开 Quickfix 窗口
  • :cfirst: 跳转到第一项
  • :clast: 跳转到最后一项
  • :cnfile: 跳转到下一个文件中的第一项
  • :cpfile: 跳转到上一个文件中的最后一项
  • :cc N: 跳转到第 n 项
  • :cclose : 关闭 Quickfix 窗口
  • :cdo {cmd}: 在 quickfix 列表中的每一行上执行 {cmd}
  • :cfdo {cmd}: 在 quickfix 列表上的每个文件上执行一次 {cmd}
  • :cl[ist] : 打开 location list 窗口, 目前看来不需要使用此选项

Location List

与 Quick-List 相似, 最大的不同是: Quick-List 是针对多个窗口共享一个结果, 而 Location List 则是各个窗口的结果互相独立

  • lopen: 用于打开位置列表窗口
  • lclose: 用于关闭位置列表窗口
  • lnext: 用于切换到位置列表中的下一项
  • lprevious: 用于切换到位置列表中的上一项
  • lwindow: 用于在错误出现时才触发位置列表窗口

  • q + 小写字母: 进入宏记录模式, 记录到小写字母寄存器中, 记录完成后再次按下 q 即可.
  • q + 大写字母: 进入宏记录模式, 在 小写字母寄存器尾部接着添加命令, 记录完成后再次按下 q 即可.
  • @ + 小写字母: 执行对应寄存器内的宏. 可使用前缀添加数字的方式重复多次命令
  • @:: 重复执行上一次运行过的命令, : 寄存器总是保存着最后执行的命令行命令
  • @@: 直接重复上一次的 @ 命令, 此命令必须建立在上一次使用了以 @ 开头的寄存器宏 或者 刚刚建立了一个寄存器宏的 基础上, 因此经常配合 @: 使用.
  • 10@a: 执行寄存器 a中所存储宏 10 次(串行处理, 如果有错误, 则立刻停止, 后续命令不再执行)

参数列表

参数列表与缓冲区的概念很类似, 参数列表的原始含义是我们在终端中使用 vim a.txt b.txt 时后面的一系列文件或参数名, 但是我们也可以在进入 vim 后使用 args手动添加参数文件. 其与缓冲区的区别是:

  1. 位于参数列表的文件必然位于缓冲区列表中
  2. 缓冲区列表永远是乱糟糟的, 但是参数列表永远是秩序井然
  • :args *.* : 将当前目录下的所有类型的文件加入到参数列表中(不包括文件夹中的文件)
  • :args **/*.* : 将当前目录下的所有文件及子文件夹的所有文件都匹配加入到参数列表中
  • :args *.md aa/**/*.md 表示添加子文件夹下的 md 文件及 aa 文件夹下的和其子文件夹下的 md 文件到参数列表中
  • :args 'cat list.txt': 用反撇号将命令包围起来, 然后将命令被执行后的结果作为参数加入参数列表中
  • :argdo %s/oldword/newword/egc | update : 对所有存在参数列表中的文件执行命令, s 代表替换, % 指对所有行进行匹配, g 代表整行替换(必用), e 指使用正则表达式, c 代表每次替换前都会进行确认, update 表示对文件进行读写
  • :argdo write: 将所有参数列表中的内容进行缓冲区保存
  • `:argdo normal @a`: 将当前参数列表的所有缓冲区执行寄存器 a 中所存储的宏
  • :argd * : 清空参数列表
  • :argdo bw : 将参数列表中的所有文件清除出缓冲区
  • :args: 显示当前的所有参数列表
  • :next: 跳转到下一个参数列表的文件
  • :prev: 跳转到上一个参数列表的文件
  • :first: 跳转到第一个参数列表的文件
  • :last: 跳转到最后一个参数列表的文件
  • :args **/*.md : 将当前文件夹下所有.md 文件加入到参数列表中(包括子文件夹中的文件)
  • :argdo %s/![.*]/![img]/gc: 将所有参数列表中的以 ![ 开头, 以 ] 结尾的所有字段改为 [img]
  • :argdo source FormatCN.vim: 对参数列表中的所有文件执行脚本 FormatCN.vim

命令行模式

  • :shell: 调用系统的 shell 来在 vim 进程中执行命令, 执行完使用 exit 退出
  • :term bash: 在底部分割出一个独立窗口并调用 bash, 也可以使用 term zsh 来调用 zsh, 或 :terminal zsh
  • <C-w> N: 在进入 :term 的终端模式后, 使用本命令可以获得 Normal 模式 的效果, 使用 i 返回正常的终端模式
  • :col<C-d>: 在 Ex 命令模式中使用补全查看可能的选项, 然后使用 Tab/S-Tab 进行选择/反向选择
  • <C-r><C-w>: 将当前的光标下的单词插入到命令行中
  • <C-f>: 将正在命令行中输入的内容放入到命令行窗口开始编辑
  • <C-c>: 与 <C-f> 相反, 此命令可以使命令行窗口的当前行内容从命令行窗口放回到命令行中
  • <C-z>: 在终端中将 vim 最小化, 然后如果再需要调用的话使用 fg 进行操作, 使用 jobs 查看所有处于后台的工作
  • <C-b>: beginning, 在命令行模式中跳转到行首
  • <C-e>: end, 在命令行模式中跳转到结尾
  • <C-p>: 在命令行模式中显示上次的命令
  • <C-n>: 在命令行模式中显示下次的命令
  • :!!: 重复执行上一次运行过的命令
  • :!<command>: 在 shell 中执行命令
  • !sh %: 将当前文件所有行作为输入使用外部程序 sh 执行, % 代表本文件所有行
  • !!<command>: 运行命令并将结果作为当前行的内容, 同 :read !<command>
  • :read !<command>: 将命令的结果输入(重定向)到当前缓冲区
  • :!ls: 显示当前工作目录下的所有文件(此操作属于调用系统进程, 使用!来调用系统操作是 Vim 的一大特点)
  • :[range]write !sh: 将当前缓冲区的内容, 在 shell 中逐行执行, 与 read !<command>作用正好相反, !表示外部程序
  • :[range]write ! sh: 将当前缓冲区的内容, 在 shell 中逐行执行, !表示外部程序
  • :[range]write! sh: 将当前缓存区内容写入到一个名为 sh 的文件, !表示强制覆盖式写入
  • :[range]write! filename: 将当前缓冲区内容另存为到 filename 文件中
  • :.,$ sort [option]: 从当前行到末尾进行排序
    • !: 翻转顺序, 默认小在前, 翻转后大在前
    • i: 忽略大小写
    • l: …
    • n: …
    • o: …
    • r: …
    • u: …
    • x: …
  • :2,$ !sort -t',' -k2: 使用外部 sort 程序进行排序, 以 , 为分隔符, 以第二项进行排序
  • :w !sudo tee % > /dev/null: 在当前用户没有权限对当前文件做操作时使用超级管理员身份进行操作
  • :ls: 列出当前所有的缓冲区文件列表, 执行的是 vim 的 ls 命令
  • :f: 显示当前文件路径, (使用了 <C-g> 代替, 此项基本不会用了)
  • :command: 显示当前所文件的所有可使用命令
  • :retab : 重新生成所有的 tab(主要用于在 .vimrc 中重新设置了 tab 格式, 然后在已存在旧格式 tab 的文档进行重生成)
  • :map g: 查看所有以 g 开头的映射

Vim 的先祖是 vi, 正是 vi 开创了区分模式编辑的范例. 相应的, vi 奉 一个名为 ex 的行编辑器为先祖, 这就是为什么会有 Ex 命令.

Ex 命令在命令行模式中执行, 而命令行模式的进入方式为 : 键, 因此我们可以看到所有的 Ex 命令都是以 : 开始的, 输入完命令后按下确定键 <CR> 即可执行, 虽然 Ex 命令年代久远, 但是不可否认其语法的简洁明了以及高效, 很多复杂的操作往往都是通过 Ex 命令来进行处理.

  • :[range] <command> [target]: 执行命令并将结果放入目标位置
    • :3,5 w !bash: 将 3~5 行写入 bash
    • :. w !bash: 将当前行写入 bash
    • :. !bash: 将当前行执行结果写入当前 buffer
    • :3,5 delete x: 将当前行执行结果删除到 x 寄存器
    • :.,$delete x: 将当前行到文件结尾的所有内容删除
    • :3,5 yank x: 将当前行执行结果复制到 x 寄存器
    • :. put x: 在当前行后粘贴寄存器 x 的内容
    • :3,5 copy .: 将 3~5 行复制到当前行下
    • :3,5 move .: 将 3~5 行移动到当前行下
    • :3,5 join: 将 3~5 行进行合并
    • [range] normal [cmd]: normal 用来指定在 normal 模式下对文本的操作命令
      • :3,5 normal .: 对 3~5 行执行 . 重复命令
      • :3,5 normal 对 3~5 行执行寄存器q` 内存储的命令
      • `'<,’> normal @a`: 在所选高亮区域上执行宏(如果有错误也不停止, 因为是针对每一行执行的, 出错了只需要不处理那一行就行了)
    • :[range] global/{pattern}/[cmd]: 对指定范围内匹配的所有行执行 Ex 命令
      • :g/re/d: 删除所有匹配到 re 的行
      • :g/re/p: 打印所有匹配到 re 的行
      • :g//d: 使用上次的查找结果进行匹配然后删除
      • :v/re/d: vglobal 的反面, 只保留匹配到 re 的行
      • :g/TODO/yank A: 将结果匹配到 TODO 的行复制到寄存器 a 的原内容尾部
      • :g/TODO/t$: 将结果匹配到 TODO 的行复制到本缓冲区的尾部
      • :g:/{pattern}/[range][cmd]: 可以用 :g/{pattern} 匹配作为参考点, 动态设置 [cmd 的 range
      • g/{/ .+1,/}/-1 sort: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行排序
      • g/{/sil .+1,/}/-1 >: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行缩进(加入 sil 是为了屏蔽提示信息)
      • g/从这里删除/ .,$ d: 从内容中搜出的第一个 从这里删除 开始, 一直删除到文章结尾
    • :3,5 s/{pattern}/{string}/[flags]: 将 3~5行进行相应替换
    • :3,5 join: 将 3~5行进行合并
    • :3 p: 打印第 3 行
    • :3,5 p: 打印 3~5 行
    • :.,.+3 p: 打印本行以下的三行内容, +3 代表偏移
    • :% p: 打印本 buffer 的所有行, % 代表所有行, 是 1:$ 的简写
    • :0,$ p: 打印本 buffer 所有行, $ 代表最后一行
    • :.,$ p: 打印本 buffer 内从本行到结尾的所有内容, . 代表当前行
    • /<html>/+1,/</html>/-1 p: 使用 patten 指定范围, +1 表示偏移
    • :6t.: 把第 6 行复制到当前行下方, tail 代表尾巴, 遵守 from...to... 的含义
    • :t6: 把当前行复制到第 6 行下方, *. 位于首位时可以省略 . *, 因此全称是 :.t6
    • :t.: 粘贴当前行到下方, 与 yyp 不同的是本方式不会将内容放到寄存器中, 而 yyp 会将内容复制到 unname 寄存器与 0 寄存器
    • :t$: 粘贴当前行到文本结尾
    • :'<,'>t0: 把高亮选中的行复制到文件开头, '< 代表高亮选取的第一行, '> 代表高亮选取的最后一行
    • :'<,'>m$: 把高亮选中的行移动到文件结尾
    • :'<,'>A;: 把当前文件的所有行的尾部加上 ;

Insert 模式

  • <C-p>: 选择上方补全
  • <C-n>: 选择下方补全
  • : 退出插入模式(推荐)
  • <C-c>: 退出插入模式
  • <C-[>: 退出插入模式
  • <C-u>: 向左删除到行首
  • <C-w>: 向左删除一个单词
  • <C-h>: 向左删除一个字符
  • <C-t>: 整行向右偏移
  • <C-d>: 整行向左偏移
  • <C + r>= <function>: 进行计算并将结果输出到当前缓冲区中
  • <C-v>065: 输入大写字母 A
  • <C-v>u{123}: 按照 unicode 码以 10 进制来输入
  • <C-v>u{1234}: 按照 unicode 码以 16 进制来输入
  • <C-v> <Tab>: 无论 expandtab 选项是否开启都会插入制表符
  • 插入模式中的粘贴操作参考这里

路径

vim 的工作路径是使用中要格外注意的地方, 简单来说, 终端中的 vim 默认会把终端当前的路径作为其工作路径, 当然我们可以使用 cd 使其工作路径变更

  • :cd [path]: 设置此次vim的工作目录为path
  • :cd %:h: cd 到当前缓冲区所属目录中
  • :cd ../: cd 到上一级
  • :pwd: 显示当前工作路径
  • :lcd [path]: 设置当前窗口的工作目录为 path(与 cd 不同的是只会改变当前 window 的工作路径, 其他 window 的不受此影响)

vim 为我们提供了一些可以使用的宏用来表示相关路径或文件名称:

  • %:h: 表示当前文件所在目录的相对工作目录路径(不含文件名及扩展)
  • %:p: 表示当前文件所在目录的绝对路径(含文件名及扩展)
  • %:t: 文件名及扩展
  • %:r: 移除扩展之后的所有内容
  • %:e: 扩展名

在使用以上这几种宏时, 我们可以使用 <Tab> 使其自动展开, 有些命令不支持自动展开的话需要使用 expand() 命令

  • echo expand('%:e'): 打印当前文档扩展名, markdown 是 md
  • cd %:h<Tab>: cd 到当前缓冲区所属目录中, 在最后可以使用 <Tab> 进行自动展开
  • e %<Tab>: 会自动扩展为当前文件含相对工作目录的路径全名

寄存器

寄存器是 vim 的一种特有概念, 其他文本编辑器默认都会用系统剪贴板作为复制粘贴的根据地, 然后 vim 另辟蹊径使用多种不同类型寄存器作为临时内容存储位置. 我们可以在复制粘贴时使用指定的寄存器定制化我们的需求, 也可以在录制宏及使用宏时指定寄存器, 大大地提高了我们的工作效率.

很多刚使用 vim 的人会抱怨无法复制内容到 vim 外或 vim 内, 然后各种搜索如何使 vim 的默认复制操作与剪贴板交互, 最后定义了一大堆按键, 譬如 "*y, set clipboard=unnamed, 其实大可不必, 寄存器是 vim 的高效操作方式之一, 接受了这种方式才能更好地利用 vim 来为我们服务(虽然刚开始适应的过程必然是痛苦的)

总的来说 Vim 的删除, 复制与粘贴命令以及定义宏时都会用到众多寄存器中的某一个. 可以通过给命令加 "{register} 前缀的方式指定要用的寄存器. 若不指明, Vim 将缺省使用无名寄存器

  • 无名寄存器

    所有删除复制粘贴操作如果不显示指明寄存器类型的话使用的都是无名寄存器, 其标志符是 "".

  • 复制寄存器

    使用 y 复制后内容会被放到复制寄存器及无名寄存器中, 但是复制寄存器是稳定的, 无名寄存器的内容会时刻被重置替换. 其标志符是 "0

  • 粘贴板寄存器

    用于与系统的其他应用中进行复制粘贴交互, 等于系统的剪贴板. 其标识符是 "*(或 "+)

  • 黑洞寄存器

    所有放入黑洞寄存器的内容全部被丢弃, 相当于完全删除, 不留痕迹, 其标识符是 "_

  • 有名寄存器

    以单个小写字母命名的寄存器, 可用于自定义存储空间, 一共有 26 个

  • 特殊寄存器

    • "%: 当前文件名
    • "#: 轮换文件名
    • ".: 上次插入的文本
    • ":: 上次执行的 Ex 命令
    • "/: 上次查找的模式

使用方式

  • ""p: 从无名寄存器中取值进行粘贴
  • "ay: 将内容复制到有名寄存器 a
  • "_y: 将内容复制到黑洞寄存器, 相当于彻底地删除
  • "ap: 从自定义寄存器中取出内容进行粘贴
  • "0p: 从复制寄存器中取出内容进行粘贴, 默认的 p 是从无名寄存器取值
  • "*p: 从系统粘贴板寄存器中取出内容进行粘贴
  • <C-r>": 在插入模式中将无名寄存器的内容粘贴进来
  • <C-r>*: 在插入模式中将系统粘贴板寄存器的内容粘贴进来
  • <C-r>0: 在插入模式中将复制寄存器的内容粘贴进来
  • <C-r>%: 插入当前文件名(因为 “% 寄存器中存储了当前文件名)
  • :reg a: 查看有名寄存器 a 的内容
  • :reg *: 查看粘贴板寄存器 * 的内容
  • :reg ": 查看无名寄存器 " 的内容
  • :put a: 将有名寄存器 a 的内容粘贴到当前缓冲区中, 与 "ap 不同的是 p 用于只能在光标之前或光标之后进行粘贴, 但是 put 则会始终将内容粘贴到新的一行上
  • :d a: 将内容删除到有名寄存器 a
  • :let, 'iphone', 'iPhone', 'g'): 对寄存器 0 的内容进行替换处理然后再赋值到寄存器 q
  • `:let @*=@0`: 将粘贴寄存器内容赋值到系统剪贴板寄存器

使用 Visual Mode 时, 在选中的文本上使用 p 将直接替换该部分文本(替换后被替换的文本会被放入到无名寄存器中), 可用于解决需要删除然后粘贴但是会影响到无名寄存器的问题

vimdiff

神级编辑器 Vim 使用-操作篇

git 与 vim 可以说是非常好的一对搭档了, 平时在终端中提交 commit 我们都少不了与 vim 打交道, vimdiff 是 vim 提供的专门用于修正 git 冲突文件的一款工具

若想使用 vimdiff 作为冲突修改工具, 需要设置 ~/.gitconfig 的以下项

[diff]     tool = vimdiff [merge]     tool = vimdiff

在 vimdiff 中, 一共有四个窗口, 上面依次是 LOCAL, BASE, REMOTE, 底部则是一个最终的文件结果窗口, 整个过程我们只需要将光标在最下方窗口上上下移动, 使用 diffget 命令从 LOCAL, BASE, REMOTE 中选择需要使用哪一个作为本行的最终结果(当然也可以跳到上面的窗口中使用 diffput 放置结果到底部窗口上

  • :diffget LOCAL: 选择 LCOAL 作为本行最终结果
  • :diffget REMOTE: 选择 REMOTE 作为本行最终结果
  • :diffget BASE: 选择 BASE 作为本行最终结果
  • :diffput [num]: 放置结果到缓冲区上, num 为缓冲区编号
  • :diffg L: 这里 vim 为我们做了简略命令, 同样可用于 REMTOEBASE
  • dp/do: 如果只有两个文件则可以使用 dp/do 来替代 :diffput/:diffget
  • :ls!: 显示当前所有缓冲区的号码
  • [c: conflict, 移动到上一个冲突处
  • ]c: conflict, 移动到下一个冲突处
  • :wqa: 冲突修复完成保存退出, 如果仍然有文件冲突则进入下一个冲突
  • $git merge --continue: 冲突全部解决完后在外界终端中使用 git merge --continue 继续之前的 merge 操作

最后

本文作者 Hanley Lee, 首发于 闪耀旅途, 如果对本文比较认可, 欢迎 Follow

本部分笔记可作为速查 CheatSheet 使用

神级编辑器 Vim 使用-操作篇

<!– more –>

本系列教程共分为以下五个部分:

  1. 神级编辑器 Vim 使用-基础篇
  2. 神级编辑器 Vim 使用-操作篇
  3. 神级编辑器 Vim 使用-插件篇
  4. 神级编辑器 Vim 使用-正则操作篇
  5. 神级编辑器 Vim 使用-最后

基础命令

  • $ vim code.c: 在终端中打开 code.c 文件
  • $ vim ~/.vimrc: 打开根目录下的 .vimrc 文件
  • $ vim -u NONE -N: 以不加载任何插件的方式启动 vim
  • :h [option]: 显示对命令的帮助
  • :source ~/.vimrc: 重载配置文件(可以在不重启 vim 的情况下重载配置文件)
  • :syntax on: 开启语法
  • :set number: 设置行号
  • :set ft=json: 设置的文件格式为json 格式
  • :set ft?: 查看当前文件的 ft 值
  • .: 修改完之后移动至下一个单词出按. 可重复相同操作(厉害!)
  • 5.: 重复 5 次相同动作
  • *: 向下查找光标下的单词
  • #: 向上查找光标下的单词
  • ga: 查看当前光标下字符的 unicode 码及其他详细信息
  • :e.: . 代表 pwd 的结果, 即当前工作路径, 这个命令会进入 netrw 的文件管理界面

保存退出

  • :q: 退出文件
  • q:: 进入命令历史记录, 与:history 等价
  • q/: 进入搜索历史记录
  • :wq: 保存退出
  • :wa: 保存所有缓冲区
  • :wn: 保存当前缓冲区并进入下一个参数列表
  • :qa: 退出所有缓冲区
  • ZZ: 保存退出
  • :sav path/to.txt: 将本缓冲区保存为文件(相当于另存为, 命令全名是 saveas)
  • :w path/to.txt: 保存到某路径
  • :e!: 重载本文件, 即使有未保存的内容也会被丢弃(edit 缩写)
  • :e path/to.txt: 打开指定文件
  • :e .: 进入 netrw 浏览目录

移动

  • hjkl: 左下上右键
  • 10 + hjkl: 向左下上右跳 10 个格
  • gj: 在一段被折为多行时, 将光标向下移动一行(向下移动一个屏幕行)
  • gk: 在一段被折为多行时, 将光标向上移动一行(向上移动一个屏幕行)
  • >>: 整行向右缩进
  • <<: 整行向左缩进
  • :le: 当前行居左对齐
  • :ce: 当前行居中对齐
  • :ri: 当前行居右对齐
  • 0: 移动到行首(非字符)
  • ^: 光标移至行首(字符)
  • g^: 移动到屏幕行的行首
  • $: 光标移至行尾(换行符)
  • g$: 移动到屏幕行的行尾
  • g_: 光标移至最后一个可见字符上
  • 0: 光标移动至行首
  • g;: 跳转到上次修改的位置
  • g,: 跳转到下次修改的位置
  • gi: 跳转到上次退出插入模式的位置并直接进入 Insert Mode
  • %: 在 (), [], {} 之内跳转到包围符号上
  • '', 双反撇号, 跳转到当前文件中最近一次跳转动作发生时的位置
  • '.: 反撇号, 跳转到上次修改的地方
  • w: 跳至下一个词首
  • b: 跳至上一个词首
  • e: 跳至下一个词末端
  • ge: 跳转到上一个词的结尾
  • f: 移动到行内下一个字符, 如 fx 将查找行内出现的下一个 x 字符
  • F: 移动到行内上一个字符, 用法同 f
  • t: 移动到行内下一个字符的前一字符上
  • T: 移动到行内上一个字符的下一字符上
  • ;: 重复查找, 即重复 ft, 非常有用, 可以与 . 想媲美
  • ,: ; 的反面, 当按 ; 过头了可以用 , 退回来
  • <C-b>: 向前滚一页
  • <C-f>: 向后滚一页
  • <C-e>: 向上滚一行
  • <C-y>: 向下滚一行
  • <C-u>: 向上滚半页
  • <C-d>: 向下滚半页
  • gg: 跳至文件顶部
  • G: 跳至文件底部
  • M: 光标移至页中部
  • L: 光标移至页底部
  • H: 光标移至页顶部
  • 88gg: 跳至第 88 行
  • 88G: 跳至第 88 行
  • zz: 将当前行置于视图中央
  • zt: 将当前行置于视图顶部
  • zb: 将当前行置于视图底部
  • gd: 跳转到局部变量定义处
  • gD: 跳转到文件内全局声明(从文件开头开始查找)
  • gf: 跳转到相应的头文件
  • <C-o>: Normal 模式下返回上一个操作的位置, Insert 模式下切换到 Normal 模式, 输入完命令后再次进入 Insert 模式: c-o zz
  • <C-t>: Normal 模式下返回上一个操作的位置
  • <C-i>: Normal 模式下返回下一个操作的位置
  • <C-^>: 在当前文件与上次编辑的文件中快速切换
  • mm: 为当前位置在当前缓冲区内设置标记 m
  • 'm: 反撇号, 跳转到设置的标记 m
  • mM: 为当前位置设置全局标记 M(必须是大写, 可以跨文件使用)
  • 'M: 跳转到全局标记

复制/粘贴/删除

  • c: 删除并进入插入模式 (理解: cert , 会插入)
  • cw: 删除一个单词并进入插入模式
  • C: 删除自游标处到当前行尾, 并进入插入模式
  • c2c: 删除两行并进入插入模式
  • cc: 删除一行并进入插入模式
  • d^: 删除至行首 (理解: delete , 不会插入, 直接删除, 不会复制)
  • D: 从当前光标处删除至行尾
  • dw: 向右删除一个单词
  • d2d: 删除两行
  • dd: 删除一行
  • d121gg: 从当前行删除到 121 行
  • d121j: 从当前行向下删除 121 行
  • x: 删除本字符(等于 delete)
  • X: 向前删除一个字符(等于 backspace)
  • s: 删除右侧并进入插入模式
  • S: 删除整行并进入插入模式
  • yy: 复制一行
  • y$: 从光标当前处复制到结尾, 不会复制到换行符, 但是如果 v$y 则会复制到换行符
  • y: 复制所选(可视模式)
  • y5j: 向下复制 5 行
  • v/d/c/y + [文本对象]
    • 操作分隔符的文本对象: 用于确定范围
      • i(/[/{/"/': 由(/[/{/"/' 包围起来的字符, 不包含 (/[/{/"/'
      • a(/[/{/"/': 由 (/[/{/"/'包围起来的字符及包围符号本身
      • it: 由 tag 包围起来的字符
      • at: 由 tag 包围起来的字符及 tag 本身
    • 操作文本块的文本对象
      • iw: 当前单词
      • aw: 当前单词及一个空格
      • iW: 当前字串
      • aW: 当前字串及一个空格
      • is: 当前句子
      • as: 当前句子及一个空格
      • ip: 当前段落
      • ap: 当前段落记一个空行
    • 一般来说, d{motion} 命令和 aw, asap 配合起来使用比较好,而 c{motion} 命令和 iw 及类似的文本对象一起用效果会更好.
  • p: 如果整行复制, 粘贴在下方一行. 如果选中复制, 粘贴到当前光标后方
  • P: 与 p 方向相反
  • gp: 与p类似, 不过会把光标移动至文本的结尾
  • gP: 与 P类似, 不过会把光标移动到文本的结尾, 在粘贴多行的时候尤其有用

模式切换

  • i: 当前字符之前插入
  • I: 行首插入
  • a: 当前字符之后插入
  • A: 当前字符行尾插入
  • o: 在下方插入一行并进入Insert Mode
  • O: 在上方插入一行并进入Insert Mode
  • <C-v>: 进入列选择模式, 可沿垂直方向选中多行, 然后使用大写的 I 和 A 分别可以实现在前侧和后侧批量添加字符, 使用 > 可以向右缩进, 使用 r 可以替换, 特别好用!
  • v: 进入 visual 模式, 移动光标可进行批量选择删除
  • gv: 重复选择上次选择并操作的区域
  • O: 在 Visual 模式下切换高亮选取的活动端使之可调整

大小写/加减

  • ~: 将当前光标处的大小写翻转
  • g~5j: 将当前行向下 5 行大小写反转
  • gu5j: 将当前行向下 5 行改为小写
  • gU5j: 将当前行向下 5 行改为大写
  • gUit: 将 tag 包围的内容改为大写
  • Vu: 将当前行改为小写
  • VU: 将当前行改为大写
  • veu: 当前光标至尾端的字符改为小写
  • vG~: 将当前光标至文本结尾的字符翻转大小写
  • <C-a>: 对数字进行增加操作, 在列选择模式下批量增加数字, 对 Markdown 的列表排序特别好用
    • <C-v> + select + C-a: 将选择区域数字统一增加 1
    • <C-v> + select + 2 + C-a: 将选择区域数字统一增加 2
    • <C-v> + select + g + C-a: 将选择区域的数字改为递增为 1 的序列
    • <C-v> + select + 2 + g + C-a: 将选择区域的数字改为递增为 2 的序列
  • <C-x>: 对数字进行缩小操作(用法同C-a )

撤销

  • u: 撤销 undo(命令模式, 可多次撤销)
  • U: 无论当前行修改了多少次, 全部撤销操作
  • <C-r>: Normal 模式下反撤销
  • :undolist: 撤销历史(命令模式)
  • :undo 5: 撤销 5 个改变(命令模式)

Folding

  • zc: close, 关闭当前光标下可折叠区域
  • zo: open, 打开当前光标下可折叠区域
  • za: toggle, 打开/关闭当前光标下可折叠区域
  • zC/zO/zA: 与小写不同的是操作对象为全局, 与光标位置无关
  • zr: reduce, 整体减少折叠等级(与光标位置无关)
  • zR: 将所有折叠级别减值最小(直观看来就是缓冲区完全展开了)
  • zm: more, 整体增加折叠级别(与光标位置无关)
  • zM: 增加折叠级别至最高(直观看来就是缓冲区完全折叠了)
  • zd: 删除当前折叠
  • zE: 删除所有折叠
  • zj: 移动至下一个折叠
  • zk: 移动至上一个折叠
  • zn: 禁用折叠
  • zN: 启用折叠

window/tab

  • :tabnew [filename]: 新建一个标签页, 例: tabnew% 以当前文件新建一个标签页, % 表示当前文件
  • :tabclose: 关闭当前标签
  • :tabonly: 关闭所有其他的tab
  • :tabn: 前一个 tab
  • :tabp: 后一个 tab
  • tabdo %s/foo/bar/g: 在所有打开的 tab 上执行替换
  • tab ball: 将所有的缓冲区在 tab 中打开
  • gt: 跳转到下一个 tab
  • gT: 跳转到上一个 tab
  • gt5: 跳转到第 5 个 tab 上
  • :tabn: 移动至下一个标签, 直接使用 gt 也可
  • :tabp: 移动至上一个标签, 直接使用 gT 也可
  • :sp: 上下切割当前文件, 同 <C-w> s
  • :vs: 左右切割当前文件, 同 <C-w> v
  • :sp [filename]: 上下分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • :vs [filename]: 左右分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • <C-w> T: 如果当前 tab 存在多个不同的window, 那么将当前 window 移动到新标签上, 必须是大写
  • <C-w> s: 水平切割当前窗口
  • <C-w> v: 垂直切割当前窗口
  • <C-w> h/j/k/l: 光标向某个方向分屏移动
  • <C-w> w: 在所有窗口间进行切换
  • <C-w> _: 使窗口高度最大化
  • <C-w> |: 使窗口宽度最大化
  • <C-w> =: 使所有窗口等宽等高
  • <C-w> q: quit, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> c: close, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> o: only, 关闭所有除当前屏幕外的所有分屏
  • <C-w> L: 当前分屏向右移动
  • [N]<C-w> +: 分屏增加 N 列高度(可选)
  • [N]<C-w> <: 分屏减少 N 列宽度(可选)
  • :close: 关闭活动窗口
  • :only: 只留下当前活动窗口
  • new abc.txt: 在新窗口中编辑文件

Buffer

  • :ls: 显示当前所有 buffer(缓冲区列表)
  • :ls! : 列出非缓冲区列表文件
  • :bn: buffer next, 下一个 buffer
  • :bp: buffer previous, 上一个 buffer
  • :bf: 打开第一个 buffer
  • :bl: 打开最后一个 buffer
  • :b1: 切换到 buffer1(同理可按照数字切换到不同的 buffer)
  • :bd: 删除 buffer(并没有删除文件本身, 只是 buffer 而已)
  • :bd 1 3: 删除 buffer 编号为 1, 3 的两个 buffer
  • :bw 3 : 将非缓冲区文件全部删除
  • :bufdo [command]: 对所有缓冲区执行操作
  • :1,3 bd: 删除 buffer 编号在 1~3之间的所有 buffer

Tag

  • <C-]>: 跳转到当前光标的定义处
  • g<C-]>: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • g]: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • tag {keyword}: 根据 keyworkd 查找有多少个匹配的 tag
  • tag: 正向遍历标签历史
  • tnext: 跳转到下一处匹配的标签
  • tprev: 跳转到上一处匹配的标签
  • tfist: 跳转到第一处匹配的标签
  • tlast: 跳转到最后一处匹配的标签
  • tselect: 提示用户从标签匹配的列表中选择一项进行跳转

Quick-list

  • :cnext : 显示当前页下一个结果
  • :cpre : 显示当前页上一个结果
  • :copen : 打开 Quickfix 窗口
  • :cfirst: 跳转到第一项
  • :clast: 跳转到最后一项
  • :cnfile: 跳转到下一个文件中的第一项
  • :cpfile: 跳转到上一个文件中的最后一项
  • :cc N: 跳转到第 n 项
  • :cclose : 关闭 Quickfix 窗口
  • :cdo {cmd}: 在 quickfix 列表中的每一行上执行 {cmd}
  • :cfdo {cmd}: 在 quickfix 列表上的每个文件上执行一次 {cmd}
  • :cl[ist] : 打开 location list 窗口, 目前看来不需要使用此选项

Location List

与 Quick-List 相似, 最大的不同是: Quick-List 是针对多个窗口共享一个结果, 而 Location List 则是各个窗口的结果互相独立

  • lopen: 用于打开位置列表窗口
  • lclose: 用于关闭位置列表窗口
  • lnext: 用于切换到位置列表中的下一项
  • lprevious: 用于切换到位置列表中的上一项
  • lwindow: 用于在错误出现时才触发位置列表窗口

  • q + 小写字母: 进入宏记录模式, 记录到小写字母寄存器中, 记录完成后再次按下 q 即可.
  • q + 大写字母: 进入宏记录模式, 在 小写字母寄存器尾部接着添加命令, 记录完成后再次按下 q 即可.
  • @ + 小写字母: 执行对应寄存器内的宏. 可使用前缀添加数字的方式重复多次命令
  • @:: 重复执行上一次运行过的命令, : 寄存器总是保存着最后执行的命令行命令
  • @@: 直接重复上一次的 @ 命令, 此命令必须建立在上一次使用了以 @ 开头的寄存器宏 或者 刚刚建立了一个寄存器宏的 基础上, 因此经常配合 @: 使用.
  • 10@a: 执行寄存器 a中所存储宏 10 次(串行处理, 如果有错误, 则立刻停止, 后续命令不再执行)

参数列表

参数列表与缓冲区的概念很类似, 参数列表的原始含义是我们在终端中使用 vim a.txt b.txt 时后面的一系列文件或参数名, 但是我们也可以在进入 vim 后使用 args手动添加参数文件. 其与缓冲区的区别是:

  1. 位于参数列表的文件必然位于缓冲区列表中
  2. 缓冲区列表永远是乱糟糟的, 但是参数列表永远是秩序井然
  • :args *.* : 将当前目录下的所有类型的文件加入到参数列表中(不包括文件夹中的文件)
  • :args **/*.* : 将当前目录下的所有文件及子文件夹的所有文件都匹配加入到参数列表中
  • :args *.md aa/**/*.md 表示添加子文件夹下的 md 文件及 aa 文件夹下的和其子文件夹下的 md 文件到参数列表中
  • :args 'cat list.txt': 用反撇号将命令包围起来, 然后将命令被执行后的结果作为参数加入参数列表中
  • :argdo %s/oldword/newword/egc | update : 对所有存在参数列表中的文件执行命令, s 代表替换, % 指对所有行进行匹配, g 代表整行替换(必用), e 指使用正则表达式, c 代表每次替换前都会进行确认, update 表示对文件进行读写
  • :argdo write: 将所有参数列表中的内容进行缓冲区保存
  • `:argdo normal @a`: 将当前参数列表的所有缓冲区执行寄存器 a 中所存储的宏
  • :argd * : 清空参数列表
  • :argdo bw : 将参数列表中的所有文件清除出缓冲区
  • :args: 显示当前的所有参数列表
  • :next: 跳转到下一个参数列表的文件
  • :prev: 跳转到上一个参数列表的文件
  • :first: 跳转到第一个参数列表的文件
  • :last: 跳转到最后一个参数列表的文件
  • :args **/*.md : 将当前文件夹下所有.md 文件加入到参数列表中(包括子文件夹中的文件)
  • :argdo %s/![.*]/![img]/gc: 将所有参数列表中的以 ![ 开头, 以 ] 结尾的所有字段改为 [img]
  • :argdo source FormatCN.vim: 对参数列表中的所有文件执行脚本 FormatCN.vim

命令行模式

  • :shell: 调用系统的 shell 来在 vim 进程中执行命令, 执行完使用 exit 退出
  • :term bash: 在底部分割出一个独立窗口并调用 bash, 也可以使用 term zsh 来调用 zsh, 或 :terminal zsh
  • <C-w> N: 在进入 :term 的终端模式后, 使用本命令可以获得 Normal 模式 的效果, 使用 i 返回正常的终端模式
  • :col<C-d>: 在 Ex 命令模式中使用补全查看可能的选项, 然后使用 Tab/S-Tab 进行选择/反向选择
  • <C-r><C-w>: 将当前的光标下的单词插入到命令行中
  • <C-f>: 将正在命令行中输入的内容放入到命令行窗口开始编辑
  • <C-c>: 与 <C-f> 相反, 此命令可以使命令行窗口的当前行内容从命令行窗口放回到命令行中
  • <C-z>: 在终端中将 vim 最小化, 然后如果再需要调用的话使用 fg 进行操作, 使用 jobs 查看所有处于后台的工作
  • <C-b>: beginning, 在命令行模式中跳转到行首
  • <C-e>: end, 在命令行模式中跳转到结尾
  • <C-p>: 在命令行模式中显示上次的命令
  • <C-n>: 在命令行模式中显示下次的命令
  • :!!: 重复执行上一次运行过的命令
  • :!<command>: 在 shell 中执行命令
  • !sh %: 将当前文件所有行作为输入使用外部程序 sh 执行, % 代表本文件所有行
  • !!<command>: 运行命令并将结果作为当前行的内容, 同 :read !<command>
  • :read !<command>: 将命令的结果输入(重定向)到当前缓冲区
  • :!ls: 显示当前工作目录下的所有文件(此操作属于调用系统进程, 使用!来调用系统操作是 Vim 的一大特点)
  • :[range]write !sh: 将当前缓冲区的内容, 在 shell 中逐行执行, 与 read !<command>作用正好相反, !表示外部程序
  • :[range]write ! sh: 将当前缓冲区的内容, 在 shell 中逐行执行, !表示外部程序
  • :[range]write! sh: 将当前缓存区内容写入到一个名为 sh 的文件, !表示强制覆盖式写入
  • :[range]write! filename: 将当前缓冲区内容另存为到 filename 文件中
  • :.,$ sort [option]: 从当前行到末尾进行排序
    • !: 翻转顺序, 默认小在前, 翻转后大在前
    • i: 忽略大小写
    • l: …
    • n: …
    • o: …
    • r: …
    • u: …
    • x: …
  • :2,$ !sort -t',' -k2: 使用外部 sort 程序进行排序, 以 , 为分隔符, 以第二项进行排序
  • :w !sudo tee % > /dev/null: 在当前用户没有权限对当前文件做操作时使用超级管理员身份进行操作
  • :ls: 列出当前所有的缓冲区文件列表, 执行的是 vim 的 ls 命令
  • :f: 显示当前文件路径, (使用了 <C-g> 代替, 此项基本不会用了)
  • :command: 显示当前所文件的所有可使用命令
  • :retab : 重新生成所有的 tab(主要用于在 .vimrc 中重新设置了 tab 格式, 然后在已存在旧格式 tab 的文档进行重生成)
  • :map g: 查看所有以 g 开头的映射

Vim 的先祖是 vi, 正是 vi 开创了区分模式编辑的范例. 相应的, vi 奉 一个名为 ex 的行编辑器为先祖, 这就是为什么会有 Ex 命令.

Ex 命令在命令行模式中执行, 而命令行模式的进入方式为 : 键, 因此我们可以看到所有的 Ex 命令都是以 : 开始的, 输入完命令后按下确定键 <CR> 即可执行, 虽然 Ex 命令年代久远, 但是不可否认其语法的简洁明了以及高效, 很多复杂的操作往往都是通过 Ex 命令来进行处理.

  • :[range] <command> [target]: 执行命令并将结果放入目标位置
    • :3,5 w !bash: 将 3~5 行写入 bash
    • :. w !bash: 将当前行写入 bash
    • :. !bash: 将当前行执行结果写入当前 buffer
    • :3,5 delete x: 将当前行执行结果删除到 x 寄存器
    • :.,$delete x: 将当前行到文件结尾的所有内容删除
    • :3,5 yank x: 将当前行执行结果复制到 x 寄存器
    • :. put x: 在当前行后粘贴寄存器 x 的内容
    • :3,5 copy .: 将 3~5 行复制到当前行下
    • :3,5 move .: 将 3~5 行移动到当前行下
    • :3,5 join: 将 3~5 行进行合并
    • [range] normal [cmd]: normal 用来指定在 normal 模式下对文本的操作命令
      • :3,5 normal .: 对 3~5 行执行 . 重复命令
      • :3,5 normal 对 3~5 行执行寄存器q` 内存储的命令
      • `'<,’> normal @a`: 在所选高亮区域上执行宏(如果有错误也不停止, 因为是针对每一行执行的, 出错了只需要不处理那一行就行了)
    • :[range] global/{pattern}/[cmd]: 对指定范围内匹配的所有行执行 Ex 命令
      • :g/re/d: 删除所有匹配到 re 的行
      • :g/re/p: 打印所有匹配到 re 的行
      • :g//d: 使用上次的查找结果进行匹配然后删除
      • :v/re/d: vglobal 的反面, 只保留匹配到 re 的行
      • :g/TODO/yank A: 将结果匹配到 TODO 的行复制到寄存器 a 的原内容尾部
      • :g/TODO/t$: 将结果匹配到 TODO 的行复制到本缓冲区的尾部
      • :g:/{pattern}/[range][cmd]: 可以用 :g/{pattern} 匹配作为参考点, 动态设置 [cmd 的 range
      • g/{/ .+1,/}/-1 sort: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行排序
      • g/{/sil .+1,/}/-1 >: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行缩进(加入 sil 是为了屏蔽提示信息)
      • g/从这里删除/ .,$ d: 从内容中搜出的第一个 从这里删除 开始, 一直删除到文章结尾
    • :3,5 s/{pattern}/{string}/[flags]: 将 3~5行进行相应替换
    • :3,5 join: 将 3~5行进行合并
    • :3 p: 打印第 3 行
    • :3,5 p: 打印 3~5 行
    • :.,.+3 p: 打印本行以下的三行内容, +3 代表偏移
    • :% p: 打印本 buffer 的所有行, % 代表所有行, 是 1:$ 的简写
    • :0,$ p: 打印本 buffer 所有行, $ 代表最后一行
    • :.,$ p: 打印本 buffer 内从本行到结尾的所有内容, . 代表当前行
    • /<html>/+1,/</html>/-1 p: 使用 patten 指定范围, +1 表示偏移
    • :6t.: 把第 6 行复制到当前行下方, tail 代表尾巴, 遵守 from...to... 的含义
    • :t6: 把当前行复制到第 6 行下方, *. 位于首位时可以省略 . *, 因此全称是 :.t6
    • :t.: 粘贴当前行到下方, 与 yyp 不同的是本方式不会将内容放到寄存器中, 而 yyp 会将内容复制到 unname 寄存器与 0 寄存器
    • :t$: 粘贴当前行到文本结尾
    • :'<,'>t0: 把高亮选中的行复制到文件开头, '< 代表高亮选取的第一行, '> 代表高亮选取的最后一行
    • :'<,'>m$: 把高亮选中的行移动到文件结尾
    • :'<,'>A;: 把当前文件的所有行的尾部加上 ;

Insert 模式

  • <C-p>: 选择上方补全
  • <C-n>: 选择下方补全
  • : 退出插入模式(推荐)
  • <C-c>: 退出插入模式
  • <C-[>: 退出插入模式
  • <C-u>: 向左删除到行首
  • <C-w>: 向左删除一个单词
  • <C-h>: 向左删除一个字符
  • <C-t>: 整行向右偏移
  • <C-d>: 整行向左偏移
  • <C + r>= <function>: 进行计算并将结果输出到当前缓冲区中
  • <C-v>065: 输入大写字母 A
  • <C-v>u{123}: 按照 unicode 码以 10 进制来输入
  • <C-v>u{1234}: 按照 unicode 码以 16 进制来输入
  • <C-v> <Tab>: 无论 expandtab 选项是否开启都会插入制表符
  • 插入模式中的粘贴操作参考这里

路径

vim 的工作路径是使用中要格外注意的地方, 简单来说, 终端中的 vim 默认会把终端当前的路径作为其工作路径, 当然我们可以使用 cd 使其工作路径变更

  • :cd [path]: 设置此次vim的工作目录为path
  • :cd %:h: cd 到当前缓冲区所属目录中
  • :cd ../: cd 到上一级
  • :pwd: 显示当前工作路径
  • :lcd [path]: 设置当前窗口的工作目录为 path(与 cd 不同的是只会改变当前 window 的工作路径, 其他 window 的不受此影响)

vim 为我们提供了一些可以使用的宏用来表示相关路径或文件名称:

  • %:h: 表示当前文件所在目录的相对工作目录路径(不含文件名及扩展)
  • %:p: 表示当前文件所在目录的绝对路径(含文件名及扩展)
  • %:t: 文件名及扩展
  • %:r: 移除扩展之后的所有内容
  • %:e: 扩展名

在使用以上这几种宏时, 我们可以使用 <Tab> 使其自动展开, 有些命令不支持自动展开的话需要使用 expand() 命令

  • echo expand('%:e'): 打印当前文档扩展名, markdown 是 md
  • cd %:h<Tab>: cd 到当前缓冲区所属目录中, 在最后可以使用 <Tab> 进行自动展开
  • e %<Tab>: 会自动扩展为当前文件含相对工作目录的路径全名

寄存器

寄存器是 vim 的一种特有概念, 其他文本编辑器默认都会用系统剪贴板作为复制粘贴的根据地, 然后 vim 另辟蹊径使用多种不同类型寄存器作为临时内容存储位置. 我们可以在复制粘贴时使用指定的寄存器定制化我们的需求, 也可以在录制宏及使用宏时指定寄存器, 大大地提高了我们的工作效率.

很多刚使用 vim 的人会抱怨无法复制内容到 vim 外或 vim 内, 然后各种搜索如何使 vim 的默认复制操作与剪贴板交互, 最后定义了一大堆按键, 譬如 "*y, set clipboard=unnamed, 其实大可不必, 寄存器是 vim 的高效操作方式之一, 接受了这种方式才能更好地利用 vim 来为我们服务(虽然刚开始适应的过程必然是痛苦的)

总的来说 Vim 的删除, 复制与粘贴命令以及定义宏时都会用到众多寄存器中的某一个. 可以通过给命令加 "{register} 前缀的方式指定要用的寄存器. 若不指明, Vim 将缺省使用无名寄存器

  • 无名寄存器

    所有删除复制粘贴操作如果不显示指明寄存器类型的话使用的都是无名寄存器, 其标志符是 "".

  • 复制寄存器

    使用 y 复制后内容会被放到复制寄存器及无名寄存器中, 但是复制寄存器是稳定的, 无名寄存器的内容会时刻被重置替换. 其标志符是 "0

  • 粘贴板寄存器

    用于与系统的其他应用中进行复制粘贴交互, 等于系统的剪贴板. 其标识符是 "*(或 "+)

  • 黑洞寄存器

    所有放入黑洞寄存器的内容全部被丢弃, 相当于完全删除, 不留痕迹, 其标识符是 "_

  • 有名寄存器

    以单个小写字母命名的寄存器, 可用于自定义存储空间, 一共有 26 个

  • 特殊寄存器

    • "%: 当前文件名
    • "#: 轮换文件名
    • ".: 上次插入的文本
    • ":: 上次执行的 Ex 命令
    • "/: 上次查找的模式

使用方式

  • ""p: 从无名寄存器中取值进行粘贴
  • "ay: 将内容复制到有名寄存器 a
  • "_y: 将内容复制到黑洞寄存器, 相当于彻底地删除
  • "ap: 从自定义寄存器中取出内容进行粘贴
  • "0p: 从复制寄存器中取出内容进行粘贴, 默认的 p 是从无名寄存器取值
  • "*p: 从系统粘贴板寄存器中取出内容进行粘贴
  • <C-r>": 在插入模式中将无名寄存器的内容粘贴进来
  • <C-r>*: 在插入模式中将系统粘贴板寄存器的内容粘贴进来
  • <C-r>0: 在插入模式中将复制寄存器的内容粘贴进来
  • <C-r>%: 插入当前文件名(因为 “% 寄存器中存储了当前文件名)
  • :reg a: 查看有名寄存器 a 的内容
  • :reg *: 查看粘贴板寄存器 * 的内容
  • :reg ": 查看无名寄存器 " 的内容
  • :put a: 将有名寄存器 a 的内容粘贴到当前缓冲区中, 与 "ap 不同的是 p 用于只能在光标之前或光标之后进行粘贴, 但是 put 则会始终将内容粘贴到新的一行上
  • :d a: 将内容删除到有名寄存器 a
  • :let, 'iphone', 'iPhone', 'g'): 对寄存器 0 的内容进行替换处理然后再赋值到寄存器 q
  • `:let @*=@0`: 将粘贴寄存器内容赋值到系统剪贴板寄存器

使用 Visual Mode 时, 在选中的文本上使用 p 将直接替换该部分文本(替换后被替换的文本会被放入到无名寄存器中), 可用于解决需要删除然后粘贴但是会影响到无名寄存器的问题

vimdiff

神级编辑器 Vim 使用-操作篇

git 与 vim 可以说是非常好的一对搭档了, 平时在终端中提交 commit 我们都少不了与 vim 打交道, vimdiff 是 vim 提供的专门用于修正 git 冲突文件的一款工具

若想使用 vimdiff 作为冲突修改工具, 需要设置 ~/.gitconfig 的以下项

[diff]     tool = vimdiff [merge]     tool = vimdiff

在 vimdiff 中, 一共有四个窗口, 上面依次是 LOCAL, BASE, REMOTE, 底部则是一个最终的文件结果窗口, 整个过程我们只需要将光标在最下方窗口上上下移动, 使用 diffget 命令从 LOCAL, BASE, REMOTE 中选择需要使用哪一个作为本行的最终结果(当然也可以跳到上面的窗口中使用 diffput 放置结果到底部窗口上

  • :diffget LOCAL: 选择 LCOAL 作为本行最终结果
  • :diffget REMOTE: 选择 REMOTE 作为本行最终结果
  • :diffget BASE: 选择 BASE 作为本行最终结果
  • :diffput [num]: 放置结果到缓冲区上, num 为缓冲区编号
  • :diffg L: 这里 vim 为我们做了简略命令, 同样可用于 REMTOEBASE
  • dp/do: 如果只有两个文件则可以使用 dp/do 来替代 :diffput/:diffget
  • :ls!: 显示当前所有缓冲区的号码
  • [c: conflict, 移动到上一个冲突处
  • ]c: conflict, 移动到下一个冲突处
  • :wqa: 冲突修复完成保存退出, 如果仍然有文件冲突则进入下一个冲突
  • $git merge --continue: 冲突全部解决完后在外界终端中使用 git merge --continue 继续之前的 merge 操作

最后

本文作者 Hanley Lee, 首发于 闪耀旅途, 如果对本文比较认可, 欢迎 Follow

本部分笔记可作为速查 CheatSheet 使用

神级编辑器 Vim 使用-操作篇

<!– more –>

本系列教程共分为以下五个部分:

  1. 神级编辑器 Vim 使用-基础篇
  2. 神级编辑器 Vim 使用-操作篇
  3. 神级编辑器 Vim 使用-插件篇
  4. 神级编辑器 Vim 使用-正则操作篇
  5. 神级编辑器 Vim 使用-最后

基础命令

  • $ vim code.c: 在终端中打开 code.c 文件
  • $ vim ~/.vimrc: 打开根目录下的 .vimrc 文件
  • $ vim -u NONE -N: 以不加载任何插件的方式启动 vim
  • :h [option]: 显示对命令的帮助
  • :source ~/.vimrc: 重载配置文件(可以在不重启 vim 的情况下重载配置文件)
  • :syntax on: 开启语法
  • :set number: 设置行号
  • :set ft=json: 设置的文件格式为json 格式
  • :set ft?: 查看当前文件的 ft 值
  • .: 修改完之后移动至下一个单词出按. 可重复相同操作(厉害!)
  • 5.: 重复 5 次相同动作
  • *: 向下查找光标下的单词
  • #: 向上查找光标下的单词
  • ga: 查看当前光标下字符的 unicode 码及其他详细信息
  • :e.: . 代表 pwd 的结果, 即当前工作路径, 这个命令会进入 netrw 的文件管理界面

保存退出

  • :q: 退出文件
  • q:: 进入命令历史记录, 与:history 等价
  • q/: 进入搜索历史记录
  • :wq: 保存退出
  • :wa: 保存所有缓冲区
  • :wn: 保存当前缓冲区并进入下一个参数列表
  • :qa: 退出所有缓冲区
  • ZZ: 保存退出
  • :sav path/to.txt: 将本缓冲区保存为文件(相当于另存为, 命令全名是 saveas)
  • :w path/to.txt: 保存到某路径
  • :e!: 重载本文件, 即使有未保存的内容也会被丢弃(edit 缩写)
  • :e path/to.txt: 打开指定文件
  • :e .: 进入 netrw 浏览目录

移动

  • hjkl: 左下上右键
  • 10 + hjkl: 向左下上右跳 10 个格
  • gj: 在一段被折为多行时, 将光标向下移动一行(向下移动一个屏幕行)
  • gk: 在一段被折为多行时, 将光标向上移动一行(向上移动一个屏幕行)
  • >>: 整行向右缩进
  • <<: 整行向左缩进
  • :le: 当前行居左对齐
  • :ce: 当前行居中对齐
  • :ri: 当前行居右对齐
  • 0: 移动到行首(非字符)
  • ^: 光标移至行首(字符)
  • g^: 移动到屏幕行的行首
  • $: 光标移至行尾(换行符)
  • g$: 移动到屏幕行的行尾
  • g_: 光标移至最后一个可见字符上
  • 0: 光标移动至行首
  • g;: 跳转到上次修改的位置
  • g,: 跳转到下次修改的位置
  • gi: 跳转到上次退出插入模式的位置并直接进入 Insert Mode
  • %: 在 (), [], {} 之内跳转到包围符号上
  • '', 双反撇号, 跳转到当前文件中最近一次跳转动作发生时的位置
  • '.: 反撇号, 跳转到上次修改的地方
  • w: 跳至下一个词首
  • b: 跳至上一个词首
  • e: 跳至下一个词末端
  • ge: 跳转到上一个词的结尾
  • f: 移动到行内下一个字符, 如 fx 将查找行内出现的下一个 x 字符
  • F: 移动到行内上一个字符, 用法同 f
  • t: 移动到行内下一个字符的前一字符上
  • T: 移动到行内上一个字符的下一字符上
  • ;: 重复查找, 即重复 ft, 非常有用, 可以与 . 想媲美
  • ,: ; 的反面, 当按 ; 过头了可以用 , 退回来
  • <C-b>: 向前滚一页
  • <C-f>: 向后滚一页
  • <C-e>: 向上滚一行
  • <C-y>: 向下滚一行
  • <C-u>: 向上滚半页
  • <C-d>: 向下滚半页
  • gg: 跳至文件顶部
  • G: 跳至文件底部
  • M: 光标移至页中部
  • L: 光标移至页底部
  • H: 光标移至页顶部
  • 88gg: 跳至第 88 行
  • 88G: 跳至第 88 行
  • zz: 将当前行置于视图中央
  • zt: 将当前行置于视图顶部
  • zb: 将当前行置于视图底部
  • gd: 跳转到局部变量定义处
  • gD: 跳转到文件内全局声明(从文件开头开始查找)
  • gf: 跳转到相应的头文件
  • <C-o>: Normal 模式下返回上一个操作的位置, Insert 模式下切换到 Normal 模式, 输入完命令后再次进入 Insert 模式: c-o zz
  • <C-t>: Normal 模式下返回上一个操作的位置
  • <C-i>: Normal 模式下返回下一个操作的位置
  • <C-^>: 在当前文件与上次编辑的文件中快速切换
  • mm: 为当前位置在当前缓冲区内设置标记 m
  • 'm: 反撇号, 跳转到设置的标记 m
  • mM: 为当前位置设置全局标记 M(必须是大写, 可以跨文件使用)
  • 'M: 跳转到全局标记

复制/粘贴/删除

  • c: 删除并进入插入模式 (理解: cert , 会插入)
  • cw: 删除一个单词并进入插入模式
  • C: 删除自游标处到当前行尾, 并进入插入模式
  • c2c: 删除两行并进入插入模式
  • cc: 删除一行并进入插入模式
  • d^: 删除至行首 (理解: delete , 不会插入, 直接删除, 不会复制)
  • D: 从当前光标处删除至行尾
  • dw: 向右删除一个单词
  • d2d: 删除两行
  • dd: 删除一行
  • d121gg: 从当前行删除到 121 行
  • d121j: 从当前行向下删除 121 行
  • x: 删除本字符(等于 delete)
  • X: 向前删除一个字符(等于 backspace)
  • s: 删除右侧并进入插入模式
  • S: 删除整行并进入插入模式
  • yy: 复制一行
  • y$: 从光标当前处复制到结尾, 不会复制到换行符, 但是如果 v$y 则会复制到换行符
  • y: 复制所选(可视模式)
  • y5j: 向下复制 5 行
  • v/d/c/y + [文本对象]
    • 操作分隔符的文本对象: 用于确定范围
      • i(/[/{/"/': 由(/[/{/"/' 包围起来的字符, 不包含 (/[/{/"/'
      • a(/[/{/"/': 由 (/[/{/"/'包围起来的字符及包围符号本身
      • it: 由 tag 包围起来的字符
      • at: 由 tag 包围起来的字符及 tag 本身
    • 操作文本块的文本对象
      • iw: 当前单词
      • aw: 当前单词及一个空格
      • iW: 当前字串
      • aW: 当前字串及一个空格
      • is: 当前句子
      • as: 当前句子及一个空格
      • ip: 当前段落
      • ap: 当前段落记一个空行
    • 一般来说, d{motion} 命令和 aw, asap 配合起来使用比较好,而 c{motion} 命令和 iw 及类似的文本对象一起用效果会更好.
  • p: 如果整行复制, 粘贴在下方一行. 如果选中复制, 粘贴到当前光标后方
  • P: 与 p 方向相反
  • gp: 与p类似, 不过会把光标移动至文本的结尾
  • gP: 与 P类似, 不过会把光标移动到文本的结尾, 在粘贴多行的时候尤其有用

模式切换

  • i: 当前字符之前插入
  • I: 行首插入
  • a: 当前字符之后插入
  • A: 当前字符行尾插入
  • o: 在下方插入一行并进入Insert Mode
  • O: 在上方插入一行并进入Insert Mode
  • <C-v>: 进入列选择模式, 可沿垂直方向选中多行, 然后使用大写的 I 和 A 分别可以实现在前侧和后侧批量添加字符, 使用 > 可以向右缩进, 使用 r 可以替换, 特别好用!
  • v: 进入 visual 模式, 移动光标可进行批量选择删除
  • gv: 重复选择上次选择并操作的区域
  • O: 在 Visual 模式下切换高亮选取的活动端使之可调整

大小写/加减

  • ~: 将当前光标处的大小写翻转
  • g~5j: 将当前行向下 5 行大小写反转
  • gu5j: 将当前行向下 5 行改为小写
  • gU5j: 将当前行向下 5 行改为大写
  • gUit: 将 tag 包围的内容改为大写
  • Vu: 将当前行改为小写
  • VU: 将当前行改为大写
  • veu: 当前光标至尾端的字符改为小写
  • vG~: 将当前光标至文本结尾的字符翻转大小写
  • <C-a>: 对数字进行增加操作, 在列选择模式下批量增加数字, 对 Markdown 的列表排序特别好用
    • <C-v> + select + C-a: 将选择区域数字统一增加 1
    • <C-v> + select + 2 + C-a: 将选择区域数字统一增加 2
    • <C-v> + select + g + C-a: 将选择区域的数字改为递增为 1 的序列
    • <C-v> + select + 2 + g + C-a: 将选择区域的数字改为递增为 2 的序列
  • <C-x>: 对数字进行缩小操作(用法同C-a )

撤销

  • u: 撤销 undo(命令模式, 可多次撤销)
  • U: 无论当前行修改了多少次, 全部撤销操作
  • <C-r>: Normal 模式下反撤销
  • :undolist: 撤销历史(命令模式)
  • :undo 5: 撤销 5 个改变(命令模式)

Folding

  • zc: close, 关闭当前光标下可折叠区域
  • zo: open, 打开当前光标下可折叠区域
  • za: toggle, 打开/关闭当前光标下可折叠区域
  • zC/zO/zA: 与小写不同的是操作对象为全局, 与光标位置无关
  • zr: reduce, 整体减少折叠等级(与光标位置无关)
  • zR: 将所有折叠级别减值最小(直观看来就是缓冲区完全展开了)
  • zm: more, 整体增加折叠级别(与光标位置无关)
  • zM: 增加折叠级别至最高(直观看来就是缓冲区完全折叠了)
  • zd: 删除当前折叠
  • zE: 删除所有折叠
  • zj: 移动至下一个折叠
  • zk: 移动至上一个折叠
  • zn: 禁用折叠
  • zN: 启用折叠

window/tab

  • :tabnew [filename]: 新建一个标签页, 例: tabnew% 以当前文件新建一个标签页, % 表示当前文件
  • :tabclose: 关闭当前标签
  • :tabonly: 关闭所有其他的tab
  • :tabn: 前一个 tab
  • :tabp: 后一个 tab
  • tabdo %s/foo/bar/g: 在所有打开的 tab 上执行替换
  • tab ball: 将所有的缓冲区在 tab 中打开
  • gt: 跳转到下一个 tab
  • gT: 跳转到上一个 tab
  • gt5: 跳转到第 5 个 tab 上
  • :tabn: 移动至下一个标签, 直接使用 gt 也可
  • :tabp: 移动至上一个标签, 直接使用 gT 也可
  • :sp: 上下切割当前文件, 同 <C-w> s
  • :vs: 左右切割当前文件, 同 <C-w> v
  • :sp [filename]: 上下分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • :vs [filename]: 左右分割并打开一个新文件, 如果不输入 filename 会切割打开本文件(光标在文件开头位置)
  • <C-w> T: 如果当前 tab 存在多个不同的window, 那么将当前 window 移动到新标签上, 必须是大写
  • <C-w> s: 水平切割当前窗口
  • <C-w> v: 垂直切割当前窗口
  • <C-w> h/j/k/l: 光标向某个方向分屏移动
  • <C-w> w: 在所有窗口间进行切换
  • <C-w> _: 使窗口高度最大化
  • <C-w> |: 使窗口宽度最大化
  • <C-w> =: 使所有窗口等宽等高
  • <C-w> q: quit, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> c: close, 关闭当前分屏, 如果是最后一个, 则退出 vim
  • <C-w> o: only, 关闭所有除当前屏幕外的所有分屏
  • <C-w> L: 当前分屏向右移动
  • [N]<C-w> +: 分屏增加 N 列高度(可选)
  • [N]<C-w> <: 分屏减少 N 列宽度(可选)
  • :close: 关闭活动窗口
  • :only: 只留下当前活动窗口
  • new abc.txt: 在新窗口中编辑文件

Buffer

  • :ls: 显示当前所有 buffer(缓冲区列表)
  • :ls! : 列出非缓冲区列表文件
  • :bn: buffer next, 下一个 buffer
  • :bp: buffer previous, 上一个 buffer
  • :bf: 打开第一个 buffer
  • :bl: 打开最后一个 buffer
  • :b1: 切换到 buffer1(同理可按照数字切换到不同的 buffer)
  • :bd: 删除 buffer(并没有删除文件本身, 只是 buffer 而已)
  • :bd 1 3: 删除 buffer 编号为 1, 3 的两个 buffer
  • :bw 3 : 将非缓冲区文件全部删除
  • :bufdo [command]: 对所有缓冲区执行操作
  • :1,3 bd: 删除 buffer 编号在 1~3之间的所有 buffer

Tag

  • <C-]>: 跳转到当前光标的定义处
  • g<C-]>: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • g]: 查看当前光标处有多少个定义(可输入数字然后跳转)
  • tag {keyword}: 根据 keyworkd 查找有多少个匹配的 tag
  • tag: 正向遍历标签历史
  • tnext: 跳转到下一处匹配的标签
  • tprev: 跳转到上一处匹配的标签
  • tfist: 跳转到第一处匹配的标签
  • tlast: 跳转到最后一处匹配的标签
  • tselect: 提示用户从标签匹配的列表中选择一项进行跳转

Quick-list

  • :cnext : 显示当前页下一个结果
  • :cpre : 显示当前页上一个结果
  • :copen : 打开 Quickfix 窗口
  • :cfirst: 跳转到第一项
  • :clast: 跳转到最后一项
  • :cnfile: 跳转到下一个文件中的第一项
  • :cpfile: 跳转到上一个文件中的最后一项
  • :cc N: 跳转到第 n 项
  • :cclose : 关闭 Quickfix 窗口
  • :cdo {cmd}: 在 quickfix 列表中的每一行上执行 {cmd}
  • :cfdo {cmd}: 在 quickfix 列表上的每个文件上执行一次 {cmd}
  • :cl[ist] : 打开 location list 窗口, 目前看来不需要使用此选项

Location List

与 Quick-List 相似, 最大的不同是: Quick-List 是针对多个窗口共享一个结果, 而 Location List 则是各个窗口的结果互相独立

  • lopen: 用于打开位置列表窗口
  • lclose: 用于关闭位置列表窗口
  • lnext: 用于切换到位置列表中的下一项
  • lprevious: 用于切换到位置列表中的上一项
  • lwindow: 用于在错误出现时才触发位置列表窗口

  • q + 小写字母: 进入宏记录模式, 记录到小写字母寄存器中, 记录完成后再次按下 q 即可.
  • q + 大写字母: 进入宏记录模式, 在 小写字母寄存器尾部接着添加命令, 记录完成后再次按下 q 即可.
  • @ + 小写字母: 执行对应寄存器内的宏. 可使用前缀添加数字的方式重复多次命令
  • @:: 重复执行上一次运行过的命令, : 寄存器总是保存着最后执行的命令行命令
  • @@: 直接重复上一次的 @ 命令, 此命令必须建立在上一次使用了以 @ 开头的寄存器宏 或者 刚刚建立了一个寄存器宏的 基础上, 因此经常配合 @: 使用.
  • 10@a: 执行寄存器 a中所存储宏 10 次(串行处理, 如果有错误, 则立刻停止, 后续命令不再执行)

参数列表

参数列表与缓冲区的概念很类似, 参数列表的原始含义是我们在终端中使用 vim a.txt b.txt 时后面的一系列文件或参数名, 但是我们也可以在进入 vim 后使用 args手动添加参数文件. 其与缓冲区的区别是:

  1. 位于参数列表的文件必然位于缓冲区列表中
  2. 缓冲区列表永远是乱糟糟的, 但是参数列表永远是秩序井然
  • :args *.* : 将当前目录下的所有类型的文件加入到参数列表中(不包括文件夹中的文件)
  • :args **/*.* : 将当前目录下的所有文件及子文件夹的所有文件都匹配加入到参数列表中
  • :args *.md aa/**/*.md 表示添加子文件夹下的 md 文件及 aa 文件夹下的和其子文件夹下的 md 文件到参数列表中
  • :args 'cat list.txt': 用反撇号将命令包围起来, 然后将命令被执行后的结果作为参数加入参数列表中
  • :argdo %s/oldword/newword/egc | update : 对所有存在参数列表中的文件执行命令, s 代表替换, % 指对所有行进行匹配, g 代表整行替换(必用), e 指使用正则表达式, c 代表每次替换前都会进行确认, update 表示对文件进行读写
  • :argdo write: 将所有参数列表中的内容进行缓冲区保存
  • `:argdo normal @a`: 将当前参数列表的所有缓冲区执行寄存器 a 中所存储的宏
  • :argd * : 清空参数列表
  • :argdo bw : 将参数列表中的所有文件清除出缓冲区
  • :args: 显示当前的所有参数列表
  • :next: 跳转到下一个参数列表的文件
  • :prev: 跳转到上一个参数列表的文件
  • :first: 跳转到第一个参数列表的文件
  • :last: 跳转到最后一个参数列表的文件
  • :args **/*.md : 将当前文件夹下所有.md 文件加入到参数列表中(包括子文件夹中的文件)
  • :argdo %s/![.*]/![img]/gc: 将所有参数列表中的以 ![ 开头, 以 ] 结尾的所有字段改为 [img]
  • :argdo source FormatCN.vim: 对参数列表中的所有文件执行脚本 FormatCN.vim

命令行模式

  • :shell: 调用系统的 shell 来在 vim 进程中执行命令, 执行完使用 exit 退出
  • :term bash: 在底部分割出一个独立窗口并调用 bash, 也可以使用 term zsh 来调用 zsh, 或 :terminal zsh
  • <C-w> N: 在进入 :term 的终端模式后, 使用本命令可以获得 Normal 模式 的效果, 使用 i 返回正常的终端模式
  • :col<C-d>: 在 Ex 命令模式中使用补全查看可能的选项, 然后使用 Tab/S-Tab 进行选择/反向选择
  • <C-r><C-w>: 将当前的光标下的单词插入到命令行中
  • <C-f>: 将正在命令行中输入的内容放入到命令行窗口开始编辑
  • <C-c>: 与 <C-f> 相反, 此命令可以使命令行窗口的当前行内容从命令行窗口放回到命令行中
  • <C-z>: 在终端中将 vim 最小化, 然后如果再需要调用的话使用 fg 进行操作, 使用 jobs 查看所有处于后台的工作
  • <C-b>: beginning, 在命令行模式中跳转到行首
  • <C-e>: end, 在命令行模式中跳转到结尾
  • <C-p>: 在命令行模式中显示上次的命令
  • <C-n>: 在命令行模式中显示下次的命令
  • :!!: 重复执行上一次运行过的命令
  • :!<command>: 在 shell 中执行命令
  • !sh %: 将当前文件所有行作为输入使用外部程序 sh 执行, % 代表本文件所有行
  • !!<command>: 运行命令并将结果作为当前行的内容, 同 :read !<command>
  • :read !<command>: 将命令的结果输入(重定向)到当前缓冲区
  • :!ls: 显示当前工作目录下的所有文件(此操作属于调用系统进程, 使用!来调用系统操作是 Vim 的一大特点)
  • :[range]write !sh: 将当前缓冲区的内容, 在 shell 中逐行执行, 与 read !<command>作用正好相反, !表示外部程序
  • :[range]write ! sh: 将当前缓冲区的内容, 在 shell 中逐行执行, !表示外部程序
  • :[range]write! sh: 将当前缓存区内容写入到一个名为 sh 的文件, !表示强制覆盖式写入
  • :[range]write! filename: 将当前缓冲区内容另存为到 filename 文件中
  • :.,$ sort [option]: 从当前行到末尾进行排序
    • !: 翻转顺序, 默认小在前, 翻转后大在前
    • i: 忽略大小写
    • l: …
    • n: …
    • o: …
    • r: …
    • u: …
    • x: …
  • :2,$ !sort -t',' -k2: 使用外部 sort 程序进行排序, 以 , 为分隔符, 以第二项进行排序
  • :w !sudo tee % > /dev/null: 在当前用户没有权限对当前文件做操作时使用超级管理员身份进行操作
  • :ls: 列出当前所有的缓冲区文件列表, 执行的是 vim 的 ls 命令
  • :f: 显示当前文件路径, (使用了 <C-g> 代替, 此项基本不会用了)
  • :command: 显示当前所文件的所有可使用命令
  • :retab : 重新生成所有的 tab(主要用于在 .vimrc 中重新设置了 tab 格式, 然后在已存在旧格式 tab 的文档进行重生成)
  • :map g: 查看所有以 g 开头的映射

Vim 的先祖是 vi, 正是 vi 开创了区分模式编辑的范例. 相应的, vi 奉 一个名为 ex 的行编辑器为先祖, 这就是为什么会有 Ex 命令.

Ex 命令在命令行模式中执行, 而命令行模式的进入方式为 : 键, 因此我们可以看到所有的 Ex 命令都是以 : 开始的, 输入完命令后按下确定键 <CR> 即可执行, 虽然 Ex 命令年代久远, 但是不可否认其语法的简洁明了以及高效, 很多复杂的操作往往都是通过 Ex 命令来进行处理.

  • :[range] <command> [target]: 执行命令并将结果放入目标位置
    • :3,5 w !bash: 将 3~5 行写入 bash
    • :. w !bash: 将当前行写入 bash
    • :. !bash: 将当前行执行结果写入当前 buffer
    • :3,5 delete x: 将当前行执行结果删除到 x 寄存器
    • :.,$delete x: 将当前行到文件结尾的所有内容删除
    • :3,5 yank x: 将当前行执行结果复制到 x 寄存器
    • :. put x: 在当前行后粘贴寄存器 x 的内容
    • :3,5 copy .: 将 3~5 行复制到当前行下
    • :3,5 move .: 将 3~5 行移动到当前行下
    • :3,5 join: 将 3~5 行进行合并
    • [range] normal [cmd]: normal 用来指定在 normal 模式下对文本的操作命令
      • :3,5 normal .: 对 3~5 行执行 . 重复命令
      • :3,5 normal 对 3~5 行执行寄存器q` 内存储的命令
      • `'<,’> normal @a`: 在所选高亮区域上执行宏(如果有错误也不停止, 因为是针对每一行执行的, 出错了只需要不处理那一行就行了)
    • :[range] global/{pattern}/[cmd]: 对指定范围内匹配的所有行执行 Ex 命令
      • :g/re/d: 删除所有匹配到 re 的行
      • :g/re/p: 打印所有匹配到 re 的行
      • :g//d: 使用上次的查找结果进行匹配然后删除
      • :v/re/d: vglobal 的反面, 只保留匹配到 re 的行
      • :g/TODO/yank A: 将结果匹配到 TODO 的行复制到寄存器 a 的原内容尾部
      • :g/TODO/t$: 将结果匹配到 TODO 的行复制到本缓冲区的尾部
      • :g:/{pattern}/[range][cmd]: 可以用 :g/{pattern} 匹配作为参考点, 动态设置 [cmd 的 range
      • g/{/ .+1,/}/-1 sort: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行排序
      • g/{/sil .+1,/}/-1 >: 会在每个 { 开始找, 然后在之后一直执行到 } 为止, 进行缩进(加入 sil 是为了屏蔽提示信息)
      • g/从这里删除/ .,$ d: 从内容中搜出的第一个 从这里删除 开始, 一直删除到文章结尾
    • :3,5 s/{pattern}/{string}/[flags]: 将 3~5行进行相应替换
    • :3,5 join: 将 3~5行进行合并
    • :3 p: 打印第 3 行
    • :3,5 p: 打印 3~5 行
    • :.,.+3 p: 打印本行以下的三行内容, +3 代表偏移
    • :% p: 打印本 buffer 的所有行, % 代表所有行, 是 1:$ 的简写
    • :0,$ p: 打印本 buffer 所有行, $ 代表最后一行
    • :.,$ p: 打印本 buffer 内从本行到结尾的所有内容, . 代表当前行
    • /<html>/+1,/</html>/-1 p: 使用 patten 指定范围, +1 表示偏移
    • :6t.: 把第 6 行复制到当前行下方, tail 代表尾巴, 遵守 from...to... 的含义
    • :t6: 把当前行复制到第 6 行下方, *. 位于首位时可以省略 . *, 因此全称是 :.t6
    • :t.: 粘贴当前行到下方, 与 yyp 不同的是本方式不会将内容放到寄存器中, 而 yyp 会将内容复制到 unname 寄存器与 0 寄存器
    • :t$: 粘贴当前行到文本结尾
    • :'<,'>t0: 把高亮选中的行复制到文件开头, '< 代表高亮选取的第一行, '> 代表高亮选取的最后一行
    • :'<,'>m$: 把高亮选中的行移动到文件结尾
    • :'<,'>A;: 把当前文件的所有行的尾部加上 ;

Insert 模式

  • <C-p>: 选择上方补全
  • <C-n>: 选择下方补全
  • : 退出插入模式(推荐)
  • <C-c>: 退出插入模式
  • <C-[>: 退出插入模式
  • <C-u>: 向左删除到行首
  • <C-w>: 向左删除一个单词
  • <C-h>: 向左删除一个字符
  • <C-t>: 整行向右偏移
  • <C-d>: 整行向左偏移
  • <C + r>= <function>: 进行计算并将结果输出到当前缓冲区中
  • <C-v>065: 输入大写字母 A
  • <C-v>u{123}: 按照 unicode 码以 10 进制来输入
  • <C-v>u{1234}: 按照 unicode 码以 16 进制来输入
  • <C-v> <Tab>: 无论 expandtab 选项是否开启都会插入制表符
  • 插入模式中的粘贴操作参考这里

路径

vim 的工作路径是使用中要格外注意的地方, 简单来说, 终端中的 vim 默认会把终端当前的路径作为其工作路径, 当然我们可以使用 cd 使其工作路径变更

  • :cd [path]: 设置此次vim的工作目录为path
  • :cd %:h: cd 到当前缓冲区所属目录中
  • :cd ../: cd 到上一级
  • :pwd: 显示当前工作路径
  • :lcd [path]: 设置当前窗口的工作目录为 path(与 cd 不同的是只会改变当前 window 的工作路径, 其他 window 的不受此影响)

vim 为我们提供了一些可以使用的宏用来表示相关路径或文件名称:

  • %:h: 表示当前文件所在目录的相对工作目录路径(不含文件名及扩展)
  • %:p: 表示当前文件所在目录的绝对路径(含文件名及扩展)
  • %:t: 文件名及扩展
  • %:r: 移除扩展之后的所有内容
  • %:e: 扩展名

在使用以上这几种宏时, 我们可以使用 <Tab> 使其自动展开, 有些命令不支持自动展开的话需要使用 expand() 命令

  • echo expand('%:e'): 打印当前文档扩展名, markdown 是 md
  • cd %:h<Tab>: cd 到当前缓冲区所属目录中, 在最后可以使用 <Tab> 进行自动展开
  • e %<Tab>: 会自动扩展为当前文件含相对工作目录的路径全名

寄存器

寄存器是 vim 的一种特有概念, 其他文本编辑器默认都会用系统剪贴板作为复制粘贴的根据地, 然后 vim 另辟蹊径使用多种不同类型寄存器作为临时内容存储位置. 我们可以在复制粘贴时使用指定的寄存器定制化我们的需求, 也可以在录制宏及使用宏时指定寄存器, 大大地提高了我们的工作效率.

很多刚使用 vim 的人会抱怨无法复制内容到 vim 外或 vim 内, 然后各种搜索如何使 vim 的默认复制操作与剪贴板交互, 最后定义了一大堆按键, 譬如 "*y, set clipboard=unnamed, 其实大可不必, 寄存器是 vim 的高效操作方式之一, 接受了这种方式才能更好地利用 vim 来为我们服务(虽然刚开始适应的过程必然是痛苦的)

总的来说 Vim 的删除, 复制与粘贴命令以及定义宏时都会用到众多寄存器中的某一个. 可以通过给命令加 "{register} 前缀的方式指定要用的寄存器. 若不指明, Vim 将缺省使用无名寄存器

  • 无名寄存器

    所有删除复制粘贴操作如果不显示指明寄存器类型的话使用的都是无名寄存器, 其标志符是 "".

  • 复制寄存器

    使用 y 复制后内容会被放到复制寄存器及无名寄存器中, 但是复制寄存器是稳定的, 无名寄存器的内容会时刻被重置替换. 其标志符是 "0

  • 粘贴板寄存器

    用于与系统的其他应用中进行复制粘贴交互, 等于系统的剪贴板. 其标识符是 "*(或 "+)

  • 黑洞寄存器

    所有放入黑洞寄存器的内容全部被丢弃, 相当于完全删除, 不留痕迹, 其标识符是 "_

  • 有名寄存器

    以单个小写字母命名的寄存器, 可用于自定义存储空间, 一共有 26 个

  • 特殊寄存器

    • "%: 当前文件名
    • "#: 轮换文件名
    • ".: 上次插入的文本
    • ":: 上次执行的 Ex 命令
    • "/: 上次查找的模式

使用方式

  • ""p: 从无名寄存器中取值进行粘贴
  • "ay: 将内容复制到有名寄存器 a
  • "_y: 将内容复制到黑洞寄存器, 相当于彻底地删除
  • "ap: 从自定义寄存器中取出内容进行粘贴
  • "0p: 从复制寄存器中取出内容进行粘贴, 默认的 p 是从无名寄存器取值
  • "*p: 从系统粘贴板寄存器中取出内容进行粘贴
  • <C-r>": 在插入模式中将无名寄存器的内容粘贴进来
  • <C-r>*: 在插入模式中将系统粘贴板寄存器的内容粘贴进来
  • <C-r>0: 在插入模式中将复制寄存器的内容粘贴进来
  • <C-r>%: 插入当前文件名(因为 “% 寄存器中存储了当前文件名)
  • :reg a: 查看有名寄存器 a 的内容
  • :reg *: 查看粘贴板寄存器 * 的内容
  • :reg ": 查看无名寄存器 " 的内容
  • :put a: 将有名寄存器 a 的内容粘贴到当前缓冲区中, 与 "ap 不同的是 p 用于只能在光标之前或光标之后进行粘贴, 但是 put 则会始终将内容粘贴到新的一行上
  • :d a: 将内容删除到有名寄存器 a
  • :let, 'iphone', 'iPhone', 'g'): 对寄存器 0 的内容进行替换处理然后再赋值到寄存器 q
  • `:let @*=@0`: 将粘贴寄存器内容赋值到系统剪贴板寄存器

使用 Visual Mode 时, 在选中的文本上使用 p 将直接替换该部分文本(替换后被替换的文本会被放入到无名寄存器中), 可用于解决需要删除然后粘贴但是会影响到无名寄存器的问题

vimdiff

神级编辑器 Vim 使用-操作篇

git 与 vim 可以说是非常好的一对搭档了, 平时在终端中提交 commit 我们都少不了与 vim 打交道, vimdiff 是 vim 提供的专门用于修正 git 冲突文件的一款工具

若想使用 vimdiff 作为冲突修改工具, 需要设置 ~/.gitconfig 的以下项

[diff]     tool = vimdiff [merge]     tool = vimdiff

在 vimdiff 中, 一共有四个窗口, 上面依次是 LOCAL, BASE, REMOTE, 底部则是一个最终的文件结果窗口, 整个过程我们只需要将光标在最下方窗口上上下移动, 使用 diffget 命令从 LOCAL, BASE, REMOTE 中选择需要使用哪一个作为本行的最终结果(当然也可以跳到上面的窗口中使用 diffput 放置结果到底部窗口上

  • :diffget LOCAL: 选择 LCOAL 作为本行最终结果
  • :diffget REMOTE: 选择 REMOTE 作为本行最终结果
  • :diffget BASE: 选择 BASE 作为本行最终结果
  • :diffput [num]: 放置结果到缓冲区上, num 为缓冲区编号
  • :diffg L: 这里 vim 为我们做了简略命令, 同样可用于 REMTOEBASE
  • dp/do: 如果只有两个文件则可以使用 dp/do 来替代 :diffput/:diffget
  • :ls!: 显示当前所有缓冲区的号码
  • [c: conflict, 移动到上一个冲突处
  • ]c: conflict, 移动到下一个冲突处
  • :wqa: 冲突修复完成保存退出, 如果仍然有文件冲突则进入下一个冲突
  • $git merge --continue: 冲突全部解决完后在外界终端中使用 git merge --continue 继续之前的 merge 操作

最后

本文作者 Hanley Lee, 首发于 闪耀旅途, 如果对本文比较认可, 欢迎 Follow

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 神级编辑器 Vim 使用-操作篇求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们