算法竞赛中好用的 .vimrc 配置分享与说明
in 杂文 with 2 comments

算法竞赛中好用的 .vimrc 配置分享与说明

in 杂文 with 2 comments

前言

好久没有发过博客了,高三和大一的生活都比较忙碌(摸鱼),一直没什么时间整理博客。

一来, 是因为自己最近主要还是以学习基础知识为主,倒是没什么好分享的。
二来,也是因为自己发博客并不喜欢只是单纯地记录日常,而是希望写的东西能帮到其他人,才发的博客。

言归正传,因为最近在算法竞赛中纠结于各种 IDE,于是就选择了比较广泛使用的 VIM 文本编辑器

又称之为乌干达编辑器

34556-1nnnr5rcq1c.png

Bram Moolenaar是vim的作者,他和其他一些热心的人去过基巴莱区的儿童救助中心(KCC),在那儿他们作为志愿者在KCC服务。
在此过程中,他们了解了当地儿童的生存状态,知道他们需要帮助,于是回国后他们创立了ICCF Holland来帮助KCC,Bram Moolenaar自然就是创始人之一了。
其中,基巴莱区是非洲中部国家乌干达的111个区之一,主要经济是农业,非常贫困。现在应该可以解释,为什么欢迎页面上是“帮助乌干达的可怜儿童”了。

正文

特点

学习如何使用 VIM 是一个方面,另一方面,自己也要配一个方便使用.vimrc 配置文件。

这个方便,有哪些特点呢:

  1. 配置文件要符合自己的使用习惯,包括换行缩进这些码风的偏好。
  2. 配置文件要精简易输入,因为在比赛中是需要自己配置环境的时候手动输入 .vimrc 配置文件的。

.vimrc 内容

filet indent on
se nocp hi=1000 rnu fdm=indent fen wmnu ic scs ls=2 sc nomagic report=0 mat=0 sm nu si ts=4 hls sw=4 sts=4 sta
sy on

