~sirver/ultisnips/trunk

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
*UltiSnips.txt*  The Ultimate Plugin for snippets in Vim.

UltiSnips                                      *snippet* *snippets* *UltiSnips*

1. Description                                  |UltiSnips-description|
2. Installation and Updating                    |UltiSnips-installnupdate|
3. Settings & Commands                          |UltiSnips-settings|
   3.1 Commands                                 |UltiSnips-commands|
   3.2 Triggers                                 |UltiSnips-triggers|
   3.3 Snippet Search Path                      |UltiSnips-snippet-search-path|
   3.4 Warning About Select Mode Mappings       |UltiSnips-warning-smappings|
   3.5 Functions                                |UltiSnips-functions|
      3.5.1 UltiSnips_AddSnippet                |UltiSnips_AddSnippet|
      3.5.2 UltiSnips_Anon                      |UltiSnips_Anon|
4. Syntax                                       |UltiSnips-syntax|
   4.1 Adding Snippets                          |UltiSnips-adding-snippets|
      4.1.1 Character Escaping                  |UltiSnips-character-escaping|
   4.2 Plaintext Snippets                       |UltiSnips-plaintext-snippets|
   4.3 Visual Placeholder                       |UltiSnips-visual-placeholder|
   4.4 Interpolation                            |UltiSnips-interpolation|
      4.4.1 Shellcode                           |UltiSnips-shellcode|
      4.4.2 VimScript                           |UltiSnips-vimscript|
      4.4.3 Python                              |UltiSnips-python|
      4.4.4 Global Snippets                     |UltiSnips-globals|
   4.5 Tab Stops and Placeholders               |UltiSnips-tabstops|
   4.6 Mirrors                                  |UltiSnips-mirrors|
   4.7 Transformations                          |UltiSnips-transformations|
      4.7.1 Replacement String                  |UltiSnips-replacement-string|
      4.7.2 Demos                               |UltiSnips-demos|
   4.8 Clearing snippets                        |UltiSnips-clearing-snippets|
5. Helping out                                  |UltiSnips-helping|      
6. Contact                                      |UltiSnips-contact|      
7. Contributors                                 |UltiSnips-contributors|
   7.1 Patches & Coding                         |UltiSnips-contricoding|
   7.2 Snippets                                 |UltiSnips-contrisnippets|

For Vim version 7.0 or later.
This plugin only works if 'compatible' is not set.
{Vi does not have any of these features}

This plugin needs Python support >= 2.6 compiled into Vim.

=============================================================================
DESCRIPTION                                           *UltiSnips-description*

UltiSnips aims to provide a snippets solution that users came to expect from
editors. A Snippet is a short piece of text which is either typed very often
or which contains a lot of redundant text. Such snippets are very often
encountered in structured text like Source Code but I also use them for email
signatures and to insert the current date or time into the text while typing.

UltiSnips is an implementation that is developed with in the philosophy of TDD
(Test driven development). This guarantees that features do not disappear and
bugs do not reappear after they have been fixed once.

You can learn what UltiSnips can do by watching some short screencasts and
reading the accompanying blog posts on my blog:

http://www.sirver.net/blog/2011/12/30/first-episode-of-ultisnips-screencast/
http://www.sirver.net/blog/2012/01/08/second-episode-of-ultisnips-screencast/
http://www.sirver.net/blog/2012/02/05/third-episode-of-ultisnips-screencast/


 Acknowledgments:                                 *UltiSnips-acknowledgments*

UltiSnips is inspired by the snippets solution implemented in TextMate
(http://macromates.com/). The idea of implementing snippets for vim is not new
and I want to thank Michael Sanders (Author of snipMate) for some
implementation details I stole from him and for the permission to use some of
his snippets.

=============================================================================
2. INSTALLATION AND UPDATING                       *UltiSnips-installnupdate*

To use UltiSnips, you need a python enabled Vim 7. You have python if either
   :echo has("python") or :echo has("python3")
yields '1'. Recent versions have been tested with python 2.7 and python 3.2,
theoretically, UltiSnips should work with all versions >= python 2.6.

UltiSnips tries to autodetect which Vim Python command to use (there are two:
:py and :py3). Unfortunately, some Vim versions choke when you test for both
versions. In this case you have to tell UltiSnips which version to use via >
   
   let g:UltiSnipsUsePythonVersion = 2   " or 3

Using Pathogen:                                     *UltiSnips-using-pathogen*

If you are a Pathogen user, you can track the official mirror of UltiSnips on github: >

   $ cd ~/.vim/
   $ git submodule add https://github.com/sirver/ultisnips bundle/ultisnips

See the pathogen documentation how to update a bundle.

Using Bzr:                                               *UltiSnips-using-bzr*

To track the main repository on github, you will need bzr
(http://bazaar-vcs.org/). It is in all major linux distribution (either
package bzr or bazaar) and can be easily installed under Mac OS X: >
   $ pip install bzr

To get UltiSnips, check it out into a directory of your choice. Then add this
directory to your Vim runtime path: >
   $ cd ~/.vim/
   $ bzr get lp:ultisnips ultisnips_rep
   $ vim ~/.vimrc

add the line: >
   set runtimepath+=~/.vim/ultisnips_rep

Restart vim. UltiSnips should work now. To access the help, use >
   :helptags ~/.vim/ultisnips_rep/doc
   :help UltiSnips

To Update an installation, simply pull the latest revision: >
   $ cd ~/.vim/ultisnips_rep
   $ bzr pull

Using a downloaded packet:               *UltiSnips-using-a-downloaded-packet*

See UltiSnips-using-bzr. Just unpack into a directory of your choice and add
the path to runtimepath.

=============================================================================
3. SETTINGS                                              *UltiSnips-settings*

3.1 Commands                                             *UltiSnips-commands*
------------

                                                             *:UltiSnipsEdit*
UltiSnipsEdit opens or creates your private snippet definition file for the
current filetype. You can easily open them manually of course, this is just a
shortcut. There is also a variable called: >
   g:UltiSnipsEditSplit
which can be set to "normal" (default), "horizontal" or "vertical" that
defines if a new window should be opened for the edit. There is also a
variable called: >
   g:UltiSnipsSnippetsDir
that, when set to a directory like "~/.vim/mydir/UltiSnips", becomes the base
directory for the snippet file to open. For example, if it is set to
"~/.vim/mydir/UltiSnips" and the current 'filetype' is "cpp", then
:UltiSnipsEdit will open "~/.vim/mydir/UltiSnips/cpp.snippets".

3.2 Triggers                                             *UltiSnips-triggers*
------------

You can freely define the keys used to expand a snippet and jump forward and
backwards in it. There is also a key to list all snippets available for the
current expand situation. The variables with the default values are: >
   g:UltiSnipsExpandTrigger               <tab>
   g:UltiSnipsListSnippets                <c-tab>
   g:UltiSnipsJumpForwardTrigger          <c-j>
   g:UltiSnipsJumpBackwardTrigger         <c-k>

It is possible to set the Expand and Forward trigger to the same value. You
can get a more TextMate like configuration by adding the next three lines to
your vimrc: >
   let g:UltiSnipsExpandTrigger="<tab>"
   let g:UltiSnipsJumpForwardTrigger="<tab>"
   let g:UltiSnipsJumpBackwardTrigger="<s-tab>"

3.3 Snippet Search Path                       *UltiSnips-snippet-search-path*
-----------------------

UltiSnips lets you override the name of the directories that are searched
for snippets. You need to set the variable g:UltiSnipsSnippetDirectories,
which defaults to: >
   g:UltiSnipsSnippetDirectories          ["UltiSnips"]

Snippet definition files are searched in 'runtimepath', but the 'runtimepath'
variable is traversed in reversed order (last item first). If you would like
to have UltiSnips traverse this in proper order, add these to your vimrc: >
   let g:UltiSnipsDontReverseSearchPath="1"

In each directory, UltiSnips will search for the folder names in the order
they appear in g:UltiSnipsSnippetDirectories. If you keep your snippets in a
folder called "mycoolsnippets" in your .vim directory and you want the
snippets that ship with UltiSnips to be available as well, use >
   let g:UltiSnipsSnippetDirectories=["UltiSnips", "mycoolsnippets"]
If you do not want the shipped snippets to be available, only use
"mycoolsnippets".

By default, UltiSnips will check for updates to .snippets files whenever
it is activated. This behavior can be disabled as follows: >
   let g:UltiSnipsDoHash=0

See |UltiSnips-adding-snippet| for an introduction which files are parsed for
which file type.

3.4 Warning About Select Mode Mappings          *UltiSnips-warning-smappings*
--------------------------------------

The help for vim's |mapmode-s| states: >
   NOTE: Mapping a printable character in Select mode may confuse the user.
   It's better to explicitly use :xmap and :smap for printable characters.  Or
   use :sunmap after defining the mapping.

But most vim plugins (even the ones shipped with vim) do not adhere to this.
As UltiSnips uses select mode to mark tabstops in snippets for overwriting
these wrong mappings get in the way. UltiSnips therefore defaults to
|:sunmap| all mappings for printable characters in select mode. It will not
touch any other mappings, especially not normal, insert or visual mode
mappings.

If this behaviour is not desired, you can disable it via >
   let g:UltiSnipsRemoveSelectModeMappings = 0

If you want to keep certain mappings, you can modify the list of ignores for
this feature. For example >
   let g:UltiSnipsMappingsToIgnore = [ "somePlugin", "otherPlugin" ]

will not unmap any mapping that contains the string "somePlugin" or
"otherPlugin" in its complete definition as listed by |:smap|.


3.5 Functions                                           *UltiSnips-functions*
-------------

UltiSnips provides two functions for extending core functionality.

 3.5.1 UltiSnips_AddSnippet                            *UltiSnips_AddSnippet*

The first function is UltiSnips_AddSnippet(trigger, value, description,
options, ...) which adds a new snippet to the current list of snippets with
the provided trigger, value, description, and options, see |UltiSnips-syntax|
for details on the meaning of those. All of the arguments are strings. You can
also specify the filetype for the new snippet with the final optional
argument.

 3.5.2 UltiSnips_Anon                                        *UltiSnips_Anon*

The second function is UltiSnips_Anon(value, ...), which expands an anonymous
Snippet. The snippet that gets expanded doesn't get added to the global list
of snippets, so it can't be expanded a second time unless the function is
called again. The value argument is the same as |UltiSnips_AddSnippet|. There
are also optional arguments, which are 1) the trigger, 2) the description of
the snippet, and 3) the options. All of the optional arguments are the same as
the |UltiSnips_AddSnippet| function. The description is unused right now,
whereas the trigger and options can change the way the snippet expands.

This feature is frequently used in .vimrc. A typical use case from my
restructured text file looks like this:

   inoremap <silent> $$ $$<C-R>=UltiSnips_Anon(':latex:\`$1\`', '$$')<cr>

This expands the snippet whenever I type two $ signs. Note that In the right
hand site of the mapping, I retype the '$$' trigger and also inform UltiSnips
about the trigger; if I do not do this or give an empty trigger, vim will
trick UltiSnips by unreliably claiming that there is already one or zero '$'
signs before the snippet is expanded.

=============================================================================
4. SYNTAX                                                  *UltiSnips-syntax*

This chapter describes where to add new snippets and how to write them. I'll
provide many examples to make things clearer.

4.1 Adding Snippets                               *UltiSnips-adding-snippets*
-------------------

See |UltiSnips-snippet-search-path| for an explanation of where directories
with snippet definitions are expected.

UltiSnips follows the same search pattern that Vim itself uses when searching
for ftplugins: While iterating over the snippet definition directories found,
files are listed with the following glob patterns: ft.snippets, ft_*.snippets,
ft/*. ft is the current 'filetype', and the "*" matches anything, for example:
   ruby.snippets
   c.snippets
   c_mine.snippets
   c/a
   c/b.snippets
   perl.snippets
Those files are than traversed in order to gather snippet definitions for the
various file types. A special filetype is all, e.g.  >
   all.snippets
   all/a.snippets
which contains snippets that are always expanded, no matter what file type is
defined. For example, I keep mail signatures and date insertion snippets here.

The dotted file type syntax of vim is supported. For example, for my cpp or
CUDA files, I keep the file type set to ":set ft=cpp.c" or ":set
ft=cuda.cpp.c". This activates all snippets for each file type in the order
specified.

As an alternative, a snippet file may contain a line that looks like this: >
   extends ft1, ft2, ft3
For example, the first line in cpp.snippets looks like this: >
   extends c
This means, first search all snippets for c, then add the snippets from this
file. This is a convenient way to add more special cases to more general ones.
Multiple "extends" lines are permitted throughout the snippets file.

The snippets file format is simple. A line starting with # is a comment, each
snippet starts with a line in the form of: >
   snippet tab_trigger [ "description" [ options ] ]
The following lines are the snippets definition; a line starting with >
   endsnippet
marks the end of the snippet. The trailing newline is chopped from the
definition. In the starting line, the description and options are optional.

If you want to use a multi-word trigger, you can surround the trigger with any
single character on each side. e.g. >
    snippet "tab trigger" [ "description" [ options ] ]
or >
    snippet !"tab trigger"! [ "description" [ options ] ]
if you actually want to include the double-quote characters in the trigger.

The description is only needed when more than one snippet is defined with the
same tab trigger. The user is then given a choice and the description is
displayed for the user as helper.

The options is a word of characters, each turning a specific option for this
snippet on. The options currently supported are >
   !   Overwrite - This snippet will overwrite all previously defined
       snippets with this tab trigger. Default is to let the user choose at
       expansion which snippet to expand. This option is useful to overwrite
       bundled tab stops with user defined ones.
   b   Beginning of line - This snippet will only be expanded if you are at
       the beginning of a line (that is if there are only whitespaces in front
       of the cursor). Default is to expand snippets at every position, even
       in the middle of a line. Most of my snippets have this option set, it
       keeps UltiSnips out of the way.
   i   Inword expansion - Normally, triggers need whitespace before them to be
       expanded. With this option, triggers are also expanded in the middle of
       a word.
   w   Word boundary - Normally, triggers need whitespace before them to be
       expanded. With this option, the trigger will be expanded at a "word"
       boundary as well, where word characters are letters, digits, and the
       underscore character ('_').  This enables expansion of a trigger that
       adjoins punctuation (for example) without expanding suffixes of larger
       words.
   r   Regular expression - This uses a python regular expression for the
       match. The regular expression MUST be surrounded like a multi-word
       trigger (see above) even if it doesn't have any spaces. The resulting
       match is also passed to any python code blocks in your snippet
       definition as the local variable "match".
   t   Don't expand tabs - By default, UltiSnips tries to expand leading tabs
       in a snippet to match the results of automatic indentation. If this
       option is set, UltiSnips will not try to do this expansion, and will
       leave the tabs alone. This can be useful for snippets dealing with
       tab delimited formats, etc.
<

 4.1.1 Character Escaping:                             *UltiSnips-character-escaping*

In the snippet descriptions, various characters have special meaning
(e.g. '`{$\). If you want to insert any one of these characters literally,
prepend them with a single backslash (\).

4.2 Plaintext Snippets                         *UltiSnips-plaintext-snippets*
----------------------

Lets start with a simple example. Add this to your all snippets file: >
   ~/.vim/UltiSnips/all.snippets

------------------- SNIP -------------------
snippet bye "My mail signature"
Good bye, Sir. Hope to talk to you soon.
- Arthur, King of Britain
endsnippet
------------------- SNAP -------------------

UltiSnips will pick up that you added/changed this file automatically, so just
try it in insert mode:
bye<tab> -->
Good bye, Sir. Hope to talk to you soon.
- Arthur, King of Britain

4.3 Visual Placeholder                         *UltiSnips-visual-placeholder*
----------------------

Snippets can contain a special placeholder called ${VISUAL}. When you select
some text in visual mode and press the key to expand a trigger
(see g:UltiSnipsExpandTrigger) the selected text will get deleted and you will
drop to insert mode. The next snippet you expand will have the selected text
in the place of the ${VISUAL}. The place holder can also contain default text
when there is no visual text to be selected: ${VISUAL:default text}. And it
can also contain transformations on the contents of the visual (See
|UltiSnips-transformations| ). This will take the form
${VISUAL:default/search/replace/option}. 

As a small example, let's take this snippet. It will take the visual text,
replace all "should" via "is" and put it in.
------------------- SNIP -------------------
snippet t
<tag>${VISUAL:inside text/should/is/g}</tag>
endsnippet
------------------- SNAP -------------------
And starting with this line: >
   this should be cool
position the cursor on the should, then press viw (visual mode -> select inner
word). Then press tab, type "t" and press tab again >
   -> this <tag>is</tag> be cool
If you expand this snippet without having been in visual mode before, e.g. by
writing in insert mode t<tab>, you will get >
   <tag>inside text</tag>

4.4 Interpolation                                   *UltiSnips-interpolation*
-----------------

 4.4.1 Shellcode:                                         *UltiSnips-shellcode*

You can enter shellcode in your snippets in nearly all places. Shell code is
written to a script and then executed. The output is inserted into the snippet
instead of the shell code itself. Since the code is executed as a shell
script, you can use #!/bin/ notation to feed the input of your code to every
program you like. Let's consider an example that inserts the current date.

------------------- SNIP -------------------
snippet today
Today is the `date +%d.%m.%y`.
endsnippet
------------------- SNAP -------------------

today<tab> ->
Today is the 15.07.09.

Another example doing the same using perl
------------------- SNIP -------------------
snippet today
Today is `#!/usr/bin/perl
@a = localtime(); print $a[3] . '.' . $a[4] . '.' . ($a[5]+1900);`.
endsnippet
------------------- SNAP -------------------
today<tab> ->
Today is 15.6.2009.

 4.4.2 VimScript:                                         *UltiSnips-vimscript*

You can also use VimScript (also sometimes called VimL) in interpolation. This
works very much the same as interpolation of shellcode, expect that it must be
started by using `!v `. Let's consider a simple example, that counts the
indent of the current line:

------------------- SNIP -------------------
snippet indent
Indent is: `!v indent(".")`.
endsnippet
------------------- SNAP -------------------
    (note the 4 spaces in front): indent<tab> ->
    (note the 4 spaces in front): Indent is: 4.

 4.4.3 Python:                                               *UltiSnips-python*

By far the most powerful interpolation is by using python code. The syntax is
similar to the one for Vimscript, but in python code the value of the property
"rv" on the "snip" object is inserted at the position of the code. Also, the
code is inside a `!p ` block.  Python code gets some special variables defined
which can be used: >

   fn   - The current filename
   path - The complete path to the current file
   t    - The values of the placeholders, t[1] -> current text of ${1} and so on
   snip - Provides easy indentation handling.

The snip object provides the following methods: >

    snip.mkline(line="", indent=None):
        Returns a line ready to be appended to the result. If indent
        is None, then mkline prepends spaces and/or tabs appropriate to the
        current tabstop and expandtab variables.

    snip.shift(amount=1):
        Shifts the default indentation level used by mkline right by the
        number of spaces defined by shiftwidth, 'amount' times.

    snip.unshift(amount=1):
        Shifts the default indentation level used by mkline left by the
        number of spaces defined by shiftwidth, 'amount' times.

    snip.reset_indent():
        Resets the indentation level to its initial value.

    snip.opt(var, default):
        Checks if the vim variable "var" has been set, if so, it returns it,
        otherwise it returns "default".

The snip object provides some properties as well: >

    snip.rv:
        the text that will fill this python block's position, it always starts
        out as an empty string. This deprecates the "res" variable.

    snip.c:
        the text currently in the python block's position in the snippet
        in it. You can check if snip.c is != "" to make sure that the
        interpolation is only done once. This deprecates the "cur" variable.

   snip.v:
        information about the content for ${VISUAL}. Has two attributes:
         snip.v.mode   ('v', 'V', '^V', see *visualmode* )
         snip.v.text   the text that was selected

    snip.fn:
        the current filename.

    snip.basename:
        the current filename without it's extension.

    snip.ft:
        the current filetype.

The snip object also provides some operators to make python snippets
easier: >

    snip >> amount:
        is equivalent to snip.shift(amount)
    snip << amount:
        is equivalent to snip.unshift(amount)
    snip += line:
        is equivalent to "snip.rv += '\n' + snip.mkline(line)"

Any variables set in a python block can be used in any following blocks.
Also, the vim, re, os, string and random modules are already imported inside
the snippet code. This allows for very flexible snippets. For example, the
following snippet mirrors the first Tab Stops value on the same line in
uppercase and right aligned:

------------------- SNIP -------------------
snippet wow
${1:Text}`!p snip.rv = (75-2*len(t[1]))*' '+t[1].upper()`
endsnippet
------------------- SNAP -------------------
wow<tab>Hello World ->
Hello World                                                     HELLO WORLD

The following snippet is an example of the use of the match in snippets with
regular expression. It shows how to build snippets whose expansion depends
on the actual definition of the snippet which can vary:

------------------- SNIP -------------------
snippet "be(gin)?( (\S+))?" "begin{} / end{}" br
\begin{${1:`!p
snip.rv = match.group(3) if match.group(2) is not None else "something"`}}
	${2:${VISUAL}}
\end{$1}$0
endsnippet
------------------- SNAP -------------------
be<tab>center<c-j> ->
\begin{center}

\end{center}
------------------- SNAP -------------------
be center<tab> ->
\begin{center}

\end{center}

The second form is just a variation of the first one but, it serves as an
illustration of how to match groups in regular expressions but it has some 
drawbacks:
1. If you use <tab> for expanding the snippets and also for completion then
   if you were trying to use <tab> to complete "be form" to "be formatted"
   then you would end up with the above SNAP which is not what you want.
2. The snippet is harder to read.


 4.4.4 Global Snippets:                                   *UltiSnips-globals*

Global snippets provide a way to take common code out of snippets. Currently,
only python code is supported. The result of executing the contents of the
snippet is put into the globals of each python block in the snippet file. To
create a global snippet, you use the keyword "global" in place of "snippet",
and for python code, you use "!p" for the trigger, for example, the following
is identical to the previous example, except that "upper_right" can be reused:

------------------- SNIP -------------------
global !p
def upper_right(inp):
    return (75 - 2 * len(inp))*' ' + inp.upper()
endglobal

snippet wow
${1:Text}`!p snip.rv = upper_right(t[1])`
endsnippet
------------------- SNAP -------------------
wow<tab>Hello World ->
Hello World                                                     HELLO WORLD

Sometimes you want to have helper functions that are available in all your
snippet files. This is easily achieved using a global snippet and a python
module. First, add a search path to your python path by adding something along
this line to your vimrc: >

   py import sys; sys.path.append("/home/sirver/.vim/python")

Now use a global snippet in your snippet file to import modules from this
directory: >

   global !p
   from my_snippet_helpers import *
   endglobals

4.5 Tab Stops and Placeholders  *UltiSnips-tabstops* *UltiSnips-placeholders*
------------------------------

Very often, it is convenient to quickly add some text snippet and jump on to
the next point of interest. This is were tabstops come in:

------------------- SNIP -------------------
snippet jump
I $1 I was a $2.
$0
endsnippet
------------------- SNAP -------------------
jump<tab>wish<c-j>hunter<c-j>more text ->
I wish I was a hunter.
more text

You can use <c-j> and <c-k> to jump to the next tab or the previous. <Tab> was
not used for jumping forward because many people (like myself) use <tab> also
for completion. $0 is a special tab: This is the last tab in the snippet, no
matter how many tabs were defined before.

Most of the time it is more useful to have some default text for a tabstop and
sometimes it is also useful to have a tab stop in a tab stop. Consider the
next example which could be a real life scenario from a HTML snippet:

------------------- SNIP -------------------
snippet a
<a href="$1"${2: class="${3:link}"}>
    $0
</a>
endsnippet
------------------- SNAP -------------------

Here, $1 marks the first tabstop; it is assumed that you always want to add a
url as href. After entering it you jump to $2 which has the default text '
class="link"'. Now, you can either hit backspace, because you do not want to
enter a class attribute for this tag or you hit <c-j> to change the class name
(which is tab stop $3). When you are satisfied with the first line you hit
<c-j> again to finish this snippet and continue inside the anchor.

a<tab>http://www.google.com<c-j><BS><c-j>hi ->
<a href="http://www.google.com">
	hi
</a>

a<tab>http://www.google.com<c-j><c-j>visited<c-j>hi ->
<a href="http://www.google.com" class="visited">
	hi
</a>

Default tab stop text can also contain mirrors, transformations or
interpolation.

4.6 Mirrors                                               *UltiSnips-mirrors*
-----------

Mirrors simply repeat the content of a tabstop. A classical example would be a
TeX Environment which needs a \begin{} and an \end{} tag:

------------------- SNIP -------------------
snippet env
\begin{${1:enumerate}}
    $0
\end{$1}
endsnippet
------------------- SNAP -------------------
env<tab>itemize ->
\begin{itemize}

\end{itemize}

Another typical example is #ifndef block in C code:
------------------- SNIP -------------------
snippet ifndef
#ifndef ${1:SOME_DEFINE}
#define $1
$0
#endif /* $1 */
endsnippet
------------------- SNAP -------------------
ifndef<tab>WIN32 ->
#ifndef WIN32
#define WIN32

#endif /* WIN32 */

4.7 Transformations                               *UltiSnips-transformations*
-------------------

A complete description of the features follows, the chapter closes with some
demos, because this feature is rather mighty and hard to understand.

Transformations are like mirrors. But instead of just verbatim copying text
from the original tab stop, a regular expression is matched to the content of
the referenced tab stop and a transformation is then applied to the matched
pattern. UltiSnips follows the syntax and features of TextMate very closely
here.

A Transformation has the syntax >
   ${<tab stop no/regular expression/replacement/options}

with >
   tab stop no        - The number of the tab stop to reference
   regular expression - The regular expression to match to the value of the
                        tab stop
   replacement        - The replacement string, see below
   options            - options for the regular expression

The options can be any combination of >
   g    - global replace, replaces all matches of the regular expression, not
        just the first

Regular expressions are not handled here. Python regular expressions are used
internally, so the reference for matching is the re module of python:
   http://docs.python.org/library/re.html

The replacement string is using a own syntax and is handled in the next paragraph.

 4.7.1 Replacement String:                       *UltiSnips-replacement-string*

The replacement string can contain $no variables to reference matched groups
in the regular expression, $0 is special and yields the whole match. The
replacement string can also contain special escape sequences: >
   \u   - Uppercase next letter;
   \l   - Lowercase next letter
   \U   - Uppercase everything till the next \E
   \L   - Lowercase everything till the next \E
   \E   - End upper or lowercase started with \L or \U
   \n   - A newline
   \t   - A literal tab

Last, but not least the replacement string might contain conditional
replacements with the following syntax (?no:text:other text). This reads as
follows: if the group $no has matched, insert "text", otherwise insert "other
text". "other text" could be skipped and would default to "", that is the
empty string. This is a very powerful feature to add optional text into
snippets.

 4.7.2 Demos:                                                 *UltiSnips-demos*

The transformations are very powerful but yield often a convoluted snippet
syntax. Therefore I offer for each feature a simple example below.

This shows uppercasing one character
------------------- SNIP -------------------
snippet title "Titelize in the Transformation"
${1:a text}
${1/\w+\s*/\u$0/}
endsnippet
------------------- SNAP -------------------
title<tab>big small ->
big small
Big small


This shows uppercasing one character and global replace:
------------------- SNIP -------------------
snippet title "Titelize in the Transformation"
${1:a text}
${1/\w+\s*/\u$0/g}
endsnippet
------------------- SNAP -------------------
title<tab>this is a title ->
this is a title
This Is A Title

This is a clever c-like printf snippet, the second tabstop is only shown
when there is a format (%) character in the first tab stop.
------------------- SNIP -------------------
snippet printf
printf("${1:%s}\n"${1/([^%]|%%)*(%.)?.*/(?2:, :\);)/}$2${1/([^%]|%%)*(%.)?.*/(?2:\);)/}
endsnippet
------------------- SNAP -------------------
printf<tab>Hello<c-j> // End of line ->
printf("Hello\n"); // End of line

