-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmu-template.txt
1042 lines (842 loc) · 47.2 KB
/
mu-template.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
*mu-template.txt* Utility for loading and expanding template-files
*mu-template.vim* For Vim version 7+ Last change: 03rd Oct 2024
*µTemplate*
µTemplate MANUAL by Luc Hermitte (LH)
Version 4.5.0
==============================================================================
CONTENTS *MuT-contents* {{{1
|MuT-presentation| Presentation
|MuT-features| Features
|MuT-syntax| Template-files syntax
|MuT-config| Configuration
|MuT-design| Design considerations
|MuT-files| Files
|MuT-external-plugins| Other plugins of interest
|MuT-trojan-horse| Security concerns
|MuT-credits| Credits
|add-local-help| Instructions on installing this file
}}}1
==============================================================================
PRESENTATION *MuT-presentation* {{{1
µTemplate is a template-files loader for Vim. Once loaded, templates are
interpreted and expanded according to a flexible syntax (|MuT-syntax|).
Disclaimer: Every time you read "I", "me" or "my", consider that I, Luc
Hermitte, have written this documentation.
------------------------------------------------------------------------------
{{{2 Template-files paths ~
*MuT-paths*
The template-files are searched within a list of directories specified by
|{runtimepath}/template/|, |(bpg):[{ft}_]mt_templates_paths| and by
|$VIMTEMPLATES|.
*{runtimepath}/template/* refers to `'template/'` subdirectories, built from
the list of directories specified in the 'runtimepath' vim-option.
*$VIMTEMPLATES* is a comma (or semicolon) separated list of directories. When
set, it has precedence over paths of the form |{runtimepath}/template/|.
*(bpg):[{ft}_]mt_templates_paths* can be either a |List| or a comma (or
semicolon) separated list of directories. When set, it has precedence over
paths of the form |{runtimepath}/template/|, or even from |$VIMTEMPLATES|.
N.B.: this feature requires |lh-dev|
*MuT-paths-override*
Precedence~
By default, the template-files should be installed into your
`$HOME/.vim/template/` directory. (`$HOME/vimfiles/template` under windows
systems ... cf. 'runtimepath' for other acceptable directories).
Hence, you can easily override a default template-file by yours. Put your file
into your `$HOME/.vim/template/` directory.
By setting |$VIMTEMPLATES,| with plugins like |project| or |local_vimrc|, you
can also override your default template-files on a per project basis -- see
|lhvl#project|.
Sharing template-files~
As template-files are searched within a list of directories, sharing them
between several people or teams becomes really easy. There are several ways to
proceed:
- put all the template-files into `$VIM/vimfiles/after/template/`
At this point, VIM administrators (often known as system administrators) on
your environment should not let anybody add new template-files to the common
repository. Cf. |MuT-trojan-horse|.
- Import the configuration from another VIM user by adding '`~hislogin/.vim'` to
your 'runtimepath'. By doing so, you will use the plugin and ftplugins he is
using, but also the template-file he uses.
- More interresting, on a project you work on with other VIM users, you can
share a directory (directly, or through a CVS/SVN base) with everybody and
set |$VIMTEMPLATES| point to this directory.
*MuT-multiprojects*
If you are working on several projects, I recommend the use of a
|MuT-local_vimrc| plugin. There set `b:mut_templates_paths` or
`p:mut_templates_paths`.
Note: Every time you share template-files with other people, be sure that these
template-files are not |MuT-trojan-horse|s. Actually, it is exactly the same
issue as using someone else's plugins.
Note: Since Version 2.0.0 template-files naming policy has drastically
changed. From `template.{id}`, it has become `{id}.template`. Here is a little
oneliner that may help you convert filenames (the *nix tools find, xargs, and
perl are required) >
find /some/pathname/ -name "template.*" | perl -pe 's/(.*)(template)\.(.*)/$1$2.$3 $1$3.$2/ ' | xargs -l1 mv
I'm quite sure there are simplier solutions when we are true Perl mongers.
(NB: be sure to exclude `{rtp}/ftplugin/template.vim` which is a |ftplugin|,
its name must not be changed)
------------------------------------------------------------------------------
{{{2 Loading template-files ~
*MuT-load*
There are several ways to load template-files:
- Automatic expansion .... |MuT-autoload|
- Explicit expansion ..... |:MuTemplate|
- Insert-mode expansion .. |Mut-snippets|
- Visual-mode expansion .. |MuT-surround|
- Through the menu ....... |MuT-menu|
{{{3 Automatic expansion of templates when opening new files ~
*MuT-autoload*
When opening a new file, if |g:mt_IDontWantTemplatesAutomaticallyInserted|
is false, then the first template-file found whose name matches:
{path}/{filetype}.template
is loaded and interpreted.
{path} refers to directories listed within |{runtimepath}/template/| or
|$VIMTEMPLATES|.
{filetype} refers to the |filetype| of the new file.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Explicit expansion of template-files ~
*:MuTemplate*
We can explicitly load and interpret the template-file whose name matches:
{path}/{extension}.template
thanks to the command: >
:MuTemplate {extension}
< Note: {path} still refers to directories listed within |$VIMTEMPLATES| or
|{runtimepath}/template/|.
The code snippets associated to a particular filetype can be accessed thanks
to the call:
:MuTemplate {ft}/{code}
which loads and interprets the template-file whose name matches:
{path}/{ft}/{code}.template
Note: The filetype of the current file does not need to be the same as {ft}.
Note: A partially successful auto completion is implemented. As
:MuTemplate expects {ft}/{code}, and as vim filters the acceptable
parameters to commands (when auto completion is triggered), the auto
completion works best on "*/pattern". e.g.: >
:MuTemplate */f<tab>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Insert-mode expansion of template-files ~
*MuT-snippets*
*i_CTRL-R_SPACE* *i_CTRL-R_TAB*
This plugin defines two default insert-mode mappings:
(*) `i_CTRL-R_SPACE`
uses as a {pattern}: the keyword (check 'iskeyword') before the cursor.
(*) `i_{WORD}_CTRL-R_TAB`
uses as a {pattern}: the |WORD| before the cursor.
]Contrary to |expand()|, "before" means "whose first character is placed on
]a column prior to the column where is cursor is".
The work of the mappings consists in:
- listing all the template-files whose names match:
{path}/{filetype}-{pattern}.template
or {path}/template/{filetype}/{pattern}.template
NB: template-files may come from the ones inherited from another
filetype (see |g:mt_inherited_ft_for_{filetype}|.
- If there are several matches, the user will have to choose one template-
file. See |g:mt_chooseWith|.
- The template-file thus selected is inserted in place of the (key)word
before the cursor.
If there were characters before and after the word, the line is not split.
For instance, let's suppose the xslt line: >
blah xsl:val foo
< with the cursor just after "val".
Hitting `CTRL-R_TAB` expands the line into: >
blah <xsl:value-of select=«XPath»/> foo
< In order to replace these mapping keybindings with some you found more
ergonomic, see |<Plug>MuT_ckword|.
*g:mt_chooseWith*
mu-template offers two ways to choose the template-file to expand when
several match:
- When `g:mt_chooseWith` values `"complete"`, the choices are displayed with a
|ins-completion-menu|. A hint about the snippet will be displayed (if
available). This is the default behaviour (since v2.2.0).
- When `g:mt_chooseWith` values `"confirm"`, the choices are displayed with a
|confirm()| box.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Visual-mode expansion of template-files ~
*MuT-surround*
*v_CTRL-R_TAB*
This plugin defines one default visual-mode mapping:
(*) `v_CTRL-R_TAB`
asks the user which snippet to use,
and surrounds the selected text with the snippet selected.
The work of the mappings consists in:
- listing all the template-files whose names match the snippet-name typed:
{path}/{filetype}-{pattern}.template
or {path}/template/{filetype}/{pattern}.template
NB: template-files may come from the ones inherited from another
filetype (see |g:mt_inherited_ft_for_{filetype}|.
- If there are several matches, the user will have to choose one template-
file.
- The template-file thus selected is inserted around the text selected.
In order to replace these mapping keybindings with some you found more
ergonomic, see |<Plug>MuT_ckword|.
Some snippets may put the selected text in various places, see for
instance the various control-statements shipped with mu-template. To
select where the selected-text goes, enter a |count| before executing the
mapping, the count is optional and considered to be 1 by default. The
default control-statement snippets use the following policy:
- {1} is for the code,
- {2} is for the condition
e.g.: >
while ({2}) {
{1}
}<++>
< See |s:Surround()| to know how to define a snippet that can surround the
current selection.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Through the menu ~
See |MuT-menu|.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Through the API~
You may be wrtting plugins that need to expand stuff. mu-template offers
several functions for this need.
{{{4 Expand text directly at the current position~
*lh#mut#expand_text()*
This function takes two parameters:
- Whether we need to join what is inserted with what follow on next line
(0 or 1)
- and the text to expand. It could also be a list of lines to expand.
e.g. >
call lh#mut#expand_text(0, ['I am <+Author()+>', 'And you are <+fill-in-your-name+>'])
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Filetype inheritance ~
*g:mt_inherited_ft_for_{filetype}*
The template-files to expand are searched according to the current |filetype|.
Sometimes, we want to reuse the template-files written for other filetypes.
For instance, a C code-snippet is likely to be usefull in C++.
There several two ways to achieve this:
- If every template-files from a given {root-filetype} are acceptable with another
{filetype}, then we can set the global option
|g:mt_inherited_ft_for_{filetype}| to {root-filetype}. By default,
mu-template makes C template-files available in C++, Java and C# thanks to: >
let g:mt_inherited_ft_for_cpp = 'c'
let g:mt_inherited_ft_for_java = 'c'
let g:mt_inherited_ft_for_csharp = 'c'
< If you don't want these default settings, then set these variables to an
empty string ('') in your |.vimrc|.
@todo: support list of filetypes.
- On a file per file basis, we can call |s:Include()| in order to import the
definition from a template-file into another one. This approach will require
as many template-files in the leaf filetype, as template-files from the
{root-filetype} we want to support.
- We can also on the operating system, and more precisely, on the file
system's links (hard links, symbolic links, connection points (? -- NTFS))
==============================================================================
FEATURES *MuT-features* {{{1
{{{2 Markers -- a.k.a `placeholders' ~
*MuT-markers*
{{{3 Inserting markers ~
*MuT-lh#marker#txt()|*
This plugin supports |markers| -- also known as |placeholders| in Srinath
Avadhanula's imaps.vim plugin, and vim-latex.
To benefit (of?) the power of advanced markers systems, you can:
- either directly write "<+{marker/placeholder-text}+>" in your
template-file,
- or use the function |lh#marker#txt()| within your template-files -- or even
|lh#marker#open()| or |lh#marker#close()|.
The text will be expanded into "«{parameter}»", "<+{parameter}+>" or
whatever according to your configuration and your environment. See
|marker|.
Note that if the text within a marker can be is a valid VimL expression,
the marker will be replaced with the result of the evalution -- unless
|s:dont_eval_markers| is set.
Almost every default template-files are already relying on this feature.
All the definitions required to take advantage of the markers are defined
into |bracketing.base.vim|, which comes from |lh-map-tools|.
Right now, they are compatible with my |markers| system and Srinath
Avadhanula's |placeholders| system. However, to use his configuration
variables instead of mine, don't forget to set |g:use_place_holders| to 1.
If you want to develop or support another n-th markers system, then you will
have to define these three functions in a plugin that MUST be placed into
one of your `{runtimepath}/after/plugin/` directories (not just
`{rtp}/plugin/`), and to define as well the mappings to |!jump!| -- see
|MuT-!jump!|.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Jumping to markers ~
|!jump!| *MuT-!jump!*
|bracketing.base.vim| also proposes some default mappings that jump to the
next marker. These mappings are required by µTemplate.
Note: This means that by default, the jumping-forward function from my
|markers| system will be used. The jumping functions defined are quite
accurate (they handle multi-characters markers, multi-byte characters, don't
mess when jumping to markers hidden within folds, etc), very flexible
(through options), and can jump forward and backward.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Automatic jump to the first marker ~
*b:mt_jump_to_first_markers* *g:mt_jump_to_first_markers*
After a template-file has been loaded and expanded, the cursor is moved to
the first |marker| encountered. If the marker is within a fold, then the
fold will be opened and the marker selected.
Sometimes, we define scripts that generate code. Usually, these scripts
will expect neither the cursor to move on its own, nor to be in
|Select-mode|.
In order to not mess things up this plugin defines the option
|g:mt_jump_to_first_markers|, which must be set to 0.
So, when a new buffer is created, we can prevent µTemplate from jumping to
the first marker. For instance, |lh-cpp|-ftplugins detects µTemplate
presence on the system, and sets off this options while generating code.
If you are using such a tool unable to work with µTemplate, patch it
(contacting the author is even better) to integrate something like: >
if exists('g:mu_template') &&
\ ( !exists('g:mt_jump_to_first_markers')
\ || g:mt_jump_to_first_markers)
" NB: g:mt_jump_to_first_markers is true by default
let mt_jump = 1
let g:mt_jump_to_first_markers = 0
endif
... where a new buffer is opened and filled ...
if exists('mt_jump')
let g:mt_jump_to_first_markers = mt_jump
unlet mt_jump
endif
------------------------------------------------------------------------------
{{{2 Other features of interest ~
{{{3 Syntax easy to enhance ~
The syntax is only limited by VimL's syntax. See |MuT-syntax|.
Thus, you can add |plugins| of our own that define new |functions| or
|:command|s that you can use within your own template-files.
Right now, you can use all the builtin-|functions| that Vim proposes plus
some wrappers I propose with µTemplate (see |MuT-lh#marker#txt()|,
|s:Include()|) and |ui-functions.vim|.
In |lh-cpp|, a few functions constitute an API (|lh-cpp-API|) that can be
used to analyze C++ code. For instance, |Cpp_SearchClassDefinition()|
tells the complete name of the current class.
Note also the command |:DOX| that parses C++ functions signature and then
relies on mu-template to insert a doxygen template-comment listing every
parameters from the function.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Other things provided if not yet defined ...~
*g:author* *Author()* ([$USER/$USERNAME]/"")
This function is used in some templates.
- `Author([0])` tries to return in order: `b:author`, or `g:author`, or
`$USERNAME` (win32), or `$USER` (unix), or an empty string
- `Author(1)` tries to return in order: `b:author_short`, or `g:author_short`,
or `$USERNAME` (win32), or `$USER` (unix), or an empty string
*DateStamp()*
Used in some templates. See this function as a overrideable |strftime()|.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Menus ~
*MuT-menu*
µTemplate will propose a |menu| on systems that support them.
The placement of the menu can be adjusted thanks to the two options:
|g:mt_menu_priority| and |g:mt_menu_name|.
The menu-items are based on the template-files detected on your system ;
see |MuT-paths|:
- First, it lists all the skeletons that can be used when a new buffer is
created
- Then, it lists the different filetypes for which there are code snippets
- Finally, the last menu item permits to rebuild the menu when some
template-files are added or deleted from the system.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{{3 Post Expansion Hooks~
*MuT-post-expand-hooks* *s:AddPostExpandCallback()*
It's possible to execute hooks after the expansion has been done.
The typical use case is for programming langages: the snippet expanded
uses a symbol that is defined in a header file/module/package. In order
for the expanded code to be valid, this symbol needs to be
included/imported/... Hooks can be used to import the missing definitions.
For instance, lh-cpp defines the following vector-snippet: >
VimL: call s:AddPostExpandCallback('lh#cpp#include#add("<vector>")')
std::vector<¡s:Surround(1, '<+type+>')¡> <++>
< Expanding vector, will of course insert std::vector<>, but also it will
automatically include <vector> (if not already included).
Note: this is achieved thanks to |lh#cpp#include#add|. Equivalent functions
are still to be written for other languages (Java, Python, Perl, ...)
Important: the hook function needs to return the number of lines added (in
case they are added before the place where the snippet has been expanded)
==============================================================================
TEMPLATE FILES SYNTAX *MuT-syntax* {{{1
{{{2 Syntax ~
¡|expression|¡ *MuT-expression*
is expanded into the result of the VimL {expression}.
If the {expression} results into an empty line, this empty line is
trimmed.
The characters delimiting the {expression} can be changed thanks to
|s:value_start| and |s:value_end|.
VimL: {VimL-instruction} *MuT-intruction*
{VimL-instruction} is an Ex command that is executed.
This statement is expanded into an empty string,
Note however that this command must not attempt to modify the current
buffer, or directly change the |s:content| of the lines being added.
This may lead to an undefined behaviour.
VimL: hint: {snippet-hint} *MuT-hint*
{snippet-hint} is a textual hint intended to summarize what the
snippet will be expanded into. So far hints serve only with
|MuT-snippets|.
When displayed hints will be processed through |lh#style#apply_these()|,
and `\n` will be transformed into newlines. To produce `\n` sequence,
use `\%n`.
------------------------------------------------------------------------------
{{{2 How-To ~
*MuT-howto*
Q: "How can I automate the insertion of |markers|/placeholders matching my
current configuration (defined in lh's bracketing.base.vim, or in Srinath
Avadhanula's imaps.vim)?"
A: There are two ways to accomplish that.
1- With |lh#marker#txt()| >
¡lh#marker#txt('comment text')¡
< *MuT-<++>*
2- It is also possible to just type >
<+comment text+>
< which simplifies the syntax of the template-file.
The `"<+"` and `"+>"` will be replaced by the current markers characters. In
order to use other characters, in the template-file (only!), just set
*s:marker_open* and *s:marker_close* to anything you like. for instance: >
VimL: let s:marker_open ='<<<'
VimL: let s:marker_close ='<<<'
Some text <<<the placeholder to replace>>> other text.
Q: "How can I insert the current date?" *MuT-date*
A: Use |MuT-expression| with a VimL function that returns the current date. >
¡strftime({format})¡
< check |strftime()|, and |DateStamp()|
Q: "How can I insert the name of the current file?" *MuT-filename*
A: Use |MuT-expression| with a VimL function that returns the name of the
current file. >
¡expand('%:t')¡
< check |expand()|
Q: "How can I insert my name?" *MuT-whoami*
A: Have it stored in a VimL variable and use a |MuT-expression|.
Note that mu-template tries to deduce it, the result is stored in
|g:author|. If you only need one version of your name in a given project
(|MuT-multiprojects|), you'd rather set |g:author| yourself.
Examples of use: >
Maintainer: ¡g:author¡
< Prefer |Author()|in case its value may change depending on the filetype,
... >
Maintainer: ¡Author()¡
Q: "How can I store the result of a expression into a variable?" *MuT-:let*
A: Use the VimL instruction |:let|, and make the scope of the variable to be
either |s:var|, |b:var|, |w:var| or |g:var|.
|local-variables| can not be used.
Ex.: >
VimL: let s:my_variable = 1 + 2
< However, note that some script-symbol are reserved and must not be used. See
|MuT-reserved-symbols|.
You can also use the MuT: command :let >
MuT: let s:my_variable1 = 1 + 2
MuT: let my_variable2 = 1 + 2
< which is very similar to |:let| but differs in:
- The variable is cleared (with |:silent| |:unlet!|) before being
assigned.
This permits to workaround |E706|.
This is not done if the variable name is found in the right hand side
operand.
- `"s:"` is implicit. If not used, it will be forced upon you (local
variables are not possible in template-files)
Note: For now, |b:var|, |w:var| or |g:var| are not supported.
Note: neither dictionary fields nor list elements can be assigned this
way for now either.
- When a new template-file will be expanded, all variables set with
"MuT: let" will be automatically cleared.
Q: "How can I interactively insert things?" *MuT-UI*
A: Use interactive functions like |confirm()|, |input()|, ..., or their
wrappers from |ui-functions.vim|. >
VimL: let s:choice = CONFIRM('prompt', "&Yes\n&No", 2)
¡IF(s:choice, 'I agree', 'I disagree')¡
VimL: let s:name = INPUT('what name ?')
The name chosen is ¡s:name¡
< Examples: check cpp/class.template
Q: "How can I select which group of lines to insert *MuT-control-flow*
depending on a given criteria?"
A: If you want to insert a lot of lines according to a given case (for
instance, vim ftplugins, plugins, syntax files, etc. are quite different
and required specialized skeletons), you'd better use |s:Include()|
instead of |IF()|.
Examples: check c.template, vim.template
*MuT-if* *MuT-else* *MuT-endif*
You can also use "MuT: if", e.g.: >
MuT: if lh#dev#cpp#use_cpp11()
std::shared_ptr<<+type+>> <++>
MuT: else
boost::shared_ptr<<+type+>> <++>
MuT: endif
Q: "How can I re-indent the lines inserted?" *s:reindent*
A: Set the special variable |s:reindent| to 1. Then, the inserted lines will
be automatically re-indented according to the current indent scheme. >
VimL: let s:reindent = 1
< Examples: check */*.template.
Q: "But how can it work with python?"
In that case, set |s:reindent| to `"python"`. mu-template will then apply
last indent to new lines.
And if your template/snippet wants to include another one and if the
included one shall be indented, then call |s:Include()| with
`{'indented':1'}` parameter. >
VimL: call s:Include('python', 'docstring', {'indented':1})
< Examples: check python/def.template
Q: "How do I specify where the automated insertion starts?" *s:StartIndentingHere()*
A: Call s:StartIndentingHere: >
VimL: call s:StartIndentingHere()
< Notes:
- This feature will make sense after file headers that shall not be
indented.
- |s:reindent| will be automatically set when calling this function.
Examples: check `template/c/internals/c-header.template`
Q: "How can I load another skeleton?" *s:Include()*
A: This can be achieved with the special function |s:Include()|.
Examples: check c.template that loads the template-file for C header
files, or C implementation files according to the current buffer's file
extension (.h or .c) >
VimL: call s:Include( (expand("%:e") =~ '^hh\=$') ?'c-header' : 'c-imp')
< Or {swith}-template that loads {case}-template with an argument: >
VimL: call s:Include('case', 'c', arg)
< However, if several snippets need to be included, don't call
`s:Include()` from a |:for| loop -- µTemplate engine won't be able to
correctly stack contexts in that case. Instead use
*s:IncludeSeveralSnippets()* which takes:
- a snippet name, or a list of snippet names,
- the directory/filetype where the snippet file is stored,
- a |dict| parameter passed to all subsequent calls to |s:Include()|,
- a specific parameter merge to the previous one for current
|s:Include()| call. For instance, in `python/class.template`, it's used
this way: >
VimL: call s:IncludeSeveralSnippets('def', 'python',
\ {'indented': 1},
\ map(copy(s:function_list), '{"function": v:val}'))
Q: "How can I pass parameters to imported skeletons?" *s:Args()* *s:PushArgs()* *s:Params()*
A: Three API functions are provided for this purpose:
- |s:PushArgs()| permits to push arguments to the skeleton
- |s:Include()| which takes an optional third parameter to push arguments
to the imported skeleton.
- |s:Args()| permits to fetch the arguments passed.
- |s:Params()| permit to fetch a named argument passed.
Prefer this method to fetch parameters.
Note: |s:Params()| returns a reference to the parameter if it makes
sense (|String|, |List|, |Dict|), the parameter is inserted in the
parameter stack with the default value specified, it didn't exist
before.
|s:Params()| takes 2 parameters:
- the parameter name
- and the optional default value -- if not specified, it's assumed to be
`lh#marker#txt(parametername)`.
In order to support optional arguments, the arguments passed (to
|s:PushArgs()|, not to |s:Include()|), and fetched, shall be wrapped in a
|List|. An empty list will be equivalent the C void argument.
Beware of the non conventional behaviour when including skeletons one after
the other (and not one from within another): The arguments will be
resolved in reverse order. NB: This is not a feature, but a side-effect of
the dirty hack behing these functions. It's likelly to change to the far
future. I'd advice you to use recursivity instead of iteration when loop
are required. See the implementation of {switch} and {case} snippets.
Example: template/vim/raii.template and template/vim/finally.template >
" In template/vim/raii.template
VimL: call s:Include('finally', 'vim', {'cleanup': 'call cleanup.finalize()'})
" In template/vim/finally.template
try
<+s:Surround(1, s:Param('code', lh#marker#txt('code')))+>
finally
<+s:Surround(2, s:Param('cleanup', lh#marker#txt('cleanup')))+>
endtry
Q: "How can I return parameters and cache them from sub-skeleton?" *s:InjectInParentArgs()*
A: When a sub-skeleton is imported with |s:Include()|, we cannot store
information in |s:Args()| and expect it to remain once we return to the
_callee_.
`s:InjectInParentArgs()` is provided for this exact purpose.
Q: "How can I change the expression delimiters?" *s:value_start* *s:value_end*
A: Just change the special variables |s:value_start| and |s:value_end|.
Doing so can help us release the default latin1 character used (¡ ==
Spanish inverted exclamation mark). I must admit I do not know how the
character 0xa1 translates in other encodings.
Any string is fine here. As long it is not expected to have it plainly
written in the template-file. For instance, avoid '{' and '}' in C++ code
snippets.
Note: this option is not just cosmetic, it enables us to have a
template-file used in different 'encoding's. See also |MuT-encodings|.
>
VimL: let s:value_start = '%((('
VimL: let s:value_end = '%)))'
Creation date: %(((strftime(%c)%)))
< Note: You can also embed expression into placeholders/marker as long as
they are a valid expression -- this feature can be disabled with
|s:dont_eval_markers|
Q: "How can I disable the evaluation of expressions within *s:dont_eval_markers*
markers/placeholders?"
A: In the template-files where you don't want marker-texts to be evaluated (as
VimL-|expression|, set |s:dont_eval_markers| to 1. You may want to reset it
to its previous value at the end of the template file (in case it is
included by another template that requires the support of that kind of
evaluation)
Q: "How comments are written in the template-file?" *MuT-comments*
A: "VimL:" introduces Ex commands (|MuT-intruction|). This means comments
are lines starting with a double |:quote|. >
VimL:" This is a comment that won't be inserted.
Q: "I want to use expressions that expands on several *MuT-multilines*
lines, but mu-template keeps doing funny things: it joins lines that
should not"
A: Be sure the expression to expand does not end with a "\n". You may want to
append a neutral space. >
VimL: let s:expr = "first line\nsecond line\n "
text ¡s:expr¡
text
< «todo: check if it concerns every ending \n, or only strings strictly equal to "\n"»
*MuT-loops* *MuT-instruction-injection*
*s:Inject()* *s:InjectAndTransform()*
You can also inject text (or even |MuT-instruction|) into |s:content| with: >
VimL: call s:Inject(["list", "of", "lines"]
< You can also define complex functions in |autoload| plugins instead, or
even use |s:Include()| recursively or not, but that would be code
obfuscation.
Q: "How can I make CVS/Subversion ignore special tags *MuT-RC-tag$*
in a template-file?"
A: There is a nasty trick accomplished with |MuT-expression|: >
¡'$'¡Id$
Q: "How can I use template-files from another filetype?" *MuT-inherit-ft*
A: Set the corresponding |g:mt_inherited_ft_for_{filetype}| variable in your
|.vimrc|.
Example, to accept all xml template-files when editing xslt files: >
let g:mt_inherited_ft_for_xslt = 'xml'
Q: "When I expand my template-file, I get funny characters" *MuT-funny-chars*
A: If your |MuT-expression|s are not expanded, be sure to:
- explicitly set |s:value_start| and |s:value_end|
- save your template-file in utf-8 (see next Q/A)
If the text you want to insert contains non ASCII characters and that your
are not working in latin1, nor in utf-8. I'm afraid I have no answer yet.
Anyway, let me know.
Q: "I want to write a template-file, but I do not succeed to *MuT-encoding*
have a utf-8 file."
A: To save your template-file in utf-8, save it with >
:w ++enc=utf-8
< See |++enc|, 'encoding', and |MuT-encodings|
Q: "How can I refer to the root of my current project?" *s:path_from_root()*
A: First you'll need a way to define project-specific informations. Plugins
like |project.vim| or |MuT-local_vimrc| will help you define the
project-specific variable *b:sources_root* -- note: so far only
|MuT-local_vimrc| will be able to set that variable before the
template-file is expanded, hence I recommend its use over |project.vim|
regarding this particular task.
Finally, in your template-files, you'll be able to refer to this variable
thanks to the muT-function |s:path_from_root()|.
Remark: |lh-vim-lib| provides functions that helps manipulate and transform
pathnames (see |lhvl#path|)
Q: "Which is the line number of the current line in the final buffer?" *s:Line()*
A: This information can be obtained thanks to a call to |s:Line()|
Q: "How may I know the content of the lines being expanded?" *s:content*
A: The |Dictionary| |s:content| contains the lines already interpreted, and
those that will be. Its fields are:
- "`lines`": a |List| of all the lines,
- "`start`": line number where the first line of a:content.lines will be
inserted,
- "`first_line_indented`": line number where the indentation starts,
- "`crt_indent`": current indent value (used in Python)
- "`crt`": number of the line being currently interpreted,
- "`callbacks`": stored the |MuT-post-expand-hooks|,
- "`variables`": list of variables to clear,
- "`scope`": used to implement |MuT-if| and so on,
- "`can_apply_style`": tells whether |lhdev-style| shall be applied,
- Surrounding related fields (|MuT-surround|):
- "`count0`": which stores |v:count| when surrounding selection,
- "`surround`{n}]": surround id internally used (may be deprecated),
- "`is_surrounding`": tells whether we are surrounding a selection.
NB: This is an implementation detail. This can be deprecated at any moment.
Q: "How to define a snippet that surrounds the current selection?" *s:Surround()*
A: You can use the `s:Surround()` function that takes two parameters:
- a surround-id tied to the count passed to the mapping (see |MuT-surround|),
- and a default text in case no surrounding is done (snippet used in
INSERT-mode, or with an incompatible count).
For instance, |C-if| snippet looks like:
>
if (¡s:Surround(2,'<+cond+>')¡) {
¡s:Surround(1,'<+code+>')¡
}<++>
Q: "How to have indenting style applied on separated lines?" *s:mut_merge_next_line*
A: Sometimes we cannot have two lines merged in a snippet, but still want to
apply styling options on bot line. A typical scenario would be: >
VimL: Some first snippet
auto a_function()
VimL: call s:Include('anothersnippet', 'cpp', arg)
VimL: The other snippet
VimL: let s:mut_merge_next_line = 1 " <<---- what makes the difference!!
{return expression;}
Than depending on the style used (|:UseStyle|), this could be translated into:
- with `:UseStyle -b indent_brace_style=java`: >
auto a_function() {
return expression;
}
- with `:UseStyle -b indent_brace_style=allman`: >
auto a_function()
{
return expression;
}
------------------------------------------------------------------------------
{{{2 Encoding issues ~
*MuT-encodings*
After many trials and errors, I came up to the conclusion that template-files
must be encoded in utf-8. Whatever 'encoding' we are running vim within.
So far, this approach has been successfully tested on:
- a Windows XP box, with vim compiled with |+multi_byte|, in latin1 as well as
in utf-8
- a Sun Solaris system, with vim not compiled with |+multi_byte|
- Linux systems
I had partially successful results on my French XP box, with vim running in
latin2.
- |MuT-expression|s were correctly expanded (with |s:value_start| and
|s:value_end| both set to a non ASCII character)
- Simplified textual placeholders (|MuT-<++>|) were correctly replaced with my
non ASCII marker characters («»).
- However, non ASCII characters (even «») were not correctly translated in
latin2. In latin1, I had no such problems.
Please note that my version of vim is compiled with |+iconv/dyn|. However,
neither `has('iconv')`, nor `has('iconv/dyn')` return 1.
The completely unsuccessful approach was to have the template-file in latin1,
and load them in a buffer while being in utf-8. To be more exact, it worked
only with |s:value_start| and |s:value_end| set to plain ASCII characters (1
or more characters coded on 7bits) -- in that case, the main difficulty is to
avoid meaningful characters like `!` in C template-files.
THIS MEANS
As a consequence, do not try to have non-utf-8 template-files that contain
non-ASCII characters.
*s:fileencoding*
If you need to insert non-ASCII characters with a template-file, tell
mu-template to convert all the lines expanded to the current encoding by
setting: >
VimL: let s:fileencoding = 'utf-8'
However ...
WARNING~
... if vim is not compiled with |+multi_byte| support, template expansion will
still work correctly (even with template-files in utf-8), however NON-ASCII
characters cannot be converted. If you need such characters in your
template-files, save them in the encoding you are using with vim.
------------------------------------------------------------------------------
{{{2 Reserved symbols ~
*MuT-reserved-symbols*
Several symbols are reserved and you must NOT use them in your template-files.
The correct execution of the plugin can not be guarantied otherwise.
The (non) exhaustive list of the reserved symbols is:
- s:content, s:r, s:NeedToJoin
- s:menu_prio, s:menu_name, s:AddMenu(), s:BuildMenu(),
- s:Interpret(), s:InterpretValues(), s:InterpretValue(),
s:InterpretCommand(), s:InterpretLines(),
- s:Template(), s:TemplateDirs(), s:LoadTemplate s:SearchTemplates(),
- s:Option().
- s:NoRegex(), s:Marker(), s:Value(), s:Command(), s:Special(), s:Comment()
Moreover, all `s:` variables starting will a double underscore will be reserved.
==============================================================================
CONFIGURATION *MuT-config* {{{1
{{{2 Options ~
*b:mt_how_to_join* *g:mt_how_to_join*
Used only with |i_CTRL-R_TAB|.
== 0 : "{pattern}^r\t foo" -> "{the template}\nfoo"
== 1 : "{pattern}^r\t foo" -> "{the template} foo"
== 2 : "{pattern}^r\t foo" -> "{the template}«» foo"
|b:mt_jump_to_first_markers| |g:mt_jump_to_first_markers| (bool; default 1)
Specifies whether we want to automatically jump to the first |marker|
inserted. Mainly aimed at |ftplugin| writers who wish to be compatible
with µTemplate.
*g:mt_IDontWantTemplatesAutomaticallyInserted* (boolean; default: 0)
Forbids µtemplate from automatically inserting template-files when
opening new files.
*g:mt_menu_priority* (number/string; default: 59)
*g:mt_menu_name* (string; default: "&Templates")
These two options enable µTemplate's menu to be placed wherever we wish
it to be. For instance: >
let g:mt_menu_priority = '40.700'
let g:mt_menu_name = '&Tools.Templates'
< Must be set once before mu-template.vim is sourced -> .vimrc
|g:mt_chooseWith| (string; "complete"/"confirm"; default: "complete")
Specifies how the user will choose which snippet must be inserted when
there is an ambiguity.
------------------------------------------------------------------------------
{{{2 Mappings ~
*<Plug>MuT_ckword*
*<Plug>MuT_cWORD*
*<Plug>MuT_Surround*
To override the default INSERT-mode, and VISUAL-mode mappings used to insert
and expand template-files, choose a key sequence that suits you best, and map
it to:
|<Plug>MuT_ckword|,|<Plug>MuT_cWORD|, or |<Plug>MuT_Surround| in your |.vimrc|.
e.g. >
imap ` <Plug>MuT_cWORD
imap ² <Plug>MuT_ckword
vmap <c-space> <Plug>MuT_Surround
Note: if you have installed COC, don't use these mappings and let COC be a
front-end for µTemplate. See |MuT-COC|.
==============================================================================
DESIGN CONSIDERATIONS *MuT-design* {{{1
Out there, there are several other template-expander plugins that use a
predefined set of "expandable" tags.
µTemplate, on the contrary, does not use any predefined set of tags. Instead,
it expands VimL |expression|s and interprets VimL commands. Thus, we can
expand almost any kind of tags we wish to. Our possibilities are limited only
by VimL.
The default template-files, shipped with the vimball archive, are also best
placed into a `{rtp}/after/` directory. Thus, it leaves us the possibility to
override them. See |MuT-paths|.
µTemplate uses some other plugins. I (LH)'d rather use one (even complex) plugin
that defines a feature I need in several places, instead of copying an
over-simplified and limited version of the functions defined in that plugin in
every other (ft)plugin that need this specific feature.
In other words, I prefer modularity over redundancy. That's why µTemplate
depends on other plugins.
==============================================================================
FILES *MuT-files* {{{1
Mu-Template depends on:
- |lh-vim-lib|
- |lh-brackets|
- |lh-dev|
Mu-Template takes advantage of:
- |searchInRuntime|
- |stakeholders|
==============================================================================
OTHER PLUGINS OF INTEREST *MuT-external-plugins* {{{1
|stakeholders.txt| *MuT-stakeholders*
<http://www.vim.org/scripts/script.php?script_id=3326>
<http://github.com/tomtom/stakeholders_vim>
stakeholders is the plugin that will change your mu-template experience.
Thanks to it, identical placeholders will be modified simustaneously.
Just install it and enjoy. The template-file c/fori exploits Tom Link's
plugin.
If you don't want to take advantage of stakeholders and yet install it, just
set *g:mt_use_stakeholders* to 0 in your .vimrc.
In case you are using several template/snippets expanders plugins that exploit
stakeholders, be sure to use the same syntax for the placeholders (see
|:SetMarker|)
|local_vimrc| *MuT-local_vimrc*
<http://github.com/LucHermitte/local_vimrc>
mu-template is able to take advantage of local_vimrc plugins that expose a
*:SourceLocalVimrc* command. Thanks to this command, some project variables,
like |b:sources_root|, can be set before a new |buffer| is created.
|lh-cpp-readme| *MuT-lh-cpp*
<http://github.com/LucHermitte/lh-cpp>
Note: This set of ftplugins contains many C&C++ specific code-snippets that
are not shipped with mu-tempate.
|coc-nvim.txt| *MuT-COC*
<https://github.com/neoclide/coc.nvim>
µTemplate can register itself as a |coc-custom-source|. Actually if COC is
detected after Vim has been started, µTemplate will try to avoid to register
any keybinding to |<Plug>MuT_ckword| and |<Plug>MuT_cWORD|. Selection of the
snippet to expand will be taken care of by COC.
Moreover, µTemplate historic selection of snippets to complete seems to be
incompatible with COC (or the other way around...) and typed characters may
be scrambled. That's why it's preferable to rely entirelly on COC to select
snippets, when both are installed.