浅谈 Vim 的配置
用来用去,兜兜转转,还是回到了 Vim 这该死的 Editor 上面来。
之前再一次放弃 Vim 的原因是响应速度突然慢的完全受不了,我起初认为是 Gvim windows 适配的问题。
后来得知了一些关于 Vim 底层相关的东西之后,排查了自己原来的 .vimrc
,发现罪魁祸首是 Vim-airline。
它和一个叫做 Whitespace check 的玩意儿冲突了,导致文件加载速度奇慢无比,具体可以看这个 issue。
和 EarthMessenger 交流了一下,觉得其实 Airline 这东西,本质上就是花里胡哨的玩意儿,其实也没有必要。
除了它 git repo 的一些显示之外,其实也没啥用。
还有些原因是,有些使用非 vim script 的语言编写的 extension,在和 vim 交互的时候容易因为接口之类的问题响应过慢。
综合考虑之后,我觉得应当尝试一下一个,尽量轻量级,配置上手很快,依赖其他第三方语言和软件极少的 Vim,并且,最重要的是,效率。
有些之前觉得方便,实际上违背了初衷的习惯也可以改过来。
配置相关仓库,不定期更新。
考场 Vimrc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
C++ψ(`∇´)ψ
这个是最基本的需求。
正常来说需要的东西也就这些:
- 语法高亮
- 括号补全
- 一些基本的代码格式化(
tab = 4
,自动换行) - 编译和运行
- 调试
第一点比较简单,只需要在 vimrc 里面写一句:
1 |
|
就可以了。
第二点也比较简单,我个人使用习惯是,希望输入前半括号,能直接弹出后半括号并且自动跳到括号里面。
这个利用 vim 的映射就可以做到:
1 2 3 4 5 |
|
第二行需要在有 autoindent
选项的情况下使用,这样会自动换行并缩进到大括号里面,这个原理也很简单,就是基本的 vim command.
因为我一般是大括号不换行的,所以我一般是 <SPACE>{<CR>
,行内花括号我用的不多,用了也习惯不补全,所以这样就够用了。
当然,因为 vim 在处理有公共前缀的映射时会有一个 timeoutlen,为了方便可以按照自己手速调整一下,我一般设置在 600ms
左右。
第三点,也是 vimrc 能直接解决的:
1 |
|
就可以了。
第四点,如果直接在 vim 里使用 !<command>
,在 win 下会弹出窗口,linux 下会直接在 vim 里切屏到一个终端。
但是这个时候你就不能对 vim 里原有的代码进行操作了,这很麻烦,所以我们需要异步编译的功能。
这个需要 Vim 7.4 以及之后的版本,因为 7.4 开始,Bram 才引入了 job 这个概念。
Vim 圈著名大神 skywind3000 曾经写过一个异步运行插件 asyncrun.vim,原理什么的可以在他的博客看到。
因为我目前没有时间深入学习这个东西,所以我选择比较粗暴的方式,直接开一个 Terminal 编译,vim8.1 之后可以有内置的 terminal
,比较方便
反正有上下键,也不是很费时间,而且改一些选项也很快。
但还有一个问题是,我经常在粘样例的时候把代码粘贴进去,这就导致我用↑找不到我的编译命令了。
于是想到了一个办法!开两个终端!我是天才!
第五点,我已经习惯了 GDB 这种命令行调试的模式,所以直接 Terminal 就行,也可以在 Vim8.1 过后使用
1 |
|
来引入 TermDebug 包,然后你就可以在 Vim 里实时查看断点了。
话说 Bram 在更新 8.1 的时候都在想啥,咋更新了这么多人性化功能。
很可惜我们学校装的是 8.0,有点难受,所以我一般都是手动 vim90。
但是 TermDebug 有一个很严重的问题,它不能支持 <CR>
继续上一个命令。
所以我还是直接 :Terminal
,然后 <C-w> <S-n>
就可以在 Terminal 里面进入 NORMAL 模式了。
但是调用的还是 CMD,所以我在思考怎么调用外部终端。
upd: EarthMessenger 提供了一种解决方案::term
是可以调用外部终端的。
类似这样::term msys2_shell.cmd -here -no-start -defterm
(参数可以自己使用 msys2_shell.cmd -help
查看)
别忘记加 Path.
把这个映射成命令就好了!
不过如果调用 Msys2 的话,系统 PATH 里的程序是没法调用的,所以有的时候还是要用一用 Terminal
然后 Msys2 如果没有配置过,可能需要更新一下 pacman
,不然下载会出事:
1 2 |
|
如果是用 Gitbash,也是类似的::term bash.exe --login -i
(后面的参数是为了阻止它打开窗口)
Markdownψ(`∇´)ψ
这个也是很重要的需求。
- 语法高亮和一些基本的补全
- Preview
- 文件名补全。
- 一些数学公式的快速输入(写莫反题题解太痛苦了)
关于第一个,之前选择了插件:preservim\vim-markdown
,但是后来发现它会拖慢整个 vim 的效率,这是不能忍受的,所以删除了,干脆直接 syntax off
,或者就用原生的 syntax。
但是发现代码块高亮没了,烦恼,最后在知乎上发现了解决方案:
let g:markdown_fenced_languages =['c', 'cpp']
这个甚至可以识别到我缩进过的代码块,比 vim-markdown
牛逼多了。
果然,原生 vim 才是最牛的()
然后公式渲染没了,愤怒,所以在国外大神博客里找到了解决方案
大致就是尝试匹配 $$
并给他加上高亮,不过还有点 bug,之后来修。
第二个,我之前就一直在用,是一个国内大佬开发的,感觉挺好用,毕竟可以同步预览还可以导出:iamcco/markdown-preview.nvim
。
第三个主要是因为,我经常会引用我自己博客目录下的图片,文章,所以这东西对我来说很有必要。
我以前以为 vim 没有内置补全,某天闲来无事乱按的时候按出了一个 popmenu,发现可以补全文件,搜索了一下之后发现只需要 <C-x><C-f>
就可以了。感叹,vim 果然还是技高一筹,早就有了这样的功能。
第四个的话,我写了几个映射,放在 $VIM/ftplugin/markdown.vim
里面就可以了。
Miscψ(`∇´)ψ
还有一些其他的功能,比如字典,这个 vim 其实也自带了,不过不会自动弹出,而是要
有点难受,之前选用了 skywind3000 大佬的 vim-autopopmenu,但是因为我需要读取 buffer,在大文件编辑时会很卡,于是放弃。
upd:其实不需要读取 Buffer,可以用 i 只读取当前文件和 include,已经够用了,但考试的时候要禁用。
然后关于系统剪贴板这个事情,这个我之前喜欢同步 vim 的剪切板和系统剪贴板。
不过现在还是觉得,独立一下会比较好,因为 vim 里经常 dd 啊,临时移动一下代码之类的,剪切操作很多,而且 vim 本身这个 register 功能又不是摆设,肯定还是要用用的,所以我现在的 vimrc 就没有同步了。
还有一个是关于相对行号的,发现其实这个比直接弄行号要好的多,可以少打一个 shift?
但是要快速跳到视野之外的地方就不太方便,但是可以直接滚屏,所以还挺不错。
中文输入法的话,之前看到过一个内嵌,可以方便在服务器之类的地方操作,不过我没有在奇怪的环境下输入中文的需求,所以暂时不需要,有系统词库就好了。
不过还有一些需求,比如一个内置 todolist manager,我没有看到比较符合我心意的,于是打算自己写一个,vim script 太烦,所以我的想法是使用 c++ 实现,在终端当中工作,有时间了再考虑通过调用的方式内嵌到 vim 里,或者是用 Qt 加个图形化界面直接封装成应用。
有一个叫 Nerdcommenter 的插件,可以提供一些快速注释的功能,经过以下配置之后可以直接用 leader 键来实现注释(leader 默认是 \
)。
1 2 3 4 5 6 7 8 9 |
|
就只需要记住 \ci
以及 \cc
即可(\
是 <leader>
键)。
还有一个事情是,我不喜欢在我的代码文件夹里放 ~un, swp
之类的文件。
不过这些文件还是非常有必要的,所以我选择把它们存在一个指定的位置,这个可以使用以下的设置:
1 2 3 4 |
|
当然,如果提示了无法写入,建议检查一下路径格式是不是正确的,这个可以看 :help backupdir
,或者是把当前文件原有的 ~, ~un, .swp
文件删掉解决冲突就行。
另外,vim 自带了一个文件管理系统 netrw,我很喜欢,这个放到单独的一篇文章里来写。
last but not least, 我写了一个主题,感觉挺爽,有兴趣可以用一用: enonya/yuyuko.vim。
当然有一些地方的 syntax 因为我还没发现所以可能会显示为青色,看起来不太爽,发现了可以 open an issue.
upd: 修复了,并且调整了对比度,现在更舒服一点。
最近尝试了 fzf 和 fzf.vim。
感觉很好用啊!只是似乎它不太能和我的 yuyuko.vim 适配,可能是因为我没做非 256 色的支持。
有时间再来弄一下好了。
然后发现老是 Files:
太麻烦,刚好发现一个 [N]f
空着没啥用,就拿来映射了一下。
又突然想到我经常直接 e ./
,为啥不提升一下效率,直接映射呢?于是在 _vimrc
里面就又多了几行:
1 2 3 4 |
|
感叹,Vim 果然是越调教效率越高啊。
更新了 yuyuko.vim 对 Termcolor 的适配。
之前一直不知道 g:terminal_ansi_colors
是什么,今天翻阅文档并实验之后发现,似乎是给 vim 中启动的终端默认提供的颜色列表。
是一个包含十六个 HEX code 的列表,编号 0~15,终端启动的时候如果输出颜色文本,就会发起对这个颜色的请求。
所以之前没加这个适配的时候,fzf 没有显示出对应的颜色的问题就得到了解决。
我写了一个简单的词频统计,对 yuyuko.vim
统计了一下常用颜色,然后放进去之后做了一些调整,fzf 就支持 yuyuko.vim 的 theme 了!
一开始其实只是想改 fzf 的适配,后来发现 fzf 本质是调用了一个 cmd,所以启动的 cmd 当中的带颜色文本也是 yuyuko.vim 的主题了,包括上面调用的 msys2 和 gitbash.
upd: 回家之后发现 fzf 对中文的支持有问题:#issue 1377。
而且作者咕咕咕了好久了,我也没那个能力自己 fork 然后修复,所以我找到了另外的一个替代品 vim-clap。
因为 LeaderF 安装和依赖太麻烦,我的 gvim 的 python3
支持总是弄不好,然后 CtrlP 又太慢。
这个东西配置主题也挺方便的,速度和 FZF 差不多,功能甚至更强大,而且对中文的支持没问题(毕竟是国人作者)
然后就 fork 了一下原 repo 的 default 主题,改了一个适合我的配色:yuyuko-clap。
不过现在里面还有一些部分依赖于 yuyuko.vim (因为用了 hi! link
),反正现在只有我一个人用,以后再说修复的事情()
另外发现了 vimtweak.dll
这个东西,可以支持 gvim 的透明,原理好像是 Vim 可以调用外部扩展函数,dll 本质是 msvc 编译出来的一个扩展库,有人用 msvc 写了窗口透明,然后加了进来,vim 就可以调用了。
现在 vimrc 多了这些:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
最近在适应 vim 的滚动,但是发现这个切屏一样的感觉,每次滚动完都反应不过来自己在那里(got lost)
所以找到了之前用过的 smooth-scroll,挺好用的。
在调试考场 vimrc 的时候发现可视模式如果使用上下左右移动会取消选择。
经过测试发现是 nocompatible 没有开,这个是兼容 vi 的设置,看起来会导致这样那样的各种问题,还是开了为好。
有一个叫 renderoptions
的选项可以在 ms gvim 下开启字体连字,设为 type:directx
。
原理我还没看,不过这个略有一定缺陷,需要以主动或者被动方式刷新才能正确显示。
不过已经够用了。
之前在 noilinux 下用的 vim 都会自动高亮匹配(搜索,不是括号匹配)
但是没找到这个选项,今天发现是 hlsearch
,但是匹配完了需要用 :noh(nohlsearch)
取消。
所以就给 <C-l>
绑了下,刷新的同时 :noh
。
<C-r> <reg(寄存器名称)>
可以在 command 模式下复制粘贴。
又是一个困扰我好久的老问题:在一些 vim 上我的 inoremap {<CR> {}<ESC>i<CR><ESC>O
不起作用,他不会自动缩进。
和 Earthmessager 经过二分和删除 vimrc 的排查,发现是因为没有开启 smartindent
,cindent
。
发现 ms-vim 好像是不用开的,很神秘,但是又发现一个问题,这两个选项不管什么语言,它都会直接判大括号的缩进,如果没 close 就会缩进。
书写本文的上上句的时候就遇到了这个问题,不过鉴于一般在 md 里也不会写大括号,真要写也是 \{
,cindent 倒是不会判这个。
所以就这样吧,如果之后遇到问题了再做修改,保留 cin si
两个设置。
然后在测试 cindent
的时候发现它对 lambda 表达式的缩进不是很满意,help ci<TAB>
发现还有一个 cinoptions
,查看文档发现我需要的是 j1
。
默认的是(在我上面那个 imap
生效之后):
1 2 3 |
|
如果是 j1
,那么效果是:
1 2 3 |
|
我比较喜欢的是这种。
然后对于 if 里面多条件的缩进,我想要的差不多是这样:
1 2 3 4 5 |
|
这个似乎不需要额外设置了。
另外 set list
可以看不可见字符,所有设置取消不是用 unset
而是 set noxxxx
。