:inoremap ( ()<ESC>i
:inoremap [ []<ESC>i
:inoremap { {}<ESC>i
:inoremap {<CR> {<CR>}<ESC>O

:inoremap ) <c-r>=Close(')')<CR>
:inoremap ] <c-r>=Close(']')<CR>
:inoremap } <c-r>=Close('}')<CR>

func! Close(char)
    if getline('.')[col('.') - 1] == a:char
        return "\<Right>"
    else
        return a:char
    endif
endfunc

map <C-A> ggVG"+y
map <C-S> ggVGc
map <F5> :w<CR>:!g++ -O2 -std=c++11 -Wall -Wextra -Wshadow % -o %<<CR>
map <F6> :!time ./%< <in.txt

注解

配置文件内容贴出来了之后,就来介绍一下里面内容的配置含义。

设置属性部分

关于设置项里面的缩写,这里给出表格:

缩写全称
filetfiletype
seset
hihistory
rnurelativenumber
fdmfoldmethod
fenfoldenable
wmnuwildmenu
icignorecase
scssmartcase
lslaststatus
scshowcmd
nocpnocompatiable
matmatchtime
smshowmatch
nunumber
sismartindent
tstabstop
hlshlsearch
swshiftwidth
stssofttabstop
stasmarttab
sysyntax

filetype indent on ,用于开启文件类型检查,并且载入与该类型对应的缩进规则。


set ,表示设置 VIM 内的可设置项目。


history ,表示 VIM 保留多少条历史操作记录可供你回退,这里设置的是 hi=1000,也就是1000条。


number,用于在窗体左侧显示行号。

relativenumber ,表示显示相对行号,有利于输入各种 VIM 操作而不需要自己计算行数,比如 d6j 的多行删除操作。

开启相对行号效果:

67462-gz6klft6ans.png

关闭相对行号(只开启行号显示)效果:

60092-qfhs6f4kh19.png


foldenable ,用于开启代码折叠的功能。

foldmethod ,用于设置折叠所依据的规则,
可以分为 manual(手工折叠)、indent(缩进折叠)、marker(标记折叠)和 syntax(语法折叠)等几种。

关于折叠有以下快捷键:

操作说明
za打开/关闭当前的折叠
zc关闭当前打开的折叠
zo打开当前的折叠
zm关闭所有折叠
zM关闭所有折叠及其嵌套的折叠
zr打开所有折叠
zR打开所有折叠及其嵌套的折叠
zd删除当前折叠
zE删除所有折叠
zj移动至下一个折叠
zk移动至上一个折叠
zn禁用折叠
zN启用折叠

效果如下:

48974-ikp3idpptx.png

73932-zrbb1n81rt.png

更多介绍参照这篇博客 VIM学习笔记 折叠 (Fold)


wildmenu,用于扩展 VIM 命令行的补全功能。

在命令模式下,输入部分指令后,按下 Tab 键自动补全。
如果有多个选项,第一次按下 Tab,会显示所有匹配的操作指令的清单,再按下 Ctrl-n 或者 Ctrl-p 进行左右切换选择。

78263-3s5rk9tge2t.png


ignorecase ,用于设置搜索时默认忽略大小写。

smartcase ,如果也设置了 ignorecase,那么对于有大写字母的搜索词,将大小写敏感;其他情况都是大小写不敏感。

63844-ue6o14carf.png

81026-zxbk29lo7iq.png


laststatus,用于是否显示状态栏。0 表示不显示,1 表示只在多窗口时显示,2 表示显示。

有状态栏:

45942-5nn4rnxpczp.png

无状态栏:

16488-041722h0n548.png


showcmd,用于在普通模式下,在底部显示当前键入的指令。

如图,当我想输入 d6j 的时候,刚按到 6 时显示的情况:

25331-wu3mej5777a.png


nocompatiable,不与 Vi 兼容,即采用 Vim 自己的操作命令。


nomagic,关闭正则表达式匹配的功能,仅有 ^ $ 具有特殊含义。

因为正则表达式本人不怎么常用,就算是背了,几个星期没用,各种元字符又忘得七七八八了。
所以干脆就把正则表达式匹配给关了23333

21540-75sbj40cj4r.png


report,用于设定在多少数值以上的行被更改时,在屏幕下方提示更改的行数,设置为 0 则总是提示。

还是以操作 d6j 为例子,会显示有七行的更改:

59993-fqy3na1dfro.png


showmatch,表示在光标遇到圆括号、方括号、大括号时,自动高亮对应的另一个圆括号、方括号和大括号。

matchtime,输入成对的括号时,Vim 会帮助你跳转并高亮一下匹配的括号,然后回到你正在输入的位置。
不过默认的 500ms 停留时间比较拖沓,这里改成 0 以达成快速跳转的目的。


smartindent,开启智能缩进,对当前输入的语句和符号做出相应的缩进行为


tabstop,设置当按下 Tab 键时,VIM 显示的空格数。


hlsearch,打开搜索高亮模式,若搜索找到匹配项就高亮显示所有匹配项。

63844-ue6o14carf.png


shiftwidth,定义了每一次缩进的长度,比如说,当使用 <<>> 进行缩进的时候,VIM 使用的数值就是这个。


softtabstop,会影响 TAB 插入的空格。所以我们总是把 softtabstop 设定成和 tabstop 一样的数值。


smarttab,只作用于行首位置。当 smarttab 开启时,在行首键入 TAB 会填充 shiftwidth 设定的数值,在其他地方则填充 tabstop 设定的数值。


syntax,用于开启语法高亮。或许称为词法高亮更加贴切,因为 VIM 并不去分析文件的语法。
为了保证快速的解析,VIM 使用特定的语法来匹配词法规则并为它们着色。


设置过程中,可以输入:help '属性名' 来查询对应的设置属性的详细介绍
87873-0k212yskbtr.png

键盘映射部分

inoremap 中,i 表示在插入模式下工作,nore 表示不递归调用(毕竟这里是把输入括号映射到输出一对括号),map 则是表示键盘映射

:inoremap ( ()<ESC>i
:inoremap [ []<ESC>i
:inoremap { {}<ESC>i

这里表示输入一个左括号,映射到输出一对左右括号,并把光标移动到括号中间继续进行插入


:inoremap ) <c-r>=Close(')')<CR>
:inoremap ] <c-r>=Close(']')<CR>
:inoremap } <c-r>=Close('}')<CR>

这里表示输入一个右括号的时候,使用 Close() 函数判断是否已有配对的括号来决定是否输出括号。


func! Close(char)
    if getline('.')[col('.') - 1] == a:char
        return "\<Right>"
    else
        return a:char
    endif
endfunc

这里是 Close() 函数的定义。


map <C-A> ggVG"+y

这里把 Ctrl-a 映射为 ggVG"+y 的操作,目的是把从首到尾行的代码都复制进系统的剪贴板里。


map <C-S> ggVGc

这里是把 Ctrl+s 映射为 ggvVGc,也就是删除文件里所有内容,是用来修改样例输入文件 in.txt 常用的。


map <F5> :w<CR>:!g++ -O2 -std=c++11 -Wall -Wextra -Wshadow % -o %<<CR>

这里是用 F5 键进行一键编译,并加上了常用的编译参数。


map <F6> :!time ./%< <in.txt

此处把 F6 键映射为运行键,可以从 in.txt 文件直接读取样例输出结果,并返回程序运行时间。

后记

虽然说 VIM 似乎是什么比赛都通用的,但是,大概今年除外。

因为疫情原因,很多比赛都改为线上测评 + 线下监考的形式进行了,像是 CCPC、ICPC、蓝桥杯等等比赛。
所以线下的环境基本都是 Windows 系统的机器,而且默认的软件也没有 GVIM 这些软件。

到头来,还是只能拿着 Dev-C++ 和 Code::Block 硬干代码了23333。

Responses
  1. 强行记忆 vimrc 内容,牛皮

    Reply
    1. @ryan4yin

      其实就是写个博客来注释一下23333,感觉加在文件里不太好看,然后也方便以后修改的时候回想一下是什么意思

      Reply