myhome/.config/nvim/plugged/bash-support.vim/doc/templatesupport.txt

2369 lines
88 KiB
Plaintext
Raw Normal View History

*templatesupport.txt* MM Template Support Mar 28 2014
MM Template Support *template-support*
Plug-in version 0.9.3
for Vim version 7.0 and above
Wolfgang Mehner <wolfgang-mehner at web.de>
--- The Maps & Menus Template Support ... ---
-- ... for Vim Users --
This plug-in aims at providing extendible template libraries. A template
library can assist in speeding up the writing of code, while at the same time
ensuring a consistent style. The templates are written in an easy to use
markup language, which enables the user to customize templates without much
hassle.
Menus and maps to access the templates are created automatically. While maps
might or might not be the preferred way of inserting templates (as well as
using Vim in general), the menus always provide an overview of the templates
and the associated maps. This makes it quite easy to use the templates and
learn their maps at the same time.
-- ... for Plug-Ins --
The template support is controlled by an API and thus can be integrated into
another plug-in. A template library is essentially an object, several of which
can exist in parallel. This makes it relatively easy to write a plug-in for
the programming language of your choice.
Here is a list of high profile plug-ins which use the template support:
- Bash-Support (www.vim.org/scripts/script.php?script_id=365)
- C-Support (www.vim.org/scripts/script.php?script_id=213)
- Perl-Support (www.vim.org/scripts/script.php?script_id=556)
==============================================================================
0. TABLE OF CONTENTS *template-support-contents*
==============================================================================
1. Introduction |template-support-intro|
2. Basic Usage |template-support-basics|
3. Template Library |template-support-library|
3.1 Personalization |template-support-lib-person|
4. Templates |template-support-templates|
4.1 Macros |template-support-templ-macro|
4.1.1 Predefined Macros |template-support-templ-predef|
4.2 Tags |template-support-templ-tags|
4.3 Placement |template-support-templ-place|
4.3.1 Visual Mode |template-support-templ-visual|
4.4 Maps & Menus |template-support-templ-maps|
5. Lists |template-support-lists|
5.1 Formats |template-support-lists-format|
5.2 Hashes |template-support-lists-hash|
6. Advanced Features |template-support-advanced|
6.1 Coding Styles |template-support-adv-styles|
6.2 File Pickers |template-support-adv-files|
7. Menus |template-support-menus|
8. Help Templates |template-support-help-templ|
9. API |template-support-api|
9.1 Basic Usage |template-support-api-basic|
9.2 Creating Maps and Menus |template-support-api-maps|
9.3 Access |template-support-api-access|
9.4 Miscellany |template-support-api-misc|
10. Backwards Compatibility |template-support-backwards|
A. Syntax |template-support-syntax|
A.1 Command Section |template-support-syntax-cmd|
A.2 Templates |template-support-syntax-templ|
A.3 Lists |template-support-syntax-list|
B. Commands |template-support-commands|
B.1 Command Section |template-support-cmd-cmd-sct|
B.2 Templates |template-support-cmd-templates|
C. Options |template-support-options|
C.1 Templates |template-support-opt-templ|
C.2 List |template-support-opt-list|
D. Change Log |template-support-change-log|
==============================================================================
1. INTRODUCTION *template-support-intro*
==============================================================================
The manual at hand documents the Maps & Menus Template Support. The next
chapter |template-support-basics|, gives a short preview of the capabilities of
the template support. Templates are listed, together with further
configuration, in a so-called template library. Template libraries are
explained in |template-support-library|, followed by the description of
templates in |template-support-templates|. These chapters will enable the
average user to configure his or her templates.
Advanced topics are addressed in the following chapters. Lists are explained
in |template-support-lists|, followed in |template-support-advanced| by more
advanced features. The customization of the automatic menu creation is
explained in |template-support-menus|. Help templates offer a mechanism to
quickly access different documentations, they are documented in
|template-support-help-templ|.
Plug-In developers will find information on the API in |template-support-api|.
==============================================================================
2. BASIC USAGE *template-support-basics*
==============================================================================
Templates are short pieces of text which can be included into source code or
text of any other kind. But they are not just plain text, they can be extended
with macros and tags to provide further convenience. Macros can be
automatically replaced with the date or the filename, or they can be replaced
with input from the user, for example the name of a new function.
The following example shows two templates, as they appear in a so-called
template library. A template library is a text file which lists several
templates, along with their maps and menu shortcuts.
>
== file description == start ==
// ==================================================
// File: |FILENAME|
// Description: <CURSOR>
//
// Author: |AUTHOR|
// Version: 1.0
// Created: |DATE|
// ==================================================
== function == below ==
void |?FUNCTION_NAME| ( <CURSOR> )
{
<SPLIT>
} /* end of function |FUNCTION_NAME| */
== ENDTEMPLATE ==
<
Each line (the so-called header) >
== <name> == <options> ==
starts a new template, >
== ENDTEMPLATE ==
marks the end of the template "function".
When the template "file description" is inserted, it is placed at the start of
the file (option "start"). The filename and the date are inserted where the
macros *|FILENAME|* and *|DATE|* appear, the name of the user is also inserted.
After insertion, the cursor is placed where the <CURSOR> tag appears (the
cursor is represented by "|"):
>
// ==================================================
// File: helloworld.cc
// Description: |
//
// Author: Me!
// Version: 1.0
// Created: 29.2.2000
// ==================================================
<
The template "function" is inserted below the current line (option "below").
The user is asked to provide a replacement for the macro *|FUNCTION_NAME|* (it
is marked with "?"), which is then inserted into the text:
>
void say_hello ( | )
{
} /* end of function say_hello */
<
The macro can also be used in visual mode (it contains the tag <SPLIT>). The
template is then inserted surrounding the selected lines, which appear at the
position of the split tag.
Assume the line "printf(...)" is selected:
>
// ...
<
printf ( "Hello world!" ); ~
>
// ...
<
After inserting the template, the code looks like this:
>
// ...
void say_hello ( | )
{
printf ( "Hello world!" );
} /* end of function say_hello */
// ...
<
==============================================================================
3. TEMPLATE LIBRARY *template-support-library*
==============================================================================
A template library is a text file which lists several templates, along with
other objects, and commands to configure the behavior of the templates. This
file must be given to the template support in order to be loaded. If you are
working with a plug-in which uses the template support, the plug-in itself
will take care of that.
Along with templates, a library file can contain comments. Comments always
start at the beginning of a line. The standard is for comments to start with
the character '§'. This may vary, depending on which plug-in uses the template
support.
Comment lines end the current template, so comments should only be used
outside of templates.
Outside of templates, the library can contain commands. Among other things,
they configure the behavior of the templates and the menus the template
support creates.
Commands always start at the beginning of the line and, as all other names in
the library, are case sensitive.
A template library can be organized in several files. The command: >
IncludeFile ( "<path>/<file>" )
loads templates from another file (|template-support-IncludeFile|). The path
is given relative to the including file. The call: >
IncludeFile ( "<path>/<file>", "abs" )
interprets the path as a absolute path instead.
The names of the templates also define the menu structure which the template
support creates. Dots appearing in the names place the templates into
submenus. The following library will create two menus and a submenu "special".
>
== Comments.special.GNU license == below ==
// License: Copyright (c) |YEAR|, |AUTHOR|
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, version 2 of the
// License.
// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.
// See the GNU General Public License version 2 for more details.
== Comments.file description == start ==
// ==================================================
// File: |FILENAME|
// Description: <CURSOR>
//
// Author: |AUTHOR|
// Version: 1.0
// Created: |DATE|
// ==================================================
== Idioms.function definition == below ==
void |?FUNCTION_NAME| ( <CURSOR> )
{
<SPLIT>
} /* end of function |FUNCTION_NAME| */
== ENDTEMPLATE ==
<
Menus and entries are generated in the order in which the corresponding
templates are encountered in the library. The above example will generate this
menu structure:
>
Plug-In Menu
>-+ Comments
| >-+ Special
| | >--- GNU license
| >-- file description
>-+ Idioms
| >-- function definition
<
This also means that a new menu entry can be added by simply putting a new
template at that position in the library. Details on the menu creation can be
found in |template-support-menus|.
------------------------------------------------------------------------------
3.1 PERSONALIZATION *template-support-lib-person*
------------------------------------------------------------------------------
A personalization of the template library can be achieved by using macros. The
command 'SetMacro' (|template-support-SetMacro|) is used to set replacements
for various macros (my settings as an example):
>
SetMacro( 'AUTHOR', 'Wolfgang Mehner' )
SetMacro( 'AUTHORREF', 'wm' )
SetMacro( 'EMAIL', 'wolfgang-mehner@web.de' )
SetMacro( 'ORGANIZATION', '' )
SetMacro( 'COPYRIGHT', 'Copyright (c) |YEAR|, |AUTHOR|' )
<
The replacements may contain other macros. When a template is inserted all
macros will be substituted by the respective replacements.
Other macros and replacements can be added at will, e.g. the following could
be used in a template library for Bash: >
SetMacro( 'INTERPRETER', '/bin/sh' )
Then the template for the file description may look as follows:
>
== file description == start ==
#! |INTERPRETER|
# ==================================================
# File: |FILENAME|
# Description: <CURSOR>
#
# Author: |AUTHOR|
# Version: 1.0
# Created: |DATE|
# ==================================================
== ENDTEMPLATE ==
<
The format of the included dates and times can be set in a similar fashion,
using 'SetFormat' (|template-support-SetFormat|):
>
SetFormat( 'DATE', '%D' )
SetFormat( 'TIME', '%H:%M' )
SetFormat( 'YEAR', 'year %Y' )
<
These special macros can never be set by 'SetMacro'. The following call will
have no effect and produce a warning: >
SetMacro( 'DATE', "April Fools' Day" )
<
During template insertion, the macros *|DATE|* , *|TIME|* and *|YEAR|* will be
replaced with the current date and time.
==============================================================================
4. TEMPLATES *template-support-templates*
==============================================================================
Templates are short pieces of text which are enhanced by so-called macros and
tags. They define a simple markup language which determines the preparation of
the text before it is inserted and control is handed back to the user.
Beyond that, every template has a name which also determines its place in the
menu structure the template support creates. Together with the template, its
menu shortcut and map are defined. The whole accessibility of the template is
specified in this one place.
Each template starts with a header: >
== <name> == [ <options> == ]
For consistency with other constructs, the following format is also supported: >
== TEMPLATE: <name> == [ <options> == ]
The list of options can be omitted.
The name of the template starts with a letter or underscore, and can not end
with a whitespace. Whitespaces in between the name and "==" will be ignored.
The name can contain these characters:
a-z, A-Z, 0-9
_ + - . , <Space>
Dots have a special meaning. They determine the menu structure the template
support will create (see |template-support-library| for a short introduction).
The list of option defines the map and menu shortcut of the template, and some
aspects of its behavior during insertion into a text, such as its placement
relative to the position of the cursor.
The following example shows a possible template for the C statement "if":
>
== Statements.if == below, map:si, sc:i ==
if ( <CURSOR> )
{
}
== ENDTEMPLATE ==
<
The option "below" specifies that the template should always be inserted in
the lines below the current cursor position. The map is set by the option
"map", it will be |<LocalLeader>|si. The option "sc" sets the shortcut of the
entry within the menu "Statements".
------------------------------------------------------------------------------
4.1 MACROS *template-support-templ-macro*
------------------------------------------------------------------------------
Templates are useful because in source code, certain structures are repeated
regularly. Within this structures however, certain parts a variable. Templates
represent those via macros. Macros have a name, which has to follow the same
rules as C identifiers. They start with a letter or underscore, and can
contain numbers after that. Within a template, macros are written as their
names, surrounded by two bars:
*|AUTHOR|*
Replacement for macros can be given in the template library itself: >
SetMacro( 'AUTHOR', 'Wolfgang Mehner' )
These macros are replaced when inserting the template:
>
== Comments.file description == start ==
# ==================================================
# File: |FILENAME|
# Description: <CURSOR>
#
# Author: |AUTHOR|
# Version: 1.0
# Created: |DATE|
# ==================================================
== ENDTEMPLATE ==
<
The template library will appropriately replace *|FILENAME|* and *|DATE|* and
take the replacement for *|AUTHOR|* from the template library.
Another option is to ask the user for a replacement every time the template is
inserted:
>
== Idioms.function == below ==
void |?FUNCTION_NAME| ( <CURSOR> )
{
<SPLIT>
} /* end of function |FUNCTION_NAME| */
== ENDTEMPLATE ==
<
The question mark in front of the name means the user will be prompted for a
replacement for "FUNCTION_NAME". This replacement is then inserted twice. This
becomes particularly useful if this name appears in another template. If a
replacement for a certain macro has been given before, this replacement will
be suggested the next time the user has to replace this macro:
>
== Comments.function description == below ==
# ==================================================
# Function: |?FUNCTION_NAME|
# Purpose: <CURSOR>
# Description: TODO
# ==================================================
== ENDTEMPLATE ==
<
Certain uses come with special requirements on the format of the replacement.
Consider an include guard, where usually an upper case version of the files
name is used to name the guard, such as "_THISFILE_INC":
>
== Preprocessor.include guard == below, noindent ==
#ifndef _|BASENAME:u|_INC
#define _|BASENAME:u|_INC
<CURSOR>
#endif // ----- #ifndef _|BASENAME:u|_INC -----
== ENDTEMPLATE ==
<
The macro *|BASENAME|* is automatically replaced with the name of the current
file, not including the extension. The flag ":u" means the replacement will be
inserted with all letters in uppercase. So a file named "string.h" will have
an include guard named "_STRING_INC".
The possible flags are listed below:
:l - change text to lowercase
:u - change text to uppercase
:c - capitalize text (change first letter to uppercase)
:L - legalize name (replace all non-word characters with underscores)
------------------------------------------------------------------------------
4.1.1 Predefined Macros *template-support-templ-predef*
The replacements for various macros are handles automatically by the template
support. Mostly, they will help with the basic documentation of the file: What
was edited and when?
*|PATH|* : the path of the current file
*|FILENAME|* : the name of the file
*|BASENAME|* : the name of the file without the suffix
*|SUFFIX|* : the suffix of the file
Except for using flags, the user has no further influence on the replacements
of these macros, they can not be set via SetMacro().
*|TIME|* : the current time
*|DATE|* : the current date
*|YEAR|* : the current year
The format of the inserted dates and times can be set via SetFormat (see
|template-support-SetFormat|).
------------------------------------------------------------------------------
4.2 TAGS *template-support-templ-tags*
------------------------------------------------------------------------------
Templates can contain tags, which influence the behavior after the template
has been inserted into the current buffer. The simplest one is <CURSOR>,
which specifies the position of the cursor after the template has been
inserted. Consider the following example:
>
== Statements.if == below ==
if ( <CURSOR> )
{
}
== ENDTEMPLATE ==
<
After template insertion the cursor is placed between the round brackets and
the user can write down the condition.
The cursor tag may cause the indentation to be slightly off after template
insertion. Therefore a second version of the cursor tag exists: {CURSOR}. You
should always choose the one which is more naturally compatible with the
languages syntax, and in extension its automatic indentation:
>
== Statements.block == below ==
{
{CURSOR}
}
== ENDTEMPLATE ==
<
Further convenience is introduced by jump tags. Instead of moving into the
block using arrow keys, the user can be given the possibility to jump to the
next position where editing is required:
>
== Statements.if == below ==
if ( <CURSOR> )
{
<+IF_PART+>
}
== ENDTEMPLATE ==
<
The standard map for jumping is <ctrl+j>, also it may vary with each plug-in
using the template support.
Jump tags have one of the following formats:
<+NAME+> <-NAME->
{+NAME+} {-NAME-}
The text will be indented automatically with the jump tags still appearing in
it, so for every language the appropriate version has to be chosen. The name
consists of arbitrary word characters (letters, digits and underscores) and
can even be empty. The name has no other function than "documenting" the
inserted code:
>
== Statements.if, else == below ==
if ( <CURSOR> )
{
<+IF_PART+>
}
else
{
<+ELSE_PART+>
}
== ENDTEMPLATE ==
------------------------------------------------------------------------------
4.3 PLACEMENT *template-support-templ-place*
------------------------------------------------------------------------------
Templates can be placed at different positions relative to the cursor. In most
examples above the option "below" has been used. It means the template is
inserted below the current line. The opposite can be achieved using "above",
while "start" places the template at the beginning of the file, which makes
sense for example for file descriptions:
>
== Comments.file description == start ==
...
== Idioms.function definition == below ==
...
== ENDTEMPLATE ==
<
These options cause whole lines to be inserted. Two other options exist:
>
== Comments.end-of-line comment == append ==
/* <CURSOR> */
== Comments.date and time == insert ==
|DATE|, |TIME|<CURSOR>
== ENDTEMPLATE ==
<
The template "Comments.end-of-line comment" will be inserted at the end of the
current line, while "Comments.date and time" will insert a timestamp at the
cursor position.
These placement modes are available:
start - the text is placed above the first line
above - the text is placed above the current line
below - the text is placed below the current line (default)
append - the text is appended to the current line
insert - the text is inserted at the cursor position
By default, the lines containing a newly inserted template are automatically
indented. To suppress this behavior use the option "noindent". This can be
used for code fragments which contain constructs the indentation program does
not handle correctly.
------------------------------------------------------------------------------
4.3.1 Visual Mode *template-support-templ-visual*
Oftentimes, existing code needs to be rearranged, for example some lines of
code must be surrounded with an if-statement. For this reason, the <SPLIT>
tag exists:
>
== Statements.if == below ==
if ( <CURSOR> )
{
<SPLIT>
}
== ENDTEMPLATE ==
<
If the template is inserted in normal or insert mode, nothing changes. The tag
will be removed automatically. In visual mode however, the selected line will
be surrounded with the template. Consider these lines of code, where the lines
containing "printf" are selected:
>
// ...
<
printf ( "Loading the file ..." ); ~
printf ( "... reading %d bytes.", n ) ~
>
// ...
<
After inserting the template "Statements.if", the code looks like this:
>
// ...
if ( | )
{
printf ( "Loading the file ..." ); ~
printf ( "... reading %d bytes.", n ) ~
}
// ...
<
Now the user can type in the condition.
Jump and split tags might be in conflict. Consider the following example:
>
== Statements.if, else == below ==
if ( <CURSOR> )
{
<SPLIT><+IF_PART+>
}
else
{
<+ELSE_PART+>
}
== ENDTEMPLATE ==
<
When using the template in visual mode, the jump tag <+IF_PART+> should not
appear, since the if block already contains the selected line. This is why
jump tag exist in different versions. The two version <-NAME-> and {-NAME-}
are removed in visual mode. They behave opposite to the <SPLIT> tag, which is
removed in every other mode. A better version of the above example looks like
this:
>
== Statements.if, else == below ==
if ( <CURSOR> )
{
<SPLIT><-IF_PART->
}
else
{
<+ELSE_PART+>
}
== ENDTEMPLATE ==
<
For templates containing a split tag, the option "noindent" is particularly
useful, since it can prevent large sections of code from being indented
unnecessarily. The following example shows a template for an include guard,
using a C-macro "_THISFILE_INC":
>
== Preprocessor.include guard == below, noindent ==
#ifndef _|BASENAME:u|_INC
#define _|BASENAME:u|_INC
<CURSOR><SPLIT>
#endif // ----- #ifndef _|BASENAME:u|_INC -----
== ENDTEMPLATE ==
<
Here, running the indentation program after insertion is an unnecessary effort
and may potentially destroy hand-crafted indentation in a large piece of code.
------------------------------------------------------------------------------
4.4 MAPS & MENUS *template-support-templ-maps*
------------------------------------------------------------------------------
The template support automatically creates maps and menu entries for the
templates in the library. The menu entries appear in the order the templates
have been read. Including a file via >
IncludeFile ( "<path>/<file>" )
will cause this file to be processed first, then the rest of the including
file is read.
The map and menu shortcut of a template are defined together with the
template:
>
== Statements.if == below, map:si, sc:i ==
if ( <CURSOR> )
{
<+IF_PART+>
}
== ENDTEMPLATE ==
<
The templates will have the map |<LocalLeader>|si and the shortcut "i".
Menu entries are created by default. The option "nomenu" suppresses this
behavior:
>
== Comments.fix this == nomenu, append, map:cfx ==
// TODO: fix this
== ENDTEMPLATE ==
<
This template will not clutter the menu and can only be inserted via its map.
An overview of all the options:
nomenu - no menu entry is created
sc:<sc> - a shortcut is created for the menu entry of this template
shortcut:<sc> - long version of sc:<sc>
map:<map> - a map is created for this template
==============================================================================
5. LISTS *template-support-lists*
==============================================================================
Template libraries would regularly contain a huge number of templates with a
repetitive structure. Consider these templates for a C template library:
>
== Preprocessor.include math, map: pim ==
#include <math.h>
== Preprocessor.include stdlib, map:pisl ==
#include <stdlib.h>
== Preprocessor.include stdio, map:pisio ==
#include <stdio.h>
== Preprocessor.include string, map:pistr ==
#include <string.h>
== ENDTEMPLATE ==
<
This has several disadvantages. Besides being difficult to write and maintain,
these templates would not be well accessible. The user would have to memorize
a map for each and every one of them.
This is why lists exist. They appear as objects in the template library. The
header of a list starts with "LIST:" and then contains a name, which has to
follow the same rules as C identifiers. They start with a letter or
underscore, and can contain numbers after that.
>
== LIST: C_StandardLibs ==
'math',
'stdlib',
'stdio',
'string',
== ENDLIST ==
== Preprocessor.c libs == below, map:pcl ==
|PickList( '#include <~.h>', 'C_StandardLibs' )|
#include <|PICK|.h><CURSOR>
== ENDTEMPLATE ==
<
The template "Preprocessor.c libs" uses this list. The command: >
"|PickList( '<prompt>', '<list>' )|"
determines which list is used. During template insertion the user is prompted
to choose an entry from the list, but can also type another name. The prompt
supports tab-completion and navigation with arrow keys. The first argument is
a string which is displayed on the command line, to clarify the meaning of the
choice. After the users makes the choice, the macro *|PICK|* is created, which
contains the chosen item.
Lists can be used again in another context, for example to support C++
programming:
>
== Preprocessor.c++, c libs == below, map:ppc ==
|PickList( '#include <c~>', 'C_StandardLibs' )|
#include <c|PICK|><CURSOR>
== ENDTEMPLATE ==
<
When the template is inserted via a map, the user is prompted to choose an
entry from the list, thus only one map is required to choose from a huge
number of options. When the template is accessed via the menu, two
possibilities exists. Without further changes, the same prompt opens as when
the template is used via a map. But whenever the template includes the
"expandmenu" option, a submenu is created which lists all the entries, which
allows the user to choose in the menu, rather than on the command line: >
== Preprocessor.c libs == below, expandmenu, map:pcl ==
<
------------------------------------------------------------------------------
5.1 FORMATS *template-support-lists-format*
------------------------------------------------------------------------------
Lists also support options. The standard format for lists is named "list":
>
== LIST: C_StandardLibs == list ==
'math', 'stdlib',
'stdio', 'string',
== ENDLIST ==
<
The text contained between "== LIST: name ==" and "== ENDLIST ==" is a
comma-separated list of strings, which come as |expr-string| in double quotes
or |literal-string| in single quotes.
An easier way of writing lists are bare lists, defined with the option "bare":
>
== LIST: C_StandardLibs == list, bare ==
math
stdlib
stdio
string
== ENDLIST ==
<
They contain each entry on a new line, leading and trailing whitespaces are
ignored.
------------------------------------------------------------------------------
5.2 HASHES *template-support-lists-hash*
------------------------------------------------------------------------------
Hashes, or dictionaries, are another type of lists. They associate a key with
a value:
>
== LIST: String_Functions == hash ==
"strcpy" : "{+DEST+}, {+SRC+}",
"strncpy" : "{+DEST+}, {+SRC+}, {+N+}",
"strcmp" : "{+STR1+}, {+STR2+}",
"strncmp" : "{+STR1+}, {+STR2+}, {+N+}",
"strlen" : "{+STR+}",
== ENDLIST ==
<
A hash is a comma-separated list of entries. Each entry contains a key and a
value, separated by a colon.
During template insertion, the user has to choose one of the keys. Then two
macros *|KEY|* and *|VALUE|* are created, containing the chosen key and its
associated value. Both can be used in the template.
In this example, a function call is inserted, with jump tags named for the
parameters:
>
== Idioms.string function == insert, expandmenu ==
|PickList( "function: ", "String_Functions" )|
|KEY|<CURSOR> ( |VALUE| )
== ENDTEMPLATE ==
<
These templates also support the option "expandmenu". The menu will list all
the keys.
==============================================================================
6. ADVANCED FEATURES *template-support-advanced*
==============================================================================
Editing source code comes with challenges common to many different languages
and systems.
Different projects may require different coding styles. Template libraries can
be written to support multiple styles (|template-support-adv-styles|).
Many languages deal with files placed in one or more significant directory,
such as C's include directories or modules in other languages. File pickers
assist in working with these directories (|template-support-adv-files|).
------------------------------------------------------------------------------
6.1 CODING STYLES *template-support-adv-styles*
------------------------------------------------------------------------------
Different software projects may require different styles for comments and
code. In the case of C/C++, different kinds of comments can be chosen, with
Doxygen introducing even more possibilities. The template engine assists with
these problems by offering so called styles. Styles are named using the same
rules as macros (see |template-support-templ-macro|).
Every template is assigned to one or more styles. By default, all templates are
assigned to the style "default". Templates can be associated with different
styles by placing them inside a "USE STYLES" statement:
>
== USE STYLES : CPP ==
== Comments.function description == ==
# ==================================================
# Function: |?FUNCTION_NAME|
# Purpose: <CURSOR>
# Description: TODO
# ==================================================
== ENDTEMPLATE ==
== ENDSTYLES ==
== USE STYLES : Doxygen ==
== Comments.function description == ==
/*!
* \brief <CURSOR>
*
* TODO
*/
== ENDTEMPLATE ==
== ENDSTYLES ==
<
Now the "function description" template inserts different code, depending on
whether the style "CPP" or "Doxygen" is chosen (see the documentation of your
plug-in for how to change the style).
The "USE STYLES" statement can contain the names of several styles. Templates
inside are associated with all the styles appearing in the list. This makes
reuse of templates for different styles possible.
>
== USE STYLES : CPP, Doxygen ==
== Comments.end-of-line command == ==
// <CURSOR>
== ENDTEMPLATE ==
== USE STYLES : CPP ==
== Comments.function description == ==
...
== ENDTEMPLATE ==
== ENDSTYLES ==
== USE STYLES : Doxygen ==
== Comments.function description == ==
...
== ENDTEMPLATE ==
== ENDSTYLES ==
== ENDSTYLES ==
<
The template "end-of-line comment" inserts the same text for both styles,
while "function description" is different. If a template is not associated
with a given style it can be inserted anyway, using the version of the
template associated with the "default" style as a fallback. Only if a template
does not exist for the current style or the default style, an error message is
displayed and nothing inserted.
Using nested "USE STYLES" statement is also possible. The styles listed in a
nested statement have to be a subset of the styles listed in the one
surrounding it.
Templates inside nested statements are only associated with the styles
listed in the innermost "USE STYLES" statement.
When files are included inside a "USE STYLES" statement (see
|template-support-IncludeFile|), the templates inside the file are associated
with the style, as they would if they appeared in the including file itself.
The rules for nested "USE STYLES" statements also hold across included files.
------------------------------------------------------------------------------
6.2 FILE PICKERS *template-support-adv-files*
------------------------------------------------------------------------------
In many languages files are addressed in relation to some significant
directory, such the include mechanism of the C preprocessor or LaTeX's
\graphicspath{} command. To assist in dealing with those files, the template
support offers so-called file pickers.
File pickers are templates which use the command PickFile( <prompt>, <path> )
(|template-support-PickFile|), which asks the user to interactively select a
file:
>
SetPath( 'global_include', '/usr/include/' )
== Include.global include == below ==
|PickFile( 'global include directory', 'global_include' )|
#include "|PICK|"<CURSOR>
== Include.global, filename only == below ==
|PickFile( 'global include directory', 'global_include' )|
#include <|FILENAME|><CURSOR>
== ENDTEMPLATE ==
<
The first argument to the function is a prompt which is being displayed while
the user selects the file. The second argument is the name of a path set
beforehand, such as "global_include". After the user selects a file, several
macros are created which can be used in the template. *|PICK|* is the path and
name of the file, relative to the path given as the second argument.
*|FILENAME|* is only the name of the file. For a list of all macros, see
|template-support-PickFile|.
Names for paths are created using the function SetPath( <name>, <path> )
(see |template-support-SetPath|), which is a lot like SetMacro.
For example, if the user picks "/usr/include/GL/gl.h", the first template
would result in the line >
#include "GL/gl.h"
being inserted, while the second template would insert >
#include <gl.h>
The paths "/usr/include" or "/usr/include/GL" would have to be in the include
path, of course.
The second argument can also be a path. In fact, if it does not match an
identifier, it is always assumed to be a path:
>
== Include.local include == below ==
|PickFile( 'local include directory', './' )|
#include "|PICK|"<CURSOR>
== ENDTEMPLATE ==
<
This template lets the user pick a file relative to the current working
directory.
==============================================================================
7. MENUS *template-support-menus*
==============================================================================
The template support automatically creates menus for every template. The user
has a measure of influence on the result. Some of these options where already
explained in |templates-support-templ-maps|, this chapter will introduce further
capabilities.
The menu entries appear in the order the templates have been read. Including a
file via >
IncludeFile ( "<path>/<file>" )
will cause this file to be processed first, then the rest of the including
file is read.
The menu structure is defined by the names of the menus. Dots appearing in the
names place the templates into submenus:
>
== Comments.file description == start, sc:f ==
...
== Statements.if == below, sc:i ==
...
== ENDTEMPLATE ==
<
The shortcut for the menu entry is defined in the header. The automatic
creation of a menu entry for a template can be suppressed using the option
"nomenu".
The maps of submenus are set via the command 'MenuShortcut'
(see |template-support-MenuShortcut()|):
>
MenuShortcut ( "Comments.Special", "p" )
MenuShortcut ( "Comments", "c" )
MenuShortcut ( "Statements", "s" )
<
Each call sets the shortcut for the last submenu mentioned. So the above
example sets the shortcut "c" for the menu "Comments", "s" for "Statements"
and "p" for the submenu "Special" within "Comments". The placement of these
calls has no influence on the order of menu creation, only the appearance of
their names in template headers.
The template library can also contain menu separators, a solid line appearing
between two menu entries. They can help to provide a better overview in a menu
with lots of entries. Menu separators are defined outside of templates using
the syntax: >
== SEP: Statements.sep1 ==
The header start with "SEP:" and then contains the name of the separator. The
dots in the name again define which submenu the separator will appear in,
while the relative position in relation to the other templates defines the
placement. The last part of the name following the last dot has no influence,
but must be unique.
Unlike templates and lists, separators do not have to be ended with a line
like "== ENDTEMPLATE ==". Separators only span one line. Separators could
utilize the syntax of function calls, such as "SetMacro()". However, they have
been designed in this way to visually be on the same level as templates.
------------------------------------------------------------------------------
Note: A short remark for plug-in developers.
Each menu entry also displays the map of the template, if it has one. By
default, it is prefixes with the standard mapleader, a backslash. Using the
API, this can be changed to the mapleader the user has set: >
call mmtemplates#core#Resource (
\ <template-library>, "set", "Templates::Mapleader", "<mapleader>" )
(see |mmtemplates#core#Resource()|). This mapleader may also appear in menu
entries the plug-in itself creates. As a convenience, the mapleader is
provided by the API, already correctly escaped for menu creation: >
let [ esc_mapleader, msg ] = mmtemplates#core#Resource (
\ g:My_C_Templates, "escaped_mapleader" )
<
==============================================================================
8. HELP TEMPLATES *template-support-help-templ*
==============================================================================
A quick access to the documentation is important for every language. Help
templates offer a mechanism to pick up a word under the cursor and make a
system call using this text. For example, a browser could be opened with help
for a certain command.
Help templates look a lot like templates in the library, but do not insert
text. They share a lot of other features with regular templates though, they
will create a menu entry and can have shortcuts and maps.
The syntax of help templates is very close to that of regular templates,
except that their name is prefixed by "HELP:"
>
SetMacro( 'HELP_BROWSER', 'firefox' )
SetMacro( 'HelpPathEnglish', 'http://en.wiktionary.org/wiki/' )
== HELP: Help.english == map:he, sc:e ==
|Word( '' )|
|Substitute( '\W', '', 'g' )|
|System( '|HELP_BROWSER| |HelpPathEnglish||PICK:l|' )|
== ENDTEMPLATE ==
<
The help template "Help.english" picks up the word under the cursor, removes
every non-word character from that string and then calls >
firefox http://en.wiktionary.org/wiki/...
This will open a new tab containing the article about the word under the
cursor, which is very helpful while writing documentation.
A help template always performs three steps:
1. Pick up text under the cursor.
2. Change the text (optional).
3. Make a system call or a call on the Vim command line.
1. Picking Text
To pick up text under the cursor, the function Word(<flag>) is used. If the
flag is 'W', the |WORD| under the cursor is picked up: >
|Word('W')|
Otherwise the |word| under the cursor is picked: >
|Word('')|
Lastly, the word can be picked using a regular expression (see |regex|): >
|Pattern( '[\\@]\w\+' )|
This call picks a word prefix by "\" or "@", which in a C comment could be a
Doxygen command.
The text which has just been picked up is then stored in a sort of register,
which for the purpose of the further explanation shall be called "acc".
2. Editing the Text
After picking up text, the register "acc" can be changed by one or more calls
to the function Substitute( <pattern>, <sub>, <flag> ). For example, to remove
every non-word character: >
|Substitute( '\W', '', 'g' )|
Substitute replaces the contents of "acc" using Vim's |substitute()| function:
acc = substitute( acc, <pattern>, <sub>, <flag> )
If the flag is an empty string, the first occurrence of <pattern> is replaced
with <sub>. If flag equals "g", all occurrences are replaced. The function
LiteralSub(<string>,<sub>,<flag>) works similarly, except that the first
argument is not interpreted as a regular expression.
3. Calling Help
After picking up and changing the text, a call is made using System(<call>) or
Vim(<call>). The argument is a string and it can contain macros which are
replaced before the call. The macro *|PICK|* is replaced with "acc", the
picked and changed text. The call is however only made if "acc" is not the
empty string.
If either an empty string has been picked up in step 1, or the string is empty
after step 2, the call is made using the command given in Default(<call>). If
no default call is given, no action is performed for an empty string.
The following help template shows help for Doxygen commands:
>
SetMacro( 'HelpPathDoxygen', 'http://www.stack.nl/~dimitri/doxygen/commands.html' )
== HELP: Help.doxygen cmd == map:hd, sc:d ==
|Pattern( '[\\@]\w\+' )|
|Substitute( '[\\@]', '', '' )|
|System( '|HELP_BROWSER| |HelpPathDoxygen|#cmd|PICK|' )|
|Default( '|HELP_BROWSER| |HelpPathDoxygen|' )|
== ENDTEMPLATE ==
<
First, a Doxygen command is picked up under the cursor, then the leading "\"
or "@" is removed. Then a system call such as: >
firefox http://www.stack.nl/~dimitri/doxygen/commands.html#cmdparam
is made. If there was no Doxygen command under the cursor, the following call
is made instead, which will show a table of all Doxygen commands: >
firefox http://www.stack.nl/~dimitri/doxygen/commands.html
<
Note: The examples still worked in November, 2013.
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
==============================================================================
9. API *template-support-api*
==============================================================================
This chapter is only relevant if you want to use the template system with your
own plug-in!
The API enables other plug-ins to use the template system.
Each template library is stored in a dictionary (|Dictionary|).
- This dictionary must be a global variable, because it it used for purposes
such as callback functions for menu entries and maps.
- Do not change the entries of the dictionary directly, since the internal
structure may change. The API provides access to the stored information.
------------------------------------------------------------------------------
9.1 BASIC USAGE *template-support-api-basic*
------------------------------------------------------------------------------
These functions provide the basic functionality to load template libraries and
insert templates into a buffer. A further function expands macros in a text.
------------------------------------------------------------------------------
*mmtemplates#core#NewLibrary()*
To create a new template library call:
library = mmtemplates#core#NewLibrary ( ... ) ~
Optional parameters:
"debug", level - View debug information with the given level of detail.
(integer, default: show no debug information)
Returns:
library - The template library. (dict)
Example:
Create a new library and store it in the variable 'g:My_C_Templates': >
let g:My_C_Templates = mmtemplates#core#NewLibrary ()
<
------------------------------------------------------------------------------
*mmtemplates#core#ReadTemplates()*
Templates are loaded using the function:
mmtemplates#core#ReadTemplates ( library, ... ) ~
Parameters:
library - The template library. (string or dict)
Optional parameters:
"load", file - Load templates from 'file'. (string)
"reload", what - Reload templates according to 'what', see below.
(string or integer)
"overwrite_warning" - Print a warning each time a template is overwritten.
"debug", level - View debug information with the given level of detail.
(integer, default: show no debug information)
No returns.
The library can either be given directly, or as the name of the global
variable containing the library.
When loading a new file, it must be given with a path and filename. >
mmtemplates#core#ReadTemplates ( library, "load", "path/file.templates" )
<
The entire library can be reloaded by calling: >
mmtemplates#core#ReadTemplates ( library, "reload", "all" )
A file can be reloaded, but only if it has been loaded before: >
mmtemplates#core#ReadTemplates ( library, "reload", "path/file.templates" )
The i'th file which has been loaded can be reloaded via: >
mmtemplates#core#ReadTemplates ( library, "reload", i )
<
With the switch "overwrite_warning", a warning is displayed whenever a
template is encountered which already has been set for the current style.
Example 1:
Load a file: >
call mmtemplates#core#ReadTemplates ( g:My_C_Templates,
\ "load", "$HOME/.vim/c-support/templates/lib.templates",
\ "debug", 1, "overwrite_warning" )
Load the templates in the given file and print very little debug information.
Print a warning whenever a template is overwritten.
Example 2.1:
Load several files: >
call mmtemplates#core#ReadTemplates ( g:My_C_Templates,
\ "load", "/usr/share/vim/.../global.templates" )
call mmtemplates#core#ReadTemplates ( g:My_C_Templates,
\ "load", "$HOME/.vim/.../local.templates" )
Loads the templates in the two files.
Example 2.2:
Reload specific templates: >
call mmtemplates#core#ReadTemplates ( g:My_C_Templates, "reload", -1 )
Reload the last template which has been loaded.
(".../local.templates" from above)
Example 2.3:
Reload templates by name: >
call mmtemplates#core#ReadTemplates ( g:My_C_Templates,
\ "reload", "$HOME/.vim/.../local.templates" )
<
------------------------------------------------------------------------------
*mmtemplates#core#InsertTemplate()*
To insert templates into the current buffer use:
mmtemplates#core#InsertTemplate ( library, name, ... ) ~
Parameters:
library - The template library. (string or dict)
name - The name of the template. (string)
Optional parameters:
"i" - > "insert"
"insert" - Insert mode, special treatment of placement 'insert'.
"v" - > "visual"
"visual" - Visual mode, use the <SPLIT> tag.
"placement", place - Overwrite the template's placement. (string)
"range", a, b - Use the range from lines 'a' to 'b'. (integers)
"<macro>", replace - Set the replacement for the given macro. The string
<macro> must match a macro, e.g. *|FUNCTION_NAME|* .
(string)
"pick", choice - When inserting a list use 'choice', do not ask the user
to pick an entry. (string)
"debug", level - View debug information with the given level of detail.
(integer, default: show no debug information)
No returns.
The library can either be given directly, or as the name of the global
variable containing the library.
It the template 'name' does not exist, an error message is displayed.
Examples:
Include "Statement.If", surround the selected lines: >
call mmtemplates#core#InsertTemplate ( g:My_C_Templates,
\ "Statement.If", "v" )
------------------------------------------------------------------------------
*mmtemplates#core#ExpandText()*
To perform macro expansion in a text use:
rtext = mmtemplates#core#ExpandText ( library, text ) ~
Parameters:
library - The template library. (string or dict)
text - A text. (string)
Returns:
rtext - The text after the macro expansion (string).
The library can either be given directly, or as the name of the global
variable containing the library.
The expansion is done using all the settings in the library, as well as the
global macro replacements such as *|AUTHOR|* .
Examples:
Calling the function: >
let text = mmtemplates#core#ExpandText ( g:My_C_Templates, "|DATE| |TIME|" )
returns "29.2.2000 12:00", depending on the format set in the library.
This can be used for special menu entries such as: >
exe 'amenu Comments.Special.Date\ Time '
\ .':exe "normal! a".mmtemplates#core#ExpandText ( '
\ .'g:My_C_Templates, "\|DATE\| \|TIME\|" )<CR>'
<
------------------------------------------------------------------------------
*mmtemplates#core#EditTemplateFiles()*
Open the library for editing:
mmtemplates#core#EditTemplateFiles ( library, file ) ~
Parameters:
library - The template library. (string or dict)
file - A file. (string or integer)
No returns.
The library can either be given directly, or as the name of the global
variable containing the library.
The argument 'file' can be given as a filename, in which case it must have
been loaded before via |mmtemplates#core#ReadTemplates()|.
'file' can also be an integer i, which refers to the i'th file that has been
loaded.
A file browser is then opened for the directory containing the file.
Example:
Open a file browser in the directory "$HOME/.vim/.../templates/":
>
" load the last template file:
call mmtemplates#core#ReadTemplates ( g:My_C_Templates,
\ "load", "$HOME/.vim/.../templates/local.templates" )
" ...
" edit the library
call mmtemplates#core#EditTemplateFiles ( g:My_C_Templates, -1 )
<
------------------------------------------------------------------------------
*mmtemplates#core#JumpToTag()*
The jump to the next tag is performed by:
e = mmtemplates#core#JumpToTag ( regex ) ~
Parameters:
regex - The regex to jump to. (string)
Returns:
e - An empty string.
Jumps to the next occurrence of 'regex' and removes it from the buffer. Then
the function returns an empty string.
The regular expression can be obtained from the template library via the
function |mmtemplates#core#Resource()|.
Example:
This function is best used in maps such as this:
>
let regex = mmtemplates#core#Resource ( g:My_C_Templates, "jumptag" )[0]
" ...
nnoremap <buffer> <C-j> i<C-R>=mmtemplates#core#JumpToTag ( regex )<CR>
inoremap <buffer> <C-j> <C-R>=mmtemplates#core#JumpToTag ( regex )<CR>
<
This maps can be created automatically using |mmtemplates#core#CreateMaps()|.
------------------------------------------------------------------------------
9.2 CREATING MENUS AND MAPS *template-support-api-maps*
------------------------------------------------------------------------------
The automated generation of maps and menus is carried out by these functions.
------------------------------------------------------------------------------
*mmtemplates#core#CreateMaps()*
The automatic creation of maps is carried out by the function:
mmtemplates#core#CreateMaps ( library, localleader, ... ) ~
Parameters:
library - The name of the variable containing the library. (string)
localleader - The local mapleader. (string)
Optional parameters:
"do_jump_map" - Create a map for |mmtemplates#core#JumpToTag()|.
"do_special_maps" - Create maps for the special operations.
No returns.
If 'localleader' is an empty string, the standard mapleader is used.
Otherwise >
let maplocalleader = localleader
is executed before the maps are created. (see |mapleader|)
The maps for the jump and the special operations (choose a template/style,
reread/edit the library) are not created unless the corresponding options are
given.
This function creates maps which are local to the buffer, so it must be called
in the appropriate filetype-plugin, or by an autocommand.
An error message is displayed whenever a mapping already exists. The existing
mapping will not be overwritten.
Example:
Create maps using the standard mapleader: >
call mmtemplates#core#CreateMaps ( "g:My_C_Templates", "", "do_jump_map" )
A map to jump to the next tag is also created.
Technical Details:
- The library must be given as the name of the global variable, since this
name is required to create the maps.
- The function creates maps of the following types:
noremap, inoremap, vnoremap
------------------------------------------------------------------------------
*mmtemplates#core#CreateMenus()*
The automatic creation of menus is carried out by the function:
mmtemplates#core#CreateMenus ( library, rootmenu, ... ) ~
Parameters:
library - The name of the variable containing the library. (string)
rootmenu - The name of the root menu. (string)
Optional parameters:
"global_name", name - The name used in the menu headers.
(string, default: the value of 'rootmenu')
"existing_menu", names - The menus which already exist.
(string or list of strings)
"sub_menu", names - Additional sub-menus which should be created.
(string or list of strings)
"specials_menu", name - The name of the menu containing the special
operations. (string, default: "Run")
"priority", p - Create the sub-menu with priority p.
(integer, default: 500)
"do_all" - Action: Reset and create all menus.
"do_reset" - Action: Reset.
"do_templates" - Action: Create menus for all the templates.
"do_specials" - Action: Create a menu with the special entries.
"do_styles" - Action: Create a menu for selecting the style.
No returns.
"do_all", "do_templates", "do_specials" and "do_styles" starts the automatic
creation of menu entries. Sub-menus are created automatically as needed.
The special operations are: choose a template/style, reread/edit the library.
The corresponding menu entries are put in the sub-menus given by the option
"specials_menu".
Each sub-menu looks like this, starting with a header:
>
<menu name> <global name>
--- <separator> -------------
<entry1> <map>
<entry2>
... ...
<
The global name (option "global_name") helps to keep track of tear-off menus.
"sub_menu" can be used to create additional menus, which have the same header.
When a sub-menu is created through use of the API like this, an optional
priority can be specified.
The library keeps track of all created sub-menus, to be able to add the
headers correctly. "existing_menu" adds menus to this list.
"do_reset" resets this list and allows for the menus to be created once more.
"do_all" also reset the list before it carries out further operations.
The "&" and the trailing points in 'rootmenu' and "existing_menus" are
ignored. "sub_menus" and "specials_menu" also ignore trailing points, but use
the "&" to create shortcuts. However, if a shortcut for the menu has been set
in the library, that one is preferred.
Example 1: Basic usage.
Suppose a plug-in creates the following menus:
>
C-Support
>-+ Comments
| >-- code->comment
| >-- comment->code
| >-+ Special
| | >--- ...
>-+ Run
| >-- run
| >-- ...
<
Then the call has to look like this: >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "&C-Support",
\ "do_all", "existing_menu", [ "&Comments","Comments.&Special.","&Run." ] )
<
To create headers for each sub-menu, similar to those the template support
creates, use code like this:
>
let root_menu = "&C-Support"
let global_name = "C/C++"
exe 'amenu '.root_menu.'.'.root_menu.' <Nop>'
exe 'amenu '.root_menu.'.-Sep0- <Nop>'
exe 'amenu '.root_menu.'.&Run.Run<TAB>'.global_name.' <Nop>'
exe 'amenu '.root_menu.'.Run.-Sep00- <Nop>'
<
Example 2: Advanced usage.
This facility can be used to create all the menu headers.
It also gives more control over the order of the menu entries.
First, reset the list of created menus: >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support",
\ "do_reset" )
Then create a sub-menu (shortcut "c"): >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support",
\ "sub_menu", "&Comments" )
" entries: comment/uncomment/... :
...
Create entries for the templates: >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support",
\ "do_templates" )
Create a run menu (shortcut "r"): >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support",
\ "sub_menu", "&Run" )
" entries: compile/run/test/... :
...
Create the special entries at the end of the run menu: >
call mmtemplates#core#CreateMenus ( "g:My_C_Templates", "C-Support",
\ "do_specials", "specials_menu", "Run." )
>
Technical Details:
- The library must be given as the name of the global variable, since this
name is required to create the menus.
- The function creates menus of the following types:
amenu, imenu and vmenu (where appropriate)
------------------------------------------------------------------------------
9.3 ACCESS *template-support-api-access*
------------------------------------------------------------------------------
The following functions are used to query and change the resources of a
template library. For example, they are used to change the style or to change
the format of the date and time.
------------------------------------------------------------------------------
*mmtemplates#core#ChooseStyle()*
The style is changed using the function:
mmtemplates#core#ChooseStyle ( library, style ) ~
Parameters:
library - The template library. (string or dict)
style - The name of the style or "!pick". (string)
No returns.
The library can either be given directly, or as the name of the global
variable containing the library.
If 'style' is "!pick", the user is presented with a list of all styles, and
can choose one.
It the style 'style' does not exist, an error message is displayed and the
style remains unchanged.
Example:
Prompt the user for a new style: >
call mmtemplates#core#ChooseStyle ( g:My_C_Templates, "!pick" )
------------------------------------------------------------------------------
*mmtemplates#core#Resource()*
Access to a number of resources is provided by:
[ rval, msg ] = mmtemplates#core#Resource ( library, mode, ... ) ~
[ rval, msg ] ~
= mmtemplates#core#Resource ( library, "get", resource, key ) ~
[ rval, msg ] ~
= mmtemplates#core#Resource ( library, "set", resource, key, val ) ~
Parameters:
library - The template library. (string or dict)
mode - The operation which should be executed. (string)
Optional parameters:
... - Depending on 'mode'.
Returns:
rval - Content and type depending on 'mode'.
msg - In case of success: An empty string. (string)
In case of failure: An error message. (string)
The library can either be given directly, or as the name of the global
variable containing the library.
Special resources:
- "escaped_mapleader" : Return the mapleader, escaped for use in a menu.
- "jumptag" : Return the regex used to find jump tags.
- "style" : Return the name of the current style.
Regular resources:
- "add" : Add the property with the given key and set it to 'val'.
- "get" : Return the resource with the given key or 0.
- "set" : Change the resource with the given key to 'val'.
The mode "get" supports the following resources:
- "list", "l": The list as generated by: == List: l == ... ==
- "macro", "m": A macro as set by: SetMacro( "m", ... )
- "path", "p": A path as set by: SetPath( "p", ... )
- "property", "p": An existing resource named "p".
It returns the integer 0, if the resource 'key' does not exist.
The mode "set" can be used to overwrite these resources.
The resource "list" is returned as a reference, use it responsibly.
For "add" and "set" 'rval' is undefined.
Macros:
Setting the special macros "DATE", "TIME", and "YEAR" changes the format of
the date and time. they use the same format as the function |strftime()|.
Setting "BASENAME", "FILENAME", "PATH" and "SUFFIX" has no effect.
Properties:
The mode "get" returns the property named 'key', but only if it already
exists. Only an existing property can be set in the mode "set". To create and
set a new property, the mode "add" must be used.
Example 1:
The format of the macro *|TIME|* can be changed by calling: >
call mmtemplates#core#Resource (
\ g:My_C_Templates, "set", "macro", "TIME", "%H:%M" )
<
Example 2:
Suppose there is a template like this:
>
== Include.project include == insert, pick-file ==
|Prompt( "project include directory" )|
|GetPath( "project_include" )|
#include "|PICK|"
== ENDTEMPLATE ==
<
When switching to a new project, execute: >
call mmtemplates#core#Resource (
\ g:My_C_Templates, "set", "path", "project_include", project_incl_dir )
<
The next time the template "Include.project include" is inserted, the file
browser will already be set to the project include directory.
Example 3:
Set the property "Templates::Mapleader": >
call mmtemplates#core#Resource (
\ g:My_C_Templates, "set", "Templates::Mapleader", "." )
<
Create a new property "C::RunCompiler::Map": >
call mmtemplates#core#Resource (
\ g:My_C_Templates, "add","C::RunCompiler::Map", "rc" )
<
Get the mapleader (already escaped): >
let [ esc_mapleader, msg ] = mmtemplates#core#Resource (
\ g:My_C_Templates, "escaped_mapleader" )
<
Get the map (not escaped!): >
let [ map_run, msg ] = mmtemplates#core#Resource (
\ g:My_C_Templates, "get", "C::RunCompiler::Map" )
Create the menu entry: >
if empty ( msg )
exe 'amenu '.root_menu
\ .'.Run.run\ &compiler<TAB>'.esc_mapleader.map_run.' :call Run()<CR>'
else
" handle error ...
endif
<
Example 4:
Get the current style: >
let [ current_style, msg ] = mmtemplates#core#Resource (
\ g:My_C_Templates, "style" )
<
------------------------------------------------------------------------------
9.4 MISCELLANY *template-support-api-misc*
------------------------------------------------------------------------------
This section describes various functions, provided for convenience.
------------------------------------------------------------------------------
*mmtemplates#core#SetMapleader()*
*mmtemplates#core#ResetMapleader()*
Set and reset |maplocalleader|:
mmtemplates#core#SetMapleader ( localleader ) ~
mmtemplates#core#ResetMapleader () ~
Parameters:
localleader - The new value for |maplocalleader|. (string)
No returns.
A call to mmtemplates#core#SetMapleader sets maplocalleader to the given
value. A subsequent call to mmtemplates#core#ResetMapleader restores the
previous setting, which can also mean that maplocalleader is undefined again.
Calls to SetMapleader and ResetMapleader can be nested.
If the argument 'localleader' is an empty string, maplocalleader remains
unchanged.
------------------------------------------------------------------------------
*mmtemplates#core#EscapeMenu()*
Escape a string to be used as a menu entry:
str = mmtemplates#core#EscapeMenu ( str ) ~
Parameters:
str - The menu item. (string)
Optional parameters:
mode - How to escape the string. (string, default "entry")
Returns:
str - The same string with appropriately escaped characters. (string)
The following modes are supported:
- "menu" : A menu name with possible submenus, escapes <space> \ | &
- "entry" : A menu entry, dots are escaped as well, escapes <space> . \ | &
- "right" : The right-aligned side of a menu entry, escapes <space> . \ |
In mode "entry" the function even escapes '.', so the menu and the entry must
be escaped separately, otherwise the entry 'frame comment' in the menu
'Comments': >
"Comments.frame comment"
would turn into the entry: >
"Comments\.frame\ comment"
==============================================================================
10. BACKWARDS COMPATIBILITY *template-support-backwards*
==============================================================================
The following behavior is not compatible with the old template systems of
various plug-ins. This list does not include new features which are now
supported.
c-support:
doxygen-support:
perl-support:
- No automatic uppercase for *|BASENAME|* .
- The format for *|DATE|* , *|TIME|* and *|YEAR|* is now configured via the
template library. Plug-ins may provide other ways to do the configuration.
perl-support:
- The template header can not have the format >
== templatename == [ position == ] [ indentation == ]
< anymore, since the last part would be ignored. Use the list of template
options instead: >
== templatename == [ position, indentation == ]
< Both 'position' and 'indentation' are optional, of course.
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
==============================================================================
A. SYNTAX *template-support-syntax*
==============================================================================
The standards for the idioms are as follows, but may be changed via the API:
Idiom Changeable? Standard
CommentStart yes $
BlockDelimiter no ==
CommandName no same as MacroName
MacroName no a-z, A-Z, 0-9 and _
starting with a letter or underscore
OptionName no same as MacroName
ResourceName no same as MacroName
SeparatorName no same as MacroName
StyleName no same as MacroName
TemplateName no a-z, A-Z, 0-9 and _ + - . , <Space>
starting with a letter or underscore,
not ending with a whitespace
Mapping no a-z, A-Z, 0-9 and _ + -
The rules in the next sections use the following notation:
- Syntax category: StartsWithCapitalLetters
- Keyword: ALLCAPS
- Various items: -something-
- Square brackets [ ] mark an optional part of the rule.
- All other characters are as printed.
- Whitespaces are ignored, except where <start> marks the start of the line.
Whitespaces can not appear there.
------------------------------------------------------------------------------
A.1 COMMAND SECTION *template-support-syntax-cmd*
------------------------------------------------------------------------------
MacroAssignment (one of):
-text-
' -text- '
" -text- "
Note: Trailing whitespaces are ignored, even with the first rule.
Statement (one of):
-empty line-
<start> CommentStart -anything-
<start> CommandName ( ParameterList )
<start> *|MacroName|* = MacroAssignment
StyleBlock1
StyleBlock2
Template
HelpTemplate
MenuSeparator
List
StyleBlock1 (sequence):
<start> == IF *|STYLE|* IS MacroName ==
StatementList
<start> == ENDIF ==
StyleBlock2 (sequence):
<start> == USE STYLES : MacroNameList ==
StatementList
<start> == ENDSTYLES ==
Template (sequence):
<start> == [ TEMPLATE : ] TemplateName == [ OptionList == ]
-several lines-
<start> == ENDTEMPLATE ==
Note: The " TEMPLATE : " in the first line is optional, as opposed to the
structure of the next three rules.
HelpTemplate (sequence):
<start> == HELP : TemplateName == [ OptionList == ]
-several lines-
<start> == ENDTEMPLATE ==
MenuSeparator (one line):
<start> == SEP : SeparatorName ==
List (sequence):
<start> == LIST : MacroName == [ OptionList == ]
-several lines-
<start> == ENDLIST ==
MacroNameList (one of):
MacroName
MacroName , MacroNameList
OptionList (one of):
-empty-
Option
Option , OptionList
Option (one of):
OptionName
OptionName : MacroName
OptionName : Mapping
------------------------------------------------------------------------------
A.2 TEMPLATES *template-support-syntax-templ*
------------------------------------------------------------------------------
*Todo syntax templates
------------------------------------------------------------------------------
A.3 LISTS *template-support-syntax-list*
------------------------------------------------------------------------------
Lists can either be lists or dictionaries. (Corresponding to the types Vim
uses: |List| and |Dictionary|.)
Lists are a comma separated list of strings:
>
== LIST: Options == list ==
"tabstop", "shiftwidth",
"wrap", "nowrap",
"filetype"
== ENDLIST ==
<
Bare lists do not require quotes, each line is interpreted as an entry.
Leading and trailing whitespaces are ignored:
>
== LIST: Options == list, bare ==
tabstop
shiftwidth
wrap
nowrap
filetype
== ENDLIST ==
<
Dictionaries associate a key with a value. Key and value are separated by a
colon, different entries by a comma.
>
== LIST: FileEndings == dict ==
"C" : ".c" ,
"C++" : ".cc" ,
"Perl" : ".pl" ,
"Shell" : ".sh" ,
"Vimscript" : ".vim" ,
== ENDLIST ==
<
==============================================================================
B. COMMANDS *template-support-commands*
==============================================================================
This sections list the commands supported by the template system.
------------------------------------------------------------------------------
B.1 COMMAND SECTION *template-support-cmd-cmd-sct*
------------------------------------------------------------------------------
The following commands can be used outside of templates, in the so-called
command section.
------------------------------------------------------------------------------
*template-support-IncludeFile()*
Include the file 'filename':
IncludeFile ( filename [, "abs"] ) ~
'filename' can contain a path which can be absolute or relative. Relative
paths are interpreted in relation to the directory of the file containing the
command. The path is always understood to be relative, except when the
optional second argument "abs" is given.
------------------------------------------------------------------------------
*template-support-SetFormat()*
Set the format of 'item' to 'format':
SetFormat ( item, format ) ~
This changes the way the macros "TIME", "DATE" and "YEAR" are replaced. It
sets the format of the date and time. They use the same format as the function
|strftime()|.
Example: >
SetFormat ( "TIME", "%H:%M" )
The macro *|TIME|* will now be replaced by something like 10:24.
------------------------------------------------------------------------------
*template-support-SetMacro()*
Set the macro 'name' to 'text':
SetMacro ( name, text ) ~
This is used to set replacements for macros.
Setting the macros "TIME", "DATE", "YEAR", "BASENAME", "FILENAME" , "PATH" and
"SUFFIX" is not allowed. They are set to the appropriate values before
insertion of a template.
Example: >
SetMacro ( "AUTHOR", "My cat." )
------------------------------------------------------------------------------
*template-support-SetPath()*
Set the resource 'name' to the given path.
SetPath ( name, path ) ~
Subsequently the path can be used in templates.
------------------------------------------------------------------------------
*template-support-SetProperty()*
Set the property 'name' to the given value.
SetProperty ( name, value ) ~
Only existing properties can be set. If 'name' does not refer to an existing
property, an error will be printed.
------------------------------------------------------------------------------
*template-support-SetStyle()*
Set the active style to 'name':
SetStyle ( name ) ~
This style will be used after the library has been loaded.
------------------------------------------------------------------------------
*template-support-MenuShortcut()*
Set the shortcut for the submenu 'menu' to 'shortcut':
MenuShortcut ( menu, shortcut ) ~
The shortcut is set for the menu named by the last component of 'menu', which
can consist of several parts, separated by points. Trailing points are
ignored.
Example: >
MenuShortcut ( "Comments.Frames.", "r" )
Sets the shortcut for the submenu "Frames", not "Comments".
------------------------------------------------------------------------------
B.2 TEMPLATES *template-support-cmd-templates*
------------------------------------------------------------------------------
Templates themselves support various commands, either in the command block at
the beginning of the template, or in the text itself.
------------------------------------------------------------------------------
*template-support-PickFile()*
Open a prompt and let the user select a file:
|PickFile ( prompt, path )| ~
Displays 'prompt' and lets the user select a file. The file browser starts out
in the directory named by 'path'. If 'path' matches an identifier, the path
resource by this name serves as the path. Otherwise the string path is used as
the path directly.
After the user selected a file, several replacements for macros are created,
which can be inserted into the template:
- *|PICK_COMPL|* : the complete path and name of the selected file
- *|PATH_COMPL|* : the complete path of the selected file
- *|PICK|* : the selected path and file relative to the directory given
in 'path'
- *|PATH|* : the path in *|PICK|*
- *|FILENAME|* : the name of the file
- *|BASENAME|* : the name of the file without the suffix
- *|SUFFIX|* : the suffix of the file
Example: >
SetPath ( "global", "/usr/include/" )
== global include == below ==
|PickFile( "select a file: ", "global" )|
#include <|PICK|>
== local include == below ==
|PickFile( "select a file: ", "global/" )|
#include "|PICK|"
== ENDTEMPLATE ==
<
The path in the first template is the resource "global", which in turn is
"/usr/include/". The path in the second template will be "global/", since the
string does not match an identifier.
If the user inserts the template "global include", he will be asked to select
a file, starting in the directory "/usr/include/". If we selects the file: >
/usr/include/QtGui/QPushButton
the macro *|PICK|* will be set to "QtGui/QPushButton", and *|PATH|* to
"QtGui".
------------------------------------------------------------------------------
*template-support-PickList()*
Open a prompt and let the user select an entry from a list:
|PickList ( prompt, list )| ~
Displays 'prompt' and lets the user select an entry from a list. If 'list' is
a string and matches an identifier, the list resource by this name is used.
If 'list' is a list or a dictionary, it is used directly.
In case of lists, the user has to choose an entry from the list. In case of
dictionaries, the user has to choose one of the keys.
After the user selected an entry, several replacements for macros are created,
which can be inserted in the template:
- *|VALUE|* : the selected entry from the list or dictionary
- *|KEY|* : the selected key (dictionaries only)
- *|PICK|* : same as *|VALUE|*
Example:
>
== LIST: headers == list ==
"stdlib",
"stdio",
"string",
== LIST: functions == hash ==
"strcpy" : "{+DEST+}, {+SRC+}",
"strncpy" : "{+DEST+}, {+SRC+}, {+N+}",
"strcmp" : "{+STR1+}, {+STR2+}",
"strncmp" : "{+STR1+}, {+STR2+}, {+N+}",
"strlen" : "{+STR+}",
== ENDLIST ==
== header include == below ==
|PickList( "header file: ", "headers" )|
#include <|PICK|.h>
== function call == insert ==
|PickList( "function: ", "functions" )|
|KEY|<CURSOR> ( |VALUE| )
== ENDTEMPLATE ==
<
The first template is quite simple. The user selects a header from the list,
then the preprocessor directive is inserted.
The second template uses a dictionary. The user has to pick an entry from the
list of function names. The template is inserted using both the selected key
and value. Each value is a list of jump tags, named for the arguments of the
corresponding function.
Inserting the template "function call" and selecting "strcpy" will results in
the following text to be inserted: >
strcpy | ( {+DEST+}, {+SRC+} )
The position of the cursor is marked by "|". The jump key can be used to jump
ahead and replace the tags.
------------------------------------------------------------------------------
*template-support-Prompt()*
Prompt the user for a replacement of the macro:
|Prompt ( macro, flag )| ~
The user is prompted for a replacement of 'macro'. After the user has entered
a text, the flag is applied. The replacement is saved to be reused later.
Flags:
- "" : no change to the text
- "l" : change text to lowercase
- "u" : change text to uppercase
- "c" : capitalize text (change first letter to uppercase)
- "L" : legalize name (replace all non-word characters with underscores)
Example:
>
== chapter, alt1 == below ==
============================================================================
|?NUMBER| |?NAME:u|
============================================================================
<CURSOR>
== chapter, alt2 == below ==
|Prompt( 'NAME', '' )|
|Prompt( 'NUMBER', '' )|
============================================================================
|NUMBER| |NAME:u|
============================================================================
<CURSOR>
== chapter, toc == below ==
|NUMBER| |NAME:c|
== ENDTEMPLATE ==
<
This inserts captions for chapters as used in this document. With the first
alternative, the user is first prompted for a replacement of *|NUMBER|* ,
because of the order both macros appear in the text. The name is saved in
uppercase.
Using the second alternative, the user is prompted for the name first. The
name is saved as entered and only inserted in uppercase. Now it can be
inserted into the table of contents as entered by the user.
==============================================================================
C. OPTIONS *template-support-options*
==============================================================================
The following sections list the options for templates and lists.
------------------------------------------------------------------------------
C.1 TEMPLATES *template-support-opt-templ*
------------------------------------------------------------------------------
The template options appear in the header of the template:
== <name> == <options> == ~
It is not required to specify any options. The defaults are given below.
Help templates use the same options as normal templates.
------------------------------------------------------------------------------
*template-support-start* *template-support-append*
*template-support-above* *template-support-insert*
*template-support-below*
Placement:
start - The text is placed above the first line.
above - The text is placed above the current line.
below - The text is placed below the current line (default).
append - The text is appended to the current line.
insert - The text is inserted at the cursor position.
Note: "below" and "insert" support split tag in visual mode.
------------------------------------------------------------------------------
*template-support-visual* *template-support-indent*
*template-support-novisual* *template-support-noindent*
Insertion:
visual - Use the split tag in visual mode (default?).
novisual - No special behavior in visual mode (default?).
indent - The inserted text is indented (default).
noindent - No automatic indentation.
Note: "visual" is the default for templates containing the split tag,
"novisual" for templates without the split tag.
------------------------------------------------------------------------------
*template-support-sc* *template-support-nomenu*
*template-support-shortcut* *template-support-expandmenu*
*template-support-map*
Menus and Maps:
nomenu - No menu entry is created.
expandmenu - A submenu is created for this template with entries matching
those of a given list.
sc:<sc> - A shortcut is created for the menu entry of this template.
shortcut:<sc> - Long version of sc:<sc>.
map:<map> - A map is created for this template.
Note: The default is for a menu entry to be created.
Note: A shortcut can only be one character long. A map can be several
characters long. It is always preceded by the local mapleader.
------------------------------------------------------------------------------
C.2 LISTS *template-support-opt-list*
------------------------------------------------------------------------------
The list options appear in the header of the list:
== List: OutputModifiers == <options> == ~
It is not required to specify any options. The defaults are given below.
------------------------------------------------------------------------------
*template-support-list* *template-support-dict*
*template-support-hash* *template-support-dictionary*
Type:
list - The object is given as a list. (default)
hash - The object is a hash, or dictionary.
dict - Same as hash.
dictionary - Same as hash.
For a description see |template-support-syntax-list|.
------------------------------------------------------------------------------
*template-support-bare*
Interpretation:
bare - The list is interpreted as a bare list. Each line is considered to be
a new entry.
Note: Bare lists are not the default.
==============================================================================
D. CHANGE LOG *template-support-change-log*
==============================================================================
------------------------------------------------------------------------------
RELEASE NOTES FOR VERSION 0.9.3
------------------------------------------------------------------------------
- Change: In case several version of autoload/mmtemplates/core.vim are
available on 'runtimepath', pick out the newest one to load.
Includes the patches 0.9.2-1 to 0.9.2-2:
- Change: More checks when rereading templates.
- Change: Better compatibility with custom mappings
(use "normal!", "noremap" and "noremenu" consistently).
- Change: During template insertion, find <CURSOR> tag independent of the
settings 'magic' and 'startofline'.
- Added: API functions "mmtemplates#core#SetMapleader" and
"mmtemplates#core#ResetMapleader".
- Extended the documentation.
------------------------------------------------------------------------------
RELEASE NOTES FOR VERSION 0.9.2
------------------------------------------------------------------------------
- Added: 'SetProperty' to set properties using a template library.
- Change: Improved list picker.
API:
- Change: Extended 'mmtemplates#core#EscapeMenu'.
Includes the patches 0.9.1-1 to 0.9.1-3:
- Bugfix: Problem with macro replacements containing macros with flags.
- Change: Syntax highlighting.
- Change: Warnings about overwritten maps are only printed once for every
filetype.
- Bugfix: Inserting templates in visual mode with placement "insert" could
cause rare problems interacting with the indent program.
- Extended the documentation.
------------------------------------------------------------------------------
PATCH 0.9.2-1:
- Released with slight changes in the core functionality.
- Change: More checks when rereading templates.
- Extended the documentation.
------------------------------------------------------------------------------
PATCH 0.9.2-2:
- Released with slight changes in the core functionality.
- Change: Better compatibility with custom mappings
(use "normal!", "noremap" and "noremenu" consistently).
- Change: During template insertion, find <CURSOR> tag independent of the
settings 'magic' and 'startofline'.
- Added: API functions "mmtemplates#core#SetMapleader" and
"mmtemplates#core#ResetMapleader".
------------------------------------------------------------------------------
RELEASE NOTES FOR VERSION 0.9.1
------------------------------------------------------------------------------
- Change: When checking for already existing maps: Check each mode individually.
- Added: Menu separators can be inserted via the template library.
- Bugfix: Changing the mapleader now works.
- Bugfix: Inserting templates with placement "insert" did not work in some
cases.
- Minor improvements and bugfixes.
API:
- Added: Sub-menus can be created with priorities.
- Added: Properties.
- Added: The mapleader shown in the menu is configurable.
- Added: The maps for "edit templates", "reread templates" and "choose style"
are configurable.
Internal Changes:
- Changes to the template data structure.
- Major code cleanup.
------------------------------------------------------------------------------
PATCH 0.9.1-1:
- Released with no changes in the core functionality.
- Change: Some commands are now executed silently.
- Bugfix: Syntax highlighting.
- Extended the documentation.
PATCH 0.9.1-2:
- Released with slight changes in the core functionality.
- Bugfix: Problem with macro replacements containing macros with flags.
- Change: Syntax highlighting.
- Slightly extended the documentation.
PATCH 0.9.1-3:
- Released with slight changes in the core functionality.
- Change: Warnings about overwritten maps are only printed once for every
filetype.
- Bugfix: Inserting templates in visual mode with placement "insert" could
cause rare problems interacting with the indent program.
- Extended the documentation.
------------------------------------------------------------------------------
RELEASE NOTES FOR VERSION 0.9
------------------------------------------------------------------------------
- Initial upload.
==============================================================================
vim:tw=78:noet:ts=2:ft=help:norl:expandtab: