我已经使用Vim将近十年了。我经常说“Unix是我的IDE”—因为Vim是在Unix哲学中构建的,允许我通过管道将输入传入、传出,以及我想要的任何方式。它非常符合Unix的哲学,即做好一项任务并允许重定向。我发现它非常适合一般的Web开发,特别是PHP开发—事实上,在使用Vim时,我在尝试开发的每种语言方面都有出色的经验。
Vim也是我选择的生产力套件。当我想写文档时,我不会进入OO.oWriter或MSWord或其他文字处理器;我打开一个窗口开始打字。在大多数情况下,我可以将我的工作剪切并粘贴到其他工具中,或者将其通过管道传输到转换工具中。我首先担心内容,然后是表示……就像任何好的MVC应用程序一样。;-)
就像任何好的工具一样,您必须投入时间才能从中获益。到目前为止,我的学习分为三个时间段:
- 我第一次学习Vim的最初几个月,是通过vimtutor和SteveOualline的Vim书。
- 2006-2007年的这段时间,我觉得有必要提高我的编码效率,首先开始使用exuberant-ctags和omni-completion。
- 2010年最后一个季度(是的,就是现在),当时我通过Twitter了解到许多新工具。
所以,这是我的Vim工具箱,2010版。
获取插件
我添加了两种主要方法来将新插件添加到我的工具库中:
-
Vimana,这是一个命令行工具,用于发现、下载、安装和升级在vim.org上找到的脚本。它并不完美,但如果您知道脚本的名称,并且它以vimball格式提供和/或遵循Vim运行时文件结构,那么这是使您的插件、语法文件等保持最新的好方法。
-
VimPathogen允许您将插件安装为“捆绑包”,允许您在它们自己的文件树中分别保持最新。这看起来像下面这样:
.vim/ bundle/ vim-task/ ftdetect/ ftplugin/ syntax/
简而言之,“bundle”模拟了Vim目录的结构。
/ul>
后者Pathogen是目前我首选的安装方法。为什么?一个首字母缩略词:DVCS。
大量流行的Vim插件现在正在GitHub或其他DVCS站点上开发或镜像。这允许您克隆它们,然后创建一个特定于您的配置的分支。例如,流行的snipMate插件对其键绑定进行了硬编码——如果您已经在使用这些绑定,这会导致问题。如果您使用任何形式的全方位补全,这很有可能。我只是克隆了snipMate存储库,并为我的配置创建了一个分支(我使用来调用它)。
现在,它变得更好了:我已经为我的Vim配置创建了一个git存储库;通过明智地使用gitsubmodule
,我现在可以将病原体包添加为我的存储库的子模块。现在,我有html5.vim、mustache.vim、NErdtree、snipMate、TagList、vim-fugitive、vim-task和vimwiki的捆绑包。这使我的存储库保持精简,同时保留了我需要和每天使用的功能。
作为创建我的Vim配置存储库的一部分,我还进行了一些更改以促进该过程。首先,我将$HOME/.vimrc
移动到$HOME/.vim/vimrc
,并将前者符号链接到后者。这使我可以将所有Vim配置保存在一个地方。
接下来,我将我的Vim视图文件移到了该目录之外;此数据是易变的且不断变化的,确实不需要进行版本控制。这些现在在我的$HOME/.vim.view/
目录中。最后,我将我的标记文件移动到一个新的$HOME/.vim.tags/
目录中。稍后会详细介绍,但同样,理由是此数据是易变的,不需要进行版本控制。
DVCS
我提到我为我的Vim配置创建了一个Git存储库。这在一定程度上是因为我精通Git——我日复一日地使用它。Hgand其他DVCS系统也很棒;不过,我几乎没有像现在这样经常使用它们。
为此,我现在使用vim-fugitive。作者吹嘘它是“一个如此棒的Git包装器,它应该是非法的”;我不一定会走那么远,但我确实发现它非常有用。虽然我通常在控制台中工作,但我也经常在GVim窗口中工作—拥有一个漂亮、熟悉的Git界面非常有用。如果您同时使用Vim和Git,我强烈建议您查看vim-fugitive。
文件系统导航和项目
在某些时候,除非您是喜欢在单个文件中编写所有代码的开发人员之一,否则您需要进行某种导航。几年前,AndreiZmievski向我介绍了NErdtree,一个非常简单的彩色导航。我每次都用这个。单身的。一天。
我还使用了一个名为Project的工具。此工具允许您为项目指定“感兴趣的文件”——通过自动扫描树或手动。此外,您指定层次结构的方式可以是完全任意的——允许您在树挡道时将其展平。我也经常使用这个工具,虽然不如NErdtree那么频繁。
导航代码
现代IDE的一个经常被吹捧的功能是代码完成和提示。这些绝对是有用的功能,尤其是在处理不熟悉的代码或您有一段时间没有接触过的代码时。
Vim实际上已经有一些很棒的工具来处理这个问题。一个是built-in:omni-completion(:henew-omni-completion
用于Vim的功能帮助)。默认情况下,它会检查打开的缓冲区中的文件以提供完成(假设它有该语言的定义和/或语法突出显示)——但它也可以利用标签文件。
PHP的内置全能补全是合理的—您可以按类名、函数/方法名、变量等来回跳转。但是,当您使用标签文件时,它会变得非常非常有用,因为您不不需要文件已经打开才能完成。我以前写过关于ctags的博客;但是,我对我的脚本做了一些更新。
首先,exuberant-ctags现在比我写博客时更了解PHP。这意味着您无需执行任何特殊的regex-fu操作即可正确识别抽象类、接口和方法。其次,我发现我可以生成一个带有提示的脚本来指示目录和标记文件名。该脚本基本上如下所示:
#!/bin/sh dir="" name="" if [ $# -ge 2 ] ; then # Two arguments: first is directory, second is "alias" dir=$1 name=$2 else if [ $# -eq 1 ] ; then # One argument: use as directory, and use basename of directory as alias dir=$1 name=`basename $1` else # Otherwise: prompt echo "Enter the path to a directory containing PHP code you wish" echo "to create tags for:" read dir echo "Enter the name of the tagfile you wish to create:" read name fi fi echo "Creating tags for directory '$dir' using alias '$name'" cd $dir exec ctags-exuberant -f ~/.vim.tags/$name \ -h ".php" -R \ --exclude="\.svn" \ --totals=yes \ --tag-relative=yes \ --fields=+afkst \ --PHP-kinds=+cf echo "[DONE]"
需要注意两点:
- 它在
$HOME/.vim.tags/
中创建标签文件。我这样做是因为我的标记文件经常更改,并且可以根据需要即时重新生成。没有理由对它们进行版本控制。 - 生成后,您需要加载它们。我创建了一个“LoadTags”Vim函数,它将按给定的名称从
$HOME/.vim.tags/
目录中加载一个标记文件。默认情况下,我加载我最常用的(ZF1、ZF2、PHPUnit)。否则,快速:Ltag
将按需加载。
创建标签后,您可以使用Vim的普通标签功能来加载文件、跳转到文件等。我最常用的命令是:
:stag
,拆分当前窗口并在新创建的拆分中加载给定标签。]
,当您怀疑文本是标签(例如类名)时,将拆分当前窗口并将该标签文件加载到新窗格中。
这两个命令我经常使用,而且非常节省时间——我基本上可以将代码用作我的文档。
此外,omni-completion的主要用途是为已知标签提供tab-completion。这意味着您可以开始键入,点击,然后立即完成,或者为您提供一个潜在匹配列表。它不如一个好的IDE有用——它不是上下文感知的,所以你会从任何类中得到任何潜在的匹配——但总比没有好,提供了合理的提示,并有助于防止您出现拼写错误。
也就是说,关于让各种方法的签名和原型易于访问,还有一些话要说。为此,有VimTagList插件。这个插件将扫描打开的文件并生成一个类、变量和方法的列表。使用此列表,您可以获得方法原型,并直接跳转到它们的定义。按将显示原型,
将跳转到它。
在这两个功能(带有标签的全方位补全和TagList)之间,我可以立即使用任何IDE的大部分有用功能。
使用代码
因为我以编写代码为生,所以拥有一些插件和语法高亮功能可以使使用代码更容易。
首先,我一直在试验HTML5;因此,我将html5.vim语法高亮添加为病原体模块。这增加了对一堆HTML5特定功能的支持,同时保留了Vim提供的官方HTML语法中已有的出色HTML支持。
接下来,我使用来自vim.org的php.vimsyntax文件。这个特殊的语法文件支持PHP5.3功能,这在我为ZF2编码时非常方便。此语法的作者还创建了一个脚本(php_vimgen.php
),用于为核心类和使用反射API的扩展生成语法文件。我修改了我存储库中的工具以去除生成的语法,而是从使用php_vimgen.php
脚本创建的文件中获取它;我还更改了上述脚本以在__DIR__中创建语法。'/php_syntax_vimgen.vim'
,确保我始终可以从同一位置获取它。这使我能够使我的PHP语法突出显示保持最新。
最后,我使用了snipMate,这是一个模拟TextMate的“片段”功能的工具。基本上,这是非常简单的模板化代码生成。您可以编写自己的文件(我写过),或者使用它附带的文件。一旦你得到一些片段,你输入一个词(通常是你试图执行的操作的助记符),它要么只是吐出一个模板,要么有选择地提供“提示”供你填写(以及变量完成!)。基本上,我再也不编写访问器和修改器的代码了;snipMate为我做了这些,有一点提示。
组织
我日复一日地使用Vim来处理各种事情:邮件、起草博客文章、起草演示文稿大纲、做会议记录、管理我的待办事项列表等等。因此,我尽量将我的“组织”保留在Vim中——这样更容易。
多年来,我尝试了多种工具。整整4或5年,我的主要工具是VimOutliner。它提供了体面的语法、体面的折叠和从大纲中合理生成的HTML。然而,最近几年,我觉得这个项目停滞不前,我也发现我想使用它的方式发生了变化:大纲很好,但我经常想用大纲作为生成内容的起点;任务跟踪很好,但我发现,无论出于何种原因,VimOutliner处理任务状态的方式通常效果不佳—无论是从工具还是语法角度。
在某个时候,TravisSwicegood向我介绍了vimwiki。此工具在Vim中提供了个人维基。这个工具允许我以一种特别的、半分层的方式组织我的笔记,在它们之间来回链接,并且不仅有合理的编辑器内突出显示,而且有很棒的HTML生成。这让我可以放弃VimOutliner来处理任务跟踪以外的所有事情。将我的“wiki”目录设为Git存储库后,我基本上可以免费获得版本控制(尤其是使用vim-fugitive,这使我可以轻松点击:Gwrite
和:Gcommit
当我创建和/或更新文件时)。
vimwiki提供的另一个功能是“日记”。您可以使用ww
访问它,这会为当天打开一个新的wiki页面(或者,如果您之前已经打开过它,则重新打开当天早些时候创建的那个).这是一个非常有用的工具,可用于在会议期间或进行研究时做笔记。
将这些功能与集成搜索(:VWS/pattern/
)相结合,vimwiki是我工具箱中的杀手级生产力工具。
在另一点上,Travis接着指出了另一个工具:vim-task。这可能是我用过的最简单的任务跟踪器;每一行都是一个任务,要么是不完整的(以“-”开头),要么是完整的(以复选标记开头)。一个简单的键绑定,我已经映射到m
,切换状态-完成的项目以绿色和斜体突出显示,让您感觉良好,并为您完成的内容提供良好的视觉队列。
在某些时候,Travis也提出了将vimwiki与vim-task结合起来会很有用的想法——我接受了这个想法。我现在创建了一个带有vim-task集成的vimwiki分支,它允许我将我的任务和笔记放在一个地方……而且,由于我的wiki是版本化的,我的任务也是如此。
各种怪事
正如我在本文开头提到的,我使用Vim已经将近十年了。Vim吸引我的部分原因是它让我始终处于键盘的“主行”——这提供了巨大的效率。您不必移动到箭头键来滚动,也不必离开鼠标键盘等。也就是说,有些组合键很难达到:
键的位置因键盘而异,很少位于容易触及的位置。在我当前的键盘上,它位于左上角,功能键上方;不移动我的手是不可能到达的。当我开始使用Vim时,我学到的一个技巧是将
jj
映射到;在英语中很少重复输入
j
,而且它位于起始行的正中。这非常高效。- 在过去十年中,我已经将CapsLock键映射到我拥有的每个系统上的
。我从来没有用过它,它几乎总是在主场。同样,非常高效。
- 键绑定很棒,但已经使用的键绑定太多,很难不覆盖现有键绑定。使用
键来定义键绑定非常棒。例如,我将
m
映射到切换任务,并将映射到调用snipMate。
在Vim中,长期以来一直是“make”绑定,
用于linter。在PHP和JavaScript等语言中,这些通常没有意义。然而,我在两种语言中都绑定了它们——在PHP中,“make”使用PHP可执行文件执行当前脚本,而“lint”通过PHPlinter运行它。在JS中,我不绑定“make”,而“lint”通过jslint运行脚本。
我还添加了“php-doc.vim”插件,并映射来创建PHPdoc块;该插件是上下文感知的,并将创建适当的注释。
克隆我的仓库
如前所述,我已经为我的Vim配置创建了一个存储库。如果你想克隆它并探索它,你可以这样做:
- 浏览存储库:http://git.mwop.net/?a=summary&p=vimrc
- 克隆存储库:
gitclonegit://mwop.net/vimrc.git
请注意,有许多git子模块在起作用(所有病原体模块都是git子模块)。要初始化这些,只需运行gitsubmoduleinit
,然后在克隆存储库后运行gitsubmoduleupdate
。
资源
我不是一夜之间就学会了这一切。与任何工具集一样,它的好坏取决于您投入的学习时间。对我来说,我最近的主要资源是:
- Twitter上的#vim标签
- VimCasts是一个极好的信息来源,由DrewNeil提供。说真的,这些都是完全值得花时间观看的。
- TravisSwicegood多次发推文介绍他用Vim和Git做的有趣事情,并启发我写了vimwiki的vim任务语法。
更多工具
这篇文章已经在我的Vim工具箱中了。我最近也一直在使用其他一些工具——tmux、zsh(特别是git提示)、Hotot(GTK2+WebKitTwitterclient)等等;我可能会在未来写博客——使用Vim。;-)