-
Notifications
You must be signed in to change notification settings - Fork 96
/
templatesupport.txt
3218 lines (2662 loc) · 126 KB
/
templatesupport.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
*templatesupport.txt* MM Template Support Aug 06 2020
MM Template Support *template-support*
Plug-in version 1.1beta
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 (https://www.vim.org/scripts/script.php?script_id=365)
- C-Support (https://www.vim.org/scripts/script.php?script_id=213)
- Perl-Support (https://www.vim.org/scripts/script.php?script_id=556)
==============================================================================
0. TABLE OF CONTENTS *template-support-contents*
==============================================================================
--- Part I - User Documentation ---
1. Introduction |template-support-intro|
2. Basic Usage |template-support-basics|
3. Template Library |template-support-library|
3.1 Personalization |template-support-lib-person|
3.2 Interface Version |template-support-lib-interf|
4. Templates |template-support-templates|
4.1 Macros |template-support-templ-macro|
4.1.1 Predefined Macros |template-support-templ-predef|
4.1.2 Flags |template-support-templ-flag|
4.1.3 Format Specifiers |template-support-templ-format|
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|
5.3 Menu Customization |template-support-lists-menu|
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. Configuration |template-support-config|
--- Part II - API Documentation ---
1. API |template-support-api|
1.1 Basic Usage |template-support-api-basic|
1.2 Creating Maps and Menus |template-support-api-maps|
1.3 Access |template-support-api-access|
1.4 Miscellany |template-support-api-misc|
2. Backwards Compatibility |template-support-backwards|
--- Part III - Appendices ---
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|
D.1 Interface Versions |template-support-change-interf|
D.2 API Versions |template-support-change-api|
E. Credits |template-support-credits|
==============================================================================
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
--------- PART I --- USER DOCUMENTATION --------- ~
-------------------------------------------------------------------------- ~
-------------------------------------------------------------------------- ~
==============================================================================
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.
------------------------------------------------------------------------------
3.2 INTERFACE VERSION *template-support-lib-interf*
------------------------------------------------------------------------------
Further extension of the template engine might introduce minor
incompatibilities with previous versions. While this will generally be
avoided, not all features can be added (and bugs fixes) in a way that is
backwards compatible.
To avoid breaking existing template libraries, by default, all libraries will
use the interface introduced prior to version "1.0". Newer versions can be
unlocked by calling InterfaceVersion() (|template-support-InterfaceVersion()|)
from within the template library: >
InterfaceVersion ( "1.0" )
This will enable advanced feature for this library. Other libraries loaded
with the same core can use other versions.
When this call is inserted into a library, it has to be checked for constructs
which can not be used anymore. However, existing libraries must not be changed
immediately once a new version comes along.
See |template-support-change-interf| for a change log limited to changes in
the interface.
==============================================================================
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 options 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 are 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|*
Replacements for macros can be given in the template library itself: >
SetMacro( 'AUTHOR', 'Wolfgang Mehner' )
The 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
insert *|AUTHOR|* as specified via "SetMacro()".
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 ==
<
------------------------------------------------------------------------------
4.1.1 Predefined Macros *template-support-templ-predef*
The replacements for various macros are handled 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().
Dates and timestamps are inserted analogously. Their format can be set via
SetFormat (see |template-support-SetFormat()|).
*|TIME|* : the current time
*|DATE|* : the current date
*|YEAR|* : the current year
Further macros can be used to print "pretty" dates in READMEs and other
documentation.
*|DATE_PRETTY|* *|DATE_PRETTY1|*
*|DATE_PRETTY2|* *|DATE_PRETTY3|*
*|TIME_PRETTY|* *|YEAR_PRETTY|*
------------------------------------------------------------------------------
4.1.2 Flags *template-support-templ-flag*
Certain uses come with special requirements on the replacement text. 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 replacement text to lowercase
:u - change replacement text to uppercase
:c - capitalize text (change first letter to uppercase)
:L - legalize name (replace all non-word characters with underscores)
(for technical reasons:)
:T - remove tags (remove all cursor, split, and jump tags)
------------------------------------------------------------------------------
4.1.3 Format Specifiers *template-support-templ-format*
A format specifier can be added to change the way the macro is replaced. E.g.,
in some comment boxes the formatting should not be broken. Consider this
example:
>
== Comments.file description == start ==
# ################################################## #
# File: |FILENAME| #
# Description: <CURSOR> #
# #
# Author: |AUTHOR| #
# Version: 1.0 #
# Created: |DATE| #
# ################################################## #
== ENDTEMPLATE ==
<
Inserting this template into a file would result in a broken formatting:
>
# ################################################## #
# File: test.sh #
# Description: | #
# #
# Author: Wolfgang Mehner #
# Version: 1.0 #
# Created: 11.11.2015 #
# ################################################## #
<
Therefore macros can be specified to be inserted with fixed width, for
example:
>
== Comments.file description == start ==
# ################################################## #
# File: |FILENAME%++++++++++++++++++++++l| #
# Description: <RCURSOR> #
# #
# Author: |AUTHOR%++++++++++++++++++++++++l| #
# Version: 1.0 #
# Created: |DATE%++++++++++++++++++++++++++l| #
# ################################################## #
== ENDTEMPLATE ==
<
The format specifier causes the replacement text to be padded with spaces,
such that a text of the desired width is inserted. The special cursor tag
<RCURSOR> is replaced with the right amount of spaces as well, and after the
template insertion replacement mode is started:
>
# ################################################## #
# File: test.sh #
# Description: | #
# #
# Author: Wolfgang Mehner #
# Version: 1.0 #
# Created: 11.11.2015 #
# ################################################## #
<
The format specifier is a '%' followed by several plus characters '+', which
are used to extend the macro to the desired width. The format specifier ends
with an (optional) character 'l', 'c', or 'r' to indicate the alignment (left,
center, or right, respectively).
If the replacement text is longer than the macro in the template, the
formatting will be broken. Instead of the plus character, several dashes can
be used. In this case the replacement text will be cut off if it is longer
than the macro:
>
== Comments.file description == start ==
# ################################################## #
# File: |FILENAME%----------------------l| #
...
<
The width can also be specified by a number. To insert a text which is always
at least 4 characters long: >
|AUTHORREF%+4|
To insert it such that the text is never longer than 4 characters: >
|AUTHORREF%-4|
The following format specifiers are possible, the alignment is always optional:
%++++++l - pad the replacement text
%------l - pad the replacement text, cut off if it is too long
%+10l - the width is given by the number
%-10l - the width is given by the number, cut off if the text is too long
%10l - the width is given by the number, do not cut off
%+l %-l - align left
%+c %-c - align center
%+r %-r - align right
------------------------------------------------------------------------------
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>, but it may vary with each plug-in
using the template support.
Jump tags have one of the following formats:
<+NAME+> <-NAME->
{+NAME+} {-NAME-}
And with interface version 1.0+ (see |template-support-lib-interf|) "optional"
jump tags have been introduced:
[+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 ==
<
** Interface Version 1.0+ **
The "optional" jumps tags [+NAME+] and [-NAME-] can be used in templates for
argument lists:
>
== Idiom.open file == insert ==
fid = openfile ( <+FILENAME+>, [+MODE+] )
== ENDTEMPLATE ==
<
The user can either jump to both tags and write down the arguments or only
jump to FILENAME and then use the map <ctrl+d> to delete the optional jump tag
MODE, together with the separator "," and whitespaces.
------------------------------------------------------------------------------
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 placements 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 lines. 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 ==
Further options for customizing the look of the submenu are explained in
|template-support-lists-menu|.
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
5.3 MENU CUSTOMIZATION *template-support-lists-menu*
------------------------------------------------------------------------------
** Interface Version 1.0+ **
With interface version 1.0+, the look of the submenu created for a template
can be modified.
A list can be given explicitly with "expandmenu", which is then used to create
the menu entries: >
== Idioms.string function == insert, expandmenu:String_Functions ==
It is up to the user to ensure that the entries in this list are suitable to
select entries from the list used inside the template. The only purpose of the
list given with "expandmenu" is to change the look of the menu.
The created menu entries can use both the left- and the right-aligned text of
the entry. By default, the list element or the dictionary key are shown in the