文章目录
- 1. 安装
- 1.1 linux
- 1.2 MacOs的安装
- 1.3 Windows的安装
- 1.4 vim中文帮助文档安装
- 2. vim基本概念和基础命令
- 2.1 基本的键位映射如下:
- 2.2 vim模式
- 2.3 vim的选项和基本配置
- 2.3.1 备份和跨会话撤销文件
- 2.3.2 vim中支持鼠标
- 3. vim 常用命令 -- 应对稍复杂任务
- 3.1 光标移动
- 3.2 文本修改
- 3.3 文本对象选择
- 3.4 文本移动 -- 更快
- 3.5 重复操作
- 4. vim 的简单定制
- 4.1 vim 的目录结构
- 4.2 vim 软件包
- 5. vim 的复制与粘贴
- 6. vim的模式匹配:正则表达式
- 6.1 基本的特殊字符
- 6.2 特殊模式项
- 6.3 一些搜索举例
- 6.3.1 最长匹配和最短匹配
- 6.3.2 搜索加亮和取消
- 6.3.3 正则表达式替换
- 6.3.4 替换实例
哈哈,有点标题党的意思,vim带你成"神"?还是你通过vim成了"神"?还是学习了vim,感觉vim就是"神"? 仔细耐心体验一下vim的"神迹"。
vim 作为程序员三大美德体现:懒惰,急切,傲慢 的优秀编辑器,已经走过了接近三十个年头。
从肯·汤普逊 1978年将unix 操作系统传播开来,到比尔·乔伊 完成第一个版本的全屏编辑器 vi的开发(在此之前有很多基于行的编辑器ed,em,en ,ex),再到布莱姆·穆勒纳尔 持续维护了三十年的vi 克隆版本, 最后也就演变成了我们现在使用的vi IMproved – vim。
vim的优点如下:
-
vim 是一个完全跨平台的编辑器
从开始的unix,到 现在最为通用流行的 linux,windows,Macos,再到不经常用的操作系统OS/2, BeOS,甚至ios和android也能找到vim的移植版本。
-
vim 是一个高度定制和可扩展的编辑器
通过vim 自身脚本语言(Vim Script)可以扩展vim的功能,如果vim 脚本能力还不足,则可以通过Python ,Perl 等其他通用脚本语言进行扩展。这样就能够非常自由得打造属于自己的专属环境。
-
vim 良好的生态环境
网络上已有的现成的脚本和插件,能够直接搭建顺手的开发环境。像经常用的语法补全,语法检查等常用功能,都可以在vim下实现,且能够通过配置 不需要离开vim 编辑器就能完成从写代码、到编译运行的大部分工作。
有这么多优点,又是无数大佬自己使用的编辑器,那么vim 就需要快速搞起来,来让自己的工作效率进一步提升,希望这篇成神之路能够带给你在vim上足够多的帮助。
客观来讲,vim的配置确实非常繁琐,甚至复杂,想要达到现在
vscode
,
clion
的方便程度确实会花费不少时间。但vim的高效是能够在手指不离开键盘的情况下完成任何场景下的编辑工作,手指快速敲击三个键以内就能够达到一段文本的增删改查。
当然打造自己的vim 感觉 就像是公元前1500年前后 印欧语系游牧的蛮族潜心打造的青铜器,青铜战车 ,马具马鞍,戴着他们横扫了整个欧亚大陆的古代文明,从尼罗河的埃及文明到地中海的米诺斯文明,到幼发拉底河和底格里斯河的美索不达米亚文明,到印度河文明和中国的商朝(北方的游牧民族)都被精良高效的战争民族所取代,颠覆了整个大陆的格局。
vim所做的就是能够一统整个ide的大陆,用灵活的插件搭配强大的快捷操作实现 ,我们只需要在这个大陆上专注耕耘,建立自己的的伟大帝国。
先瞅瞅当前我的vim 使用上的一些效果:
- 窗口分割
- 自动补全
- markdown
-
查看文件历史修改记录
这上面仅仅是展示很小很小一部分插件的编辑功能,每一种编辑功能都会有很多更加方便的细节配置。
同时 本文也只是提供一条道路,希望大家能够在这条道路上找到适合自己的编辑模式。
最后vim 当然也能够支持阅读源代码,只不过源代码显示上不太舒适,这里使用clion这个老东家也很久了,所以还是不能喜新厌旧呀,用它作为撸源码的工具 还是很给力,而vim主要用在编辑或者写代码之上。
vimrc已经放置在vim-github,不过需要
vim
版本在8.2以上,或者
neovim
在0.4.4版本才行。
如果能够看懂vimrc中的简单vim script,建议先熟悉一下基本键位和操作,熟悉之后会发现编辑查看效率 急速飙升,指尖如飞。
1. 安装
1.1 linux
-
Redhat 和 Centos
查看是否已经安装vim
yum list installed |grep vim
如果只有如下这样的输出,则说明是最小的vim安装
vim-minimal.x86_64 2:7.4.160-2.el7 @centos7.3-x86_64-base
建议使用
sudo yum install vim-enhanced.x86_64
安装增强版的vim。
-
Debian 和 Ubuntu
使用apt进行安装,同时在这两种系统下vim有比较多的功能
vim
vim-athema #适用于老的 X-window 界面
vim-gnome
vim-gtk #使用于GTK环境
vim-gtk3 #适用于GTK环境
vim-nox #有比较全面的文本界面vim包
vim-tiny #最小功能的vim包
安装可以遵循如下规则
- 如果系统使用的是GNOME桌面环境时,安装
或vim-gtk3
vim-gnome
- 如果使用的是KDE桌面 ,安装
vim-gtk
- 如果使用文本界面,安装
vim-nox
可以通过
apt list --installed|grep vim
查看已经安装的vim版本
安装:
sudo apt update
sudo apt install vim-gtk3
手工编译安装,至少加上Python 支持和图形界面的支持:
./configure --enable-pythoninterp \
--enable-python3inerp \
--enable-gui=auto #auto可以根据需要换成gtk3等其他数值
make -j
sudo make install
安装成功之后,通过
vim --version
能够看到一个python版本的支持。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iNzEDN3MGOiFWMkVzM4QjNzYzXzMzMxETM0AzLcFTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
1.2 MacOs的安装
直接使用homebrew进行安装
brew install vim
brew install macvim
参考homebrew进行mac下的homebrew的安装
1.3 Windows的安装
通过网址https://www.vim.org/download.php#pc下载windows版本的vim.exe,windows下的vim版本还是以32位为主,基本也满足正常的开发需求了。
安装过程中进入如下界面:
需要注意如下几个选项:
- “安装批处理文件 (Create .bat files)” 对于使用Vim命令行的开发者来说是刚需,所以需要选择
- “创建图标 (Create icons for vim)” 根据个人选择展开
- “创建默认配置文件” 去掉这一项,可以通过后面会说到的方式创建配置文件
- “安装多语言支持” 使得vim的菜单可以支持多语言选项
点击下一步,修改安装的文件目录,安装完成即可。
这个时候会打开一个默认的README文件,输入
:e \_vimrc
,输入如下内容:
set enc=utf-8
set nocompatiable
source $VIMRUNTIME/vimrc_example.vim
按
ZZ
退出即可
这里说一下windows和linux下vim的区别
- windos下vim配置文件是_vimrc,unix下一般默认~/.vimrc
- windos下打开的vim文件都成为了_ 开头,如_viminfo
- 打.开头的vim配置目录.vim,也变成了vimfiles
同时windos下vim的插件安装也是比较费劲的,其实希望成为vim"之神"的同学应该以类unix环境为主,至少一个虚拟机下安装ubuntu镜像也并不会消耗太多的时间。
1.4 vim中文帮助文档安装
英文版的教程,使用 终端下直接输入
vimtutor
即可看到,同时一些网友也翻译了中文版本的vim帮助文档,这个安装在vim8中也是非常简单的。
以类unix环境为例(windows下需要将.vim 改为vimfiles目录),执行如下命令:
cd ~/.vim
mkdir -p pack/my/start/
git clone https://github.com/yianwillis/vimcdoc.git pack/my/start
cd pack/my/start
./vimdoc.sh -i #安装help.txt的中文帮助文档
./vimdoc.sh -u # 如果不想要中文版的help信息,则可以卸载掉
进入vim,输入
:help
之后可以有如下的效果:
一般类unix操作系统,可以通过
LANG=zh_CN.UTF-8 vimtutor
来进入一个中文版本的vim教程
PS:因为vim使用ctrl键会比较多,建议大家学习的时候将ctrl映射到之前的CAPS(mac下),或者windows CapsLock下
2. vim基本概念和基础命令
2.1 基本的键位映射如下:
建议大家在看完之前的vim 教程之后在来熟悉这一块,保证上面的基本命令都已经很熟悉了。
以上图没有说明vim的命令行命令
-
– 不保存退出:q!
-
– 保存退出:wq
-
– 替换:s
-
– 执行外部unix命令:!
-
– 一般缩写为:edit
,编辑文件:e
-
– 写入指定文件:w
-
– 读文件:r
-
查看帮助信息:help
- 使用
和 Ctrl + D
键将命令补全Tab
2.2 vim模式
- 正常模式(普通模式):缺省的编辑模式,如果不加特殊说明,一般提到的特殊命令都直接在正常模式下输入;任何其他模式都可以通过键盘上输入
回到普通模式ESC
- 插入(insert) 模式:输入文本时使用,普通模式下键入
(insert)或则i
(append)即可进入插入模式a
- 可视(visual)模式:用于选定文本块,可以使用
键来按字符选择,vim中也提供了按行和块进行选择的方法v
- 命令行(command-line)模式: 用于执行较长,较复杂的命令。普通模式键入
即可进入该模式。 使用:
或者/
开始搜索也算作命令行模式。命令行模式下需要输入回车才算完成。?
再次强调,只要按下
ESC
,无论在哪个模式下,都会回到普通模式。
这里再次说明以下,可以利用好vim命令行下的help帮助文档,能够提供非常方便的帮助操作。
2.3 vim的选项和基本配置
随着持续不断得使用vim,它的配置会不断得增加,从而应对自己在不同场景的需求。
接下来看看一些基本的vim配置,之前说过unix系统下的vim配置是
.vimrc
文件,windows的配置则是
_vimrc
文件
set enc=utf-8
set nocompatiable
source $VIMRUNTIME/vimrc_example.vim
如之前的一段类似于shell 脚本的 配置如上,三行的基本含义如下:
- 设置编辑文件的编码格式为utf-8
- 设置Vim和vi不兼容
- 倒入vim的配置示例(示例中包括一些有用的选项:语法高亮,搜索高亮,命令历史等等)
2.3.1 备份和跨会话撤销文件
vim支持跨会话的编辑能力,这个在目前的编辑器中还没有其他的能够做到的。举个例子,编辑完word,将word关闭,再重新打开,想要做到撤销上一次的操作,或者恢复到之前n次操作,这个不可能的,vim能够支持这样的功能。
基本配置如下两个:
set backup
set undofile
- 第一个选项使得我们的每一次编辑都能够保留上一次的备份文件
- 第二个选项使得vim重新打开一个文件时仍然能够撤销之前的编辑(undo),还会保留一个编辑历史的文件(undofile)
这个时候当前目录下会出现针对编辑后文件的些
~
结尾的备份文件和
.
开头的undo文件
这里通常只保留撤销文件的功能,有了跨会话撤销的能力,基本备份的功能就用不到了,将撤销的文件放在个人用户目录下,保证文件的安全和目录的干净。
set nobackup
set undodir=~/.vim/undodir
set undodir=~\vimfiles\undodir "windos下的形态,目录符合和unix有差异
为了保证目录存在,可以再增加如下判断:
if !isdirectory(&undodir)
call mkdir(&undodir, 'p' , 0700)
endif
&undodir
是之前设置的
undodir
值,mkdir括号内部指定mkdir的命令选项 和 目录权限
2.3.2 vim中支持鼠标
我们正常使用vim的过程中,看代码肯定比写代码要多, 所以这个时候鼠标还是比较有必要存在的。而且鼠标在非线性跳转上比键盘快很多。
我们在vim中对鼠标的需求是:
- vim内部使用鼠标通过可视模式(visual)选择内容,且仅在vim内部使用
- 通过将vim内部的可视模式选择的文本和外部操作系统进行编辑交互(在vim内部鼠标选择后复制,粘贴到外部系统软件之中)
所以针对以上两种的使用需求,vim都需要能够支持:
if has('mouse')
if has('gui_running') || (&term =~ 'xterm' && !has('mac'))
set mouse=a
else
set mouse=nvi
endif
endif
3. vim 常用命令 – 应对稍复杂任务
3.1 光标移动
- 基本移动 :上、下、左、右 –
,k
,j
,h
; 缺陷是这四个键不能在插入模式下移动l
- 跳转行首:
, 跳转行尾: 0
, 跳转到行首到第一个非空白字符: ^$
- 一次移动超过一个字符:
/b
, w
/B
以上含义分别是:words backward, words forward,用来向后或者向前跳转一个单词。大写跳转和小写跳转的唯一区别就是小写和编程语言的标识符类似,认为一个单词的组成是由字母,数字和下划线组成;而大写则认为非空格字符都是单词。W
- 根据单个字符进行选择:
/f
, t
/F
以上含义是:找到下一个紧接着输入的字符(如果输入f/t,F/T之前加上数字n,那就是下面第n个),比如找到当前行的第二个d字符,输入T
f2d
即可。两者的区别是f会包含这个字符,t不包含这个字符。大写的F/T则是进行反方向的搜索。
比如下面字符串
,光标在括号内的第一个字符*nc = (struct mg_connection *) data;
的位置,我想一次删除括号内所有内容,如果不用s
的话需要仔细考虑f/t
的匹配规则,最后使用w
,而现在我们只需要使用c3w
直接匹配ct)
就可以。)
- 文章内移动:
和(
分别是移动到上一句和下一句;)
和{
分别是移动到上一段和下一段}
- 开头和结尾跳转:
和 ctrl - Home
跳转到文件的开头和结尾;ctrl - End
和gg
G
也是分别跳转到文件到开头和结尾。
只不过G这里的区别是跳转到最后一行的第一个字符,不是最后一个字符
3.2 文本修改
Vim的基本教程中我们知道
c
(change),
d
(delete),
i
(insert)都能够对文本进行修改,vim的原则是常用的功能要尽可能按键少。因此很多常用的功能在vim中都会有不同的按键,而且大写键也会相应得重载相近但稍不同的含义(最后一个字符的包含与不包含这样的区别)。
-
加动作进行删除: d
删除整行,dd
相当于D
删除到行尾d$
-
加动作进行修改: c
修改整行,cc
相当于C
删除到行尾并进行插入c$
-
相当于s
,向右删除一个字符并进入插入模式,cl
相当于S
,替换整行cc
-
在当前字符前进入插入模式;i
则相当于I
把光标移动到行首非空白字符,进入插入模式^i
-
在当前光标所在字符后面进入插入模式,a
相当于A
,把光标移动到末尾,然后进入插入模式$a
-
在当前行下方插入一个新行,然后在新行进入插入模式;o
在当前行上方插入一个新行,并进入插入模式O
-
替换光标下的字符; r
进入替换模式,每次按键替换一个字符,直到按下R
退出替换模式ESC
-
撤销最近的一个动作;u
撤销当前行的所有修改U
这一些按键基本能够让大部分的编辑任务在一两个按键就能完成,不过需要长期练习,形成肌肉记忆 。
3.3 文本对象选择
这个功能非常适合程序中的逻辑块编辑,方便我们在一般模式下对程序代码或者文件进行随意自如的修改。
基础键的命令
c,
,
d
是用来对文本内容进行修改,而像
a
,
i
,
w
这样的能键能够附加到基础操作命令之后,对一段文本进行快速修改操作。
针对文本"coding boy = z_stand" 的修改利用如上键可以有如下组合策略。假设光标停在coding 的d上
-
delete word, 删除dw
,结果是ding
"co boy = z_stand"
-
delete inside word, 删除diw
,结果是coding
" boy = z_stand"
-
delete a word,删除daw
, 还有一个空格。 结果是coding
"boy = z_stand"
-
删除diW
,结果是"coding
boy = z_stand"
-
删除daA
还有一个空格。结果是"coding
boy = z_stand"
-
删除di"
结果是coding boy = z_stand
""
-
删除da"
"coding boy = z_stand"
,字符串包括双引号被全部删除
这个操作后面加"或者其他的字符,比如
,则会删除与其匹配的(
内部所有的内容)
以上介绍的是
d
操作,同样的基础键还可以用
c
进行,只不过d是执行完成删除操作之后vim还是一般模式,而c是执行了之后进入插入模式。
同时像如下的几个键也能够支持文本对象的选择,可以像
d
和
c
一样搭配
a
,
i
,
w
,单引号,双引号,左右括号等
- 搭配
(sentence)对句子进行操作 – 适合英文文本编辑s
- 搭配
(paragraph) 对段落进行操作 – 适合英文文本编辑,以及带空行的代码编辑p
- 搭配
(tag) 对HTML/XML 标签进行操作 – 适合HTML, XML等代码编辑t
- 搭配`和’,对shell或者python等脚本代码进行操作
- 搭配
和[
方括号,对括号里面的内容进行操作]
- 搭配
和{
大括号,对括号内容进行操作 – 适合C/C++语言}
- 搭配
和<
角括号 – 适合C++ 模版操作>
再进一步,在
a
和
i
之前能够增加数字,表示操作多少个文本对象,适合针对嵌套文本的操作
比如
3.4 文本移动 – 更快
-
向上翻页<C-B>
-
向下翻页<C-F>
-
向上翻半页<C-U>
-
向下翻半页<C-D>
-
跳转到第五行5G
-
跳转到第六列6l
-
, H
, M
当前屏幕下,分别移动光标到屏幕顶部,中间,底部L
-
和 <C-Y>
保持光标不动,滚动屏幕,ctrl-y向上,ctrl-e向下<C-E>
-
将光标所在行滚动到屏幕顶部,zt
将光标所在行滚动到屏幕中部,zz
将光标所在行滚动到屏幕底部zb
3.5 重复操作
-
重复最近的字符查找 ;
或者f
操作t
-
重复最近的字符查找, 反方向,
-
重复最近的字符串查找操作(/和? 查找模式)n
-
重复最近的字符串查找操作(/和?)反方向查找N
-
重复执行最近的修改操作.
4. vim 的简单定制
通过对vim目录,配置文件,扩展包管理器的一些介绍来让大家能够初步配置自己的vim
4.1 vim 的目录结构
vim的工作环境是通过运行支持的vim插件来设定的,合理得定制自己的vim需要了解vim的目录构造,知道怎么快捷得找到这一些存放插件的位置。
在vim8.2版本下,不同平台安装vim的位置有差异:
- unix 下面
/usr/share/vim/vim82
- mac下的MacVim 运行时软件位置
能够看到很多子目录,如/Applications/MacVim.app/Contents/Resources/vim/runtime
,autoload
,colors
等doc
- 最常用的是如下几个目录:
-
vim 的语法加亮文件syntax
-
vim 的帮助文件doc
-
vim 主题配色方案colors
-
vim的插件文件plugin
以
syntax
目录 为例,MacVim支持619种语法高亮格式,.vim之前的内容就是支持的语言语法。
在一般模式下可以通过
:setfiletype cpp
来指定cpp文件的语法高亮。
同时一般模式下输入
:help
显示的帮助信息都在
doc
目录之下;通过
:colorscheme
加tab键能够看到很多种不同的配色主题,这一些主题配色都会在
color
目录之下。
可以在
.vimrc
配置中加入一行
color desert
,指定每次启动vim加载的配色方案
接下来重点看一插件
plugin
目录,能够在原生vim下支持无数便捷的插件接入,这也是为什么vim被成为编辑器之神的原因。像我们在
clion
,
vscode
,
sublime
中体验到的便捷特性(代码补全,源码阅读时的跳转,代码调试等)都能够在vim中通过插件得到配置,而且我们能够将快捷键通过
vim script的map
减少来进一步加快编辑操作,以上是一些可以扩展的插件,而
plugin
目录下的插件则是系统内置的插件,分别具有如下功能:
-
获得最新的vim脚本插件getscriptPlugin.vim
-
编辑.gz结尾的压缩文件,打开时能够自动解压缩,保存为gzip.vim
结尾的文件时自动压缩.gz
-
模式匹配的逻辑运算符,允许以非标准正则表达式来写模式匹配logiPat.vim
-
使用vim来查看man帮助文档manpager
-
对括号进行高亮匹配matchparen.vim
-
从网络上编辑文件和浏览目录(支持多种协议如ftp和scp,可以直接打开目录来选择文件)netrwPlugin.vim
-
支持rrhelper.vim
编辑,vim的多服务器会用到这一个功能--remote-wait
-
在拼写文件缺失时自动下载,vim一般只安装了英文的拼写软件spellfile.vim
-
支持编辑(压缩)tarPlugin.vim
结尾的压缩文件,这里和.tar
不同的是不支持写入.gz
-
把语法加亮的结果转成htmltohtml.vim
-
创建和解压.vba文件vimballPlugin.vim
-
和zipPlugin.vim
类似,支持读和写 .gz
结尾的压缩文件.zip
这几个简单的默认配置插件已经能够体现出了一部分vim的强大之处,简单演示部分插件功能如下:
4.2 vim 软件包
vim 的目录有点传统的unix格式,一个功能(插件plugin)会分散在多个不同的目录下
- 插件的主题通常会在plugin目录下
- 插件的帮助文档会在doc目录下
- 有一些插件只对某一些文件类型有效,会有文件放在ftplugin目录下
- 有一些插件会有自己的文件类型检测规则,会有文件放在ftdetect目录下
- 有一些插件有特殊的语法加亮,会有文件放在sytax目录下
我再mac上是使用
vim-plug
作为自己的包管理器,其他的
vandle
或者
minpac
都是可以的。
- 下载:
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
-
使用 plug对插件进行管理
安装上vim-plug之后就可以在vim的配置文件中增加自己想要的插件,mac下的vim配置在
,windows可以通过打开vim输入~/.vimrc
:e \_vimrc
打开自己的vim配置文件。
插件的安装设置需要遵循如下语法,在
和plug#begin
之间就是我们要安装的插件,具体的插件需要通过plug#end
Plug
+ 插件名称来指定安装的插件:
这里需要注意的是阔行内的内容是插件下载之后的存放目录,可以自己指定,也可以按照下文中的目录存放。
call plug#begin('~/.vim/plugged')
Plug 'mzlogin/vim-markdown-toc', { 'for': ['gitignore', 'markdown', 'vim-plug'] }
Plug 'vimwiki/vimwiki'
Plug 'terryma/vim-multiple-cursors'
Plug 'junegunn/goyo.vim' " distraction free writing mode
call plug#end()
然后再保存配置文件,在vim中输入
:PlugInstall
命令就可以直接安装对应的插件了
当然,还可以直接对插件进行更新,或者清理不需要的插件,这一些命令可以通过
:Plug
按tab键自动补全。整个vim的插件管理就变得非常方便了。
5. vim 的复制与粘贴
对于命令行形式的vim,想要将外界复制的内容粘贴到 vim 的文本之中,需要有如下几步:
- 使用 vim 打开一个文件,进入 vim 的一般模式下
- 通过一般模式的 跳转命令,将光标移动到需要粘贴的行以及列处
- 输入
或者i
等插入命令进入vim的插入模式a
- 通过键盘
,粘贴到当前位置<ctrl-c>
- ESC回到一般模式,ZZ存盘退出
如果不退出vim的话则还需要通过如下两步
- 打开vim进入一般模式,通过
打开一个文件;可以使用:e file
查看有哪一些文件,通过<C-D>
选择文件并自动补全tab
- 存盘则通过:
:w
但是如果粘贴内容含有缩进,而vim又不够新的情况,还会出现缩进之间在“打架”的情况,导致整个复制缩进一直基于上一个缩进的基础上在缩进。这个情况是因为vim分不清用户是在输入,还是在粘贴,输入此时会和粘贴冲突,则会有智能缩进、制表符转换等功能。
这个可以通过
:set paste
命令来让vim知道当前文件执行的是粘贴的命令,从而不会被智能缩进和制表符转换的功能影响。
6. vim的模式匹配:正则表达式
6.1 基本的特殊字符
我们在vim的一般模式中经常需要用到模式匹配或者查找命令,通过
/
,
?
或者进入vim的命令模式
:
进行匹配操作。
vim中的正则表达式和其他常用正则表达式是有一些区别的,这里先简单介绍一下vim中的一些正则表达式的基础,在一个搜索表达式里面有如下字符,
.
,
[]
,
*
,
$
,
^
,
~
,
\
都是具有特殊含义的字符
-
可以匹配除换行符外的任何字符,如.
可以匹配 a.
, aa
等ab
-
表示之前的匹配源可以重复0次到多次,比如*
可以匹配aa*
, a
, aa
等, aaa
可以匹配a.*
, a
,ab
等,但是两者都不能匹配babc
-
匹配一行等开头,如果出现在模式的开头的话;如果在模式的其他位置,则表示字符本身^
-
匹配一行的结尾,如果出现在模式的结尾的话;在其他位置则表示字符本身$
-
匹配上一次替换的字符,如果上一次把~
替换为了abc
,那么ate
就匹配~
ate
-
匹配方括号内任意一个字符;方括号内如果第一个字符是[...]
,表示对结果取反;除开头之外的^
表示范围:如-
表示任意一个拉丁字母,[A-Za-z]
表示除了 [^+-*/]
,+
,-
,*
之外的任意一个字符。/
-
的含义取决于下一个字符,在大部分情况下包括上面的这几个(\
, .
,[
,]
, *
,$
, ^
, ~
) ,代表后面这个字符本身;在跟某一些字符时有特殊含义。\
除此之外就是普通的字符,并没有特别的含义;需要注意的是如果想要将搜索字符
/
作为普通字符来使用,则需要
\/
这样,否则vim看到的
/
就会以为模式结束了,导致错误发生。
如果模式中使用"/"作为路径的分隔符,在替换命令中可以使用使用其他模式中没有的符号作为分隔符。比如想把路径
/path/
全部替换为
/paths/
,建议不要用
:%s/\/path\//\/paths\//g
,这种样子非常容易出错。而应该使用类似的写法
:%s!/path/!/paths/!g
,当然这个只能用于替换命令。如果想要使用
/
作为搜索命令的话就没有太好的办法了,只能使用
\/
这样的形态。
6.2 特殊模式项
通过
\
开始的特殊表达式很多,如果我们想要全部了解的话可以通过
help pattern-overview
来详细查看,这里仅仅列举几个基本的特殊模式项:
-
表示之前的匹配重复零次 或一次: 如\?
可以匹配"a", “aa”, 但不能完整匹配"aaa"(可以匹配前两个字符,后两个或最后一个字符)aa\?
-
表示之前的匹配原重复一次或多次:如\+
可以匹配"aa",“aaa”, 但不能匹配"a"或"b"aa\+
-
表示之前的匹配原重复n到m遍之间。如:\{n,m}
可以匹配3个"a":“aaa”; a\{3}
表示最多匹配3个"a", 支持匹配"", “a”, “aa"和"aaa”;大括号内两个数字都省略时等价于*, 也就是之前的内容可以匹配0次或多次。a\{,3}
-
和\(
扩起一个模式, 从而组成单个匹配原:如\)
可以表示单词\(foo\)\?
出现零次或一次。foo
-
是分支内多个临接的分隔符,类似于“与”操作,表示每一项都要匹配成功,然后去最后一项的返回结果:如\&
匹配同时出现foo和bar的完整行。.*foo.*\&.*bar.*
-
是多个分支的分隔符,类似于“或”的匹配,表示任意一项匹配成功即可:如\|
可匹配foo\|bar
或foo
两个单词之一。bar
还有13个特殊模式项:
-
匹配单词的开头\<
-
匹配单词的结尾\>
-
匹配空白字符\s
-
匹配非空白字符\S
-
匹配数字,相当于\d
[0-9]
-
匹配非数字,相当于\D
[^0-9]
-
匹配十六进制数字,相当于\x
[0-9A-Fa-f]
-
匹配单词字符,相当于\w
[^0-9A-Za-z_]
-
匹配非单词字符W
-
单词首字符: \h
[A-Za-z_]
-
非单词首字符: \H
[^A-Za-z_]
-
英文字母字符: \a
[A-Za-z]
-
非英文字母字符: \A
[^A-Za-z]
-
小写字符: \l
[a-z]
-
非小写字符: \L
[^a-z]
-
大写字符: \u
[A-Z]
-
非大写字符 \U
[^A-Z]
-
其中 x 可以是以上任意一个字符: 对应字符类加上换行\_
6.3 一些搜索举例
- 想要准确匹配一个函数名:
/ \<function_name\>
- 或者将光标移动到想要匹配的关键字上面,按下
,vim就会自动提取光标下的关键字,并自动添加*
和\<
进行搜索。\>
- 如上代码片段,我想要搜索
或者ReoportError
,那么就想到了上面特殊模式中断void
\|
字符
输入
即可/\<ReportError\>\|\<void\>
6.3.1 最长匹配和最短匹配
这里有一个问题就是我们想要搜索的内容中有很多特殊字符,整个模式会变得极其复杂。
而像
*
,
\?
,
\+
和
\{}
都属于最长匹配(贪婪匹配),即模式 既可以匹配一个较长的字符串,也可以匹配一个较短的字符串的时候结果会是那个比较长的字符串。
相应的也会有一个最短匹配,同时匹配较长和较短字符是会产生较短匹配。在vim里面,最短匹配只有一种形式,
{-n,m}
,起意义和之前说得
{n,m}
相同(
\{n,m}
表示之前的匹配原重复n到m遍之间),但结果是较短而非较长的字符串。
以HTML 标签匹配为例,使用最短匹配的话,可以把模式写成
/<.\{-1,}>
,表示要求模式匹配的结果在一对尖括号里面且至少有一个字符,但越短越好。
6.3.2 搜索加亮和取消
如果也有在做上面但实验,会发现vim在搜索的过程中默认会将模式匹配的内容高亮,这个对确认自己的搜索结果是否正确非常重要。
但是如果你是用了非原生vim,比如某一个IDE的插件,那么就会发现并不是默认高亮。
而有的时候又觉得高亮太刺眼,想要去掉,这个时候vim就提供了比较方便的指令
:nohlsearch
或者
:nohls
想要恢复高亮,则可以
:set hlsearch
或者
:set hls
如果这两个取消和恢复高亮的指令使用非常频繁,则可以设置map键
noremap <LEADER><CR> :nohlsearch<CR>
我这里设置的是直接按LEADER键,我的
LEADER
键设置的是
let mapleader=" "
空格
6.3.3 正则表达式替换
替换我们正常理解就是利用之前提到的一些模式匹配特殊字符来完成,将一个字符串替换为另一个字符串。但是很多替换场景还是非常复杂的。
- 可能要保留匹配中的某一些字符,而替换另外一些字符
- 要对匹配出来的内容做大小写转换
- 可能需要 “计算” 出替换结果
- 可能要决定一行里面替换单次还是多次,是自动替换还是要 – 确认 ,等等。
-
在替换结果中保留匹配出的字符
之前我们说到
\(\)
特殊模式 除了将一个模式转变成匹配原之外,还有一个捕捉匹配的内容的作用。
按照
的出现顺序依次编号为1到9,并可以在模式和替换字符串中用\(
到\1
来访问。如果要在替换字符串中完整使用匹配内容的话,则可以使用\9
或\0
(字符 “&” 也因此要在替换字符串中写成&
\&
)
如果我想要找出作为函数调用的
,那我可以写成WebSocket
,虽然 \<WebSocket(
(
不是想要匹配的内容,但它是函数名称的一部分。从替换的角度来看需要多处理一下这个字符;在非匹配的内容比较复杂或者变化的时候,这个过程尤为麻烦。
所以vim 里还有专门匹配开始和结束的匹配原,分别是
和\zs
对于上面函数调用的这个例子,搜索模式就应该是\ze
,当然这个模式也可以匹配为\<WebSocket\ze(
或者\<WebSocket(\&WebSocket
。\<WebSocket(\&...
-
大小写转换的特殊替换字符串
把下面的字符串转变成大写,直到\U
\E
出现
\u
把下一个字符变成大写
把下面的字符变成小写,直到\L
\E
出现
\l
把下一个字符变成小写
\E
结束大小写转换
\=
开始一个返回字符串的表达式,用来计算出一个替换的结果
和其他的编程语言一样,vim的正则表达式中支持
,\t
,\r
等特殊转义字符,但在替换表达式中,\n
插入的是空字符(\n
或NULL
),而非在模式中正常的行尾符LF。如果想要插入行尾符的话我们需要使用\0
。这意味着把一个回车变成两个,需要通过\r
:s/\n/\r\r/
这样尴尬的方式来实现。
如果我们要插入
(回车)的话,需要输入CR
才行。\<C-V><CR>
6.3.4 替换实例
-
删除行尾注释
把零到多个空白字符后面出现的"//" 直到行尾全部删除, :%s!\s*//.*$!!
这个表示分隔符,是为了简化模式,否则就需要通过!
来不断转义\/
- 删除
/**/
注释
这个实现就非常复杂了,首先匹配内容可以跨行;其次,有跟HTML标签类似的问题(注释内部可能有多个
/**/
),需要使用最短匹配。
通过如下来实现
因为一行中可能有多个:%s!/\*\_.\{-}\*/!!g
,结尾通过g表示允许一行内部持续多次替换。/**/