今日题图:by Angela Zhu
今天本来是想写一点有争议的东西,不过和朋友讨论之后,我觉得朋友的观点是对的。还是不写了,别再上了吃瓜群众的当。写一点 Vim 的东西吧,因为 8.0 这个大版本终于来了。
我是从2000年开始使用 Vim 编程,六年之后,Vim 发布了7.0,这是一个大版本更新,以后十年间,Vim 不断进步,从7.0到7.4,小版本和小小版本陆续更迭,功能不断增强,十年之后,2016年9月12日,Vim 8.0 终于发布了,这是个里程碑的版本,包含了很多优秀的新特性,同时吸收了一些其他 Vi 流派的特性。
关于 Vim 的起源和基本特点、用法和一些技巧,我之前在「最帅的编程工具」里写过了,这次主要介绍一下 8.0 的新特性和一些插件。
一、Vim 8.0 新特性
8.0 版本除了 bug 修复,性能增强和细节的修饰之外,主要增加了以下这些我感兴趣的内容。
异步 I/O 和通道的支持
Vim 8.0 增加了 channel 的概念,可以允许 Vim 与后台的其他进程进行消息交互。以前我们通过 QuickRun 插件执行程序编译和运行的时候,在没有反馈结果之前,什么都做不了。现在通过异步机制,可以在后台长时间执行任务,最终把执行结果输出到 VimScript 的某个 Callback 函数中,在屏幕上输出。
推荐一个支持异步机制的插件 AsyncRun。
网址:[http://www.vim.org/scripts/script.php?script_id=5431]
定时机制
Vim 增加了异步工作的定时器,timer。我们可以在 Vim 的命令行里启动一个定时器,在系统后台不断重复调用 VimScript 里的函数,比如你可以写一个插件检查 github 上的 commit 状态,并定时显示在 Vim 的编程窗口里,命令行代码如下:
let aTimer = timer_start(5000, 'CheckCommitStatus')
Partials
Vim 之前已经有了用来做函数引用的 Funcref 功能。partial 也是一个函数引用,而且可以绑定参数或字典,这对 channels 和 timers 的 callbacks 非常有用。例如,你可以这样传递参数:
let tempTimer = timer_start(5000, function('CheckTemp', [['out']])) 。
Lambda 和 Closure
lambda 可以通过{{args -> expr}}的方式快速创建函数,这个特性对 filter() 和 map() 非常有用,而且可以接受函数的参数,比如:
:call filter(mylist, {{idx, val -> val > 20}})
插件管理
插件与日俱增,Vim 这次提供了自己的插件包管理工具,不过用惯了 pathogen 和 Vbundle 的用户,会不会尝试这个新的工具,还未可知。
窗口 ID
以前 Vim 窗口的切换可以通过窗口的数字编号来访问,之前介绍过。每次窗口打开、关闭和移动,这些数字都会变化,现在窗口有了唯一 ID,更容易访问,我们可以通过 :ls 查看窗口状态。
折行缩进
新增的了 'breakindent' 选项,可以保证在折行、复制大块文本时,缩进不变。
其他一些特性请参考:[https://laravel-news.com/2016/09/vim-8-0-is-released/]
安装
具体请参考官网的安装说明,在 Mac 上安装可以用 brew install。如果不能安装最新版本,可以用 brew uninstall 删除原来的版本,再次执行即可。
如果遇到启动错误,重新更新和编译安装 YouCompleteMe 即可。
二、插件篇
看了这些特性之后,你是不是产生了一种并没有什么 X 用的感觉。这就对了,如果你不用插件的话,确实用处不大。
之所以说 Vim 有自己的生态环境,就是因为 Vim 具备开放的插件体系,开发者为了提升开发效率,为 Vim 编写了数以万计的插件,我们可以根据需要任意选择,也可以基于 Vimscript 语言开发自己的专属插件。
每个插件都是以Vim为后缀的脚本文件,编写插件的语言一般采用 Vimscript。Vimscript 是 Vim 自己的编程语言,我们在后续会介绍到它。尽管 Vimscript 几乎为可以Vim做任何事,但还是会存在一些场景,用其他语言更好更快。考虑到这一点,Vim 的开发者为其他脚本语言设计了接口,用来编写 Vim 插件,比如 Perl,Python 和 Ruby。
常用插件分为四种:
通用插件:适用于所有类型的文件,在使用Vim的时候可以通过插件命令呼出。比如用来快速定位文件的插件CommandT,使用:CommandT
即可启动该功能,对任何类型都适用。该类插件一般放置在.vim/plugin/目录下。
文件类型插件:适用于特定类型的文件,比如c、java、xml等文件。在编辑特定类型的文件时,插件功能才会启用,该类插件一般放置在.vim/ftplugin/目录下。比如我们常用的编辑xml/html/jsp等文件的插件xmledit,安装了该插件后,编辑xml文件时,键入
,当完成了最后的>
时,xmledit会自动为你添加闭合标签,
,如果输入了最后一个>
,标签会自动展开,方便输入子标签或文本内容。这时如果你用Vim打开一个txt文件,这些功能就消失了。当然,xmledit功能远不止这么简单,我们稍后再详细介绍。
语法插件:顾名思义,语法插件主要为编程语言提供语法高亮功能,一般放置在.vim/syntax/下。Vim已经默认提供了大部分语言的语法高亮功能,但对于一些比较新的语言,就需要开发者编写支持语法高亮的插件,比如Go语言。
编译器插件:针对不同语言编写的编译器插件,主要用来设定相关语言的编译器选项。比如针对C、C++、Java、Python等可以编写各自的编译器插件,插件内容并不复杂,主要定义"errorformat"(错误格式定义)及"makeprg"(编译程序和参数)的内容即可。通过:make
可以编译正在编辑的文件。
了解了Vim插件的基本概念,再来讲下面的这些常用插件,就比较容易理解了。
pathogen
我们首先来介绍这款用来管理插件的插件——pathogen。
1、下载地址
https://github.com/tpope/vim-pathogen
2、功能说明
一个插件包往往具备多种功能,每个文件根据Vim的路径约定会放置到不同的目录下,通用插件放到plugin下,语法高亮插件放到syntax下,自动加载插件放到autoload下,文件类型插件放到ftplugin下,编码格式插件的放到indent下……如果你是重度插件用户,你会发现在.vim主目录下会有一堆文件夹,无论是你想要安装新插件,还是想删除旧插件,都非常麻烦,你不得不在每个文件夹下找相关的vim文件。
pathogen是管理插件的插件,主要用来解决上述问题。pathogen采用了bundle的概念来管理插件,如果你熟悉OSGi或OS X,那么对bundle就不会陌生。OSGi以bundle的形式封装Java程序和资源文件,而OS X中的大部分应用程序都是bundle,正是bundle的概念让OSGi可以动态管理Java组件,OS X安装大部分程序都是“绿色安装”。
pathogen在.vim
目录下建立bundle文件,所有的插件都会在该目录下管理。当Vim启动时,会自动执行runtimepath(rtp)列表中所包含文件夹下的vim脚本,pathogen会在启动时把./vim/bundle
下的文件夹中的插件按照一定顺序递归加载到rtp中,这样Vim启动时,通过pathogen管理的插件就生效了。
有了pathogen之后,一般.vim
文件夹下只有三个文件夹:autoload、bundle和doc,其他插件将被安装在bundle文件夹下。
3、安装
在.vim
文件夹下建立autoload和bundle目录
从下载地址获取pathogen.vim文件,将其复制到autoload目录下
在.vimrc
文件中增加如下代码: call pathogen#infect()
4、使用说明
无
5、注意事项
新插件安装到bundle目录下后,如果插件中包含doc,则需要在Vim中运行:Helptags
来生成在线帮助tags。
NERDTree
我们在介绍pathogen的时候,用一张图展示了插件的目录结构,这个目录结构就是基于NERDTree插件实现的。
1、下载地址
https://github.com/scrooloose/nerdtree
2、功能说明
NERDTree是Vim最常用的插件之一,可以在Vim运行时显示目录和文件结构,类似TextMate左侧的文件浏览器,但操作起来更为方便,你可以在手不离开键盘的情况下快速浏览文件,并在文件和文件夹之间进行切换。
3、安装
进入.vim/bundle
目录
执行git clone git://github.com/scrooloose/nerdtree.git
下载完成后,在bundle下会多出一个nerdtree的文件夹,所有相关插件都在该文件夹下
在Vim中运行:Helptags
来生成NERDTree的在线帮助tags
4、使用说明
打开Vim,输入:NERDTree
,即可呼出执行Vim命令的当前目录的文件目录。为了方便使用,我在.vimrc中定义了快捷键,可以用Ctrl+t打开NERDTree,你可以定义自己习惯的快捷键。
NERDTree提供了丰富的键盘操作方式来浏览和打开文件,我简单介绍一些常用的快捷键:
和编辑文件一样,通过h j k l移动光标定位
o 打开关闭文件或者目录,如果是文件的话,光标出现在打开的文件中
go 效果同上,不过光标保持在文件目录里,类似预览文件内容的功能
i和s可以水平分割或纵向分割窗口打开文件,前面加g类似go的功能
t 在标签页中打开
T 在后台标签页中打开
p 到上层目录
P 到根目录
K 到同目录第一个节点
J 到同目录最后一个节点
m 显示文件系统菜单(添加、删除、移动操作)
? 帮助
q 关闭
想了解更多操作方式,可以通过? 查看详细的帮助信息。
Command-T
1、下载地址
https://wincent.com/products/command-t
2、功能说明
Command-T是一个基于Ruby和C扩展实现的快速文件浏览的插件,类似TextMate的Go to File(Command+T呼出)功能,或Eclipse的Open Resource(Command+Shift+r)功能,可以通过模糊匹配快速定位并打开文件。
3、安装
从下载地址下载最新版本的vba文件,目前最新版本是1.4,所以安装文件是command-t-1.4.vba
在~/.vim/bundle
目录下创建文件夹command-t
用Vim打开command-t-1.4.vba
执行:UseVimball ~/.vim/bundle/command-t
进入ruby目录下编译C扩展
cd ~/.vim/bundle/command-t/ruby/command-t
ruby extconf.rb
make
4、使用说明
输入:CommandT可进入文件快速定位功能。
该插件还有个常用命令,:CommandTBuffer
,可以浏览缓冲区的文件,并重新打开。操作方式同上。
5、注意事项
Vim版本需要支持ruby扩展。我们可以在Vim中输入:ruby 1
检查,如果出现E319: Sorry, the command is not available in this version
就表示不支持。
如果出现上述情况,我们就需要自己去编译能够支持ruby的Vim,嫌麻烦的话可以直接安装vim-nox,自带Ruby支持,在Ubuntu下安装命令如下:sudo apt-get install vim-nox
。
执行ruby extconf.rb
命令时如果出现找不到mkmf包的情况,说明你需要安装ruby-dev的包,在Ubuntu下安装命令如下:sudo apt-get install ruby1.8-dev
。
Powerline
1、下载地址
https://github.com/Lokaltog/vim-powerline
2、功能说明
Powerline是Vim的一个非常漂亮的状态栏插件,安装了Powerline之后,Vim底部将会出现一个增强型状态栏,当Vim处于NORMAL、INSERT、BLOCK等状态时,状态栏会呈现不同的颜色,同时状态栏还会显示当前编辑文件的格式(uft-8等)、文件类型(java、xml等)和光标位置等,喜欢的就装。
3、安装
4、使用说明
安装之后,再次打开Vim,你就会发现底部已经多了一个彩色的状态栏了。
ctags
1、下载地址
http://ctags.sourceforge.net
2、功能说明
严格意义上来说,ctags并不是Vim的插件,而是Linux/Unix下的标签命令。通过ctags -R
命令可以对当前目录下源代码中的类、函数、方法、变量、宏等元素进行索引处理,并生成索引文件。Vim使用ctags生成的tag文件,即可实现IDE中常用的代码跳转功能,实乃居家旅行代码索引的常备利器。ctags不仅支持c/c++/java等静态语言,还支持python/perl/php/jsp等动态脚本语言,就目前我的使用情况,ctags基本不支持Objective-C,对Ruby支持的也很糟糕,随着这些语言的普及和发展,希望后续版本的ctags会对更多的编程语言有更好的支持。
3、安装
对于Ubuntu,可以使用如下命令安装:sudo apt-get install ctags
,安装完成后在终端键入ctags --help
,看到正常的帮助信息就说明安装成功了。
对于Mac用户来说,OS X自带了ctags命令,但这并不是vim所需要的ctags,要重新安装:sudo port install ctags
。由于OS X自带的ctags位于/usr/bin目录下,一般在PATH中是优先加载的,所以安装完成后,还需要设置一下环境变量,确保你在命令行使用的是新安装的ctags。如果没做特殊设置,安装的ctags一般在/opt/local/bin下,在当前用户的.profile中增加如下代码:export PATH=/opt/local/bin/:$PATH
,在终端执行source .profile
可立即生效。
4、使用说明
创建标签索引
前面我们提到过,ctags主要是用来创建Vim可以使用的tag索引文件,使用ctags -R
即可对当前目录下的代码递归建立索引文件,文件保存在当前目录下,默认文件名为tags,文件大小和你要索引的代码量有关。
如果想自己指定tag文件的位置和索引代码的位置,可以使用如下命令实现:
ctags -R -o ~/.vim/ctags/pythontags /somepythondir/
设置索引文件的位置
Vim在运行过程中需要知道tag的索引文件位置,如果不指定的话,Vim会在当前目录下寻找名为tags的文件作为tag索引文件。
如果想使用某个目录下的索引文件,在该目录下启动Vim即可。也可以在启动后通过如下命令设置或改变索引文件的位置:
set tags=/home/xxx/xx/tags, xxxx/tags,......
当然,你也可以把这条命令写到.vimrc中。
ctags主要对源代码中的类、方法、变量等元素进行了索引,所以,如果我们记得某个类名、方法名或变量名,想在命令行下直接打开隐藏在重重叠叠的目录深处的某个文件时,以下命令可以帮助我们实现这个功能:
vim -t class | method | variable
例如,你想打开包含了loadCache方法的文件,可以用如下命令:
vim -t loadCache
如果多个文件中包含loadCache方法,vim会按照字母顺利打开第一个文件。想查看其他文件,可以使用ts命令, :ts
会列出所有包含loadCache标签的文件,输入文件序号可以打开文件并定位到loadCache标签,通过j和k可以上下滚屏。
如果只是通过vim命令打开文件,那么可以使用如下命令进行文件检索和浏览:
:ta tagname 跳转到标签tagname定义的地方
:stag tagname 在分割窗口中查看包含tagname的文件
:tags 查看到达当前位置所经过的标签路径
:ts tagname 列出匹配tagname的标签,如为空,则使用标签栈中最后的标签
:tf 跳转至第一个匹配的标签
:tl 跳转至最后一个匹配的标签
跳转快捷键:
ctrl-] :跳转至光标所在对象定义之处
ctrl-t :返回跳转前位置
[n]ctrl-t :[n]为数字,向回跳转n次;等价于重复n次ctrl-t操作
5、注意事项
确认vim在打开文件时能够找到相关的标签文件tags。
taglist
1、下载地址
https://github.com/vim-scripts/taglist.vim
2、功能说明
taglist是Vim的一个代码浏览的插件,类似IDE中的Outline视图,可以根据不同语言的代码显示代码中的包、类、接口、方法、函数、变量、属性等内容,是Vim浏览代码的一个必备工具。
taglist同样需要依赖ctags命令生成tag。
3、安装
进入~/.vim/bundle
目录
执行:
git clone git://github.com/vim-scripts/taglist.vim.git
在.vimrc
文件设置taglist的配置信息,以下是我的偏好设置
"taglist{
let Tlist_Show_One_File = 1 "只显示当前文件的taglist,默认是显示多个
let Tlist_Exit_OnlyWindow = 1 "如果taglist是最后一个窗口,则退出vim
let Tlist_Use_Right_Window = 1 "在右侧窗口中显示taglist
let Tlist_GainFocus_On_ToggleOpen = 1 "打开taglist时,光标保留在taglist窗口
let Tlist_Ctags_Cmd='/opt/local/bin/ctags' "设置ctags命令的位置
nnoremap tl : Tlist "设置关闭和打开taglist窗口的快捷键
"}
4、使用说明
taglist参数介绍,大家可以根据自己的偏好在.vimrc
中设置:
Tlist_Ctags_Cmd:设置ctags命令的位置
Tlist_Use_Horiz_Window:设置为1时,taglist窗口横向显示。默认纵向显示
Tlist_WinHeight:设置taglist窗口的宽度
Tlist_WinWidth:设置taglist窗口的高度
Tlist_Show_One_File:设置Tlist_Show_One_File为1则只显示当前文件的taglist,缺省显示多个文件中的tag
Tlist_Sort_Type:taglish默认按tag在文件中出现的顺序进行排序,设置为"name",taglist将以tag名字进行排序
Tlist_Exit_OnlyWindow:设置为1时,如果taglist是最后一个窗口,则退出vim
Tlist_Use_Right_Window:设置为1时,taglist窗口出现在右侧,缺省显示在左侧
Tlist_Auto_Open:如果想在启动VIM后自动打开taglist窗口,该参数设置为1
Tlist_Close_On_Select:如果想在选择了tag后自动关闭taglist窗口,该参数设置为1
Tlist_GainFocus_On_ToggleOpen:设置为1时,打开taglist光标保留在taglist窗口
当使用vim打开某个程序文件时,我们可以用:Tlist
打开taglist窗口,如果该程序具备类、接口、属性等元素,就会在taglist窗口显示出来。我们可以通过以下这些常用快捷键来操作taglist:
5、注意事项
确认在.vimrc
中使用Tlist_Ctags_Cmd定义了正确的ctags命令的位置,否则会出现找不到tag的错误信息。
visualmark
1、下载地址
http://www.vim.org/scripts/download_script.php?src_id=4700
2、功能说明
visualmark,顾名思义,就是在你阅读代码或编写代码的时候随时快速打标签,并通过快捷键来回切换浏览。
3、安装
在.vim/bundle
下建立文件夹visualmark/plugin
,把下载的文件visualmark.vim复制到该文件夹下。
4、使用说明
使用vim打开一个文件,使用快捷键mm
设置标签,通过F2和shift+F2可以上下切换浏览。
我们还可以对标签的样式进行定制:
打开visualmark.vim,找到如下代码修改:
//根据背景色设置标签颜色,cterm表示为原生vim设置样式
if &bg == "dark"
highlight SignColor ctermfg=white ctermbg=blue guifg=white guibg=peru
else
highlight SignColor ctermbg=white ctermfg=red guibg=grey guifg=RoyalBlue3
endif
5、注意事项
无
其他推荐插件
Vbundle:管理插件的插件,类似 pathogen,基于 Git 构建,更为智能。
GitHub 地址:https://github.com/gmarik/vundle
YouCompleteMe:强大的通用代码补全和检查插件,适用于大部分编程语言,要求 Vim 版本在7.3.584以上。
GitHub 地址:https://github.com/Valloric/YouCompleteMe
TagBar:类似 taglist,功能更为强大。
GitHub 地址:https://github.com/vim-scripts/Tagbar
ctrlp:类似 Command-T
GitHub 地址:https://github.com/kien/ctrlp.vim
vim-easymotion:一款非常有趣而功能强大的字符定位插件
GitHub 地址:https://github.com/Lokaltog/vim-easymotion
Vim 世界的插件千变万化,无法穷举,以上是我常用的一些 Vim 通用插件,适用于大部分编程场景。读者可以根据自己的需要选择使用,不同的编程语言和编辑环境还可以增加其他插件,比如 Python 插件,Go 插件等。
最后,VimScript 也是值得大家了解的一门语言,非常有意思。
祝大家中秋快乐!(这篇有点长,抱歉)
豆瓣在互联网历史上是一家「独立存在」的公司,我很喜欢。2014年8月8日,豆瓣的创始人阿北说,我们今天发布了一个叫做「豆瓣」的新应用,我们希望它以后是所有人手里的「豆瓣」。
如今这个 App 的版本到了4.2,相比原来的版本,4.x 突出了更为多样性的内容,我喜欢这个版本,用它在豆瓣记录了一些书和电影的相关信息。点击原文或者长按二维码下载,在 App 里搜索池建强可以找到我。
点击阅读原文,了解详情。