vim 成“神“之路 (一)
文章目录
- 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版本的支持。
- 如果系统使用的是GNOME桌面环境时,安装
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) 模式:输入文本时使用,普通模式下键入
i
(insert)或则a
(append)即可进入插入模式 - 可视(visual)模式:用于选定文本块,可以使用
v
键来按字符选择,vim中也提供了按行和块进行选择的方法 - 命令行(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/undodirset 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=aelseset mouse=nviendif
endif
3. vim 常用命令 – 应对稍复杂任务
3.1 光标移动
基本移动 :上、下、左、右 –
k
,j
,h
,l
; 缺陷是这四个键不能在插入模式下移动跳转行首:
0
, 跳转行尾:$
, 跳转到行首到第一个非空白字符: ^一次移动超过一个字符:
b
/w
,B
/W
以上含义分别是:words backward, words forward,用来向后或者向前跳转一个单词。大写跳转和小写跳转的唯一区别就是小写和编程语言的标识符类似,认为一个单词的组成是由字母,数字和下划线组成;而大写则认为非空格字符都是单词。根据单个字符进行选择:
f
/t
,F
/T
以上含义是:找到下一个紧接着输入的字符(如果输入f/t,F/T之前加上数字n,那就是下面第n个),比如找到当前行的第二个d字符,输入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上
dw
delete word, 删除ding
,结果是"co boy = z_stand"
diw
delete inside word, 删除coding
,结果是" boy = z_stand"
daw
delete a word,删除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
,单引号,双引号,左右括号等
- 搭配
s
(sentence)对句子进行操作 – 适合英文文本编辑 - 搭配
p
(paragraph) 对段落进行操作 – 适合英文文本编辑,以及带空行的代码编辑 - 搭配
t
(tag) 对HTML/XML 标签进行操作 – 适合HTML, XML等代码编辑 - 搭配`和’,对shell或者python等脚本代码进行操作
- 搭配
[
和]
方括号,对括号里面的内容进行操作 - 搭配
{
和}
大括号,对括号内容进行操作 – 适合C/C++语言 - 搭配
<
和>
角括号 – 适合C++ 模版操作
再进一步,在a
和i
之前能够增加数字,表示操作多少个文本对象,适合针对嵌套文本的操作
比如
3.4 文本移动 – 更快
<C-B>
向上翻页<C-F>
向下翻页<C-U>
向上翻半页<C-D>
向下翻半页5G
跳转到第五行6l
跳转到第六列H
,M
,L
当前屏幕下,分别移动光标到屏幕顶部,中间,底部<C-Y>
和<C-E>
保持光标不动,滚动屏幕,ctrl-y向上,ctrl-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
等
最常用的是如下几个目录: syntax
vim 的语法加亮文件doc
vim 的帮助文件colors
vim 主题配色方案plugin
vim的插件文件
以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
目录下的插件则是系统内置的插件,分别具有如下功能:
getscriptPlugin.vim
获得最新的vim脚本插件gzip.vim
编辑.gz结尾的压缩文件,打开时能够自动解压缩,保存为.gz
结尾的文件时自动压缩logiPat.vim
模式匹配的逻辑运算符,允许以非标准正则表达式来写模式匹配manpager
使用vim来查看man帮助文档matchparen.vim
对括号进行高亮匹配netrwPlugin.vim
从网络上编辑文件和浏览目录(支持多种协议如ftp和scp,可以直接打开目录来选择文件)rrhelper.vim
支持--remote-wait
编辑,vim的多服务器会用到这一个功能spellfile.vim
在拼写文件缺失时自动下载,vim一般只安装了英文的拼写软件tarPlugin.vim
支持编辑(压缩).tar
结尾的压缩文件,这里和.gz
不同的是不支持写入tohtml.vim
把语法加亮的结果转成htmlvimballPlugin.vim
创建和解压.vba文件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配置在~/.vimrc
,windows可以通过打开vim输入: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
或者a
等插入命令进入vim的插入模式 - 通过键盘
<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
,abc
等,但是两者都不能匹配b^
匹配一行等开头,如果出现在模式的开头的话;如果在模式的其他位置,则表示字符本身$
匹配一行的结尾,如果出现在模式的结尾的话;在其他位置则表示字符本身~
匹配上一次替换的字符,如果上一次把abc
替换为了ate
,那么~
就匹配ate
[...]
匹配方括号内任意一个字符;方括号内如果第一个字符是^
,表示对结果取反;除开头之外的-
表示范围:如[A-Za-z]
表示任意一个拉丁字母,[^+-*/]
表示除了+
,-
,*
,/
之外的任意一个字符。\
的含义取决于下一个字符,在大部分情况下包括上面的这几个(.
,[
,]
,*
,$
,^
,~
,\
) ,代表后面这个字符本身;在跟某一些字符时有特殊含义。
除此之外就是普通的字符,并没有特别的含义;需要注意的是如果想要将搜索字符/
作为普通字符来使用,则需要\/
这样,否则vim看到的/
就会以为模式结束了,导致错误发生。
如果模式中使用"/"作为路径的分隔符,在替换命令中可以使用使用其他模式中没有的符号作为分隔符。比如想把路径/path/
全部替换为/paths/
,建议不要用:%s/\/path\//\/paths\//g
,这种样子非常容易出错。而应该使用类似的写法:%s!/path/!/paths/!g
,当然这个只能用于替换命令。如果想要使用/
作为搜索命令的话就没有太好的办法了,只能使用\/
这样的形态。
6.2 特殊模式项
通过\
开始的特殊表达式很多,如果我们想要全部了解的话可以通过help pattern-overview
来详细查看,这里仅仅列举几个基本的特殊模式项:
\?
表示之前的匹配重复零次 或一次: 如aa\?
可以匹配"a", “aa”, 但不能完整匹配"aaa"(可以匹配前两个字符,后两个或最后一个字符)\+
表示之前的匹配原重复一次或多次:如aa\+
可以匹配"aa",“aaa”, 但不能匹配"a"或"b"\{n,m}
表示之前的匹配原重复n到m遍之间。如:a\{3}
可以匹配3个"a":“aaa”;a\{,3}
表示最多匹配3个"a", 支持匹配"", “a”, “aa"和"aaa”;大括号内两个数字都省略时等价于*, 也就是之前的内容可以匹配0次或多次。\(
和\)
扩起一个模式, 从而组成单个匹配原:如\(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
或\0
),而非在模式中正常的行尾符LF。如果想要插入行尾符的话我们需要使用\r
。这意味着把一个回车变成两个,需要通过:s/\n/\r\r/
这样尴尬的方式来实现。
如果我们要插入CR
(回车)的话,需要输入\<C-V><CR>
才行。
6.3.4 替换实例
删除行尾注释
:%s!\s*//.*$!!
把零到多个空白字符后面出现的"//" 直到行尾全部删除,!
这个表示分隔符,是为了简化模式,否则就需要通过\/
来不断转义删除
/**/
注释
这个实现就非常复杂了,首先匹配内容可以跨行;其次,有跟HTML标签类似的问题(注释内部可能有多个/**/
),需要使用最短匹配。
通过如下来实现
:%s!/\*\_.\{-}\*/!!g
因为一行中可能有多个
/**/
,结尾通过g表示允许一行内部持续多次替换。
后续会持续分享vim的更高级操作,包括键盘宏,vim的插件,以及如何编写vim script
来让自己的指尖 有效得 飞得更快。
vim 成“神“之路 (一)相关推荐
- vimium 成神之路-键盘党的胜利
vimium 成神之路-键盘党的胜利 vimium简介 Vimium是一款 Chrome 插件,它继承了 Vim 中的常用操作,让我们在使用 Chrome 的过程中,无论是浏览网页.切换标签.搜索以至 ...
- 《Java工程师成神之路》终于免费开放下载了!
很多Java程序员一直希望找到一份完整的学习路径,但是市面上很多书都是专注某一个领域的,没有一份完整的大图,以至于很多程序员很迷茫,不知道自己到底应该从哪里开始学,或者不知道自己学习些什么. 好在,很 ...
- Java成神之路技术整理
转载自 Java成神之路技术整理 以下是Java技术栈微信公众号发布的所有关于 Java 的技术干货,会从以下几个方面汇总,本文会长期更新. Java 基础篇 Java 集合篇 Java 多线程篇 J ...
- Java成神之路[转]
阿里大牛珍藏架构资料,点击链接免费获取 针对本文,博主最近在写<成神之路系列文章> ,分章分节介绍所有知识点.欢迎关注. 主要版本 更新时间 备注 v1.0 2015-08-01 首次发布 ...
- GitHub上12k Star的《Java工程师成神之路》中终于开放阅读了!
很多Java程序员一直希望找到一份完整的学习路径,但是市面上很多书都是专注某一个领域的,没有一分完整的大图,以至于很多程序员很迷茫,不知道自己到底应该从哪里开始学,或者不知道自己学习些什么. 好在,很 ...
- cad的lisp程序大集合_大数据成神之路-Java高级特性增强(CopyOnWriteArraySet)
大数据成神之路 大数据成神之路: 点我去成神之路系列目录^_^ 预计更新500+篇文章,已经更新40+篇~ 本系列的大纲会根据实际情况进行调整,欢迎大家关注~ 导语 CopyOnWriteArrayS ...
- Java工程师成神之路思维导图
前面看Hollis的微信公众号更新了Java工程师成神之路的文档,感觉里面的内容清晰.齐全,可以用来审视自己,也能够知道自己在那些方面可以继续前行,想着有时间把它画下来,画下来之后分享出来. 主要内容 ...
- JVM成神之路-Java内存模型(JMM)
Java 内存模型基础 什么是 Java 内存模型(JMM-共享内存模型) 内存模型描述了程序中各个变量(实例域.静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存中取出变量 ...
- 「大数据成神之路」第三版更新完毕
点击上方蓝色字体,选择"设为星标" 回复"面试"获取更多惊喜 <大数据成神之路>是我于2019年在Github发起的一个项目: Github地址:h ...
最新文章
- 下拉列表怎么判断html,判断下拉列表中的值,实现页面跳转,请问这个怎么判断?...
- mapper.xml报异常The content of elhe content of element type mapper
- Java堆和栈的区别
- nginx的root alias 指令
- Vue 教程第一篇——基础概念
- java数组交集_java数组的交集和并集
- rem 之js代码获取font-size值(适合移动手机端)
- 企业微信H5_集成消息解密类,消息推送Get及Post回调处理
- linux上的定时器上的jiffies,Linux kernel -- 定时器/jiffies
- 001.常见监控简介
- a标签写链接地址跳转到下载企业微信app页面
- 约束最优化方法 (一) 最优性条件
- ai-人工智能的本质和未来_带有人工智能的动画电子设备-带来难以想象的结果...
- 哈工大2020计算机组织与体系结构期末
- “远程网络教学系统”教师参与者的用例图(志志)
- opencv轮廓检测
- 禹司凤扛鸿蒙炉,琉璃美人煞12人物结局,司凤 璇玑完满,柏麟 副宫主结局大快人心...
- 2020-04-19-如何在博客中添加视频链接
- eclipse中import existing projects into workspace和open projects from file systems分别有什么用?
- 天猫HTMl静态页面
热门文章
- visual studio 2013 中配置OpenCV2.4.13 姿势
- [leetcode] Minimum Path Sum
- vim中如何按一个键就保存文件
- Erlang服务端开发(无需Erlang基础)笔试题
- android 9 pie公司,谷歌Android 9 Pie,真正的安卓派
- java mysql 是否插入 成功_您如何确定使用Java和MySQL插入或更新是否成功?
- linux mint 屏保_Linux Mint 修复了两个孩子发现的屏保锁定绕过漏洞
- 共阳极数码管动态扫描c语言,《C语言编程实训》实训指导书三
- jedis操作set_在Java中使用jedis操作Set类型
- java三角形创建子类_如何创建子类,以便参数属于Java中的子类类型