VSCode 神兵策!--Vim篇(基础版)

1,352 阅读10分钟

该篇是 VS Code 系列文章的 Vim 基础篇,属于 VS Code + Vim 三篇子系列中的第一篇,另两篇分别是《VS Code 神兵策!--Vim篇(加强版)》、《VSCode 神兵策!--Vim篇(指令版)》。本篇主要介绍 Vim 的操作逻辑和基本应用。

划水

Vim 是啥?

装 B 神器 无出其右!有点难度,不过忍一下就过去了。一个星期的自我训练换时不时装 B,值!

有点复杂,怎么下手?

Vim 乱七八糟的概念确实有点多,但是有必要全搞懂吗?没必要啊!装个 B 而已,何必认真?

大家都是程序员,用日常熟悉的概念解读 Vim 岂不是事半功倍

下面我先按程序员思维对操作方法进行一个简单分类,一看秒懂:

  • 操作函数: 比如复制、删除、修改、粘贴,以下简称函数
  • 快捷函数: 就是预设了数量及参数的函数,快捷函数不再接受数量及参数,以下简称快捷
  • 高阶函数: 就是使用函数作为参数的函数。例如: 宏、寄存器、标注。
  • 操作范围: 比如字符、单词、行、段落、上半屏、下半屏、全文等等,以下简称参数
  • 操作数量: 比如要复制3个字,这里的3就是操作数量,以下简称数量
  • 切换方法: 仅用于切换状态,没有任何操作类型、操作数量。

插件安装

这里我选择 Vim 安装

image.png

其他选择也有:VSCode Neovim 安装 不过体验一段时间后,又切换回去了,想用的可以自己试试。

还有啥交代?

因为咱们的核心目的是VS Code 中流畅的使用 Vim,所以与 Linux 环境下的 Vim 操作有所不同,需要一些自定义配置,如果各位有仙人觉得 Vim 含量不纯了,OK,出门请右转!

正文

操作数量

操作数量不能单独使用,必须配合操作类型、操作函数使用, 通常可以与函数调换位置。操作数量在普通模式、视图模式均可使用。案例如下:

  • 2b: 往前跳转2个单词,单词开头
  • 2e: 往后跳转2个单词,单词尾部
  • 3x: 删除3个字符
  • 2dd: 删除2行
  • d2j: 删除光标所在行及下面2行

注意:

关于数量与函数的调换,d2d2dd 是等价的,dd2 是无效的,请仔细斟酌。

操作范围

字符

  • h: 光标左移
  • j: 光标下移
  • k: 光标上移
  • l: 光标右移

单词

  • w: (word)到下一个单词开头,不忽略符号
  • W: (word)到下一个单词开头,忽略符号
  • e: (end)到本单词尾部或下一单词结尾,不忽略符号
  • E: (end)到本单词尾部或下一单词结尾,忽略符号
  • b: (begin)到上一个单词开头,不忽略符号
  • B: (begin)到上一个单词开头,忽略符号
  • ge: (goto end)到上一单词结尾
  • gE: 到上一单词结尾,忽略符号

  • 0: 到行首
  • ^: 移动到行首第一个非空字符
  • H:移动到行首第一个非空字符(自定义)
  • $: 移动到到行尾
  • L:移动到行尾(自定义)
  • gg: 到第一行
  • G: 到最后一行
  • 数字G: 跳转到指定数字行,如20G即跳到第20行
  • 数字回车: 向后跳转数字行
  • f字符: 快速定位到行内指定字符(向后找)
  • F字符: 快速定位到行内指定字符(向前找)
  • -: 向上移动一行
  • +: 向下移动一行

段落

  • (: 上一段落
  • ): 下一段落

页面

  • H: 页头
  • L: 页尾
  • M: 页中
  • {: 向上翻一屏(自定义)
  • }: 向下翻一屏(自定义)
  • [: 向上翻半屏(自定义)
  • ]: 向上翻半屏(自定义)
  • zt: 快捷,将光标所在行切换到页面的顶部
  • zb: 快捷,将光标所在行切换到页面的底部
  • zz: 快捷,将光标所在行移动到屏幕的中间

普通模式 --NORMAL–

函数

复制 y:前参、后参

  • y2ge: 向左复制不含光标共2个词
  • y2h: 向左复制不含光标共2个字
  • y3l: 向右复制含光标共3个字
  • y5l: 复制含光标共5个字
  • y1j: 复制含光标行及下一行
  • y2k: 复制含光标行及上2行
  • y3w: 复制含光标单词及后续共3个单词
  • y$: 复制含光标到行尾
  • y^: 复制不含光标到行首
  • yw: 复制一个单词
  • yaw: 复制整个单词
  • ye: 复制光标后一个单词
  • yb: 复制光标前一个单词
  • yj: 复制下一行内容
  • y2j: 复制下2行内容
  • yk: 复制上一行内容
  • y3k: 复制上3行内容
  • y$: 复制到行尾,含光标处
  • y^: 向前复制至行首空字符处,不含光标
  • y0: 复制到行首,不含光标处
  • y(: 复制上一段落
  • y): 复制下一段落
  • yG: 复制到结尾
  • ygg: 复制到开头

大写 Y:快捷,复制光标所在行。

  • 4Y:复制4行,不存在 Y4

删除块 d:前参、后参

小写 d:删除指定内容块。案例如下:

  • d1j: 删除光标所在行及下一行
  • dd: 删除光标所在行
  • dw: 删除光标处开始至单词结尾。例如:单词"password",光标停在w上按dw后剩下"pass"
  • diw: 删除光标处的整个单词。例如:单词"password",光标停在d上按diw后剩下""
  • di符号: 删除光标处符号范围内全部内容。例如"your password",光标停在r上按di"后剩下""
  • da符号: 删除光标处符号范围内连同符号。例如:input “your password”!,光标停在r输入da"剩下input!

大写 D:快捷,删除光标至行尾内容块。

删除字符 x:仅前参

小写 x,向右删除字符,相当于del键。案例如下:

  • 3x: 向右删除含光标共3个字符

大写 X,向左删除字符,相当于Backspace键。案例如下:

  • 2X: 删除光标前面2个字符

删除字符 s:仅前参

小写 s 删除当前光标的字符,并进入 insert 模式

  • 3s: 删除含光标共3个字符,并进入 insert 模式

大写 S 删除当前光标所在并进入insert模式

  • 3S: 删除含光标共3,并进入 insert 模式

删除换行 J

  • J: 快捷,删除当前行行尾的换行符

插入换行 K

  • K: 快捷,在光标前插入换行符并进编辑模式(自定义)

编辑块 c:前参、后参

编辑 c :删除指定内容块后进编辑模式。案例如下:

  • ck: 删除光标所在行及上一行
  • cj: 删除光标所在行及下一行
  • cw: 删除光标处开始的一个单词
  • ce: 删除光标处开始的一个单词
  • ciw: 删除光标处开始的整个单词
  • caw: 删除光标处开始的整个单词连外面的符号
  • ci符号:删除光标所在行符号包裹范围内的内容,如编辑函数的参数时使用(光标不需要在符号范围内)
  • ca符号:删除光标所在行,符号包裹范围包括符号的内容(光标不需要在符号范围内)
  • cb: 删除光标前一个单词
  • cc: 删除整行
  • 3cc: 直接删3行
  • c$: 删除到行尾,含光标处
  • C: 删除至行尾
  • c^: 向前删除至行首空字符处,不含光标
  • c0: 删除到行首,不含光标处
  • c(: 删除上一段落
  • c): 删除下一段落
  • cG: 删除到结尾
  • cgg: 删除到开头

大写 C:快捷,删除含光标至行尾内容块后进编辑模式。

编辑字符 s:仅前参

小写 s:删除含光标处字符进编辑模式。案例如下:

  • s: 删除光标处字符进编辑模式
  • 5s: 删除含光标处及之后共计5个字符进编辑模式

大写 S:快捷,删除光标所在行后进编辑模式。

粘帖 p:仅前参

小写 p:在光标后粘贴内容。案例如下:

  • p: 将剪贴板中的最新内容复制一份到光标后面。
  • 3p: 将剪贴板中的最新内容复制三份到光标后面。

大写 P:在光标前粘贴内容,用法和小写p一致。

替换 r:仅前参

小写 r:替换光标处字符。案例如下:

  • r: 将接下来一次的输入替换光标处的那个字符(中文输入一个词也算一次输入)。对“123”的1按r然后输入中文词“中国人”,结果是“中国人23”
  • 2r: 将接下来的一次输入替换含光标向右的2个字符(中文输入一个词也算一次输入)。对“123”的1按2r然后输入中文词“中国人”,结果是“中国人中国人3”

大写 R:进入替换模式,用所有输入内容替换原内容

撤销与反撤销 u

  • u: 快捷,撤销最近一次修改
  • 数字u: 撤销最近数字次修改

重复执行 .

  • .: 快捷,最后一次操作重复执行一次
  • 数字.: 最后一次操作重复执行数字次

字母大小写切换 ~

  • ~: 切换将光标所在位置的字符大小写互换(shift+1左边的符号)
  • 3~: 将光标开始的3个字符大小写互换(shift+1左边的符号)
  • g~: 切换当前行字母的大小写
  • gUU: 将当前行的字母换成大写
  • gUaw(gUiw): 将光标处的单词换成大写
  • guaw(guiw): 将光标处的单词换成小写
  • gUa符号(gUi符号): 将光标所在行,符号包裹范围内的内容换成大写(光标需要在符号范围内)
  • gua符号(gui符号): 将光标所在行,符号包裹范围内的内容换成小写(光标需要在符号范围内)
  • 可视模式下,选中字母后,按 U 将其换成大写
  • 可视模式下,选中字母后,按 u 将其换成小写

行内查找字符 F

  • f{char}: 光标到下个{char}
  • F{char}: 光标到上个{char}
  • ;: 继续找
  • ,: 反向找

行内查找字符 T

  • t{char}: 光标到下个{char}前
  • T{char}: 光标到上个{char}前
  • ;: 继续找
  • ,: 反向找

高阶函数

宏定义 q

录制

q字母,然后操作键盘,操作结束后再按 q 即表示宏录制完毕。例如:

  • qai123,再按 <Esc>q
播放

@字母,重复宏记录的键盘操作。例如:

  • @a,就可以执行输入 i123,结果就是在光标处插入了123

寄存器 "

存入

"小写字母<y、d、x>:将 ydx 的内容存入寄存器。例如:

  • "ayk: 将当前行及上1行内容存入 a 寄存器
取出

"字母<p或P>: 将寄存器内容取出。例如:

  • "ap: 将 a 寄存器内容粘贴到光标后面

标注 m

m字母,记录当前光标的位置。例如:

  • 现在光标在第10行,按mc,记录下当前位置。
标注

标注位置后,进行翻页、跳转、移动光标,再按 '字母,光标会迅速跳回到之前记录的位置。例如:

  • 输入 gg,光标回到第1行,再按 'c,光标会回到第10行。

重复输入

  • 先输数字再按 i 再按 <Esc> 可以快速输入重复内容
  • 先按5,再按 i ,再输入 abc,再按 <Esc> ,相当于快速输入5个 abc

命令模式

全文查找

  • /{string}: 光标到下个{string}
  • ?{string}: 光标到上个{string}
  • n: 继续找
  • N: 反向找
  • :noh:取消高亮

全文替换

  • :%s/word1/word2/g: 全文直接将word1替换成word2
  • :%s/word1/word2/gc: 全文直接将word1替换成word2,替换前会询问
  • :1,$s:从第一行到最后一行
  • :10,20:从第10行到第20行
  • :10,20s#^#//#g:在 10 - 20 行添加 // 注释
  • :10,20s#^//##g:在 10 - 20 行删除 // 注释
  • :10,20s/^/#/g:在 10 - 20 行添加 # 注释
  • :10,20s/#//g:在 10 - 20 行删除 # 注释

使用正则表达式

把文中的所有字符串“abc……xyz”替换为“xyz……abc”可以有下列写法

# 在 VS Code 中操作
:%s/abc(.*)xyz/xyz\1abc/g
:%s/(abc)(.*)(xyz)/\3\2\1/g

关于在 Vim 中使用正则表达式的更多细节,请看我的《Vim 神兵策!--正则表达式》

可视模式 --VISUAL–

