惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
雷峰网
雷峰网
GbyAI
GbyAI
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
V
V2EX
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Engineering at Meta
Engineering at Meta
T
Tenable Blog
P
Privacy & Cybersecurity Law Blog
Project Zero
Project Zero
Cloudbric
Cloudbric
Help Net Security
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LINUX DO - 热门话题
J
Java Code Geeks
WordPress大学
WordPress大学
S
Securelist
F
Full Disclosure
N
News and Events Feed by Topic
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
I
InfoQ
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
U
Unit 42
Google Online Security Blog
Google Online Security Blog
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
月光博客
月光博客
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
小众软件
小众软件
V2EX - 技术
V2EX - 技术
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
The Last Watchdog
The Last Watchdog
D
DataBreaches.Net

szhshp 的第三边境研究所

假设, AI 把我代替的那一刻真的到来 | szhshp 的第三边境研究所 小傻瓜都能懂的 AstrBot QQ 机器人集成 MCP 功能实战指南 | szhshp 的第三边境研究所 《智人之上: 从石器时代到 AI 时代的信息网络简史》阅读笔记 | szhshp 的第三边境研究所 iPadOS 26 无法设置空间场景图片壁纸的解决方法 | szhshp 的第三边境研究所 《一路云海》(终) | szhshp 的第三边境研究所 《一路云海》(四): 如何不按套路旅行 | szhshp 的第三边境研究所 《一路云海》(三): In Ya Mellow Tone | szhshp 的第三边境研究所 《一路云海》(二): 关西世博参观纪实 | szhshp 的第三边境研究所 《一路云海》(一): 新的征程 | szhshp 的第三边境研究所 2025 大阪世博会 [ 3 天前-先到先得 ] 阶段 场馆预约必中独家攻略 | szhshp 的第三边境研究所 Hackathon 随想 | szhshp 的第三边境研究所 一杯双皮奶 | szhshp 的第三边境研究所 Armbian + CasaOS + NAS 配置指南 | szhshp 的第三边境研究所 Docker 构建镜像报错: error getting credentials - err: exit status 1, out: `` | szhshp 的第三边境研究所 Disqus RIP! 论过高的维护成本如何治疗固执的坏习惯 | szhshp 的第三边境研究所 炸弹猫桌游变体规则 | szhshp 的第三边境研究所 《小岛经济学》阅读笔记 | szhshp 的第三边境研究所 《金钱心理学》阅读笔记 | szhshp 的第三边境研究所 为知笔记 RIP: 迁移剩余的笔记 | szhshp 的第三边境研究所 2025 博客第十年展望 - 再见我的过去 | szhshp 的第三边境研究所 我在独立游戏里面致敬的作品 | szhshp 的第三边境研究所 《How to make thing faster》阅读笔记 | szhshp 的第三边境研究所 《The Art of Clean Code》阅读笔记 | szhshp 的第三边境研究所 《Clean Architecture: A Craftsman Guide to Software Structure and Design》阅读笔记 | szhshp 的第三边境研究所 《How AI Works》阅读笔记 | szhshp 的第三边境研究所 游戏策划废案 - Project Uranus | szhshp 的第三边境研究所 游戏策划废案 - Project X | szhshp 的第三边境研究所 人生第一款独立游戏开发复盘 | szhshp 的第三边境研究所 Trap of Life | szhshp 的第三边境研究所 如果我用手搓了个暗物质雏形 | szhshp 的第三边境研究所 《Rust Programming Language》- EX - Cheatsheet | szhshp 的第三边境研究所 新的播放器上线了 | szhshp 的第三边境研究所 Cypress - End-to-End Testing: OKTA Authentication with MFA | szhshp 的第三边境研究所 两小时 Docker 速成 - Getting Started | szhshp 的第三边境研究所 《The Joy of Javascript》- 5 - Data | szhshp 的第三边境研究所 《The Joy of Javascript》- 4 - Meta Programming | szhshp 的第三边境研究所 《The Joy of Javascript》- 3 - ADT(Algebraic Data Type) | szhshp 的第三边境研究所 Web-Automation Testing | szhshp 的第三边境研究所 《The Joy of Javascript》- 2 - Functor/Monad | szhshp 的第三边境研究所 《The Joy of Javascript》- 1 - Object/Function | szhshp 的第三边境研究所 EvalError: Possible side-effect in debug-evaluate | szhshp 的第三边境研究所 前端 QA 工具链指南 - husky,commitlint,commitizen,eslint,typescript,express | szhshp 的第三边境研究所 效率工具 & 软件推荐 | szhshp 的第三边境研究所 站点开源 Project Titan | szhshp 的第三边境研究所 cmd/powershell-命令速查-Cheatsheet | szhshp 的第三边境研究所 Git-命令速查与相关问题解决-Cheatsheet & Troubleshooting | szhshp 的第三边境研究所 Tailwind.css not included in NextJS Production | szhshp 的第三边境研究所 Github GraphQL API - Data Integration | szhshp 的第三边境研究所 尝试 Windows Terminal + z.lua | szhshp 的第三边境研究所 StrokePlus.net - Powerful Hotkey Boost | szhshp 的第三边境研究所 优雅地 Hack 一台黑苹果 | szhshp 的第三边境研究所 一杯关东煮 | szhshp 的第三边境研究所 Gitee x PicGo 管理图床 | szhshp 的第三边境研究所 Create Your Own Redux (Typescript) | szhshp 的第三边境研究所 Getting Started: Ionic + Capacitor + React + Typescript + Android | szhshp 的第三边境研究所 GraphQL: File Upload & Troubleshooting | szhshp 的第三边境研究所 吉祥航空随心飞刷票工具循环查票工具 | szhshp 的第三边境研究所 NVM Windows Portable Installation | szhshp 的第三边境研究所 NextJS x Typescript - Integration & Troubleshooting | szhshp 的第三边境研究所 全站点升级 - Project Titan | szhshp 的第三边境研究所 AWS-EC2-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 Workbox-Getting Started | szhshp 的第三边境研究所 《时间简史》阅读笔记 | szhshp 的第三边境研究所 《时间的秩序》阅读笔记 | szhshp 的第三边境研究所 ESLint-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 站点索引 | szhshp 的第三边境研究所 个人知识库搭建 - Hexo 实现 Github/Coding 持续集成 | szhshp 的第三边境研究所 BMOB-常见问题解决-Troubleshooting | szhshp 的第三边境研究所 React + Typescript: 开启 HMR/Hot Loader | szhshp 的第三边境研究所 Yarn & NPM | szhshp 的第三边境研究所 ESLint: Typescript + React + TSX 集成 | szhshp 的第三边境研究所 《10101》EP15:过年 2020 | szhshp 的第三边境研究所 Cmder-Usage | szhshp 的第三边境研究所 Redux-DOM not refreshed | szhshp 的第三边境研究所 React Semantic UI-CheatSheet | szhshp 的第三边境研究所 Typescript: Getting Started | szhshp 的第三边境研究所 Flutter-Getting Started | szhshp 的第三边境研究所 Typescript: Access window object with type check | szhshp 的第三边境研究所 VSC Extension Development-Create A Code Formatter Extension | szhshp 的第三边境研究所 OneNote Extension-Main API | szhshp 的第三边境研究所 TortoiseGit Win10 Icon not showing correctly | szhshp 的第三边境研究所 Mongoose: aggregate() 方法实现聚合函数 | szhshp 的第三边境研究所 React In Depth - React 源码解析 - render() & Fiber | szhshp 的第三边境研究所 MongoDB x Mongoose: 实现类似 Join 的功能 | szhshp 的第三边境研究所 Disqus 评论框改造工程-实现 Disqus 代理的 Serverless 服务 | szhshp 的第三边境研究所 GUI, CLI, Terminal, Shell, TTY, Console, Bash | szhshp 的第三边境研究所 Jest Async Best Practise: No Nested Async | szhshp 的第三边境研究所 关系型数据库与非关系型数据库优缺点分析 | szhshp 的第三边境研究所 New Edge & Chromium Error - Package is invalid: 'CRX_VERSION_NUMBER_INVALID' | szhshp 的第三边境研究所 选择 GraphQL 的 N 个理由 | szhshp 的第三边境研究所 StrokePlus - 鼠标手势神器的代码编写技巧 | szhshp 的第三边境研究所 嗨,好久不见 | szhshp 的第三边境研究所 Vue + ElementUI 集成 Vue Router | szhshp 的第三边境研究所 IE8 - Unknown Runtime Error Using innerHTML & Ajax | szhshp 的第三边境研究所 React: Handling Events | szhshp 的第三边境研究所 React-Navigation Integration with Redux | szhshp 的第三边境研究所 React: States is tricky | szhshp 的第三边境研究所 《10101》EP14:小剧场 | szhshp 的第三边境研究所 ColdFusion - Basic - arguments in cffunction | szhshp 的第三边境研究所 ColdFusion - Basic - cfset | szhshp 的第三边境研究所
VSC x VIM - 反正多学几个快捷键没有坏处 | szhshp 的第三边境研究所
2022-10-23 · via szhshp 的第三边境研究所