But
printf<tab>A is: %s<c-j>A<c-j> // End of line ->
printf("A is: %s\n", A); // End of line


There are many more examples of what can be done with transformations in the
bundled snippets.

 4.8 Clearing snippets                          *UltiSnips-clearing-snippets*

To remove snippets for the current file type, use the "clearsnippets"
directive:
------------------- SNIP -------------------
clearsnippets
------------------- SNAP -------------------

Without arguments, "clearsnippets" removes all snippets defined so far for the
current file type.  UltiSnips travels in reverse along the 'runtimepath', so
"clearsnippets" removes snippet definitions appearing later in the
'runtimepath' than the ".snippets" file in which it's encountered.

Instead of clearing all snippets for the current file type, one or more
individual snippets may be cleared by specifying a space-separated list of
their triggers, e.g.:

------------------- SNIP -------------------
clearsnippets trigger1 trigger2
------------------- SNAP -------------------

This is useful if you only want to override a few triggers or all triggers
that came with UltiSnips with your own definitions. Note that you can
overwrite individual triggers when redefining them using the '!' option
(see |UltiSnips-adding-snippets| for the options).

=============================================================================
5. HELPING OUT                                            *UltiSnips-helping*

UltiSnips needs the help of a vibrant vim community to make it more useful
tomorrow than it is today. Please consider joining this effort by providing
new snippets, new features or bug reports.