进入可视模式后按 v<Esc> 键可还原到普通模式

  • 字符选择模式,小写 v
  • 行选择模式,大写 V
  • 块选择模式,(自定义 // )

移动

  • h: 光标左移
  • j: 光标下移
  • k: 光标上移
  • l: 光标右移
  • o:切换选择区域的活动端点

其他可用函数

  • y:复制
  • p:粘贴
  • d:删除
  • x:删除字符

模式切换

替换模式切换 --Replace–

  • r: 替换光标所在字符
  • R: 进入替换模式

插入模式切换 --INSERT–

insert

  • i: 在光标前插入
  • I: 在行首插入

append

  • a: 在光标后插入
  • A: 在行尾插入

other line

  • o: 在下一行插入
  • O: 在上一行插入

change

  • c: 删除字符后进插入模式
  • C: 删除光标处至行尾进编辑模式

leader 快捷键(自定义)

  • 空格+u: 还原最近一次的撤销,这个和普通模式下u的逆操作。(等价于ctrl+z撤销,ctrl+shift+z取消撤销)
  • 空格+/: 当前页查找字符串跳转(原来是2个空格+/)
  • 空格+s: 当前页查找字符跳转(原来是2个空格+s)
  • 空格+p: 复制一行

vim 插件设置

我禁止 vim 使用 ctrl,因为 vscode 本身有大量快捷键用了 ctrl。为此另外增加了许多 leader 快捷操作。

"vim.leader": "<space>", // 绑定vim前导键
"vim.easymotion": true, // 启用easymotion插件
"vim.incsearch": true,
"vim.useSystemClipboard": true, // 是否启用系统粘贴板作为vim寄存器
"vim.useCtrlKeys": false, // 是否由vim接管ctrl+any的按键
"vim.hlsearch": true, // 是否突出显示与当前搜索匹配的所有文本
"vim.highlightedyank.enable": true, // 被复制时是否高亮
"vim.highlightedyank.duration": 500, // 被复制时高亮持续时间:0.5秒
// 命令模式下的非递归案件绑定 相当于norecmap
"vim.commandLineModeKeyBindingsNonRecursive": [],
// 插入模式下的非递归按键绑定 相当于 imap
"vim.insertModeKeyBindings": [],
// 可视模式下的非递归按键绑定
"vim.visualModeKeyBindings": [
    { // 粘贴不替换文本
      "before": [
        "p"
      ],
      "after": [
        "P"
      ]
    },
    ],
    // 普通模式下非递归绑定按键 相当于 vim 中的 noremap
    "vim.normalModeKeyBindingsNonRecursive": [
    { // 屏幕『向上』移动一页
      "before": [
        "{"
      ],
      "after": [
        "<C-b>"
      ]
    },
    { // 屏幕『向下』移动一页
      "before": [
        "}"
      ],
      "after": [
        "<C-f>"
      ]
    },
    { // 屏幕『向上』移动半页
      "before": [
        "["
      ],
      "after": [
        "<C-u>"
      ]
    },
    { // 屏幕『向上』移动半页
      "before": [
        "]"
      ],
      "after": [
        "<C-d>"
      ]
    },
    { // 断行并进入编辑状态
      "before": [
        "K"
      ],
      "commands": [
        "lineBreakInsert"
      ],
      "silent": true
    },
    { // 进入块选择模式
      "before": [
        "\\",
      ],
      "commands": [
        "extension.vim_ctrl+v"
      ]
    },
    { // 取消最近的撤销 等价于ctrl+z撤销,ctrl+shift+z取消撤销
      "before": [
        "<leader>",
        "u"
      ],
      "after": [
        "<C-r>",
      ]
    },
    { // 取消最近的撤销
      "before": [
        "U"
      ],
      "commands": [
        "undo"
      ]
    },
    { // 全屏查找字符串
      "before": [
        "<leader>",
        "/"
      ],
      "after": [
        "<leader>",
        "<leader>",
        "/"
      ]
    },
    { // 全屏查找字符串
      "before": [
        "<leader>",
        "s"
      ],
      "after": [
        "<leader>",
        "<leader>",
        "s"
      ]
    },
    { // 复制一行
      "before": [
        "<leader>",
        "p"
      ],
      "after": [
        "y",
        "y",
        "p",
      ]
    },
    { // 保存
      "before": [
        "<leader>",
        "w"
      ],
      "commands": [
        "workbench.action.files.save"
      ]
    },
    { // 退出编辑 关闭当前编辑窗口
      "before": [
        "<leader>",
        "q"
      ],
      "commands": [
        "workbench.action.closeActiveEditor"
      ]
    },
    { // 移动到当前行第一个非空字符的位置
      "before": [
        "H"
      ],
      "commands": [
        "cursorHome"
      ]
    },
    { // 移动到当前行最后一个非空字符的位置
      "before": [
        "L"
      ],
      "commands": [
        "cursorEnd"
      ]
    },
],

结语

本文主要以程序员视角介绍了 VS Code 中使用 Vim 的基本方法,重点是如何通过配置让操作变得更加丝滑。但实际上,你在实际使用中依然还有一些操作不便的地方,比如中英文的切换、折叠代码移动会自动展开等问题。由于篇幅问题,这些问题我将在下一篇章进行讲解,敬请期待!

引用

本篇文章内容大部分来源于网络,因为内容基本都是最基础的指令,几乎大同小异。重点是能够帮助大家快速掌握 Vim 并在 VS Code 中实践起来,早日走上装 B 之路。