Rails开发中使用的VIM插件

缘起

听从《Web开发敏捷之道》的建议,将几个IDE和编辑器尝试了一番,没一个满意的,要太大或要不太吃内存。最后,我还是回到VIM上,老实的学习如何使用VIM扩展的插件。

正文

关于VIM插件,目前,在开发Rails中需要使用插件如下:NERD_tree,CommandT,snipMate,vim-ruby,vim-rails。备注:这里只是个人的看法。

VIM不是一个简单的易学的编辑器,但也不是那么难学,花点时间熟悉命令总是好好。对于VIM的学习,伯乐在线提供很多不错的学习文章,网上有人汇总了一些资料,这里推荐池建强的《谁说Vim不是IDE?》和《手把手教你把vim改造成IDE》,当然,可以通过VIM的帮助文档来学习,VIM的中文帮助文档地址:http://vimcdoc.sourceforge.net。中文版的VIM pdf文档2601页,当然这不是我见过页数最多的文档,Mysql的英文文档3344页,长文档有个好处-详细,闲着没事是看看,打发打发时间

以下安装的插件都是通过pathogen来管理的,关于Pathogne的安装参考https://github.com/tpope/vim-pathogen的主页。

1. NERDTree

NERDTree提供了丰富的键盘操作方式来浏览和打开文件。在打开vi之后,输入:NERDTree打开NERDTree,其界面如下:

Rails开发中使用的VIM插件_第1张图片

图 1.1 NERDTree打开的界面

备注:简单的使用后发现,NERDTree打开的水平窗口的大小是固定的,要学习如何调整大小

NERDTree的一些常用的快捷键介绍如下:

  • l 和编辑文件一样,通过h j k l移动光标定位
  • l o 打开关闭文件或者目录,如果是文件的话,就会在图1.1的右侧打开该文件,启动鼠标后,鼠标点击效果相同
  • l go 效果同上,不过光标保持在文件目录里,类似预览文件内容的功能
  • l is可以水平分割或纵向分割窗口打开文件,前面加g类似go的功能
  • l t 在标签页中打开,并跳转到打开的标签页
  • l T 在标签页中打开,光标依然停留在当前页面中
  • l K 到同目录第一个节点
  • l J 到同目录最后一个节点
  • l C 切换目录,进入当前所在的目录,不会改变bash所在的目录
  • l m 显示文件系统菜单(添加、删除、移动操作)
  • l ? 帮助,有一点不好的就是,帮助显示的位置
  • l q 关闭

2. CommandT

Command-T的功能挺强大,可以在不显式目录树时(即不使用NERDTree时),检索并定位当前目录树下的文件。

安装参考《谁说Vim不是IDE?》,打开命令为:CommandT,使用界面为:

Rails开发中使用的VIM插件_第2张图片

Command-T常用操作:

  • l ctrl+j/k(↑↓)上下选择文件,选中后回车(Enter)打开文件
  • l ctrl+t tab方式打开文件
  • l ctrl+s/v 可以水平或垂直分割窗口打开文件
  • l ctrl+c 退出该模式

该插件还有个常用命令,:CommandTBuffer,可以浏览缓冲区的文件,并重新打开。操作方式同上。

备注:该插件的唯一一个缺点就是命令太长了,参考了VIM中文手册2601页)后,想了个办法,在.vimrc中设置插件的缩写,设置内容如下:

command CT CommandT

command CB CommandTBuffer

输入时,可以输入小写字母ctcb,然后按Tab键自动补全。

3. snipMate

SnipMate是为了提供类似TextMate的的文本片段。备注,看了好久,就是没能有一个可感的演示,有点不知所云。

3.1. 安装

安装SnipMate(使用pathogen管理)

$cd ~/.vim/bundle

#tlib_vim有何作用

$git clone https://github.com/tomtom/tlib_vim.git

#vim-addon-mw-utils有何作用

$git clone https://github.com/MarcWeber/vim-addon-mw-utils.git

$git clone https://github.com/garbas/vim-snipmate.git

可选的:

$git clone https://github.com/honza/vim-snippets.git

3.2. 具体使用

