初学者在学了一些 Vim 入门教程,掌握了一些基本操作后,往往不知道从何下手,日常工作中不太可能在终端下直接写代码,何况直接终端用 Vim 写代码,还需要大量插件的支持。
其实我认识的很多 Vim 用户,现在已经不用原生 Vim 了,都是先选一个自己喜欢的编辑器/IDE, 再装 Vim 插件,基本上没有哪个现代编辑器/IDE没有 Vim 插件的了。
我比较喜欢 VSCode,日常工作也是用 VSCode 写代码,所以今天就来介绍下 VSCode 里 Vim 插件的一些设置和应用技巧,至于是不是最佳实践不重要,起这样的标题完全是不知道用什么好,权当做一回标题党吧。
在讲具体内容之前,先介绍几个编辑器的 Vim 插件现状, 顺便解释下我为什么要选 VSCode
:
上面说了那么多,对于初学者来说,建议直接用 VSCode 吧,不折腾。
安装非常方便,打开插件界面,输入 Vim,第一个就是,点安装即可。
800多万的安装量,感受下 Vim 用户的庞大,是不是感觉不用 Vim 和时代脱离了:)
{
"vim.easymotion": true,
"vim.leader": ",",
"vim.searchHighlightColor": "#5f00af",
"vim.hlsearch": true,
"vim.normalModeKeyBindingsNonRecursive": [
{ "before": ["H"], "after": ["g", "T"], },
{ "before": ["L"], "after": ["g", "t"] },
],
"editor.lineNumbers": "relative",
"files.autoSave": "onFocusChange",
"workbench.editor.enablePreviewFromQuickOpen": false,
"editor.renderWhitespace": "boundary",
"editor.detectIndentation": false,
"showMusicMetrics": false,
"showGitMetrics": false,
"showWeeklyRanking": false,
"editor.minimap.enabled": false,
"git.autofetch": true,
}
首先把上面的配置放到自己的配置文件里,Mac 平台点左上角 Code->Preferences->Settings-> 在右边往下拉,找到 Edit in settings.json, 把上面内容放进去,大括号自己去掉。
解释几个:
上面设置了相对行号后,才能方便的做多行操作,在做具体操作前,先说单行操作分别是什么:
dd
删除一行, d
是 delete
, 两个 d 表示对一行操作,Vim 里的约定吧gcc
注释一行, gc
是 go comment
, 两个 c 表示注释一行<<
左移一行>>
右移一行上面的操作,在 v 模式下,都可以生效,可以试一下按 Shift+v
选中一行,然后分别按 d
, gc
,<
, >
, 看看是不是删除、注释、左移、右移
好了,有了上面的这些知识,我们可以开始多行操作了,具体操作方法如下:
H
大写的 H 移动到左边那个标签L
大写的 L 移动到右边那个标签ngt
移动到第 n 个标签(从左往右从1开始),当标签开的比较多时,由于标签上没显示数字,要自己数是第几个,所以基本上没法用。对于标签开的比较多时怎么操作,我的习惯是这样的:
zz
调整光标所在行到屏幕中间 (z 什么意思我也不知道,就硬记吧)zt
调整光标所在行到屏幕最上方 (t == top)zb
调整光标所在行到屏幕最下方 (b == bottom)这三个用的非常多,尤其是 zz
, 一定要熟练使用
把光标移到想搜索的那个函数名或变量名上,按*
就可以搜索了,按n
下一个,按N
上一个。
比如看到类里有个成员变量,想去回到它的定义处看有没有注释说它是干嘛的,一般定义的地方肯定是文件内第一次出现的地方,我们可以这么操作:
*
锁定它gg
回到行首n
到下一个它出现的地方zz
调整到屏幕中间,方便阅读这4步熟悉后基本一气呵成
这里先说两个概念,操作符(operator)和动作命令(motion), 操作符就是 d(delete)
, c(change)
, y(yank)
等等,动作命令是iw(in word)
, aw(a word)
这些,可以通过 操作符 + 动作命令
的方式,组合出千变万化的操作出来,帮助我们快速移动、修改等等。
完整列表可以在 Vim 里输入 :h motion.txt 查看,这里只列出一些常用的。
操作符 | 功能 |
---|---|
c | change (先删除再进入插入模式) |
d | delete |
y | yank into register (does not change the text) |
~ | swap case (转换大小写) |
gu | make lowercase (转为小写) |
gU | make uppercase (转为大写) |
> | shift right (右移) |
< | shift left (左移) |
动作命令 | 功能 |
---|---|
f{char} | find, 行内搜索一个字符 |
t{char} | till, 功能类型 f{chat}, 但是是在这个搜索到的字符前停下,意思是到这个字符之前,很常用的motion |
gg | 跳到行首 |
G | 跳到行尾 |
w | 移到下个单词的第一个字符 |
b | 移到上个单词的第一个字符 |
e | 移到单词最后一个字符 |
ge | 上个单词的最后一个字符 |
aw | “a word”, 选择一整个单词,包括它边上的空格 |
iw | in word, 选择一整个单词,不包括空格 |
diw
, delete in word, 删除一个单词,只删除单词本身,不会旁边的空格daw
, delete a word, 删除一个单词,并删除旁边的一个空格(至于是左还是右边空格,Vim 会根据上下文自己判断,非常智能)d
是删除, diw
就是删除一个单词v
是进入 visual 模式的,如果用 viw
, 就表示选中一个单词y
是复制(yank), yiw
表示复制一个单词gu
是变成小写,guiw
就是让一个单词变成小写gU
是变成大写, gUiw
就是让一个单词变成大写还有很多,这样只要记住一个,就可以举一反三,所以 Vim 是不需要死记硬背的,理解着记会更快。(当然不排除一些要死记硬背,但比较少)
比如有下面一段代码:
local _hello = true
function test()
print(_world)
end
-- 用复制的方式把 _world 改成 _hello
这个问题看起来很简单,但实际上用起来后就会发现并不简单,我们用鼠标时的操作逻辑是下面这样的:
想象中的 Vim 操作逻辑是下面这样的:
_hello
, yiw
复制_world
, diw
删除,再 p
粘贴这时你会发现,咦,贴出来的还是 _world
, 而不是期望中的 _hello
, 这是因为 Vim 里的删除,实际上是剪切,会把删除的东西放到“剪切板”里,所以我们不能这样操作,而应像下面这样操作:
_hello
, yiw
复制_world
, viw
选中,再 p
粘贴这个操作是目前的最优解了,《Vim 实用技巧》这本书里给的也是这个方案(我是先自己发明这个方案才看的书:),这个方案虽然也很别扭,但是够用了,习惯了也不是不能接受。
,,j
按下后,会在每一行的行首高亮且有一个字母标在高亮处,这时输入指定字母就可以跳过去了,这个可以说是起飞的关键之一,必须要熟练掌握,,k
上面是向下搜索,这个是向上,其他都一样,,w
同,,j
,只不过是单词级的向后搜索,,b
同,,k
, 只不过是单词级的向前搜索(,,w
,,b
不如行级好用,因为太花了,我们可以用行级 Jump 到指定行,再用 f 过去,或者按几个 w 也可以,如果靠近行尾,可以先按$到行尾再按几个 b,方法很多。ctrl+o
, 回到上一个编辑点ctrl+i
, 前进到下一个编辑点,和上面的相反方向gi
, 回到上一个进入插入模式的地方,并进入插入模式,这个在写代码时写到一半想看一下其他地方的代码,看完再按下 gi
回去,当然也可以 ctrl+o
回去。ctrl+f
, 下一页ctrl+b
, 上一页ctrl+d
, 下半页ctrl+u
, 上半页这四个非常常用,尤其是读代码时,我们不可能按住 j/k
不放去翻代码。
:vs
, 创建一个竖向分栏:sp
, 创建一个横向分栏在创建多个分栏后,怎样在分栏之间移动?总不能用鼠标吧!当然不需要,下面就是移动分栏的方法:
ctrl+w
再按 h
, 移到左边一个分栏ctrl+w
再按 l
, 移到右边一个分栏ctrl+w
再按 j
, 移到下边一个分栏ctrl+w
再按 k
, 移到上边一个分栏按下 ctrl+w
后,就进入“移动分栏待决模式”了,这时按 hjkl
就可以移动了。
分栏在屏幕比较大时还是很方便的,有时候写代码时,要看着另一块代码,也很方便。
暂时就想到这些,还有很多比较常用的,想到了再补充。以上这些如果能掌握,基本上在 VSCode-Vim 环境下写代码足够了,等真正用进去了,才会发现有很多不会的或者不方便的点,这时要学会去 Google 或请教别人,只有这样才能不断强化,最终让 Vim 操作变成肌肉记忆。