之前已经初步配置好的vim
http://blog.csdn.net/qkoqhh/article/details/78535236
然而还是出现了一些比较尴尬的情况。。
之前处理括号补全时是使用了autopair插件,不得不说这是一个非常友好的插件。。
然而考场上你去哪找插件。。
所以括号补全还是得自己写。。
vimrc使用的语法是vimscript,这方面的资料并不算多,也不需要深入学习。。因为只是偶尔用一下。。所以现场百度一下应该就可以。。
然后来先补充一下vimscript的一些知识吧。。只列出和我自己所写的vimrc相关的知识点,所以比较零碎。。
弃了下坑发现好多东西都忘了。。还是。。百度吧。。。
1.
inoremap a b表示insert模式下的一个映射,即在敲入a时自动等价于敲入b
nore表示的是只映射一次,即b中的命令不再映射(当然这和本文无关)
nmap表示normal模式下的一个映射,和上面效果相同
2.
由于
在写函数时返回值是字符串,如果直接返回
3.
vimscript貌似不会区分'和"还有==和=所以字符串和字符随便引。 。
4.
'.'字符表示当前光标
5.
a:表示的是一个变量空间。。申请变量和调用是要这么写的。。a表示在函数内的空间。。其他空间自行百度。。
6.
区别getline和line,getline表示获得当前行(返回整行的字符串),line表示获得当前行号(返回整数)
7.
其他。。应该看看就知道是干嘛的吧。。不造的可以提问。。_(:3 」∠)_
然后上新配置文件。。
"@file : .vimrc
"@author : qkoqhh
"@date : 2018-04-02
"@details: https://blog.csdn.net/qkoqhh/article/details/79505847
set nu "显示代码行号
syntax on "关键词高亮显示
set cindent "C语法自动缩进
set autoindent "新行自动缩进
set shiftwidth=4 "缩进宽度 4
set tabstop=4 "tab键宽度 4
set softtabstop=4 "制符表宽度 4
set nobackup "不备份
set mouse=a "鼠标滚动时为屏幕滚动而不是光标滚动,鼠标选中时自动切换V模式选中
nmap "+p
nmap "+y
vmap "+y
"设置复制和粘贴快捷键ctrl+c和ctrl+v
map ggVG
map! ggVG
inoremap ( ()i
inoremap [ []i
inoremap { {}i
"括号补全
inoremap " =QuoteDelim('"')
inoremap ' =QuoteDelim("'")
"引号补全,考虑了一些特殊情况
inoremap =PairSpace()
"主要处理大括号快速缩进
inoremap =PairRemove()
"自动删除匹配括号
function PairRemove()
let a:line=getline('.')
let a:left=a:line[col('.')-2]
let a:right=a:line[col('.')-1]
if index(["(","[","\'","\""],a:left)!=-1&&index([")","]","\'","\""],a:right)!=-1
if len(a:line)==col('.')
return "\dldla"
else
return "\dldli"
end
elseif a:left=='{'
let a:nextline=getline(line('.')+1)
if a:right=='}'
if len(a:line)==col('.')
return "\dldla"
else
return "\dldli"
end
elseif match(a:line,'}')==-1&&match(a:nextline,'}')!=-1
return "\jddk$dla"
end
end
return "\"
endf
function PairSpace()
let a:line=getline('.')
let a:col=col('.')
if a:line[a:col-1]=='}'&&a:line[a:col-2]=='{'
return "\\zzO"
endif
return "\"
endf
function QuoteDelim(char)
let line = getline('.')
let col = col('.')
if line[col - 2] == "\\"
return a:char
elseif line[col - 1] == a:char
return "\"
else
return a:char.a:char."\i"
end
endf
功能的话注释已经写得挺清楚了。。然后来讲一下如何实现的。。
主要难点是在不熟悉语法,函数语法功能很弱(貌似连循环都没。。
所以在编写上只考虑自己的习惯。。主要模仿autopairs的效果。。
对那些不带函数的inoremap,可以自己去模仿里面的映射体会实现过程,这里就不再赘述。。
那先来说说pairspace吧。。
离开autopairs之后,补全还算比较容易解决。。将左括号映射成双括号就可以了。。
然而麻烦的是像在{}中打回车时,并不会像以前一样生成一个新空行
像这样:_代表光标处
xxxx{
_
}
而是这样
xxxx{
}
这样我就还要再打多一行,十分不爽。。
网上有个解决方案,直接将{映射成{}
这样可以直接直接出现我想要的效果。。然而这样不就和dev一个德性了么。。{}我也需要啊,我还要压行呢。。
经过思考。。貌似对大括号的缩进窝只有上述这2种情况的需求,所以。。分类讨论吧。。
{}这个是需要保留的,所以网友的方案一定要被pass,然而打出换行效果是在敲了
然后就只是判断打enter的时候2边是不是{}就可以了。。
然后发现这个括号没办法自动配对删除啊 。。。
“”和‘’和()和[]还比较好解决,个人习惯只有在这2个相邻的时候才会考虑配对删除,所以这2个直接判断相邻就可以了。。
麻烦的还是{}。。因为上面功能实现后会经常出现这么2种情况:
xxxxx{
}
或者
xxxxx{
}
这个时候就会考虑配对删除了。。网上有一个非常好的方法就是用execute切换成n模式,然后使用%就可以跳转到对应括号上去(十分强大的技巧,学习学习。。)然而。。如果{}中间有东西,窝是并不想去掉的,因为偶尔会出现打多一个括号然后从又括号开始一直狂删的情况(太菜了qaq)然后这样很容易误删啊。。(有必要说明的是。。上面说到的根据相邻的删法一般并不会导致误删的情况,毕竟窝是不会这么打的,像(xx(()))。。当然有时候会。。这个bug先留着吧。。影响不大其实。。)而且就是光标跳转后一直搞不懂光标的确切位置在哪(菜蛙qaq),所以放弃了这个蛮不错的方案。。
然后考虑到autopair也没有解决第二中情况。。所以我们就只考虑第一种吧。。
考虑个人习惯,第一种情况中有几个特点:
1.{肯定是其所在行的最后一个字符
2.}肯定是其所在行的最后一个字符
3.}其所在行除了}都是缩进
4.最后一个字符是}的行要么是第一种情况中的,要么是没有换行的{}
5.删除的时候光标在{后面
所以判断情况一的依据就是,在光标所在行下一行的最后一个字符是否为}
然后如果是,直接删掉下一行和该行的最后一个字符。。
可能这种删法只适合窝自己,毕竟窝是没有在第二行的}前面下过功夫的。。
还有。。还有一种情况。。就是在n模式下删除的时候,在行中删除列标不会变化,而在行末删除列标是会-1的,需要特判一下。。
这个PairRemove可能还有很多bug,虽然下了不少功夫还是写得很槽。。
最后还有一个QuoteDelim。。这个其实是抄别人的。。。来源窝也忘了_(:3 」∠)_
主要是处理引号,主要判断了转义字符 '\'的存在还是有必要考虑的。。字符串里面的括号窝是没有考虑的。。毕竟少用。。而且实现起来又不造得花多少功夫。。就不弄了。。
然后还有就是前面有一个缺一半的引号就不再打2个引号这样来补全。。。当然括号是没有这样的问题的23333
bug是肯定有的啦。。不过对窝个人编写而言几乎不会出现什么问题。。其他人实在难以保证。。所以这就是vim最大的好处,可以根据自己的习惯和需求为自己量身定做自己的映射法则。。故本代码仅供参考,可能只勉强适用于写c++的ACMer/OIer,所以出了问题也别来找窝丫23333333
以后可能自己使用过程中会发现更多bug,会有所修正。。可以说会持续更?