SnipMate仅工作在VI不兼容模式下。SnipMateVIM中实现了片段特性,片段类似模板,可以减少重复性插入的文件片段。每个片段包含一个扩展和一个触发器,在buffer中输入触发器,然后按下触发按钮。SnipMate允许多个片段使用相同的触发器,触发时会弹出可选的列表。SnipMate搜索包含在'runtimepath'中的每个实体。文件加载依赖filetypesyntax。片段可以被自动加载和刷新。

注意:SnipMate本身不携带任何片段,用户可以自己编写或者使用vim-snippets库。

3.2.1. 命令

:SnipMateOpenSnippetFiles 打开基于当前SnipMate-scopes中所有有效的位置。已存在的片段先显示。

:SnipMateLoadScope[!] scope [scope ...] 加载附加的片段域。没有[!]时,附加的域仅被加载到当前缓冲区中。例如,:SnipMateLoadScopes rails就会将rails的片段加载到当前缓冲区。

3.2.2. 选项

g:snipMate 该字典包含其他SnipMate的选项,简而言之,在设置其他的SnipMate之前,添加let g:snipMate = {}到你的.vimrc文件中。

 

g:snipMate.scope_aliases 关联到带有其他域的特定文件类型的字典值。其中的实体由文件类型(filetype)的键值和以逗号分隔的别名值组成。例如:

let g:snipMate.scope_aliases = {}

let g:snipMate.scope_aliases['ruby'] = 'ruby,ruby-rails'

告诉SnipMate,当编辑ruby或者包含ruby的文件类型时,ruby-rails片段附加到ruby片段中。局部缓冲区变量b:snipMate_scope_aliases被合并到全局变量中。

 

g:snipMate_no_default_aliases 注意:该选项将会被重命名

g:snipMate.no_default_aliases 设置为1时,确保SnipMate加载默认的域别名,默认值为(Filetype:Alias):cpp:c,cu:c,eruby:eruby-rails,html,html:javascript,mxml:actionscript,Objc:c,php:php,html,javascript,ur:html,javascript,xhtml:html

个别默认值可以通过设置为空来禁止,比如:let g:snipMate.scope_aliases.php = ''将会禁止PHP的别名。

 

g:snipMate['no_match_completion_feedkeys_chars'] 在某一触发器没有任何匹配时插入的字符串,默认情况下,根据'expandtab','tabstop','softtabstop'插入tab健。设置为空可以避免插入任何东西。

3.2.3. 映射

SnipMate使用的映射可以通过:map命令定制。例如,改变触发片段的健和移动到下一个tabstop的健。

        :imap <C-J> <Plug>snipMateNextOrTrigger

        :smap <C-J> <Plug>snipMateNextOrTrigger

下面列出可能的<Plug>映射:

<Plug>snipMateNextOrTrigger: 默认为<Tab>,跳到下一个tab stop,或者尝试扩展一个片段。可工作在插入和选择模式。

 

<Plug>snipMateTrigger           Default: unmapped       Mode: Insert

                                Try to expand a snippet regardless of any

                                existing snippet expansion. If done within an

                                expanded snippet, the outer snippet's tab

                                stops are lost, unless expansion failed.

没有默认映射,

<Plug>snipMateBack              Default: <S-Tab>        Mode: Insert, Select

                                Jump to the previous tab stop, if it exists.

                                Use in both insert and select modes.

 

<Plug>snipMateShow              Default: <C-R><Tab>     Mode: Insert

                                Show all available snippets (that start with

                                the previous text, if it exists). Use in

                                insert mode.

 

<Plug>snipMateVisual            Default: <Tab>          Mode: Visual

                                See |SnipMate-visual|.

 

Additionally, <CR> is mapped in visual mode in .snippets files for retabbing

snippets.

3.3. 实现相关

SnipMate是可配置的.plugin/SnipMate.vim分配了三个重要的健:

    " default implementation collecting snippets by handlers

    let g:SnipMate['get_snippets'] = SnipMate#GetSnippets

    " default handler:

    let g:SnipMateSources['default'] = SnipMate#DefaultPool

    " default directories containing snippets:

    let g:SnipMate['snippet_dirs']

                \ = funcref#Function('return split(&runtimepath,",")')

这些设置是可以覆盖的。默认的snippets集是由vimrtp决定的。

 

Example 1:~

autoload/SnipMate_python_demo.vim 演示了如何通过Python函数即刻注册附加的创建片段源。

 

Example 2:~

Add to your ~/.vimrc: For each know snippet add a second version ending in _

adding folding markers >

添加到你的配置文件(~/.vimrc)中,

 

    let g:commentChar = {

                \   'vim': '"',

                \   'c': '//',

                \   'cpp': '//',

                \   'sh': '#',

                \   'python': '#'

                \ }

    " url https://github.com/garbas/vim-snipmate/issues/49

    fun! AddFolding(text)

        return substitute(a:text,'\n'," ".g:commentChar[&ft]." {{{\n",1)."\n".g:commentChar[&ft]." }}}"

    endf

 

    fun! SnippetsWithFolding(scopes, trigger, result)

        " hacky: temporarely remove this function to prevent infinite recursion:

        call remove(g:SnipMateSources, 'with_folding')

        " get list of snippets:

        let result = SnipMate#GetSnippets(a:scopes, substitute(a:trigger,'_\(\*\)\?$','\1',''))

        let g:SnipMateSources['with_folding'] = funcref#Function('SnippetsWithFolding')

 

        " add folding:

        for k in keys(result)

        let a:result[k.'_'] = map(result[k],'AddFolding(v:val)')

        endfor

    endf

 

    " force setting default:

    runtime plugin/SnipMate.vim

    " add our own source

    let g:SnipMateSources['with_folding'] = funcref#Function('SnippetsWithFolding')

参考SnipMate-syntax寻找更多关于rtp所有可能的相关定位的信息。

4. vim-ruby

Vim-ruby提供了对vim的在ruby中移动动作和文本对象功能的增强。扩展不多,看起来应该很实用,具体的实现,我猜是通过正则匹配。

4.1. Vim-ruby中动作

Vim提供了诸如[m]m这样的跳转到方法定义的开始和结束的动作,但这仅对花括号的语言,而不是RubyVim-ruby插件增强了这些动作,使其能够在ruby文件中工作。

]m 跳转到下一个方法定义开始的地方

]M 跳转到下一个方法定义结束的地方

