Ⅰ. 插件描述
Vim template-files expanderⅡ. 基本信息
|
Ⅲ. 安装方法
使用Vundle管理器安装
在你的.vimrc下添加:Plugin 'luchermitte/mu-template-safe-and-sound'
… 然后在Vim中运行以下命令:
:source %
:PluginInstall
对于Vundle版本 < 0.10.2,请用上面的Bundle替换Plugin。
使用NeoBundle管理器安装
在你的.vimrc下添加:NeoBundle 'luchermitte/mu-template-safe-and-sound'
… 然后在Vim中运行以下命令:
:source %
:NeoBundleInstall
使用VimPlug管理器安装
在你的.vimrc下添加:Plug 'luchermitte/mu-template-safe-and-sound'
… 然后在Vim中运行以下命令:
:source %
:PlugInstall
使用Pathogen管理器安装
在终端中运行以下命令:cd ~/.vim/bundle
git clone https://github.com/luchermitte/mu-template
Ⅳ. 文档说明
Introduction
µTemplate is a template-files loader for Vim. Once loaded, templates are interpreted and expanded according to a flexible syntax.
Features
Template-files can be expanded:
- automatically when opening a new buffer (unless deactivated from the .vimrc),
- explicitly through menus or the command line,
- from the INSERT-mode in a snippet-like fashion ;
- from the VISUAL-mode to surround the selection with a snippet ;
- All snippets are defined in their own template-file ;
- The template-files can be overridden by the user, or in the context of a specific project ;
- Filetype specific snippets can be defined for the INSERT-mode (they can be inherited, e.g. C snippets can be used from C++, Java, _etc._), the list of matching snippets will be presented with a hint for each snippet ;
- Computed VimL expressions can be inserted ;
- VimL instructions can be executed during the expansion ;
- Template-files can include other template-files in a function-like manner (parameters are even supported);
- Fully integrated with my placeholders-system ;
- Supports re-indentation (if desired), and Python indentation ;
- Works well with vim folding ;
- I18n friendly ;
- The expansion happens after any local vimrcs present are loaded -- in order to set project-specific variables before the expansion is done.
- Thanks to Tom Link's StakeHolders plugin, µTemplate does now have tied placeholders (modifying one named placeholder modifies other placeholders with the same name). Not installing Stakeholders will not prevent you from using µTemplate.
However, it misses the following features:
- Several snippets per template-file -- It's extremely unlikely that µTemplate will ever work this way.
- One key that does everything: expansion of snippets/previously typed keywords/dictionary/..., or jump to the next placeholder depending on the context.
Examples
A few examples are better than a long speech, check the documentation for more precisions.
Note: all the default template-files shipped with mu-template can be browsed from the repository
C-if snippet
Snippet that uses ¡, s:Surround(), lh-style's styling feature
VimL:"{if} Template-File, Luc Hermitte
VimL:" hint: if (cond) { action }
VimL: let s:value_start = '¡'
VimL: let s:value_end = '¡'
VimL: let s:reindent = 1
VimL: let s:marker_open = '<+'
VimL: let s:marker_close = '+>'
if(¡substitute(s:Surround(2, '<+cond+>'), '^\_s*\|\_s*$', '', 'g')¡){
¡s:Surround(1, '<+code+>')¡
}<+s:TerminalPlaceHolder()+>C-case snippet
Snippet that uses ¡, s:TerminalPlaceHolder(), lh-style's styling feature, and that takes options.
VimL:" {case:} File Template, Luc Hermitte, 05th Jan 2011
VimL:" hint: case {tag: ...; break;}
VimL: let s:value_start = '¡'
VimL: let s:value_start = '¡'
VimL: let s:value_end = s:value_start
VimL: let s:marker_open = '<+'
VimL: let s:marker_close = '+>'
VimL: let s:case = empty(s:Args()) ? lh#marker#txt('case') : (s:Args()[0])
VimL: let s:_with_block2 = len(s:Args()) <= 1 ? INPUT("Insert a block for the case (0/1) ?") : (s:Args()[1])
case <+s:case+>:
<+s:_with_block2?'{':''+>
<+¡substitute(s:case, lh#marker#txt('\(.\{-}\)'), '\1', '')¡-code+>;
break;
<+s:_with_block2?'}':''+>Vim-plugmap snippet
Recursive snippet that takes options, uses s:Include(),s:SurroundableParam(), :MuT-commands, and that contain a loop
VimL:" ``VimL <Plug> mappings'' File Template, Luc Hermitte <hermitte {at} free {dot} fr>
VimL:" hint: <Plug>mapping + default mapping
VimL: let s:reindent = 1
VimL: let s:marker_open = '<+'
VimL: let s:marker_close = '+>'
MuT: let s:mapmode = s:SurroundableParam('mode', 1, lh#option#unset())
MuT: let s:plugname = s:SurroundableParam('plug', 2, lh#option#unset())
MuT: if lh#option#is_unset(s:mapmode)
MuT: let s:mapmode = INPUT('Mode (invox)?', lh#marker#txt('mode'))
MuT: endif
MuT: if lh#option#is_unset(s:plugname)
MuT: let s:plugname = INPUT('<Plug>?', lh#marker#txt('name'))
MuT: endif
VimL: call s:Include('get-script-kind', 'vim/internals')
VimL: let s:buffer = s:ftplug ? '<buffer> ' : ''
MuT: if strlen(s:mapmode) == 1 || lh#marker#is_a_marker(s:mapmode)
<+s:mapmode+>noremap <+s:buffer+><silent> <Plug><+s:plugname+> <+definition+>
if !hasmapto('<Plug><+s:plugname+>', '<+s:mapmode+>')
<+s:mapmode+>map <+s:buffer+><silent> <unique> <+keybinding+> <Plug><+s:plugname+>
endif
MuT: else
VimL: for mode in split(s:mapmode, '\zs') | call s:Include('plugmap', 'vim', {'mode': mode, 'plug': s:plugname}) | endfor
MuT: endifInteractive template-file: C++ Class Template
VimL:" C++ Class Template, Luc Hermitte
VimL:" hint: Class Wizard (asks for class semantics)
VimL: let s:value_start = '¡'
VimL: let s:value_end = '¡'
VimL: let s:reindent = 1
VimL: let s:marker_open = '<+'
VimL: let s:marker_close = '+>'
VimL: let s:clsname = empty(s:Args()) ? INPUT("class name ?", lh#marker#txt(expand('%:t:r'))) : (s:Args()[0])
VimL: call CppDox_ClassWizard(s:clsname)
VimL:"
VimL:"
VimL: call s:Include("section-sep", "c", s:clsname." class")
VimL: silent! unlet s:doc
VimL: let s:doc = []
VimL: let s:doc += [{ "tag": "ingroup", "text": "g".lh#option#get('dox_group', lh#marker#txt('Group')) }]
VimL: let s:doc += [{ "tag": "brief" }]
VimL: let s:doc += [{ "text": "\n" }]
VimL: let s:doc += [{ "text": "<+doc+>" }]
VimL: let s:doc += [{ "text": "\n" }]
VimL: let s:doc += [{ "tag": "invariant"}]
VimL: let s:doc += [{ "text": "\n" }]
VimL: let s:doc += [{ "tag": "semantics"}]
VimL: let s:doc += [{ "text": g:CppDox_semantics}]
VimL: let s:doc += [{ "text": "\n" }]
VimL: let s:doc += [{ "tag": "version", "text": "$"."revision$"}]
VimL: let s:doc += [{ "tag": "author"}]
VimL: call s:Include("formatted-comment", "cpp/internals", s:doc)
class <+s:clsname+>
¡g:CppDox_inherits¡
{
public:
/**<+lh#dox#tag('name')+> Construction/destruction
*/
//<+lh#dox#tag('{')+>
VimL: let s:fn_comments = { }
VimL: let s:fn_comments.brief = "Default constructor."
VimL: let s:fn_comments.throw = {"optional": 1}
VimL: call s:Include("function-comment", "cpp/internals",s:fn_comments)
<+s:clsname+>();
VimL: "
VimL: " not documented, this is :DOX job
<+s:clsname+>(<+define the params, and document me w/ :DOX+>);
VimL: "
VimL: " todo: support using default implementations
MuT: if g:CppDox_do_copy
VimL: call s:Include("copy-constructor", "cpp", s:clsname)
VimL: call s:Inject([""])
VimL: call s:Include("copy-and-swap", "cpp", s:clsname)
MuT: endif
VimL: call s:Include("destructor", "cpp",{"name":(s:clsname), "virtual": (g:CppDox_isVirtualDest) })
//<+lh#dox#tag('}')+>
<+Other public functions+>;
¡IF(strlen(g:CppDox_protected_members), "protected:\n", '')¡
¡g:CppDox_protected_members¡
private:
¡g:CppDox_forbidden_members¡
<+Private functions+>;
<+Attributes+>;
};<++>Completely useless recursive example
- test.template
VimL: let s:value_start = '¡'
VimL: let s:value_end = '¡'
VimL: let s:marker_open = '<+'
VimL: let s:marker_close = '+>'
VimL: let s:var = 1
BEGIN<++>
/*
* ¡'$'¡Id$
*/
¡s:var¡
a¡s:var¡
¡s:var + 5¡a
a¡s:var¡a¡s:var¡
a¡s:var¡a¡s:var¡a
here <+we go+>
VimL: let s:msg =''
VimL: call s:Include('test-included')
VimL: let s:msg =' again'
VimL: call s:Include('test-included')
------
Some tests:
VimL: let s:expr = "first line\nsecond line\n "
text ¡s:expr¡
text
END- test-included.template
VimL: let s:times = exists('s:times') ? (s:times+1) : 1
This part has been included¡s:msg¡ ¡((s:times==1)?'once':(s:times==2 ? 'twice' : (s:times.' times')))¡.
VimL: if s:times <= 4 | call s:Include('test-included') | endif
VimL: silent! unlet s:timesInstallation
- Requirements: Vim 7.+, lh-vim-lib, lh-style, and my bracketing-system, and optionally lh-dev.
With vim-addon-manager, install
mu-template@lh. This is the preferred method because of the various dependencies.ActivateAddons mu-template@lh " And don't forget ActivateAddons stakeholders " don't forget also to support a few default snippets ActivateAddons lh-devor you can use vim-flavor that also
supports dependenciesflavor 'LucHermitte/mu-template' " And don't forget flavor 'tomtom/stakeholders_vim' " don't forget also to support a few default snippets flavor 'LucHermitte/lh-dev'- N.B.: installing lh-cpp or lh-refactor with VAM or vim-flavor will also install µTemplate.
or you can clone the git repositories
git clone git@github.com:LucHermitte/lh-vim-lib.git git clone git@github.com:LucHermitte/lh-style.git git clone git@github.com:LucHermitte/lh-brackets.git git clone git@github.com:LucHermitte/mu-template.git # and don't forget: git clone git@github.com:tomtom/stakeholders_vim.git # don't forget also to support a few default snippets git clone git@github.com:LucHermitte/lh-dev.gitor with Vundle/NeoBundle:
Bundle 'LucHermitte/lh-vim-lib' Bundle 'LucHermitte/lh-style' Bundle 'LucHermitte/lh-brackets' Bundle 'LucHermitte/mu-template' " and don't forget: Bundle 'tomtom/stakeholders_vim' " don't forget also to support a few default snippets Bundle 'LucHermitte/lh-dev'
Credits
- Gergely Kontra is the author of the first version of µTemplate.
- Luc Hermitte (LH) is the current maintainer of this enhanced version of mu-template.
- Robert Kelly IV, Zdenek Sekera for their insight and the feedback they provided me (LH).
- Troy Curtis Jr, for his intensive testing.
See also
There are many other template-files loaders for Vim, see the non exhaustive list of vim.wikia, or the comparative matrix in Marc Weber's vim wiki.