Meta

目录

2024.08 Update

一年过去了, 我的感想是: MD, 我以前没有VIM是怎么活过来的!!!

2023.04 Update

硬是压着自己使用了两个月, 现在我的效率又提高了一级

推荐使用的几个VIM插件:

  1. Easy-Motion
  2. Vim-Surround
  3. Vim-Sneak(optional)
  4. vim-indent-object(optional, 但是有时候挺有用)

2023.02 Update

距离这一篇文章的第二次更新已经过去了半年, 这段时间我不断地尝试 VIM, 期间也不断放弃和重试, 终于在 2023 年的今天, 我成功用 VIM 代替 IDE 的普通编辑模式

用于开发最好的组合是 VSC + VIM, VSC 弥补了 VIM 的不足(比如其他的一些选择快捷键, 代码提示, Hover, Reference 查看等等), VIM 却从效率上提升了 VSC 的编辑体验

前言

这篇文章编辑自 2016 年的一篇文章.

当年研究过一段时间 VIM, 因为操作不熟练没有用作主力 IDE, 而是单纯在 CLI 里面用于轻度编辑

多年过去了, VSC 成为了主力 IDE, VSC 的 VIM 插件也变得更好用了

我使用 VSC 的快捷键已经可以达到很高的操作速度, 不过多学几个快捷键没什么坏处

VSC VIM 插件

首先需要安装 VSC 的 VIM 插件

模拟 VSC 的基础功能

Ref

  • gd: VSC 类似 Ctrl+点击, 查看所选内容的引用
  • gh: 类似于鼠标 hover
  • af - visua mode command which selects increasingly large blocks of text. For example, if you had “blah (foo [bar ‘ba|z’])” then it would select ‘baz’ first. If you pressed af again, it’d then select [bar ‘baz’], and if you did it a third time it would select “(foo [bar ‘baz’])”.
  • gt/gT: 正向反向跳转文件标签页, VSC 自身也有快捷键这个可以选择性使用
    • 2gt: 这个其实是激活第二个标签页, 注意不是跳两次

vim-easymotion

这个插件的目的是为了方便使用 motion 命令快速跳转

Based on vim-easymotion and configured through the following settings:

需要进行一些配置:

  "vim.leader": "<space>", // 关键快捷键
  "vim.easymotion": true, // 开启功能

如上配置之后可以通过 <space><space>w{char} 快速跳转到包含特定字母的字符的开头

Hotkeys

Motion CommandDescription
<leader><leader> s <char>Search character 搜索单个字母
<leader><leader> f <char>Find character forwards 向后搜索单个字母, 建议使用 <leader><leader> s <char> 代替
<leader><leader> F <char>Find character backwards 向前搜索单个字母, 建议使用 <leader><leader> s <char>
<leader><leader> t <char>Til character forwards
<leader><leader> T <char>Til character backwards
<leader><leader> wStart of word forwards 向后搜索单词头
<leader><leader> bStart of word backwards 向前搜索词头
<leader><leader> lMatches beginning & ending of word, camelCase, after _, and after # forwards 向后搜索单词词首或者词尾, 单词数量少的情况下 <leader><leader> w
<leader><leader> hMatches beginning & ending of word, camelCase, after _, and after # backwards 向前搜索单词词首或者词尾, 单词数量少的情况下 <leader><leader> w
<leader><leader> eEnd of word forwards
<leader><leader> geEnd of word backwards
<leader><leader> jStart of line forwards
<leader><leader> kStart of line backwards
<leader><leader> / <char>... <CR>Search n-character
<leader><leader><leader> bdtTil character
<leader><leader><leader> bdwStart of word
<leader><leader><leader> bdeEnd of word
<leader><leader><leader> bdjkStart of line
<leader><leader><leader> jJumpToAnywhere motion; default behavior matches beginning & ending of word, camelCase, after _ and after #

<leader><leader> (2s|2f|2F|2t|2T) <char><char> and <leader><leader><leader> bd2t <char>char> are also available. The difference is character count required for search. For example, <leader><leader> 2s <char><char> requires two characters, and search by two characters. This mapping is not a standard mapping, so it is recommended to use your custom mapping.

Usage

  1. 首先是最简单的用法: <leader><leader> s <char> 搜索单个字母
    • 例如: <leader><leader> s a 搜索所有的 a 字母
    • 匹配的数量可能会很多, 导致跳转的时候可能需要多按两次
  2. <leader><leader> / <char>... <CR> 搜索多个字母
  • 例如: <leader><leader> / abc <CR> 搜索所有的 abc 字符串
  • 由于匹配了多个字母, 所以跳转的时候需要按的次数会少很多
  • 但是需要额外按下回车也很麻烦
  1. <leader><leader> j 搜索所有的行首
  • 多数情况下选择多行时会用到, V <leader><leader> j 就可以选中当前行和目标行

Personal Mapping

{
	"before": ["J"], // 将 Shift+J 设置成 Easymotion 的
	"after": ["<leader>", "<leader>", "/"]
},

// 或者你也可以绑定到 f 按键上, 因为我一直觉得 f 的查找效率不高, 而且绑定到 f 上也不会影响到原来的功能
{
  "before": [ "f", ],
  "after": [ "<leader>", "<leader>", "/" ]
},

vim-surround

Based on surround.vim, the plugin is used to work with surrounding characters like parentheses, brackets, quotes, and XML tags.

SettingDescriptionTypeDefault Value
vim.surroundEnable/disable vim-surroundBooleantrue

t or < as <desired> or <existing> will enter tag entry mode. Using <CR> instead of > to finish changing a tag will preserve any existing attributes.

Surround CommandDescription
S <desired>Surround when in visual modes (surrounds full selection)
需要预先选中内容
y s <motion> <desired>Add desired surround around text defined by <motion>
经常误操作, 建议选中后使用 S <desired> 代替此操作
d s <existing>Delete existing surround
删除包裹的符号, 不需要选中, 直接查找最近的符号
c s <existing> <desired>Change existing surround to desired
替换包裹的符号, 不需要选中, 直接查找最近的符号

Some examples:

  • "test" with cursor inside quotes type cs"' to end up with 'test'
  • "test" with cursor inside quotes type ds" to end up with test
  • "test" with cursor inside quotes type cs"t and enter 123> to end up with <123>test</123>

vim-sneak

Based on vim-sneak, it allows for jumping to any location specified by two characters.

另一种跳转工具, 实现搜索两个首字母方便跳转, 缺点在于需要输入两个字母, 如果单词较长, 会比较麻烦

SettingDescriptionTypeDefault Value
vim.sneakEnable/disable vim-sneakBooleanfalse
vim.sneakUseIgnorecaseAndSmartcaseRespect vim.ignorecase and vim.smartcase while sneakingBooleanfalse

Once sneak is active, initiate motions using the following commands. For operators sneak uses z instead of s because s is already taken by the surround plugin.

Motion CommandDescription
s<char><char>Move forward to the first occurrence of <char><char>
核心在于搜索两个首字母
S<char><char>Move backward to the first occurrence of <char><char>
<operator>z<char><char>Perform <operator> forward to the first occurrence of <char><char>

VSCode 文件配置

  "vim.leader": "<space>",
  "vim.easymotion": true,
  "vim.surround": true,
  "vim.useSystemClipboard": true,
  "vim.sneak": true,
  "vim.sneakUseIgnorecaseAndSmartcase": true,
  "vim.autoSwitchInputMethod.enable": true,
  "vim.autoSwitchInputMethod.defaultIM": "1033",
  "vim.autoSwitchInputMethod.obtainIMCmd": "D:\\Tools_For_Work\\im-select\\im-select.exe",
  "vim.autoSwitchInputMethod.switchIMCmd": "D:\\Tools_For_Work\\im-select\\im-select.exe {im}",
  "vim.handleKeys": {
    "<C-d>": false,
    "<C-b>": false,
    "<C-h>": false,
    "<C-f>": false,
    "<C-a>": false,
    "<C-x>": false,
    "<C-w>": false,
    "<C-s>": false,
    "<C-c>": false,
    "<C-v>": false,
    "<C-z>": false,
    "<C-e>": false,
    "<C-n>": false,
    "<C-t>": false
  },
  "vim.normalModeKeyBindingsNonRecursive": [
    // {"before": ["<leader>", "g"], "after": ["<cmd>", "Rg", " "]},
    {"before": ["f"], "after": ["<leader>", "<leader>", "/"]},
    {"before": ["x"], "after": ["\"", "_", "x"]},
    {"before": ["X"], "after": ["\"", "_", "X"]},
    {"before": ["d", "d"], "after": ["\"", "_", "d", "d"]}
  ],
  "vim.normalModeKeyBindings": [
    {"before":["H"], "after":["^", "a"]},
    {"before":["K"], "after":["g", "T"]},
    {"before":["J"], "after":["g", "t"]},
    {"before":["H"], "after":["^", "i"]},
    {"before":["L"], "after":["g", "_"]}
  ]

Vim - 基础

