缘起
听从《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的主页。
NERDTree提供了丰富的键盘操作方式来浏览和打开文件。在打开vi之后,输入:NERDTree打开NERDTree,其界面如下:
图 1.1 NERDTree打开的界面
备注:简单的使用后发现,NERDTree打开的水平窗口的大小是固定的,要学习如何调整大小
NERDTree的一些常用的快捷键介绍如下:
Command-T的功能挺强大,可以在不显式目录树时(即不使用NERDTree时),检索并定位当前目录树下的文件。
安装参考《谁说Vim不是IDE?》,打开命令为:CommandT,使用界面为:
Command-T常用操作:
该插件还有个常用命令,:CommandTBuffer,可以浏览缓冲区的文件,并重新打开。操作方式同上。
备注:该插件的唯一一个缺点就是命令太长了,参考了VIM中文手册(2601页)后,想了个办法,在.vimrc中设置插件的缩写,设置内容如下:
command CT CommandT
command CB CommandTBuffer
输入时,可以输入小写字母ct或cb,然后按Tab键自动补全。
SnipMate是为了提供类似TextMate的的文本片段。备注,看了好久,就是没能有一个可感的演示,有点不知所云。
安装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
SnipMate仅工作在VI不兼容模式下。SnipMate在VIM中实现了片段特性,片段类似模板,可以减少重复性插入的文件片段。每个片段包含一个扩展和一个触发器,在buffer中输入触发器,然后按下触发按钮。SnipMate允许多个片段使用相同的触发器,触发时会弹出可选的列表。SnipMate搜索包含在'runtimepath'中的每个实体。文件加载依赖filetype和syntax。片段可以被自动加载和刷新。
注意:SnipMate本身不携带任何片段,用户可以自己编写或者使用vim-snippets库。
:SnipMateOpenSnippetFiles 打开基于当前SnipMate-scopes中所有有效的位置。已存在的片段先显示。
:SnipMateLoadScope[!] scope [scope ...] 加载附加的片段域。没有[!]时,附加的域仅被加载到当前缓冲区中。例如,:SnipMateLoadScopes rails就会将rails的片段加载到当前缓冲区。
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健。设置为空可以避免插入任何东西。
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.
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集是由vim的rtp决定的。
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所有可能的相关定位的信息。
Vim-ruby提供了对vim的在ruby中移动动作和文本对象功能的增强。扩展不多,看起来应该很实用,具体的实现,我猜是通过正则匹配。
Vim提供了诸如[m和]m这样的跳转到方法定义的开始和结束的动作,但这仅对花括号的语言,而不是Ruby。Vim-ruby插件增强了这些动作,使其能够在ruby文件中工作。
]m 跳转到下一个方法定义开始的地方
]M 跳转到下一个方法定义结束的地方
[m 跳转到上一个方法定义开始的地方
[M 跳转到上一个方法定义结束的地方
]] 跳转到下一个模块或类定义开始的地方
][ 跳转到下一个模块或类定义结束的地方
[[ 跳转到前一个模块或类定义开始的地方
[] 跳转到前一个模块或类定义结束的地方
备注:这里的动作看起来不似那么难记,估计多用用就熟了。
VIM的文本对象可以用来对文本域进行选择和操作。vim-ruby插件增加操作方法和类的文本对象。
am:"a method",选择从def到end文本快,包括def和end
im:"inner method",选择def和end之间的块,不包括def和end本身。
aM:"a class",选择从class到end之间的文本,包括class和end
iM:"inner class",选择从class到end之间的文本,不包括class和end.
Vim-rails提供了可以在VIM编辑界面下处理一切开发事宜的强大命令,前提是vim必须在Rails项目根目录打开。Rails.vim提供在VIM下开发RoR应用的一些特性如下:
如果没有喜好的安装方法,推荐使用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来查看手册。
Vim-rails提供了可以在VIM编辑界面下处理一切开发事宜的强大命令,前提是vim必须在Rails项目根目录打开。下面是该插件的一部分命令,详情请看帮助(备注:有些命令好像不太管用,难道是我自己没有学习到家):
> 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).
使用gt或gT切换标签页(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