阅读 174

Vim 的命令模式记录

基本使用

我们通常只要在 Normal 模式下输入 : 冒号就可以进入命令模式.

行号跳转

通常我们使用 Vim 的命令中, 最常用且高效的命令就是跳转行号, 譬如我现在要跳转到 30 行去改点东西

:30
复制代码

我想多跳几行

可以在一个行数范围区间内跳转, 譬如我要在 20 到 30 这个范围跳转, 只要这样

:20, 30
复制代码

那假如我只想指定某一行的多少行呢?

:20; +10
复制代码

效果同上, 只是可以通过 +/- 来控制

删除指定行代码

Vim 可以在 Normal 模式下使用 dd 来删除整行代码, 我现在可以通过命令模式输入 30 行然后按 dd 来删除该行, 能不能再快点呢?

:30 d
复制代码

我想删多点

需求又变了, 如果有多行代码需要删除, 一般我的习惯是进入 可视化模式选中要删除的代码, 然后按下 d, 其实我们还可以通过命令来删除多行代码, 譬如我要删除 20, 30 之间的代码就可以像这样

:20, 30 d
复制代码

这样就可以做到删除指令行范围内的代码, 一个字爽.

从我脚下开始删

我现在光标在某一行, 但是我不说, 我只想从这一行开始删到底

:., $ d
复制代码

我要删清爽

现在我们要把当前文件的所有的代码删掉, 经过上面的例子, 你可能会猜, 这还不简单

:1, $ d
复制代码

是的没错, 但是我们还可以这样

:% d
复制代码

移动代码

突然我想把 20 到 30 行的代码移到 15 行的下面, 一般我们会在删除的基础上到指定行下面按 p 粘贴, 当然通过命令也能满足需求.

:20, 30 m 15
复制代码

不想移动想复制

继续刚才的例子, 不过这趟我是想把 20 到 30 行的代码复制到 15 行, 只要这样

:20, 30 t 15
复制代码

先到这里吧, 还有一些 +/- 的操作, 但是我平常基本上没怎么用过.

搜索

最简单的搜索

先从普通的搜索开始, 这个用正则去匹配的, 只需要在命令模式下键入斜杠 / 来搜索就可以了.
然后实战一下, 假设我们平常写前端样式的时候, 有个地方想改一下, 但是只记得关键字

.my-area {
    .my-area__item {
        font-size: 0.24rem;
        /* ... */
    }
    
    .my-area__icon {
        width: 0.5rem;
        height: 0.5rem;
        /* ... */
    }
    /* ... */
}
复制代码

只要像下面这样, 我们就可以全局将每一行的 my-area 替换成 some-area

:%s /my-area/some-area/
复制代码

如果我只是想在当前光标处替换, 我只要把 % 去掉就可以.
继续举例子, 假设有如下文本

.test {
    .test__test__item {
        /* ... */
    }
}
复制代码

现在我们用上面的 命令来将 test 处理成 hi, 你会发现原本 test__test__item 变成了 hi__test__item, 如果我们是要将所有的 test 改成 hi 怎么办?

:%s /test/hi/g
复制代码

只要加一个 g 选项就可以解决问题了.

Vim 的正则支持

Vim 的正则有四种模式, 分别是 \v \m \M \V, 一般默认的跟常用的 JavaScript(Perl 风格) 的正则稍微有点区别. 下面只讲 \m 模式

元字符 说明
. 匹配任意字符
[xyz] 匹配括号中的任意一个字符, [a-z] 可匹配小写字母, [0-9] 可匹配数字
[^xyz] 匹配除括号中字符以外的任意字符
\d 匹配数字, 同 [0-9]
\D 匹配数字之外的字符, 同 [^0-9]
\s 匹配空白字符(含<TAB>)
\S 匹配非空白字符
\t 匹配<TAB>
* 匹配 0- 任意个字符
\+ 匹配 1- 任意个字符
\? 匹配 0-1 个字符
\{n,m} 匹配 n-m 个字符
\{n} 匹配 n 个字符
\{n,} 匹配 n- 任意个字符
\{,m} 匹配 0-m 个字符
^ 匹配行首
$ 匹配行尾
\< 匹配单词首
\> 匹配单词尾
\ 可以通过 \ 转义, 如 \\ 表示反斜杠本身
\(\) 分组

\m 模式下跟常规正则的不同

Vim Perl 说明
\+ + 匹配 1- 多个字符
\? ? 匹配 0-1 个字符
\{n,m} {n,m} 匹配 1-m 个字符
\(\) () 分组

正则变量

大概了解了一下 Vim 支持的正则之后, 我们可以玩点花头, 先来匹配一下 aabbbaa, 找规律就好了, 第一部分是两个 a, 就假设有多个 a\+, 第二部分不是 a 同时假设有多个, 所以是 [^a]\+, 第三部分跟第一部分一样, 其实可以用正则的变量 \1 来表示第一部分匹配的规则, 但是第一部分没有加 \(\), 这样是没法用变量的, 所以最后就是这样

:/\(a\+\)[^a]\+\1
复制代码

接着把 aa 换成 bbb, bbb 换成 aa

:s /\(a\+\)\([^a]\+\)\1/\2\1\2/
复制代码

其实还有一种函数用法

:s /\(a\+\)\([^a]\+\)\1/\=submatch(2) . submatch(1) . submatch(2)
复制代码

Vim 玩法还是蛮多的, 就很棒

跟命令模式指令结合

其实这个只要举一反三就行, 不过还是备个忘, 譬如现在有一段代码, 我要把空行删掉

#include <stdio.h>
        
int main(int argc, char **argv) {
    printf("hello world");
    return 0;
}
复制代码

而空行可能有 <TAB> 或 空格

:/^\s*$/d
复制代码

通过 d 指令这样就可以把 int main 上面那行空行删掉了.

再来个贪婪模式跟惰性模式, 现在有一串数字 123 1234 12345 123456, 这样替换就会换成 a a a a

:s /\d\{2, 6}/a/g
复制代码

而下面这样替换就会变成 a3 aa aa5 aaa

:s /\d\{-2, 6}/a/g
复制代码

要想使用贪婪模式, 就不要用 \{-, 这样就是匹配优先的行为, 把 - 去掉就是忽略优先的行为, 也就是惰性模式.

其他

Vim 的正则还支持环视等操作, 但是我不会, 就这样吧.


身为 95 后, 我为什么要用 Vim. 从上面的例子中可以看出 Vim 编辑文本方面是高效的, 君不见基本上每个编辑器都提供了 Vim 模式或插件, 我平常工作中用到的 CLionIdeaVim 插件非常好使, 能模拟大部分常用的功能, 配合 IntelliJ 平台的代码提示, 开发效率特别高.


打广告

欢迎关注我的公众号

关注下面的标签,发现更多相似文章
评论