编辑模式

  1. 普通模式下按下 i 进入插入模式
    1. 使用 i 将光标定位到选择内容前方
    2. 使用 a 将光标定位到选择内容后方
  2. 插入模式下按下 Esc 或者 Ctrl+[ 回到普通模式
  • 如果不确认在哪个模式就按两下 Esc 回到普通模式

Command Cheatsheet

  • 移动 (motion)
    • 按照单词移动
      • w: 跳到下一个单词的开头
      • b: 跳到当前单词或者上一个单词的开头
      • e: 跳到当前单词或者下一个单词的结尾
      • ge: 调到上一个单词的结果
    • 行按照行移动j
      • 0: 数字 0, 跳到行首的任何字符
      • $: 跳到行尾的任何字符
      • ^: 跳到行首的非空字符
      • g_: 跳到行尾的非空字符
      • gg: 跳到文件第一行的行首非空字符
      • G: 跳到文件最后一行的行首非空字符
    • 字符查找
      • f{char}: 跳转到行内下一个 {char} 位置
      • F{char}: 跳转到行内上一个 {char} 位置
      • t{char}: 跳转到行内下一个 {char} 前, 比 f{char} 少取一个字符
      • T{char}: 跳转到行内上一个 {char} 后, 同样少取一个字符
    • 翻页 (注意这里几个快捷键可能和 VSC 的快捷键会冲突, 修改 vim.handleKeys 可以防止冲突 )
      • Ctrl+f/b: 向前/向后移动一页
      • Ctrl+d/u: 向前/向后移动半页
  • 重复
    • ;/,: 正向/反向重复行内查找
    • ./u: 正向/反向重复文本改变
    • n/N: 正向/反向重复全文查找
    • &/u: 正向/反向重复替换
    • @{marco}/u: 正向/反向执行宏
  • 动作 (action)
    • i: 选中范围内(Inner), vi( 会选括号内的内容
    • a: 选中范围(Around), va( 会连括号一起选中
    • d: 删除(同时会复制)
    • c: 修改(同时进入插入模式)
    • y: 复制
    • v: 进入 VISUAL 模式
  • 混合使用
    • dd: 删除一行
    • cc: 删除一行并从非空位置开始输入
    • yy: 复制一行
    • 2yy: 复制三行
    • di(/dib: 删除小括号内的内容
    • da(/dab: 删除小括号以及里面的内容
    • di{/diB: 删除大括号内的内容
    • ci<: 快速修改尖括号里面的内容
    • dfa: 从当前开始删除到下一个字母 a
    • ya`: 快速复制 backtick 符号以及里面的内容
    • d$: 从当前一直删除到结尾
    • d^: 从当前一直删除到开头
    • die: 删除整个文件
    • dit: 删除一个 Tag 里面的内容, 适合 XML 文件
    • dat: 删除一个 Tag 全部
  • 宏的录制
    • q{char}: 录制一个宏命令并保存到 {char} - q: 输入完毕后停止录制, 可能不会有什么反应但是会停止录制 - @{char}: 执行录制的名称为 {char} 的宏 - :register {char}: 查看已经录制的宏的细节 - qaq: 清楚所有宏

普通模式

  1. {char} 指任何可输入字符
  2. <CR>Enter 按键
  3. <C-{char}> 指按住 Ctrl 然后按下 {char} 对应的按钮

简单命令

命令码含义Comment
h j k l光标左,下,上,右
x删除一个字符
y复制
.重复上次编辑行为,重复命令码之前执行的所有编辑行为圆点符号
u撤销
>增加缩进
w正向移动到下一单词的开头改为大写按钮后则不按照单词移动,按照字串移动
b反向移动到上一单词的开头改为大写按钮后则不按照单词移动,按照字串移动
e正向移动到下一单词的结尾改为大写按钮后则不按照单词移动,按照字串移动
c修改从当前字符修改至单词末尾: cw
修改整个单词: caw
d删除光标所在整个单词删除整个单词: daw
删除整个段落: dap
<C-a>
对选中的数字进行加 1
对选中的数字进行减一
对负数也有效
f{char}在行内查找下一指定字符继续查找下一个: ;
继续查找上一个: ,
/pattern<CR>在文档中查找下一处匹配项继续查找下一个: n
继续查找上一个: N
?pattern<CR>在文档中查找上一处匹配项同上
:s/target/replacement替换继续替换下一个: &
回退: u
替换特定行范围内的文字: {num},{num}s/old/new/
$行尾单独使用可以跳到行尾,也可配合其他命令使用
r替换可以替换单个字符,如果选中多个字符则会换为相同长度的重复单个字符
%跳转括号跳转到对应括号的字符处
a在光标之后插入文本在行末插入文本: A
:wq保存并退出前方加上! 可以强制执行
:q不保存并退出前方加上! 可以强制执行
:{number}直接跳转特定行号
0无脑移动到行首
^移动到本行第一个非blank的位置
$无脑移动到行尾注意这里和 ^ 并不是完全相反的功能
g_移动到本行最后一个非blank的位置注意是 g 后面带上一个下划线
o O在当前行的前或后重新创建一行开始输入并进入编辑模式这里是大小写的字母 O
I A在当前行的行首或行尾开始输入并进入编辑模式

附一张 VIM 键位图1

Example

快速选取 1

例如下面这样的文字:

	|  aaa| vaaaa<br>aaaa<br>bbbb  |

如果我们要修改出左边的aaa,则可以直接双击然后修改

而若要修改右边的一团 vaaaa<br>aaaa<br>bbbb,只需要几个按键:vt|

  1. v 代表开始选择
  2. t 代表直到某个特定字符
  3. | 就代表竖线字符

如此可以快速的选中右边的一团,最重要的是不需要操作鼠标

如果有多个这样格式的一团需要进行批量选中修改,那么VIM可以节省很多时间

快速选取 2

	[^2]: [http://www.vimer.cny](http://www.vimer.cn)

例如需要选取大括号内的数据,只需要输入vi[ 即可快速选中括号内所有数据,而不用移动鼠标来进行选取

如果选取是为了修改则可以直接输ci[

之前就听说 Marco Recording 是个很 6 的功能,这次正好来体验一下2

比如有 100 个这样的 item,要从中筛选出 30 个,如果用普通方法我们需要选中每个 item,然后删除,如果使用普通vim,我们可以使用5dd来删除每个 item,但是需要定位到 item 开头的cards标签才能执行,这时候macro是个很不错的 Solution

	cards
		cardNamecardName
		cardDesc-cardDesc
		cardType7cardType
	cards
	cards
		cardNamecardName
		cardDesc-cardDesc
		cardType7cardType
	cards
	cards
		cardNamecardName
		cardDesc-cardDesc
		cardType7cardType
	cards

宏相关命令

命令码含义Comment
q{char}录制宏并保存到{char}这个变量中
q停止录制
「{char}p显示{char}变量里录制好的命令细节,会输出到光标所在位置
{num}@{char}执行{char}里面录制的宏命令

这时候只需要以下几步

  1. qa : 开始录制宏并保存到变量a
  2. ?cards{Enter} : 跳转到前一个 cards 的位置并取消选择
  3. 5ddq : 删除 5 行并停止录制

然后如果想要删除特定 item 就只需要输入@a来调用变量a里面保存的宏命令

参考文献

  1. http://www.vimer.cny

  2. http://www.cnblogs.com/ini_always/archive/2011/09/21/2184446.html