Sublime Text 中的代码块 (Snippets) 缩减了码字的过程,极大的提高编程效率,是非常方便的工具。当我把编辑器迁移到 Vim 后就开始寻觅一款适合自己的 Snippet 插件,以下是我折腾 Vim 代码块的经验总结。
初学 Vim,还有很多不懂的地方,若有纰漏,请及时指出。
Vim 比较流行的代码块引擎有 SnipMate 和 UltiSnips。目前越来越多的人选用 UltiSnips,它的优点有:
UltiSnips 只是个引擎,需要搭配预设的代码块才能运转起来,以下是我创建的几个常用代码块。
# 当我在编辑器里输入 `test + tab`, 会自动补全以下代码
# test 'method name' do
#
# end
snippet "test" "test a method" r
$0
endsnippet
# 当我在编辑器里输入 `defs + tab`,会自动补全以下代码
# def self.method(*args)
#
# end
snippet "defs" "define a class method" r
def self.method${1:(${2:*args})}
$0
end
endsnippet
在创建代码块的过程中我遇到很多问题,如 trigger 命名不合理,Tab 的跳转不高效等。我特别想借鉴别人撰写 snippet 的经验。这个世界上总是有一批又懒又聪明的程序员,我在 Github 中轻松搜到一个比较好的代码块合集,叫 honza/vim-snippets,几乎涵盖所有编程语言。
与其自己一个个创建代码块,不如先站在巨人的肩上,然后再慢慢折腾,于是乎我的折腾思路调整为
使用 Vundle 管理 vim 插件,安装插件十分简便,在 .vimrc 中引入一行代码即可。
Plugin 'SirVer/ultisnips'
Plugin 'honza/vim-snippets'
安装完后就可以在 Vim 中使用代码块了,以下是几个经常用到的代码片段 demo,是不是很酷?
插入当前日期 (trigger: date)
插入当前时间 (trigger: datetime)
插入一个大的注释框 (trigger: bbox)
在 erb 中插入 if 语句
我们需要定制代码块来满足特殊需求,比如我希望在 rb 文件中输入 atc + tab
时可以快速的生成一个 ActiveSupport::Testcase,可以按照以下步骤实现这个功能。
有的同学会直接修改
~/.vim/bundle/vim-snippets
中的 snippets,建议不要这个干!因为这个目录是 Git 仓库,每次重装插件会丢失未提交的文件。还是单独创建一个 UltiSnips 文件夹来保存自定义代码片段比较稳妥。
# UltiSnips 插件会自动加载这个文件夹下的文件
mkdir ~/.vim/UltiSnips
touch ~/.vim/UltiSnips/ruby.snippets
代码块的文件命名是有讲究的,ruby.snippets 中定义的代码块只会在 rb 文件中生效;python.snippets 中定义的代码块只会在 py 文件中生效。
假如你想定义一个通用的代码块,在所有的文件类型中都能用,你可以把它定义在 all.snippets 中。
# ~/.vim/UltiSnips/ruby.snippets
snippet atc "test case of ActiveSupport::TestCase" !b
require 'test_helper'
class ${1:klass}Test < ActiveSupport::TestCase
test '${2:case_name}' do
${0}
end
end
endsnippet
# when I type head + tab, I hope...
---
title: title
layout: post
guid: e1eff5aaf0db41198c0f4acfc5ba4a9c
date: 2015-04-02 21:45:31
tags:
-
---
假如你用 jekyll 写博客,肯定对上面这段代码很熟。这是每篇博文头部的 head 信息 ,输入十分繁琐。
我特别希望在 markdown 文件中输入 head + tab
时可以自动生成博客的头部。自定义一个 markdown.snippets 就可解决这个问题。
# ~/.vim/UltiSnips/markdown.snippets
snippet head "Jekyll post header" b
---
title: ${1:title}
layout: post
guid: `!p
import uuid
if not snip.c:
guid = uuid.uuid4().get_hex()
snip.rv = guid
`
date: `!v strftime("%Y-%m-%d %H:%M:%S")`
tags:
- ${4}
---
${0}
endsnippet
# vim:ft=snippets:
这段代码中 guid 是用一段 Python 脚本生成的,date 是用 Vim 脚本生成的,${0}
代表 tab 最终停留的位置, b
代表 begin (snippet should be expanded only at the beginning of a line)。
It's cool!
有好多 Vim er 高手不用代码块 (snippet) ,他们手工撸制每一行代码,喜欢原汁原味。每个人的偏好不同,使用 Snippet 真的极大的提高了工作效率。