Why VSCode + Vim?
开篇狗头保命,这篇文章只聊具体配置,不涉及任意编辑器优劣的争论,如论是 Vim,Emacs 这类编辑工具,还是 VSCode,Jetbrain 这样的 IDE,他们都是非常优秀的产品。
作为一个从学生时代就开始接触 Vim 的老玩家,对于 Vim 提供的高效能编辑体验,我是深有感触的,不论是快速的 navigation,还是极其灵活的 text object 编辑体验,确实都是我自己日常开发中不可或缺的生产力工具。但是 Vim 自己只能算是一个高级的文本编辑器,在日常开发中我们需要的 IDE 的其他能力,它是并不具备的(或者说捯饬起来极其的硬核)。
VSCode 凭借它极快的启动速度,非常轻巧的 memory footprint(相比于 WebStorm),以及丰富的插件系统,一直在前端圈子里非常流行,也是我自己一直使用的 IDE。并且它本身对于 Vim 的支持也非常不错,不仅有官方一直维护的 Vim 插件,也有社区非常流行 Neovim 插件。另外,这里要着重提一嘴,VSCode 本身针对编辑过程的体验优化也做了非常多的工作,像 multi-cursor 这样的能力,本身也是极好的生产力工具,这里我并没有无脑在 VSCode 里强行复刻 Vim 的键位,而是结合两者的编辑能力和快捷键来提高生产力。
基础配置及其能力
只要安装官方的 vim 插件并 reload window,就可以获得绝大多数的 vim 编辑体验,比如 text object,search/replace 等等。这里额外需要提到的几个官方建议的键位:
gd
:goto deinition.不过我个人还是更习惯<C-o>和<C-i>的方式af
:这个还是蛮有用的,语义化的扩大选区,在编辑组件里的标签的时候很方便
另外 VSCode 提供的 multi-cursor 的能力真的是非常好用,只是默认的配置需要很多辅助按键和方向键,我这里增加了一个 keymap binding:
json
[
{
"key": "ctrl+j",
"command": "editor.action.insertCursorBelow",
"when": "editorTextFocus"
},
{
"key": "ctrl+k",
"command": "editor.action.insertCursorAbove",
"when": "editorTextFocus"
}
]
这组键位可以非常方便我们编辑连续出现的多个相同标签或者属性 。但是更多的时候,我们需要的可能是针对一个 Pattern 的编辑,比如把这个组件里所有的div
换成a
。这样,这里就有两个很方便的 VSCode 快捷键可以使用:
- Add Selection To Next Find Match:选中下一个和当前选区相同的内容(默认快捷键
Command + D
) - Select All Occurrences of Find Match:选中所有和当前选区相同的内容(默认快捷键
Command + Shift + L
)
另外,有一个复制粘贴的小技巧。在 Vim 里,我们使用p/P
粘贴完光标是在原位置的,改用gp/gP
光标会到粘贴内容的另一侧,方便我们连续粘贴内容。
surround.vim
这个tpope 大神维护的插件是我使用频率最高的一个 Vim 插件了,它通过扩展 text object 的方式,来极大的增强了我们编辑各种包裹内容 的效率,不论是单双引号,还是大中小括号,甚至是 html tag,我们都可以很快的去对其内部或者外部来增删,而且其对原本的 Vim 按键侵入性极小,只需要在原本的 action 和 text object 中间加 s,如yiw
变成ysiw
即可。这里写一个简单的 demo,更多的使用方式可以参考官方 repo。
例:<p>Hello World</p>
执行cst<a>
即可将 p 标签换为 a 标签
Emmet + vim
VSCode 本身对于 Emmet 的支持其实是非常好的,常用的 Emmet 缩写 在 VSCode 里都可以直接拿来用,在 JSX/TSX 文件里通过类似ul>li*5
这样的代码块生成 html 代码想必大家都不陌生。除了这块内容,Emmet 其实还提供了两个很好用的功能,隐藏在Command + Shift + P
的功能菜单里。
- Go To Matching Pair。熟悉 Vim 的朋友应该对 Vim 里的
%
操作不陌生,它可以非常方便的在各种开闭括号之间跳转,配上matchit
插件更是可以在 html 开闭标签,甚至是语义化的开始/结束词语之间跳转。非常可惜 VSCode 不支持这类 Vim 插件,而 Emmet 这个功能就是为了补全前端场景下这块能力而生的,可以很方便的在 html 开闭标签之间跳转。建议专门为这个功能设置一个快捷键(我是设置为Shift + Ctrl + 5
,以便尽可能和 Vim 保持一致) - Update Tag / Wrap with Abbreviation。这个做的事情和上面
Surround.vim
提供的能力有点像,用来修改当前 html tag 或者在当前 tag 外面包一层 tag,但是和纯文本不同的是,这里去定义新 tag 的时候,可以使用完整的 Emmet 表达式,在 tailwindcss 的场景简直不要太好用。
TailwindCSS
针对 tailwindcss,我自己的使用场景,基本上装一个 TailwindCSS IntelliSense 插件就够用了,这里特别讲一下,这个插件还支持 Emmet 的补全,在设置里搜Emmet tailwind
,然后把Tailwind CSS: Emmet Completion
勾上。然后你的 Emmet 使用起来会更加丝滑。