Vim 技巧 - 用次数做简单的算术运算
大多数普通模式命令可以在执行时指定次数,我们可以利用这个功能来做简单的算术运算。
很多普通模式命令都可以带一个次数前缀,这样 Vim 就会尝试把该命令执行指定的次数,而不是只执行一次
# 简单加减
<C-a>
和 <C-x>
命令分别对数字执行加和减操作。在不带次数执行时,它们会逐个加减,但如果带一个次数前缀,那么就可以用它们加减任意整数。例如,如果我们把光标移到字符 5
上,执行 10<C-a>
就会把它变成 15
。
但是如果光标不在数字上会发生什么?文档里说,<C-a>
命令会“把当前光标之上或之后的数值加上 [count]
”。因此,如果光标不在数字上,那么 <C-a>
命令将在当前行正向查找一个数字,如果找到了,它就径直跳到那里。我们可以利用这一点简化操作。
下面是一段 CSS 片段:
我们要复制最后一行并且对其做两个小改动,即用“news”替换单词“blog”,以及把“0px”改为“-180px”。我们可以运行 yyp
来复制此行,然后用 cw
来修改第一个单词。但我们该怎么处理那个数值呢?
一种做法是用 f0
跳到此数字,然后进入插入模式手动修改它的值,即 i-18<Esc>
。不过,运行 180<C-x>
则要快得多。由于我们的光标不在要操作的数字上,所以该命令会正向跳到所找到的第一个数字上,从而省去了手动移光标的步骤。让我们看看整个操作过程
在本例中,我们只复制了一行并做出改动。但是,假设你要复制 10
份,并对后续数字依次减 180
。如果要切换到插入模式去修改每个数字,我们每次都得输入不同的内容(-180
,然后 -360
,以此类推)。但是如果用 180<C-x>
命令的话,对后续行也可以采用相同的操作过程。我们甚至还可以把这组按键操作录制成一个宏,然后根据需要执行多次。
# 数字的格式
007
的后面是什么?不,这不是詹姆斯·邦德的恶作剧,我是在问:如果对 007
加 1
,你觉得会得到什么结果。
如果你的答案是 008
,那么当你尝试对任意以 0
开头的数字使用 <C-a>
命令时,也许会感到诧异。像在某些编程语言中的约定一样,Vim 把以 0
开头的数字解释为八进制值,而不是十进制。在八进制体系中,007 + 001 = 010
,看起来像是十进制中的 10
,但实际上它是八进制中的 8
,糊涂了吗?
如果你经常使用八进制,Vim 的缺省行为或许会适合你。如果不是这样,那么你可能想把下面这行加入你的 vimrc 里:
set nrformats=
这会让 Vim 把所有数字都当成十进制,不管它们是不是以 0 开头的。
而 VSCodeVim 目前还不支持此设置,详见:<C-a>
increment does not work at 07 · Issue #6693 · VSCodeVim/Vim (opens new window)
# 批量自增自减
假如要生成如下的字符,该怎么办呢?
index: 1
index: 2
...
index: 10
2
3
4
我们可以这样做:
先生成一个基础模板:
index: 0
然后使用 yy9p
复制粘贴 9 次
index: 0
index: 0
index: 0
index: 0
index: 0
index: 0
index: 0
index: 0
index: 0
index: 0
2
3
4
5
6
7
8
9
10
然后将光标放在首行的 0 上,使用 <C-v>
进入 visual block model, 使用 9j
选中到第十行,最后使用 g<C-a>
完成自增
index: 1
index: 2
index: 3
index: 4
index: 5
index: 6
index: 7
index: 8
index: 9
index: 10
2
3
4
5
6
7
8
9
10
自减类似
# vscode 插件 increment-and-decrement
使用 Incrementor - Visual Studio Marketplace (opens new window) 这个插件可以实现类似的功能
数字增减就不说了,这个扩展还增加了 enums
枚举,比如 true
和 false
互转,let
和 const
互转等,也可以自定义
但转换以后,默认进入选择模式了,我们需要再按一下 <Esc>
所以我们需要在插件执行完转换后再调用一下 <Esc>
// increment-and-decrement
{
"before": ["<Leader>", "a"],
"commands": [
"incrementor.incrementByOne",
{
"command": "vim.remap",
"args": {
"after": ["<Esc>"]
}
}
]
},
{
"before": ["<Leader>", "x"],
"commands": [
"incrementor.decrementByOne",
{
"command": "vim.remap",
"args": {
"after": ["<Esc>"]
}
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05