[m 跳转到上一个方法定义开始的地方

[M 跳转到上一个方法定义结束的地方

]] 跳转到下一个模块或类定义开始的地方

][ 跳转到下一个模块或类定义结束的地方

[[ 跳转到前一个模块或类定义开始的地方

[] 跳转到前一个模块或类定义结束的地方

备注:这里的动作看起来不似那么难记,估计多用用就熟了。

4.2. Vim-ruby文本对象

VIM的文本对象可以用来对文本域进行选择和操作。vim-ruby插件增加操作方法和类的文本对象。

am:"a method",选择从defend文本快,包括defend

im:"inner method",选择defend之间的块,不包括defend本身。 

aM:"a class",选择从classend之间的文本,包括classend 

iM:"inner class",选择从classend之间的文本,不包括classend.

5. vim-rails

Vim-rails提供了可以在VIM编辑界面下处理一切开发事宜的强大命令,前提是vim必须在Rails项目根目录打开。Rails.vim提供在VIM下开发RoR应用的一些特性如下:

  • l 方便的Rails目录结构导航:gf考虑上下文,:A:R方便的在文件之间跳转,:Emodel,:Eview,:Econtroller提供文件类型编辑(:edit)文件.SVT对应:split,:vsplit,:tabedit.导航帮助命令::help rails-navigation
  • l 增强的语法高亮:比如ActiveRecord中的DSL has_and_belongs_to_many
  • l rake命令的接口:使用:Rake运行当前测试,说明,夹具,迁移等,帮助命令:help rails-rake
  • l rails命令的接口,例如,:Rails console 调用rails控制台。很多命令包装了附加的特性,例如:Rgenerate controller Blog 生成blog控制器并将生成的文件添加到quickfix(??)列表中。:Rrunner包装了rails runner和直接测试运行。详细查看:help rails-scripts
  • l Partial以及concern取。在视图中,:Rextract {file}将选择的特定文本块替代为render {file}。在模型或控制器中,concern将会被创建。更多参考:help rails-:Rextract
  • l 完全定制。在全局,appgem包层次定义导航命令并复写可选的文件,默认的rake任务,语法高亮,缩写。更多参考:help rails-projections
  • l 与其他的插件的集成,[dbext.vim]安装之后,将能透明的配置和反射database.yml[abolish.vim]的用户 get pluralize and tableize coercions,[bundler.vim]的用户get a smattering of features.更多信息参考:help rails-integration

5.1. 安装

如果没有喜好的安装方法,推荐使用pathogen.vim 安装VIM插件。然后,简单的复制粘贴命令就行了:

cd ~/.vim/bundle

git clone git://github.com/tpope/vim-rails.git

git clone git://github.com/tpope/vim-bundler.git

不一定要求安装bundler.vim,但它会有一定的作用。一旦生成了help标签,就可以通过:help rails来查看手册。

5.2. 使用

Vim-rails提供了可以在VIM编辑界面下处理一切开发事宜的强大命令,前提是vim必须在Rails项目根目录打开。下面是该插件的一部分命令,详情请看帮助(备注:有些命令好像不太管用,难道是我自己没有学习到家)

  • l :Rake,例如:Rake db:migrate,  :Rake db:create, ...... 
  • l :Rmodel,例如:Rmodel info (查找model名称为info的文件
  • l :Rview,例如:Rview  infos/new (查找infos控制器下的new视图文件
  • l :Rcontroller,例如:Rcontroller infos(查找控制器名称为infos的文件
  • l :Rfind,例如:Rfind infos_controller(查找infos_controller.rb文件
  • l :Rails,例如:Rails console 或  :Rails generate model info age:integer
  • l :Rscript,例如:Rscript console 或 :Rscript generate model info age:integer(注意Rscript相当于script/rails命令
  • l :Redit,例如:Redit 相对路径 
  • l :Rlog,例如:Rlog development  打开development.log日志文件 
  • l :Rpreview 打开一个浏览器,http://localhost:3000 
  • l :Rrefresh     刷新 
  • l R,在目录下直接shift+r,可以刷新目录 
  • l gf            根据当前光标处内容跳转到文件 
  • l :Rmigration   查找migration文件 
  • l :Rlayout      查找layout文件 
  • l :Rhelper      查找helper文件 
  • l :Rstylesheet 
  • l :Rjavascript 
  • l :Rplugin 
  • l :Rlib 
  • l :Rtask 
  • l :Rserver

5.3. 常见问题

> I installed the plugin and started Vim.  Why does only the `:Rails`

> command exist?

This plugin cares about the current file, not the current working

directory.  Edit a file from a Rails application.

该插件只关心当前文件,不是当前工作目录,使用请从Rails应用程序中编辑文件。

> I opened a new tab.  Why does only the `:Rails` command exist?

This plugin cares about the current file, not the current working

directory.  Edit a file from a Rails application.  You can use the `:RT`

family of commands to open a new tab and edit a file at the same time.

 

> Can I use rails.vim to edit Rails engines?

It's not supported, but if you `touch config/environment.rb` in the root

of the engine, things should mostly work.

 

> Can I use rails.vim to edit other Ruby projects?

I wrote [rake.vim](https://github.com/tpope/vim-rake) for exactly that

purpose.  It activates for any project with a `Rakefile` that's not a

Rails application.

 

> What Rails versions are supported?

All of them.  A few features like syntax highlighting tend to reflect the

latest version only.

 

> Didn't rails.vim used to handle indent settings?

It got yanked after increasing contention over JavaScript.  Check out

[sleuth.vim](https://github.com/tpope/vim-sleuth).

6.TIPS

使用gtgT切换标签页(go tab)。

X windows中存在剪切板(vim”+)和类似剪切板的当前选择区(VIM中的“*)ctrl+v是对剪切板中内容进行复制,鼠标中健的点击对当前选择区中内容进行复制。这一点和Windows不同,windows只有剪切板,不了解的话,会对系统的行为感到困惑。不过当前选择区确实很有意思,只要被选择就被复制,很强大。

后记

上面这些,就是为了在VIM中开发Rails程序准备的一些插件。没有大量使用过,以后再修改和添加。

上面的这些程序,除了snipMate比较难以理解,其他的一些插件都很好理解和使用。

Ubuntu/Linux很有意思,就像一个神秘的盒子,有时想窥探一下其中包含的秘密,然后确实可以发现其中的秘密。对于Windows,盒子外面贴着禁止进入的封条。

参考文献

1.VIM教程与学习资料汇总:http://bbs.51osos.com/thread-8017-1-1.html

你可能感兴趣的:(vim,Ruby,Rails,snipmate,vim插件)