" File: snippetsEmu.vim " Author: Felix Ingram " ( f.ingram.lists@gmail.com ) " Description: An attempt to implement TextMate style Snippets. Features include " automatic cursor placement and command execution. " Last Change: Tuesday July 11th 2006 " Version: 0.5.4 " " This file contains some simple functions that attempt to emulate some of the " behaviour of 'Snippets' from the OS X editor TextMate, in particular the " variable bouncing and replacement behaviour. " " USAGE: " " Place the file in your plugin directory. " Define snippets using the Iabbr command which takes similar arguments to the " built in iabbr command. " Snippets are best defined in the 'after' subdirectory of your Vim home " directory ('~/.vim/after' on Unix). Filetype specific snippets can be defined " in '~/.vim/after/ftplugin/_snippets.vim. Using the argument will " restrict the abbreviations to the filetype only. " " Example One: " Iabbr fori for in :.<> " " The above will expand to the following (indenting may differ): " " for in : " .<> " " The cursor will be placed after the first < in insert mode. " Pressing will 'tab' to the next place marker () in " insert mode. Adding text between < and > and then hitting will " remove the angle brackets and replace all markers with a similar identifier. " " Example Two: " With the cursor at the pipe, hitting will replace: " for in : " .<> " " with (the pipe shows the cursor placement): " " for MyVariableName in : " MyVariableName.<> " " Enjoy. " " Additional Features: " " Commands in tags. Anything after a ':' in a tag will be run with Vim's " 'execute' command. The value entered by the user (or the tag name if no change " has been made) is passed in the @z register (the original contents of the " register are restored once the command has been run). " " Named Tags. Naming a tag (the tag in the example above) and changing " the value will cause all other tags with the same name to be changed to the " same value (as illustrated in the above example). Not changing the value and " hitting will cause the tag's name to be used as the default value. " " TextMate 'compatibility'. New since 0.5. Setting the variable " 'g:snip_set_textmate_cp' to '1' will change how the plugin operates. Snippets " will not be expanded automatically, instead the user must hit . If the " previous word was defined as a snippet then it's expanded. If there are still " active tags then the cursor is moved with replacements and commands being " performed as usual. If there is no snippet to expand and no active tags then a " is inserted. " The variable can be set in vimrc with the following command: " let g:snip_set_textmate_cp = 1 " " Multi-character start and end tags. Start and end tags can now be more than " one character in length. The main advantage of this is that a single set of " tags can be defined which will work on the majority of filetype. For example, " the default settings of '<' and '>' work for most languages except HTML " (and Visual Basic: do you know why?). You can now define tags such as '<{' and " '}>' (which probably break in some random web page template language but you " get the idea). " " Known Bugs: " " If the abbreviation starts with a tag and is inserted at the start of the line " then the cursor will not be placed in the correct tag. " " FIXED Empty tag replacement. Changing an empty tag will change all remaining " empty tags " " FIXED Short variable names. Having a single character in the tags will mess up " the insert point. " " FIXED Autoindentation breaks and too much whitespace can be swallowed. " Caused by using 'i' instead of 'a' in the redefined command. " " Test tags for pattern matching: " The following are examples of valid and invalid tags. Whitespace can only be " used in a tag name if the name is enclosed in quotes. " " Valid tags " <> " " " <:command> " <"Tag Name"> " <"Tag Name":command> " @@ " @tagName@ " @tagName:command@ " @:command@ " @"Tag Name"@ " @"Tag Name":command@ " " Invalid tags, random text " <:> " " " <"Tag Name":> " " ' as our tag delimiters: " <\([^[:punct:] \t]\{-}\|".\{-}"\)\(:[^>]\{-1,}\)\?> if exists('loaded_snippet') || &cp finish endif let loaded_snippet=1 " {{{ Set up variables if !exists("g:snip_start_tag") let g:snip_start_tag = "<" endif if !exists("g:snip_end_tag") let g:snip_end_tag = ">" endif if !exists("g:snip_elem_delim") let g:snip_elem_delim = ":" endif let s:just_expanded = 0 " }}} " {{{ Map Jumper to the default key if not set already if ( !hasmapto( 'Jumper', 'i' ) ) if exists("g:snip_set_textmate_cp") && g:snip_set_textmate_cp == 1 imap Jumper else imap Jumper endif endif if exists("g:snip_set_textmate_cp") && g:snip_set_textmate_cp == 1 imap