You can contribute by fixing or reporting bugs in our issue tracker:
https://bugs.launchpad.net/ultisnips

You can contribute snippets or patches in various ways. Here are the
possibilities in order of convenience for me (please be as convenient as you
can be):

* Clone the repository on launchpad (bzr clone lp:ultisnips), make fixes, push
  the branch and send a merge request on launchpad.
* Clone the repository on GitHub (git clone git@github.com:SirVer/ultisnips.git),
  make your changes and send a pull request on GitHub.
* Make a patch, report a bug/feature request and attach the patch to it.
* Send me an Email with a patch.
* Send me an Email with the changed files only.

If you like this plugin, please also vote for it on its vim script page. It is
life changing for me, maybe it is for you too.
You can find the page here:
http://www.vim.org/scripts/script.php?script_id=2715

=============================================================================
6. CONTACT                                                *UltiSnips-contact*

You can reach me at SirVer -AT- gmx -ADOT- de. You can find the launchpad
project for UltiSnips at https://launchpad.net/ultisnips/, there is also the
bug tracker.

This project aims to be the one-for-all solution for Snippets for Vim. If you
miss a feature or find a bug, please contact me or file a support ticket.

=============================================================================
7. CONTRIBUTORS                                      *UltiSnips-contributors*

UltiSnips is mainly developed by SirVer (Holger Rapp). The following
individuals have contributed code to UltiSnips. In order of apperance.

7.1 Patches & Coding                                 *UltiSnips-contricoding*
--------------------

Contributers are listed in chronological order:

   JCEB - Jan Christoph Ebersbach
   Michael Henry
   Chris Chambers
   Ryan Wooden
   rupa - Rupa Deadwyler
   Timo Schmiade
   blueyed - Daniel Hahler
   expelledboy - Anthony Jackson
   allait - Alexey Bezhan
   peacech - Charles Gunawan
   guns - Sung Pae
   shlomif - Shlomi Fish
   pberndt - Phillip Berndt
   thanatermesis-elive - Thanatermesis
   rico-ambiescent - Rico Sta. Cruz
   Cody Frazer
   suy - Alejandro Exojo
   grota - Giuseppe Rota

7.2 Snippets                                       *UltiSnips-contrisnippets*
------------

Contributers are listed in chronological order:

   Alec Thomas
   Ryan Wooden
   Ches Martin
   Gordin (g0rdin)
   Jan Mollowitz (phux)
   Georgi Valkov (gvalkov)
   Miek Gieben (miek)
   Aldis Berjoza (graudeejs)
   Jorge (skeept)
   Martin Grenfell (scrooloose)

vim:tw=78:ts=8:ft=help:norl: