*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 --- 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: // // Author: |AUTHOR| // Version: 1.0 // Created: |DATE| // ================================================== == function == below == void |?FUNCTION_NAME| ( ) { } /* end of function |FUNCTION_NAME| */ == ENDTEMPLATE == < Each line (the so-called header) > == == == 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 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 ). 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 ( "/" ) loads templates from another file (|template-support-IncludeFile|). The path is given relative to the including file. The call: > IncludeFile ( "/", "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: // // Author: |AUTHOR| // Version: 1.0 // Created: |DATE| // ================================================== == Idioms.function definition == below == void |?FUNCTION_NAME| ( ) { } /* 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: # # 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: > == == [ == ] For consistency with other constructs, the following format is also supported: > == TEMPLATE: == [ == ] 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 _ + - . , 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 ( ) { } == 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 ||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: # # 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| ( ) { } /* 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: # 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 #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 , which specifies the position of the cursor after the template has been inserted. Consider the following example: > == Statements.if == below == if ( ) { } == 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 ( ) { <+IF_PART+> } == ENDTEMPLATE == < The standard map for jumping is , 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 ( ) { <+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 == /* */ == Comments.date and time == insert == |DATE|, |TIME| == 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 tag exists: > == Statements.if == below == if ( ) { } == 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 ( ) { <+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 tag, which is removed in every other mode. A better version of the above example looks like this: > == Statements.if, else == below == if ( ) { <-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 #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 ( "/" ) 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 ( ) { <+IF_PART+> } == ENDTEMPLATE == < The templates will have the map ||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: - a shortcut is created for the menu entry of this template shortcut: - long version of sc: 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 == Preprocessor.include stdlib, map:pisl == #include == Preprocessor.include stdio, map:pisio == #include == Preprocessor.include string, map:pistr == #include == 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> == ENDTEMPLATE == < The template "Preprocessor.c libs" uses this list. The command: > "|PickList( '', '' )|" 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_StandardLibs' )| #include == 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| ( |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: # Description: TODO # ================================================== == ENDTEMPLATE == == ENDSTYLES == == USE STYLES : Doxygen == == Comments.function description == == /*! * \brief * * 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 == == // == 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( , ) (|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|" == Include.global, filename only == below == |PickFile( 'global include directory', 'global_include' )| #include <|FILENAME|> == 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( , ) (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 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|" == 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 ( "/" ) 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 ( \ , "set", "Templates::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() 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( , , ). 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, , , ) If the flag is an empty string, the first occurrence of is replaced with . If flag equals "g", all occurrences are replaced. The function LiteralSub(,,) 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() or Vim(). 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(). 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 tag. "placement", place - Overwrite the template's placement. (string) "range", a, b - Use the range from lines 'a' to 'b'. (integers) "", replace - Set the replacement for the given macro. The string 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\|" )' < ------------------------------------------------------------------------------ *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 i=mmtemplates#core#JumpToTag ( regex ) inoremap =mmtemplates#core#JumpToTag ( regex ) < 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: > --- ------------- ... ... < 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.' ' exe 'amenu '.root_menu.'.-Sep0- ' exe 'amenu '.root_menu.'.&Run.Run'.global_name.' ' exe 'amenu '.root_menu.'.Run.-Sep00- ' < 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'.esc_mapleader.map_run.' :call Run()' 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 \ | & - "entry" : A menu entry, dots are escaped as well, escapes . \ | & - "right" : The right-aligned side of a menu entry, escapes . \ | 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 _ + - . , 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 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- CommentStart -anything- CommandName ( ParameterList ) *|MacroName|* = MacroAssignment StyleBlock1 StyleBlock2 Template HelpTemplate MenuSeparator List StyleBlock1 (sequence): == IF *|STYLE|* IS MacroName == StatementList == ENDIF == StyleBlock2 (sequence): == USE STYLES : MacroNameList == StatementList == ENDSTYLES == Template (sequence): == [ TEMPLATE : ] TemplateName == [ OptionList == ] -several lines- == ENDTEMPLATE == Note: The " TEMPLATE : " in the first line is optional, as opposed to the structure of the next three rules. HelpTemplate (sequence): == HELP : TemplateName == [ OptionList == ] -several lines- == ENDTEMPLATE == MenuSeparator (one line): == SEP : SeparatorName == List (sequence): == LIST : MacroName == [ OptionList == ] -several lines- == 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| ( |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| ============================================================================ == chapter, alt2 == below == |Prompt( 'NAME', '' )| |Prompt( 'NUMBER', '' )| ============================================================================ |NUMBER| |NAME:u| ============================================================================ == 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: == == == ~ 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: - A shortcut is created for the menu entry of this template. shortcut: - Long version of sc:. 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 == == ~ 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 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 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: