From 48b5d02a89d444096bfff210430d1e5f6e194bb6 Mon Sep 17 00:00:00 2001 From: Michael Sanders Date: Wed, 25 Feb 2009 15:02:34 -0500 Subject: [PATCH] significantly refactored code, and added support for file-based snippets and delimeters before snippet triggers. --- README | 0 after/ftplugin/c_snips.vim | 6 +- after/ftplugin/html_snips.vim | 8 +- after/ftplugin/java_snips.vim | 4 +- after/ftplugin/javascript_snips.vim | 4 +- after/ftplugin/objc_snips.vim | 26 +- after/ftplugin/perl_snips.vim | 4 +- after/ftplugin/php_snips.vim | 4 +- after/ftplugin/python_snips.vim | 10 +- after/ftplugin/ruby_snips.vim | 4 +- after/ftplugin/sh_snips.vim | 4 +- after/ftplugin/tex_snips.vim | 16 +- after/plugin/snipMate.vim | 14 +- doc/snipMate.txt | 47 +- plugin/snipMate.vim | 818 +++++++++++++---------- snip/after/ftplugin/c_snips.vim | 56 -- snip/after/ftplugin/html_snips.vim | 94 --- snip/after/ftplugin/java_snips.vim | 41 -- snip/after/ftplugin/javascript_snips.vim | 37 - snip/after/ftplugin/objc_snips.vim | 54 -- snip/after/ftplugin/perl_snips.vim | 37 - snip/after/ftplugin/php_snips.vim | 67 -- snip/after/ftplugin/python_snips.vim | 28 - snip/after/ftplugin/ruby_snips.vim | 167 ----- snip/after/ftplugin/sh_snips.vim | 11 - snip/after/ftplugin/tex_snips.vim | 49 -- snip/after/ftplugin/vim_snips.vim | 16 - snip/after/plugin/global_snips.vim | 8 - snip/after/plugin/snipMate.vim | 23 - snip/doc/snipMate.txt | 258 ------- snip/plugin/snipMate.vim | 557 --------------- 31 files changed, 552 insertions(+), 1920 deletions(-) delete mode 100644 README delete mode 100644 snip/after/ftplugin/c_snips.vim delete mode 100644 snip/after/ftplugin/html_snips.vim delete mode 100644 snip/after/ftplugin/java_snips.vim delete mode 100644 snip/after/ftplugin/javascript_snips.vim delete mode 100644 snip/after/ftplugin/objc_snips.vim delete mode 100644 snip/after/ftplugin/perl_snips.vim delete mode 100644 snip/after/ftplugin/php_snips.vim delete mode 100644 snip/after/ftplugin/python_snips.vim delete mode 100644 snip/after/ftplugin/ruby_snips.vim delete mode 100644 snip/after/ftplugin/sh_snips.vim delete mode 100644 snip/after/ftplugin/tex_snips.vim delete mode 100644 snip/after/ftplugin/vim_snips.vim delete mode 100644 snip/after/plugin/global_snips.vim delete mode 100644 snip/after/plugin/snipMate.vim delete mode 100644 snip/doc/snipMate.txt delete mode 100644 snip/plugin/snipMate.vim diff --git a/README b/README deleted file mode 100644 index e69de29..0000000 diff --git a/after/ftplugin/c_snips.vim b/after/ftplugin/c_snips.vim index 6e36796..d6bf59e 100644 --- a/after/ftplugin/c_snips.vim +++ b/after/ftplugin/c_snips.vim @@ -1,7 +1,7 @@ -if !exists('g:loaded_snips') || exists('b:did_c_snips') +if !exists('loaded_snips') || exists('s:did_'.&ft.'_snips') fini en -let b:did_c_snips = 1 +let s:did_{&ft}_snips = 1 " main() exe "Snipp main int main (int argc, char const* argv[])\n{\n\t${1}\n\treturn 0;\n}" @@ -39,7 +39,7 @@ exe 'Snipp td typedef ${1:int} ${2:MyCustomType};' " Struct exe "Snipp st struct ${1:`Filename('$1_t', 'name')`} {\n\t${2:/* data */}\n}${3: /* optional variable list */};${4}" " Typedef struct -exe "Snipp tds typedef struct {\n\t${2:/* data */}\n} ${1:`Filename('$1_t', 'name')`};" +exe "Snipp tds typedef struct ${2:$1 }{\n\t${3:/* data */}\n} ${1:`Filename('$1_t', 'name')`};" " Class exe "Snipp cl class ${1:`Filename('$1_t', 'name')`} {\npublic:\n\t$1 (${2:arguments});\n\tvirtual ~$1 ();\n\nprivate:\n\t${3:/* data */}\n};" " Namespace diff --git a/after/ftplugin/html_snips.vim b/after/ftplugin/html_snips.vim index c4be3a9..e04a3f5 100644 --- a/after/ftplugin/html_snips.vim +++ b/after/ftplugin/html_snips.vim @@ -1,7 +1,7 @@ -if !exists('g:loaded_snips') || exists('b:did_html_snips') +if !exists('g:loaded_snips') || exists('s:did_'.&ft.'_snips') fini en -let b:did_html_snips = 1 +let s:did_{&ft}_snips = 1 " automatically add a closing '/' to the end of xhtml tags let c = &ft == 'xhtml' ? ' /' : '' @@ -42,6 +42,7 @@ exe 'Snipp escape ⎋' " Generic Doctype exe "Snipp! doctype \"HTML 4.01 Strict\" " exe "Snipp! doctype \"HTML 4.01 Transitional\" " +exe "Snipp! doctype \"HTML 5\" " exe "Snipp! doctype \"XHTML 1.0 Frameset\" " exe "Snipp! doctype \"XHTML 1.0 Strict\" " exe "Snipp! doctype \"XHTML 1.0 Transitional\" " @@ -50,6 +51,8 @@ exe "Snipp! doctype \"XHTML 1.1\" " " HTML Doctype 4.01 Transitional exe "Snipp doct " +" HTML Doctype 5 +exe 'Snipp doct5 ' " XHTML Doctype 1.0 Frameset exe "Snipp docxf " " XHTML Doctype 1.0 Strict @@ -58,6 +61,7 @@ exe "Snipp docxs " " XHTML Doctype 1.1 exe "Snipp docx " +exe "Snipp html \n${1}\n" exe "Snipp xhtml \n${1}\n" exe "Snipp body \n\t${1}\n" exe "Snipp head \n\t\n\t" diff --git a/after/ftplugin/java_snips.vim b/after/ftplugin/java_snips.vim index ab03aeb..adda47a 100644 --- a/after/ftplugin/java_snips.vim +++ b/after/ftplugin/java_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_java_snips') +if !exists('loaded_snips') || exists('s:did_java_snips') fini en -let b:did_java_snips = 1 +let s:did_java_snips = 1 exe "Snipp main public static void main (String [] args)\n{\n\t${1:/* code */}\n}" exe 'Snipp pu public' diff --git a/after/ftplugin/javascript_snips.vim b/after/ftplugin/javascript_snips.vim index b07a59a..d273791 100644 --- a/after/ftplugin/javascript_snips.vim +++ b/after/ftplugin/javascript_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_js_snips') +if !exists('loaded_snips') || exists('s:did_js_snips') fini en -let b:did_js_snips = 1 +let s:did_js_snips = 1 " Prototype exe "Snipp proto ${1:class_name}.prototype.${2:method_name} =\nfunction(${3:first_argument}) {\n\t${4:// body...}\n};" diff --git a/after/ftplugin/objc_snips.vim b/after/ftplugin/objc_snips.vim index 756b52a..6a04b71 100644 --- a/after/ftplugin/objc_snips.vim +++ b/after/ftplugin/objc_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_js_snips') +if !exists('loaded_snips') || exists('s:did_objc_snips') fini en -let b:did_js_snips = 1 +let s:did_objc_snips = 1 " #import <...> exe 'Snipp imp #import <${1:Cocoa/Cocoa.h}>${2}' @@ -15,26 +15,40 @@ exe 'Snipp log NSLog(@"${1}"${2});${3}' exe "Snipp objc @interface ${1:`Filename('', 'object')`} : ${2:NSObject}\n{\n}\n@end\n\n@implementation $1\n- (id) init\n{\n\tif (self = [super init])" \."\n\t{${3}\n\t}\n\treturn self\n}\n@end" " Class Interface -exe "Snipp cli @interface ${1:ClassName} : ${2:NSObject}\n{${3}\n}\n${4}\n@end" +exe "Snipp clh @interface ${1:ClassName} : ${2:NSObject}\n{${3}\n}\n${4}\n@end" +exe 'Snipp ibo IBOutlet ${1:NSSomeClass} *${2:$1};' " Category exe "Snipp cat @interface ${1:NSObject} (${2:Category})\n@end\n\n@implementation $1 ($2)\n${3}\n@end" " Category Interface -exe "Snipp cati @interface ${1:NSObject} (${2:Category})\n${3}\n@end" +exe "Snipp cath @interface ${1:NSObject} (${2:Category})\n${3}\n@end" " NSArray exe 'Snipp array NSMutableArray *${1:array} = [NSMutable array];${2}' " NSDictionary exe 'Snipp dict NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2}' " NSBezierPath exe 'Snipp bez NSBezierPath *${1:path} = [NSBezierPath bezierPath];${2}' +" Method +exe "Snipp m - (${1:id})${2:method}\n{\n\t${3:return self;}\n}" +" Method declaration +exe "Snipp md - (${1:id})${2:method};${3}" " Class Method -exe "Snipp M + (${1:id}) ${2:method}\n{${3}\n\treturn nil;\n}" +exe "Snipp M + (${1:id})${2:method}\n{${3}\n\treturn nil;\n}" " Sub-method (Call super) -exe "Snipp sm - (${1:id}) ${2:method}:(${3:id})${4:anArgument}\n{\n\t$1 res = [super $2:$4];${5}\n\treturn res;\n}" +exe "Snipp sm - (${1:id})${2:method}\n{\n\t[super $2];${3}\n\treturn self;\n}" " Method: Initialize exe "Snipp I + (void) initialize\n{\n\t[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWIthObjectsAndKeys:\n\t\t${1}@\"value\", @\"key\",\n\t\tnil]];\n}" " Accessor Methods For: " Object exe "Snipp objacc - (${1:id})${2:thing}\n{\n\treturn $2;\n}\n\n- (void) set$2:($1)\n{\n\t$1 old$2 = $2;\n\t$2 = [aValue retain];\n\t[old$2 release];\n}" exe "Snipp forarray unsigned int\t${1:object}Count = [${2:array} count];\n\nfor (unsigned int index = 0; index < $1Count; index++)\n{\n\t${3:id}\t$1 = [$2 $1AtIndex:index];\n\t${4}\n}" +" IBOutlet +" @property (Objective-C 2.0) +exe "Snipp prop @property (${1:retain}) ${2:NSSomeClass} *${3:$2};${4}" +" @synthesize (Objective-C 2.0) +exe "Snipp syn @synthesize ${1:NSSomeClass};${2}" " [[ alloc] init] exe 'Snipp alloc [[${1:foo} alloc] init]${2};${3}' +" retain +exe 'Snipp ret [${1:foo} retain];${2}' +" release +exe 'Snipp rel [${1:foo} release];${2}' diff --git a/after/ftplugin/perl_snips.vim b/after/ftplugin/perl_snips.vim index b2f89d5..1a0e230 100644 --- a/after/ftplugin/perl_snips.vim +++ b/after/ftplugin/perl_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_perl_snips') +if !exists('loaded_snips') || exists('s:did_perl_snips') fini en -let b:did_perl_snips = 1 +let s:did_perl_snips = 1 " Hash Pointer exe 'Snipp . =>' diff --git a/after/ftplugin/php_snips.vim b/after/ftplugin/php_snips.vim index 0299163..7a87720 100644 --- a/after/ftplugin/php_snips.vim +++ b/after/ftplugin/php_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_php_snips') +if !exists('loaded_snips') || exists('s:did_php_snips') fini en -let b:did_php_snips = 1 +let s:did_php_snips = 1 exe "Snipp php " exe 'Snipp ec echo "${1:string}"${2};' diff --git a/after/ftplugin/python_snips.vim b/after/ftplugin/python_snips.vim index 0c13a2b..e663039 100644 --- a/after/ftplugin/python_snips.vim +++ b/after/ftplugin/python_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_python_snips') +if !exists('loaded_snips') || exists('s:did_python_snips') fini en -let b:did_python_snips = 1 +let s:did_python_snips = 1 " New Class exe "Snipp cl class ${1:ClassName}(${2:object}):\n\t\"\"\"${3:docstring for $1}\"\"\"\n\tdef __init__(self, ${4:arg}):\n\t\t${5:super($1, self).__init__()}\n\t\tself.$4 = $4\n\t\t${6}" @@ -10,7 +10,7 @@ exe "Snipp def def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):\n\t\"\"\"${3:do " New Method exe "Snipp defs def ${1:mname}(self, ${2:arg})):\n\t${3:pass}" " New Property -exe "Snipp property def def ${1:foo}():\n\tdoc = \"${2:The $1 property.}\"\n\tdef fget(self):\n\t\t\t${3:return self._$1}\n\tdef fset(self, value):\n\t\t" +exe "Snipp property def ${1:foo}():\n\tdoc = \"${2:The $1 property.}\"\n\tdef fget(self):\n\t\t\t${3:return self._$1}\n\tdef fset(self, value):\n\t\t" \."${4:self._$1 = value}\n\tdef fdel(self):\n\t\t\t${5:del self._$1}\n\treturn locals()\n$1 = property(**$1())${6}" " Self exe 'Snipp . self.' @@ -19,9 +19,9 @@ exe "Snipp try try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3 " Try/Except/Else exe "Snipp trye try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nelse:\n\t${5:pass}" " Try/Except/Finally -exe "Snipp tryf try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nfinally:\n${5:pass}" +exe "Snipp tryf try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nfinally:\n\t${5:pass}" " Try/Except/Else/Finally -exe "Snipp tryef try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nelse:\n\t${5:pass}\nfinally:\n${6:pass}" +exe "Snipp tryef try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nelse:\n\t${5:pass}\nfinally:\n\t${6:pass}" " if __name__ == '__main__': exe "Snipp ifmain if __name__ == '__main__':\n\t${1:main()}" " __magic__ diff --git a/after/ftplugin/ruby_snips.vim b/after/ftplugin/ruby_snips.vim index d5439ef..de16c6e 100644 --- a/after/ftplugin/ruby_snips.vim +++ b/after/ftplugin/ruby_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_ruby_snips') +if !exists('loaded_snips') || exists('s:did_ruby_snips') fini en -let b:did_ruby_snips = 1 +let s:did_ruby_snips = 1 " New Block exe "Snipp =b =begin rdoc\n\t${1}\n=end" diff --git a/after/ftplugin/sh_snips.vim b/after/ftplugin/sh_snips.vim index 69e5e37..a7794da 100644 --- a/after/ftplugin/sh_snips.vim +++ b/after/ftplugin/sh_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_sh_snips') +if !exists('loaded_snips') || exists('s:did_sh_snips') fini en -let b:did_sh_snips = 1 +let s:did_sh_snips = 1 exe "Snipp if if [[ ${1:condition} ]]; then\n\t${2:#statements}\nfi" exe "Snipp elif elif [[ ${1:condition} ]]; then\n\t${2:#statements}" diff --git a/after/ftplugin/tex_snips.vim b/after/ftplugin/tex_snips.vim index 7b96ef6..b912802 100644 --- a/after/ftplugin/tex_snips.vim +++ b/after/ftplugin/tex_snips.vim @@ -1,7 +1,7 @@ -if !exists('loaded_snips') || exists('b:did_tex_snips') +if !exists('loaded_snips') || exists('s:did_tex_snips') fini en -let b:did_tex_snips = 1 +let s:did_tex_snips = 1 " \begin{}...\end{} exe "Snipp begin \\begin{${1:env}}\n\t${2}\n\\end{$1}" @@ -41,9 +41,9 @@ exe "Snipp subs \\subsubsection{${1:subsubsection name}} % (fold)\n\\label{ssub: exe "Snipp par \\paragraph{${1:paragraph name}} % (fold)\n\\label{par:${2:$1}}\n${3}\n% paragraph $2 (end)" " Sub Paragraph exe "Snipp subp \\subparagraph{${1:subparagraph name}} % (fold)\n\\label{subp:${2:$1}}\n${3}\n% subparagraph $2 (end)" -exe 'Snipp itd \\item[${1:description}] ${2:item}' -exe 'Snipp figure ${1:Figure}~\\ref{${2:fig:}}${3}' -exe 'Snipp table ${1:Table}~\\ref{${2:tab:}}${3}' -exe 'Snipp listing ${1:Listing}~\\ref{${2:list}}${3}' -exe 'Snipp section ${1:Section}~\\ref{${2:sec:}}${3}' -exe 'Snipp page ${1:page}~\\pageref{${2}}${3}' +exe 'Snipp itd \item[${1:description}] ${2:item}' +exe 'Snipp figure ${1:Figure}~\ref{${2:fig:}}${3}' +exe 'Snipp table ${1:Table}~\ref{${2:tab:}}${3}' +exe 'Snipp listing ${1:Listing}~\ref{${2:list}}${3}' +exe 'Snipp section ${1:Section}~\ref{${2:sec:}}${3}' +exe 'Snipp page ${1:page}~\pageref{${2}}${3}' diff --git a/after/plugin/snipMate.vim b/after/plugin/snipMate.vim index dcb00dd..96027bc 100644 --- a/after/plugin/snipMate.vim +++ b/after/plugin/snipMate.vim @@ -5,9 +5,19 @@ if exists('s:did_snips_mappings') || &cp || version < 700 en let s:did_snips_mappings = 1 -ino =ExpandSnippet() -snor i=ExpandSnippet() +ino =TriggerSnippet() +snor i=TriggerSnippet() snor b snor ' b' snor a snor bi + +" By default load snippets in ~/.vim/snippets/ +if isdirectory($HOME.'/.vim/snippets') + if isdirectory($HOME.'/.vim/snippets/_') + cal ExtractSnips($HOME.'/.vim/snippets/_', '_') + en + au FileType * if !exists('s:did_'.&ft) && + \ isdirectory($HOME.'/.vim/snippets/'.&ft) + \| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en +en diff --git a/doc/snipMate.txt b/doc/snipMate.txt index 802fa51..a3e63ff 100644 --- a/doc/snipMate.txt +++ b/doc/snipMate.txt @@ -1,7 +1,7 @@ *snipMate.txt* Plugin for using TextMate-style snippets in Vim. Snippets *snippet* *snippets* *snipMate* -Last Change: February 13, 2009 +Last Change: February 21, 2009 |snipMate-description| Description |snipMate-usage| Usage @@ -39,7 +39,34 @@ be updated. ============================================================================== USAGE *snipMate-usage* -Snippets should be installed in the 'after' directory, usually located in +There are two ways to make snippets: file-based and command-based. File-based +snippets are simply plain text files named after the trigger of the snippet +and placed in the directory of the filetype (/.snippet); +command-based snippets are snippets defined using the |Snipp| and |GlobalSnip| +commands. File-based snippets have the advantage of being easier to read, but +do not support some special characters in snippet triggers, while +command-based snippets are obviously convenient for short snippets but can +quickly get unreadable. + + *file-snippets* *'snippets'* +File-based snippets by default are looked for in the 'snippets' directory +inside your home '.vim' directory, typically located in +'~/.vim/snippets/'. To change that location or add another one, +edit '~/.vim/after/plugin/snipMate.vim' and use the |ExtractSnips()|function. + +ExtractSnips({directory}, {filetype}) *ExtractSnips()* + +ExtractSnips() extracts *.snippet files from the specified directory and +defines them as snippets for the given filetype; to define a global snippet, +use '_' for the {filetype} argument. + + *ResetSnips()* +The ResetSnips() function removes all snippets from memory. This is useful to +put at the top of a snippet setup file if you would like to :source it +multiple times. + + *command-snippets* +Command-based should be installed in the 'after' directory, usually located in '~/.vim/after'. Filetype specific snippets should be installed in 'after/ftplugin', such as 'after/ftplugin/_snips.vim'. See |ftplugins|. Global snippets should be installed in 'after/plugin'. @@ -87,6 +114,11 @@ to add: > to the top of your snippets files. + *snipMate-expandtab* *snipMate-indenting* +If you would like your snippets to use spaces instead of tabs, just enable +'expandtab' and set 'softtabstop' to your preferred amount of spaces. If +'softtabstop' is not set, 'shiftwidth' is used instead. + ============================================================================== SYNTAX *snipMate-syntax* *snipMate-${#}* @@ -184,14 +216,13 @@ to this: > FEATURES *snipMate-features* snipMate.vim has the following features among others: - - The syntax of snippets is very similar to TextMate's allowing + - The syntax of snippets is very similar to TextMate's, allowing easy conversion. - The position of the snippet is kept transparently (i.e. it does not use - regexes from text inserted in the buffer to track your position), which - allows you to escape out of an incomplete snippet, something particularly - useful in Vim. - - Variables in snippets are updated as-you-type - - Snippets can have multiple matches + markers/placeholders written to the buffer), which allows you to escape + out of an incomplete snippet, something particularly useful in Vim. + - Variables in snippets are updated as-you-type. + - Snippets can have multiple matches. - Snippets can be out of order. For instance, in a do...while loop, the condition can be added before the code. diff --git a/plugin/snipMate.vim b/plugin/snipMate.vim index ee9574b..b3116ce 100644 --- a/plugin/snipMate.vim +++ b/plugin/snipMate.vim @@ -1,150 +1,251 @@ " File: snipMate.vim " Author: Michael Sanders -" Version: 0.61803399 +" Version: 0.7 " Description: snipMate.vim implements some of TextMate's snippets features in " Vim. A snippet is a piece of often-typed text that you can " insert into your document using a trigger word followed by a "". " -" For more help see snipMate.txt; you can do this by doing: +" For more help see snipMate.txt; you can do this by using: " :helptags ~/.vim/doc " :h snipMate.txt -" Last Modified: February 16, 2009. +" Last Modified: February 25, 2009. -if exists('g:loaded_snips') || &cp || version < 700 - fini -en -let g:loaded_snips = 1 +if exists('loaded_snips') || &cp || version < 700 + finish +endif +let loaded_snips = 1 +if !exists('snips_author') | let snips_author = 'Me' | endif -" snippets for making snippets :) -au FileType vim let b:Snippet_snip = 'exe "Snipp ${1:trigger}"${2}' - \| let b:Snippet_snipp = "exe 'Snipp ${1:trigger}'${2}" - \| let b:Snippet_gsnip = 'exe "GlobalSnip ${1:trigger}"${2}' - \| let b:Snippet_gsnipp = "exe 'GlobalSnip ${1:trigger}'${2}" +com! -nargs=+ -bang Snipp call s:MakeSnippet(, &ft, 0) +com! -nargs=+ -bang GlobalSnip call s:MakeSnippet(, '_', 0) -com! -nargs=+ -bang Snipp cal s:MakeSnippet(, 'b', 0) -com! -nargs=+ -bang GlobalSnip cal s:MakeSnippet(, 'g', 0) - -if !exists('g:snips_author') | let g:snips_author = 'Me' | en +let s:snippets = {} | let s:multi_snips = {} fun! Filename(...) let filename = expand('%:t:r') - if filename == '' | retu a:0 == 2 ? a:2 : '' | en - retu !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') + if filename == '' | return a:0 == 2 ? a:2 : '' | endif + return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') endf " escapes special characters in snippet triggers fun s:Hash(text) - retu substitute(a:text, '\W', '\="_".char2nr(submatch(0))."_"', 'g') + return substitute(a:text, '\W', '\="_".char2nr(submatch(0))."_"', 'g') endf -fun s:MakeSnippet(text, scope, bang) +fun s:MakeSnippet(text, ft, multisnip) let space = stridx(a:text, ' ') let trigger = s:Hash(strpart(a:text, 0, space)) - if a:bang + if a:multisnip let space += 2 - let quote = stridx(a:text, '"', space) - let name = strpart(a:text, space, quote-space) - let space = stridx(a:text, ' ', quote) - let trigger = a:scope.':Snippets_'.trigger - el - let trigger = a:scope.':Snippet_'.trigger - en + let quote = stridx(a:text, '"', space) + let name = strpart(a:text, space, quote-space) + let space = stridx(a:text, ' ', quote) + let var = 's:multi_snips' + else " evaluating a regular snippet + let var = 's:snippets' + endif + if !has_key({var}, a:ft) | let {var}[a:ft] = {} | endif let end = strpart(a:text, space+1) - if !exists(trigger) || a:bang - if end != '' && space != -1 && (!a:bang || name != '') - if a:bang - if !exists(trigger) | let {trigger} = [] | en - let {trigger} += [[name, end]] - el - let {trigger} = end - en - el - echoh ErrorMsg - echom 'Error in snipMate.vim: Snippet '.a:text.' is undefined.' - echoh None - en - el - echoh WarningMsg + + if end == '' || space == '' || (a:multisnip && name == '') + echom 'Error in snipMate.vim: Snippet '.a:text.' is undefined.' + elseif !has_key({var}[a:ft], trigger) + let {var}[a:ft][trigger] = a:multisnip ? [[name, end]] : end + elseif a:multisnip | let {var}[a:ft][trigger] += [[name, end]] + else echom 'Warning in snipMate.vim: Snippet '.strpart(a:text, 0, stridx(a:text, ' ')) \ .' is already defined. See :h multi_snip for help on snippets' \ .' with multiple matches.' - echoh None - en + endif endf -" This updates the snippet as you type when text needs to be inserted -" into multiple places (e.g. in "${1:default text}foo$1bar$1", -" "default text" would be highlighted, and if the user types something, -" UpdateChangedSnip() would be called so that the text after "foo" & "bar" -" are updated accordingly) -" -" It also automatically quits the snippet if the cursor is moved out of it -" while in insert mode. -au CursorMovedI * cal s:UpdateChangedSnip(0) -au InsertEnter * cal s:UpdateChangedSnip(1) -fun s:UpdateChangedSnip(entering) - if exists('s:update') - if !exists('s:origPos') && s:curPos+1 < s:snipLen - " save the old snippet & word length before it's updated - " s:startSnip must be saved too, in case text is added - " before the snippet (e.g. in "foo$1${2}bar${1:foo}") - let s:origSnipPos = s:startSnip - let s:origPos = deepcopy(s:snipPos[s:curPos][3]) - en - let col = col('.')-1 +fun! ExtractSnips(dir, ft) + let s:slash = has('win16') || has('win32') || has('win64') ? '\\' : '/' + for path in split(globpath(a:dir, '*'), '\n') + if isdirectory(path) + for snipFile in split(globpath(path, '*.snippet'), '\n') + call s:ProcessFile(snipFile, a:ft, strpart(path, strridx(path, s:slash)+1)) + endfor + continue + endif + call s:ProcessFile(path, a:ft) + endfor + unl s:slash + let s:did_{a:ft} = 1 +endf - if s:endSnip != -1 - let changeLen = col('$') - s:prevLen[1] - let s:endSnip += changeLen - el " when being updated the first time, after leaving select mode - if a:entering | retu | en - let s:endSnip = col-1 - en +" Processes a snippet file; optionally add the name of the parent directory +" for a snippet with multiple matches. +fun s:ProcessFile(file, ft, ...) + let keyword = matchstr(a:file, '.*'.s:slash.'\zs.*\ze\.snippet') + if keyword == '' | return | endif + try + let text = join(readfile(a:file), '\n') + catch /E484/ + echom "Error in snipMate.vim: couldn't read file: ".a:file + endtry + return a:0 ? s:MakeSnippet(a:1.' "'.keyword.'" '.text, a:ft, 1) + \ : s:MakeSnippet(keyword.' '.text, a:ft, 0) +endf - " if the cursor moves outside the snippet, quit it - if line('.') != s:snipPos[s:curPos][0] || col < s:startSnip || - \ col-1 > s:endSnip - unl! s:startSnip s:origWordLen s:origPos s:update - cal s:RemoveSnippet() - retu - en - - cal s:UpdateSnip() - let s:prevLen[1] = col('$') - elsei exists('s:snipPos') - let col = col('.') - let lnum = line('.') - let changeLine = line('$') - s:prevLen[0] - - if lnum == s:endSnipLine - let s:endSnip += col('$') - s:prevLen[1] - let s:prevLen = [line('$'), col('$')] - en - if changeLine != 0 "&& !a:entering - let s:endSnipLine += changeLine - let s:endSnip = col - en - - " delete snippet if cursor moves out of it in insert mode - if (lnum == s:endSnipLine && (col > s:endSnip || col < s:snipPos[s:curPos][1])) - \ || lnum > s:endSnipLine || lnum < s:snipPos[s:curPos][0] - cal s:RemoveSnippet() - en - en +fun! ResetSnippets() + let s:snippets = {} | let s:multi_snips = {} endf fun s:RemoveSnippet() unl s:snipPos s:curPos s:snipLen s:endSnip s:endSnipLine s:prevLen endf -fun s:ChooseSnippet(snippet) - let snippet = [] | let i = 1 - for snip in {a:snippet} - let snippet += [i.'. '.snip[0]] | let i += 1 - endfo - if i == 2 | retu {a:snippet}[0][1] | en +fun s:ChooseSnippet(ft, trigger) + let snippet = [] + let i = 1 + for snip in s:multi_snips[a:ft][a:trigger] + let snippet += [i.'. '.snip[0]] + let i += 1 + endfor + if i == 2 | return s:multi_snips[a:ft][a:trigger][0][1] | endif let num = inputlist(snippet)-1 - retu num < i-1 ? {a:snippet}[num][1] : '' + return num < i-1 ? s:multi_snips[a:ft][a:trigger][num][1] : '' +endf + +fun! TriggerSnippet() + if pumvisible() " update snippet if completion is used, or deal with supertab + if exists('s:sid') | return "\" | endif + call feedkeys("\a", 'n') | call s:UpdateChangedSnip(0) + endif + + if !exists('s:snipPos') " don't expand snippets within snippets + if !exists('s:sid') && exists('g:SuperTabMappingForward') + \ && g:SuperTabMappingForward == "" + call s:GetSuperTabSID() + endif + let word = s:GetSnippet() + + if exists('s:snippet') + if s:snippet == '' + return unl s:snippet " if user cancelled multi snippet, quit + endif + let col = col('.')-len(word) + " if word is a trigger for a snippet, delete the trigger & expand + " the snippet + exe 'sil s/'.word.'\%#//' + return s:ExpandSnippet(col) + endif + return exists('s:sid') ? {s:sid}_SuperTab('n') : "\" + endif + return s:JumpTabStop() +endf + +" Check if word under cursor is snippet trigger; if it isn't, try checking if +" the text after non-word characters is (e.g. check for "foo" in "bar.foo") +fun s:GetSnippet() + let origWord = matchstr(getline('.'), '\S\+\%'.col('.').'c') + wh !exists('s:snippet') + let word = s:Hash(origWord) + if exists('s:snippets["'.&ft.'"]["'.word.'"]') + let s:snippet = s:snippets[&ft][word] + elseif exists('s:snippets["_"]["'.word.'"]') + let s:snippet = s:snippets['_'][word] + elseif exists('s:multi_snips["'.&ft.'"]["'.word.'"]') + let s:snippet = s:ChooseSnippet(&ft, word) + elseif exists('s:multi_snips["_"]["'.word.'"]') + let s:snippet = s:ChooseSnippet('_', word) + en + if match(origWord, '\W') == -1 | break | en + let origWord = substitute(origWord, '.\{-}\W', '', '') + endw + return origWord +endf + +fun s:GetSuperTabSID() + let old = @a + redir @a | exe 'sil fun /SuperTab$' | redir END + let s:sid = matchstr(@a, '\d\+\ze_SuperTab(command)') + let @a = old +endf + +fun s:ExpandSnippet(col) + let lnum = line('.') | let col = a:col + let afterCursor = strpart(getline('.'), col-1) + if afterCursor != "\t" && afterCursor != ' ' + sil exe 's/\%'.col.'c.*//' + else | let afterCursor = '' | endif + + call s:ProcessSnippet() + if s:snippet == '' + return unl s:snippet " avoid an error if the snippet is now empty + endif + + let snip = split(substitute(s:snippet, '$\d\|${\d.\{-}}', '', 'g'), "\n", 1) + if afterCursor != '' | let snip[-1] .= afterCursor | endif + let line = getline(lnum) + call setline(lnum, line.snip[0]) + + " for some reason the cursor needs to move one right after this + if line != '' && col == 1 && afterCursor == '' && &ve !~ 'all\|onemore' + let col += 1 + endif + " autoindent snippet according to previous indentation + let indent = matchend(line, '^.\{-}\ze\(\S\|$\)')+1 + if !indent + call append(lnum, snip[1:]) + else + call append(lnum, map(snip[1:], "'".strpart(line, 0, indent-1)."'.v:val")) + endif + + let snipLen = s:BuildTabStops(lnum, col-indent, indent) + unl s:snippet + + if snipLen + let s:curPos = 0 + let s:snipLen = snipLen + let s:endSnip = s:snipPos[0][1] + let s:endSnipLine = s:snipPos[s:curPos][0] + + call cursor(s:snipPos[0][0], s:snipPos[0][1]) + let s:prevLen = [line('$'), col('$')] + if s:snipPos[0][2] != -1 | return s:SelectWord() | endif + else + " place cursor at end of snippet if no tab stop is given + unl s:snipPos | let newlines = len(snip)-1 + call cursor(lnum + newlines, tab + len(snip[-1]) - len(afterCursor) + \ + (newlines ? 0: col)) + endif + return '' +endf + +fun s:ProcessSnippet() + " evaluate eval (`...`) expressions + " Using a loop here instead of a regex fixes a bug with nested "\=" + if stridx(s:snippet, '`') != -1 + wh match(s:snippet, '`.\{-}`') != -1 + let s:snippet = substitute(s:snippet, '`.\{-}`', + \ substitute(eval(matchstr(s:snippet, '`\zs.\{-}\ze`')), + \ "\n\\%$", '', ''), '') + endw + let s:snippet = substitute(s:snippet, "\r", "\n", 'g') + endif + + " place all text after a colon in a tab stop after the tab stop + " (e.g. "${#:foo}" becomes "${:foo}foo") + " this helps tell the position of the tab stops later. + let s:snippet = substitute(s:snippet, '${\d:\(.\{-}\)}', '&\1', 'g') + + " update the s:snippet so that all the $# become + " the text after the colon in their associated ${#} + " (e.g. "${1:foo}" turns all "$1"'s into "foo") + let i = 1 + wh stridx(s:snippet, '${'.i) != -1 + let s = matchstr(s:snippet, '${'.i.':\zs.\{-}\ze}') + if s != '' + let s:snippet = substitute(s:snippet, '$'.i, '&'.s, 'g') + endif + let i += 1 + endw + if &et " expand tabs to spaces if 'expandtab' is set + let s:snippet = substitute(s:snippet, '\t', + \ repeat(' ', &sts ? &sts : &sw), 'g') + endif endf fun s:Count(haystack, needle) @@ -154,268 +255,184 @@ fun s:Count(haystack, needle) let index = stridx(a:haystack, a:needle, index+1) let counter += 1 endw - retu counter + return counter endf -fun! ExpandSnippet() - if !exists('s:snipPos') " don't expand snippets within snippets - " get word under cursor - let word = matchstr(getline('.'), '\(^\|\s\)\zs\S\+\%'.col('.').'c\ze\($\|\s\)') - let len = len(word) | let word = s:Hash(word) - - if exists('b:Snippet_'.word) - let snippet = b:Snippet_{word} - elsei exists('g:Snippet_'.word) - let snippet = g:Snippet_{word} - elsei exists('b:Snippets_'.word) - let snippet = s:ChooseSnippet('b:Snippets_'.word) - elsei exists('g:Snippet_'.word) - let snippet = s:ChooseSnippet('g:Snippets_'.word) - en - - if exists('snippet') - if snippet == '' | retu '' | en " if user cancelled multi snippet, quit - let b:word = word - " if word is a trigger for a snippet, delete the trigger & expand - " the snippet (BdE doesn't work for just a single character) - if len == 1 | norm! h"_x - el | norm! B"_dE - en - let lnum = line('.') - let col = col('.') - - let afterCursor = strpart(getline('.'), col-1) - if afterCursor != "\t" && afterCursor != ' ' | sil s/\%#.*// - el | let afterCursor = '' | en - - " evaluate eval expressions - if stridx(snippet, '`') != -1 - let snippet = substitute(substitute(snippet, '`\(.\{-}\)`', - \ '\=substitute(eval(submatch(1)), "\n\\%$", "", "")', 'g'), - \ "\r", "\n", 'g') - if snippet == '' | retu '' | en " avoid an error if the snippet is now empty - en - - " place all text after a colon in a tab stop after the tab stop - " (e.g. "${#:foo}" becomes "${:foo}foo") - " this helps tell the position of the tab stops later. - let snippet = substitute(snippet, '${\d:\(.\{-}\)}', '&\1', 'g') - - " update the snippet so that all the $# become - " the text after the colon in their associated ${#} - " (e.g. "${1:foo}" turns all "$1"'s into "foo") - let i = 1 - wh stridx(snippet, '${'.i) != -1 - let s = matchstr(snippet, '${'.i.':\zs.\{-}\ze}') - if s != '' - let snippet = substitute(snippet, '$'.i, '&'.s, 'g') - en - let i += 1 - endw - " expand tabs to spaces if 'expandtab' is set - if &et | let snippet = substitute(snippet, '\t', repeat(' ', &sts), 'g') | en - - let snip = split(substitute(snippet, '$\d\|${\d.\{-}}', '', 'g'), "\n", 1) - if afterCursor != '' | let snip[-1] .= afterCursor | en - let line = getline(lnum) - cal setline(lnum, line.snip[0]) - - " for some reason the cursor needs to move one right after this - if line != '' && afterCursor == '' && &ve != 'all' && &ve != 'onemore' - let col += 1 - en - " autoindent snippet according to previous indentation - let tab = matchstr(line, '^.\{-}\ze\(\S\|$\)') - cal append(lnum, tab != '' ? map(snip[1:], "'".tab."'.v:val") : snip[1:]) - let tab = len(tab)+1 | let col -= tab - - " Sorry, this next section is a bit convoluted... - " This loop builds a list of a list of each tab stop in the snippet - " containing: - " 1.) The number of the current line plus the number of "\n"s (line - " breaks) before the tab stop - " 2.) The current column plus the position of the next "${#}" on - " the line by getting the length of the string between the last "\n" - " and the "${#}" tab stop, - " 3.) The length of the text after the colon for the current tab stop - " (e.g. "${#:foo}" would return 3). If there is no text, -1 is returned. - " 4.) If the "${#:}" construct is given, the fourth part of the list - " is another list containing all the matches of "$#", to be replaced - " with the variable. This list is composed the same way as the parent: - " the first part is the number of "\n"s before the tab stop, and - " second is the position (column) of the "$#" tab stop on the line. - " If there are none of these tab stop, an empty list ([]) is returned - let s:snipPos = [] | let i = 1 - " temporarily delete placeholders - let cut_snip = substitute(snippet, '$\d', '', 'g') - wh stridx(snippet, '${'.i) != -1 - let s:snipPos += [[lnum+s:Count(matchstr(cut_snip, '^.*\ze${'.i), "\n"), - \ tab+len(matchstr(substitute(cut_snip, '${'.i.'\@!\d.\{-}}', '', 'g'), +" Sorry, this next section is a bit convoluted... +" This function builds a list of a list of each tab stop in the snippet +" containing: +" 1.) The number of the current line plus the number of "\n"s (line +" breaks) before the tab stop +" 2.) The current column plus the position of the next "${#}" on +" the line by getting the length of the string between the last "\n" +" and the "${#}" tab stop, +" 3.) The length of the text after the colon for the current tab stop +" (e.g. "${#:foo}" would returnrn 3). If there is no text, -1 is returnrned. +" 4.) If the "${#:}" construct is given, the fourth part of the list +" is another list containing all the matches of "$#", to be replaced +" with the variable. This list is composed the same way as the parent: +" the first part is the number of "\n"s before the tab stop, and +" second is the position (column) of the "$#" tab stop on the line. +" If there are none of these tab stop, an empty list ([]) is returnrned +fun s:BuildTabStops(lnum, col, indent) + let s:snipPos = [] + let i = 1 + " temporarily delete placeholders + let cut_snip = substitute(s:snippet, '$\d', '', 'g') + wh stridx(s:snippet, '${'.i) != -1 + let s:snipPos += [[a:lnum+s:Count(matchstr(cut_snip, '^.*\ze${'.i), "\n"), + \ a:indent+len(matchstr(substitute(cut_snip, '${'.i.'\@!\d.\{-}}', '', 'g'), \ "^.*\\(\n\\|^\\)\\zs.*\\ze${".i.'.\{-}}')), -1]] - if s:snipPos[i-1][0] == lnum | let s:snipPos[i-1][1] += col | en + if s:snipPos[i-1][0] == a:lnum + let s:snipPos[i-1][1] += a:col + endif - " get all $# matches in another list, if ${#:name} is given - if stridx(cut_snip, '${'.i.':') != -1 - let j = i-1 - let s:snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}')) - let s:snipPos[j] += [[]] - " temporarily delete all other tab stops/placeholders - let tempstr = substitute(snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g') - wh stridx(tempstr, '$'.i) != -1 - let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i) - let linecount = lnum+s:Count(beforeMark, "\n") - let s:snipPos[j][3] += [[linecount, - \ tab+(linecount > lnum ? - \ len(matchstr(beforeMark, "^.*\n\\zs.*")) - \ : col+len(beforeMark))]] - let tempstr = substitute(tempstr, '$'.i, '', '') - endw - en - let i += 1 + " get all $# matches in another list, if ${#:name} is given + if stridx(cut_snip, '${'.i.':') != -1 + let j = i-1 + let s:snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}')) + let s:snipPos[j] += [[]] + " temporarily delete all other tab stops/placeholders + let tempstr = substitute(s:snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g') + wh stridx(tempstr, '$'.i) != -1 + let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i) + let linecount = a:lnum+s:Count(beforeMark, "\n") + let s:snipPos[j][3] += [[linecount, + \ a:indent+(linecount > a:lnum ? + \ len(matchstr(beforeMark, "^.*\n\\zs.*")) + \ : a:col+len(beforeMark))]] + let tempstr = substitute(tempstr, '$'.i, '', '') endw + endif + let i += 1 + endw + return i-1 +endf - if i > 1 " if snippet is not empty - let s:curPos = 0 - let s:snipLen = i-1 - let s:endSnip = s:snipPos[0][1] - let s:endSnipLine = s:snipPos[s:curPos][0] - - cal cursor(s:snipPos[0][0], s:snipPos[0][1]) - let s:prevLen = [line('$'), col('$')] - if s:snipPos[0][2] != -1 | retu s:SelectWord() | en - el - unl s:snipPos - " place cursor at end of snippet if no tab stop is given - let len = len(snip)-1 - cal cursor(lnum+len, tab+len(snip[-1])+(len ? 0 : col)) - en - retu '' - en - if !exists('s:sid') && exists('g:SuperTabMappingForward') - \ && g:SuperTabMappingForward == "" - cal s:GetSuperTabSID() - en - retu exists('s:sid') ? {s:sid}_SuperTab('n') : "\" - en - +fun s:JumpTabStop() if exists('s:update') - " update tab stops in snippet if text has been added via "$#", - " e.g. in "${1:foo}bar$1${2}" - if exists('s:origPos') - let changeLen = s:origWordLen - s:snipPos[s:curPos][2] - - " This could probably be more efficent... - if changeLen != 0 - let lnum = line('.') - let len = len(s:origPos) - for pos in s:snipPos[(s:curPos+1):] - let i = 0 | let j = 0 | let k = 0 - let endSnip = pos[2]+pos[1]-1 - wh i < len && s:origPos[i][0] <= pos[0] - if pos[0] == s:origPos[i][0] - if pos[1] > s:origPos[i][1] - \ || (pos[2] == -1 && pos[1] == s:origPos[i][1]) - let j += 1 - elsei s:origPos[i][1] < endSnip " parse variables within placeholders - let k += 1 - en - en - let i += 1 - endw - if pos[0] == lnum && pos[1] > s:origSnipPos | let j += 1 | en - let pos[1] -= changeLen*j | let pos[2] -= changeLen*k - - if pos[2] != -1 - for nPos in pos[3] - let i = 0 | let j = 0 - wh i < len && s:origPos[i][0] <= nPos[0] - if nPos[0] == s:origPos[i][0] && nPos[1] > s:origPos[i][1] - let j += 1 - en - let i += 1 - endw - if nPos[0] == lnum && nPos[1] > s:origSnipPos | let j += 1 | en - if nPos[0] > s:origPos[0][0] | brea | en - let nPos[1] -= changeLen*j - endfo - en - endfo - en - unl s:endSnip s:origPos s:origSnipPos - en - let changeLine = 0 - let changeCol = 0 - unl s:startSnip s:origWordLen s:update - el + call s:UpdatePlaceholderTabStops() + let changeLine = 0 | let changeCol = 0 + else let changeLine = s:endSnipLine - s:snipPos[s:curPos][0] let changeCol = s:endSnip - s:snipPos[s:curPos][1] if exists('s:origWordLen') let changeCol -= s:origWordLen | unl s:origWordLen - en - en + endif + endif let s:curPos += 1 if s:curPos == s:snipLen let sMode = s:endSnip == s:snipPos[s:curPos-1][1]+s:snipPos[s:curPos-1][2] - cal s:RemoveSnippet() - retu sMode ? "\" : ExpandSnippet() - en - if changeLine != 0 || changeCol != 0 - " there's probably a more efficient way to do this as well... - let lnum = s:snipPos[s:curPos-1][0] - let col = s:snipPos[s:curPos-1][1] - " update the line number of all proceeding tab stops if has - " been inserted - if changeLine != 0 - for pos in s:snipPos[(s:curPos):] - if pos[0] >= lnum - if pos[0] == lnum | let pos[1] += changeCol | en - let pos[0] += changeLine - en - if pos[2] != -1 - for nPos in pos[3] - if nPos[0] >= lnum - if nPos[0] == lnum | let nPos[1] += changeCol | en - let nPos[0] += changeLine - en - endfo - en - endfo - el - " update the column of all proceeding tab stops if text has - " been inserted/deleted in the current line - for pos in s:snipPos[(s:curPos):] - if pos[1] >= col && pos[0] == lnum - let pos[1] += changeCol - en - if pos[2] != -1 - for nPos in pos[3] - if nPos[0] > lnum | brea | en - if nPos[0] == lnum && nPos[1] >= col - let nPos[1] += changeCol - en - endfo - en - endfo - en - en - cal cursor(s:snipPos[s:curPos][0], s:snipPos[s:curPos][1]) + call s:RemoveSnippet() + return sMode ? "\" : TriggerSnippet() + endif + call s:UpdateTabStops(changeLine, changeCol) + + call cursor(s:snipPos[s:curPos][0], s:snipPos[s:curPos][1]) let s:endSnipLine = s:snipPos[s:curPos][0] let s:endSnip = s:snipPos[s:curPos][1] let s:prevLen = [line('$'), col('$')] - if s:snipPos[s:curPos][2] != -1 | retu s:SelectWord() | en - retu '' + return s:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord() endf -fun s:GetSuperTabSID() - let a_save = @a - redir @a - exe 'sil fu /SuperTab$' - redir END - let s:sid = matchstr(@a, '\d\+\ze_SuperTab(command)') - let @a = a_save +fun s:UpdatePlaceholderTabStops() + " update tab stops in snippet if text has been added via "$#", + " e.g. in "${1:foo}bar$1${2}" + if exists('s:origPos') + let changeLen = s:origWordLen - s:snipPos[s:curPos][2] + + " This could probably be more efficent... + if changeLen != 0 + let lnum = line('.') + let len = len(s:origPos) + for pos in s:snipPos[(s:curPos+1):] + let i = 0 | let j = 0 | let k = 0 + let endSnip = pos[2]+pos[1]-1 + wh i < len && s:origPos[i][0] <= pos[0] + if pos[0] == s:origPos[i][0] + if pos[1] > s:origPos[i][1] + \ || (pos[2] == -1 && pos[1] == s:origPos[i][1]) + let j += 1 + elseif s:origPos[i][1] < endSnip " parse variables within placeholders + let k += 1 + endif + endif + let i += 1 + endw + if pos[0] == lnum && pos[1] > s:origSnipPos + let j += 1 + endif + let pos[1] -= changeLen*j + let pos[2] -= changeLen*k + + if pos[2] != -1 + for nPos in pos[3] + let i = 0 | let j = 0 + wh i < len && s:origPos[i][0] <= nPos[0] + if nPos[0] == s:origPos[i][0] && nPos[1] > s:origPos[i][1] + let j += 1 + endif + let i += 1 + endw + if nPos[0] == lnum && nPos[1] > s:origSnipPos + let j += 1 + endif + if nPos[0] > s:origPos[0][0] | break | endif + let nPos[1] -= changeLen*j + endfor + endif + endfor + endif + unl s:endSnip s:origPos s:origSnipPos + endif + unl s:startSnip s:origWordLen s:update +endf + +fun s:UpdateTabStops(changeLine, changeCol) + " there's probably a more efficient way to do this as well... + let lnum = s:snipPos[s:curPos-1][0] + let col = s:snipPos[s:curPos-1][1] + " update the line number of all proceeding tab stops if has + " been inserted + if a:changeLine != 0 + for pos in s:snipPos[(s:curPos):] + if pos[0] >= lnum + if pos[0] == lnum + let pos[1] += a:changeCol + endif + let pos[0] += a:changeLine + endif + if pos[2] != -1 + for nPos in pos[3] + if nPos[0] >= lnum + if nPos[0] == lnum + let nPos[1] += a:changeCol + endif + let nPos[0] += a:changeLine + endif + endfor + endif + endfor + elseif a:changeCol != 0 + " update the column of all proceeding tab stops if text has + " been inserted/deleted in the current line + for pos in s:snipPos[(s:curPos):] + if pos[1] >= col && pos[0] == lnum + let pos[1] += a:changeCol + endif + if pos[2] != -1 + for nPos in pos[3] + if nPos[0] > lnum | break | endif + if nPos[0] == lnum && nPos[1] >= col + let nPos[1] += a:changeCol + endif + endfor + endif + endfor + en endf fun s:SelectWord() @@ -428,10 +445,71 @@ fun s:SelectWord() let s:endSnip = -1 let s:startSnip = s:snipPos[s:curPos][1]-1 en - if !s:origWordLen | retu '' | en + if !s:origWordLen | return '' | en let l = col('.') != 1 ? 'l' : '' - if &sel == 'exclusive' | retu "\".l.'v'.s:origWordLen."l\" | en - retu "\".l.(s:origWordLen == 1 ? 'gh' : 'v'.(s:origWordLen-1)."l\") + if &sel == 'exclusive' | return "\".l.'v'.s:origWordLen."l\" | en + return s:origWordLen == 1 ? "\".l.'gh' + \ : "\".l.'v'.(s:origWordLen-1)."l\" +endf + +" This updates the snippet as you type when text needs to be inserted +" into multiple places (e.g. in "${1:default text}foo$1bar$1", +" "default text" would be highlighted, and if the user types something, +" UpdateChangedSnip() would be called so that the text after "foo" & "bar" +" are updated accordingly) +" +" It also automatically quits the snippet if the cursor is moved out of it +" while in insert mode. +au CursorMovedI * call s:UpdateChangedSnip(0) +au InsertEnter * call s:UpdateChangedSnip(1) +fun s:UpdateChangedSnip(entering) + if exists('s:update') + if !exists('s:origPos') && s:curPos+1 < s:snipLen + " save the old snippet & word length before it's updated + " s:startSnip must be saved too, in case text is added + " before the snippet (e.g. in "foo$1${2}bar${1:foo}") + let s:origSnipPos = s:startSnip + let s:origPos = deepcopy(s:snipPos[s:curPos][3]) + endif + let col = col('.')-1 + + if s:endSnip != -1 + let changeLen = col('$') - s:prevLen[1] + let s:endSnip += changeLen + else " when being updated the first time, after leaving select mode + if a:entering | return | endif + let s:endSnip = col-1 + endif + + " if the cursor moves outside the snippet, quit it + if line('.') != s:snipPos[s:curPos][0] || col < s:startSnip || + \ col-1 > s:endSnip + unl! s:startSnip s:origWordLen s:origPos s:update + return s:RemoveSnippet() + endif + + call s:UpdateSnip() + let s:prevLen[1] = col('$') + elseif exists('s:snipPos') + let col = col('.') + let lnum = line('.') + let changeLine = line('$') - s:prevLen[0] + + if lnum == s:endSnipLine + let s:endSnip += col('$') - s:prevLen[1] + let s:prevLen = [line('$'), col('$')] + endif + if changeLine != 0 + let s:endSnipLine += changeLine + let s:endSnip = col + endif + + " delete snippet if cursor moves out of it in insert mode + if (lnum == s:endSnipLine && (col > s:endSnip || col < s:snipPos[s:curPos][1])) + \ || lnum > s:endSnipLine || lnum < s:snipPos[s:curPos][0] + call s:RemoveSnippet() + endif + endif endf fun s:UpdateSnip() @@ -449,33 +527,31 @@ fun s:UpdateSnip() for pos in s:snipPos[s:curPos][3] if updateSnip - let start = s:startSnip - if pos[0] == curLine && pos[1] <= start - let s:startSnip -= changeLen - let s:endSnip -= changeLen - en - for nPos in s:snipPos[s:curPos][3][(i):] - if nPos[0] == pos[0] - if nPos[1] > pos[1] || (nPos == [curLine, pos[1]] && - \ nPos[1] > start) - let nPos[1] -= changeLen - en - elsei nPos[0] > pos[0] - brea + let start = s:startSnip + if pos[0] == curLine && pos[1] <= start + let s:startSnip -= changeLen + let s:endSnip -= changeLen + en + for nPos in s:snipPos[s:curPos][3][(i):] + if nPos[0] == pos[0] + if nPos[1] > pos[1] || (nPos == [curLine, pos[1]] && + \ nPos[1] > start) + let nPos[1] -= changeLen en - endfo - let i += 1 + elseif nPos[0] > pos[0] | break | en + endfor + let i += 1 en - cal setline(pos[0], substitute(getline(pos[0]), '\%'.pos[1].'c'. + call setline(pos[0], substitute(getline(pos[0]), '\%'.pos[1].'c'. \ s:oldWord, newWord, '')) - endfo + endfor if oldStartSnip != s:startSnip - cal cursor('.', startCol + s:startSnip - oldStartSnip) + call cursor('.', startCol + s:startSnip - oldStartSnip) en let s:oldWord = newWord let s:snipPos[s:curPos][2] = newWordLen en endf -" vim:sw=4:ts=4:ft=vim +" vim:noet:sw=4:ts=4:ft=vim diff --git a/snip/after/ftplugin/c_snips.vim b/snip/after/ftplugin/c_snips.vim deleted file mode 100644 index d6bf59e..0000000 --- a/snip/after/ftplugin/c_snips.vim +++ /dev/null @@ -1,56 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_'.&ft.'_snips') - fini -en -let s:did_{&ft}_snips = 1 - -" main() -exe "Snipp main int main (int argc, char const* argv[])\n{\n\t${1}\n\treturn 0;\n}" -" #include <...> -exe 'Snipp inc #include <${1:stdio}.h>${2}' -" #include "..." -exe 'Snipp Inc #include "${1:`Filename("$1.h")`}"${2}' -" #ifndef ... #define ... #endif -exe "Snipp def #ifndef $1\n#define ${1:SYMBOL} ${2:value}\n#endif${3}" -" Header Include-Guard -" (the randomizer code is taken directly from TextMate; I don't know how to do -" it in vim script, it could probably be cleaner) -exe "Snipp once #ifndef ${1:`toupper(Filename('', 'UNTITLED').'_'.system(\"/usr/bin/ruby -e 'print (rand * 2821109907455).round.to_s(36)'\"))`}\n" - \ ."#define $1\n\n${2}\n\n#endif /* end of include guard: $1 */" -" Read File Into Vector -exe "Snipp readfile std::vector v;\nif (FILE *${2:fp} = fopen(${1:\"filename\"}, \"r\")) {\n\tchar buf[1024];\n\twhile (size_t len = " - \ ."fread(buf, 1, sizeof(buf), $2))\n\t\tv.insert(v.end(), buf, buf + len);\n\tfclose($2);\n}${3}" -" If Condition -exe "Snipp if if (${1:/* condition */}) {\n\t${2:/* code */}\n}" -exe "Snipp el else {\n\t${1}\n}" -" Tertiary conditional -exe 'Snipp t ${1:/* condition */} ? ${2:a} : ${3:b}' -" Do While Loop -exe "Snipp do do {\n\t${2:/* code */}\n} while (${1:/* condition */});" -" While Loop -exe "Snipp wh while (${1:/* condition */}) {\n\t${2:/* code */}\n}" -" For Loop -exe "Snipp for for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {\n\t${4:/* code */}\n}" -" Custom For Loop -exe "Snipp forr for (${1:i} = 0; ${2:$1 < 5}; $1${3:++}) {\n\t${4:/* code */}\n}" -" Function -exe "Snipp fun ${1:void} ${2:function_name} (${3})\n{\n\t${4:/* code */}\n}" -" Typedef -exe 'Snipp td typedef ${1:int} ${2:MyCustomType};' -" Struct -exe "Snipp st struct ${1:`Filename('$1_t', 'name')`} {\n\t${2:/* data */}\n}${3: /* optional variable list */};${4}" -" Typedef struct -exe "Snipp tds typedef struct ${2:$1 }{\n\t${3:/* data */}\n} ${1:`Filename('$1_t', 'name')`};" -" Class -exe "Snipp cl class ${1:`Filename('$1_t', 'name')`} {\npublic:\n\t$1 (${2:arguments});\n\tvirtual ~$1 ();\n\nprivate:\n\t${3:/* data */}\n};" -" Namespace -exe "Snipp ns namespace ${1:`Filename('', 'my')`} {\n\t${2}\n} /* $1 */" -" std::map -exe "Snipp map std::map<${1:key}, ${2:value}> map${3};" -" std::vector -exe "Snipp vector std::vector<${1:char}> v${2};" -" printf -" unfortunately version this isn't as nice as TextMates's, given the lack of a -" dynamic `...` -exe 'Snipp pr printf("${1:%s}\n"${2});${3}' -" fprintf (again, this isn't as nice as TextMate's version, but it works) -exe 'Snipp fpr fprintf(${1:stderr}, "${2:%s}\n"${3});${4}' diff --git a/snip/after/ftplugin/html_snips.vim b/snip/after/ftplugin/html_snips.vim deleted file mode 100644 index e04a3f5..0000000 --- a/snip/after/ftplugin/html_snips.vim +++ /dev/null @@ -1,94 +0,0 @@ -if !exists('g:loaded_snips') || exists('s:did_'.&ft.'_snips') - fini -en -let s:did_{&ft}_snips = 1 - -" automatically add a closing '/' to the end of xhtml tags -let c = &ft == 'xhtml' ? ' /' : '' - -" Some useful Unicode entities -" Non-Breaking Space -exe 'Snipp nbs  ' -" ← -exe 'Snipp left ←' -" → -exe 'Snipp right →' -" ↑ -exe 'Snipp up ↑' -" ↓ -exe 'Snipp down ↓' -" ↩ -exe 'Snipp return ↩' -" ⇤ -exe 'Snipp backtab ⇤' -" ⇥ -exe 'Snipp tab ⇥' -" ⇧ -exe 'Snipp shift ⇧' -" ⌃ -exe 'Snipp control ⌃' -" ⌅ -exe 'Snipp enter ⌅' -" ⌘ -exe 'Snipp command ⌘' -" ⌥ -exe 'Snipp option ⌥' -" ⌦ -exe 'Snipp delete ⌦' -" ⌫ -exe 'Snipp backspace ⌫' -" ⎋ -exe 'Snipp escape ⎋' -" Generic Doctype -exe "Snipp! doctype \"HTML 4.01 Strict\" " -exe "Snipp! doctype \"HTML 4.01 Transitional\" " -exe "Snipp! doctype \"HTML 5\" " -exe "Snipp! doctype \"XHTML 1.0 Frameset\" " -exe "Snipp! doctype \"XHTML 1.0 Strict\" " -exe "Snipp! doctype \"XHTML 1.0 Transitional\" " -exe "Snipp! doctype \"XHTML 1.1\" " -" HTML Doctype 4.01 Strict -exe "Snipp docts " -" HTML Doctype 4.01 Transitional -exe "Snipp doct " -" HTML Doctype 5 -exe 'Snipp doct5 ' -" XHTML Doctype 1.0 Frameset -exe "Snipp docxf " -" XHTML Doctype 1.0 Strict -exe "Snipp docxs " -" XHTML Doctype 1.0 Transitional -exe "Snipp docxt " -" XHTML Doctype 1.1 -exe "Snipp docx " -exe "Snipp html \n${1}\n" -exe "Snipp xhtml \n${1}\n" -exe "Snipp body \n\t${1}\n" -exe "Snipp head \n\t\n\t" -\. "${1:`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`}\n\t${2}\n" -exe 'Snipp title ${1:`substitute(Filename("", "Page Title"), "^.", "\\u&", "")`}${2}' -exe "Snipp script ${2}" -exe "Snipp scriptsrc ${2}" -exe "Snipp style ${3}" -exe 'Snipp base ' -exe 'Snipp r ' -exe "Snipp div
\n\t${2}\n
" -" Embed QT Movie -exe "Snipp movie \n\t\n\t\n\t\n\t\n${6}" -exe "Snipp fieldset
\n\t${1:name}\n\n\t${3}\n
" -exe "Snipp form
\n\t${3}\n\n\t" -\."

\n
" -exe 'Snipp h1

${2:$1}

' -exe 'Snipp input ${4}' -exe 'Snipp label ${7}' -exe 'Snipp link ${4}' -exe 'Snipp mailto ${3:email me}' -exe 'Snipp meta ${3}' -exe 'Snipp opt ${3}' -exe 'Snipp optt ${2}' -exe "Snipp select ${5}" -exe "Snipp table \n\t\n\t\n
${2:Header}
${3:Data}
${4}" -exe 'Snipp textarea ${5}' diff --git a/snip/after/ftplugin/java_snips.vim b/snip/after/ftplugin/java_snips.vim deleted file mode 100644 index adda47a..0000000 --- a/snip/after/ftplugin/java_snips.vim +++ /dev/null @@ -1,41 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_java_snips') - fini -en -let s:did_java_snips = 1 - -exe "Snipp main public static void main (String [] args)\n{\n\t${1:/* code */}\n}" -exe 'Snipp pu public' -exe 'Snipp po protected' -exe 'Snipp pr private' -exe 'Snipp st static' -exe 'Snipp fi final' -exe 'Snipp ab abstract' -exe 'Snipp re return' -exe 'Snipp br break;' -exe "Snipp de default:\n\t${1}" -exe 'Snipp ca catch(${1:Exception} ${2:e}) ${3}' -exe 'Snipp th throw ' -exe 'Snipp sy synchronized' -exe 'Snipp im import' -exe 'Snipp j.u java.util' -exe 'Snipp j.i java.io.' -exe 'Snipp j.b java.beans.' -exe 'Snipp j.n java.net.' -exe 'Snipp j.m java.math.' -exe 'Snipp if if (${1}) ${2}' -exe 'Snipp el else ' -exe 'Snipp elif else if (${1}) ${2}' -exe 'Snipp wh while (${1}) ${2}' -exe 'Snipp for for (${1}; ${2}; ${3}) ${4}' -exe 'Snipp fore for (${1} : ${2}) ${3}' -exe 'Snipp sw switch (${1}) ${2}' -exe "Snipp cs case ${1}:\n\t${2}\n${3}" -exe 'Snipp tc public class ${1:`Filename()`} extends ${2:TestCase}' -exe 'Snipp t public void test${1:Name}() throws Exception ${2}' -exe 'Snipp cl class ${1:`Filename("", "untitled")`} ${2}' -exe 'Snipp in interface ${1:`Filename("", "untitled")`} ${2:extends Parent}${3}' -exe 'Snipp m ${1:void} ${2:method}(${3}) ${4:throws }${5}' -exe 'Snipp v ${1:String} ${2:var}${3: = null}${4};${5}' -exe 'Snipp co static public final ${1:String} ${2:var} = ${3};${4}' -exe 'Snipp cos static public final String ${1:var} = "${2}";${3}' -exe 'Snipp as assert ${1:test} : "${2:Failure message}";${3}' diff --git a/snip/after/ftplugin/javascript_snips.vim b/snip/after/ftplugin/javascript_snips.vim deleted file mode 100644 index d273791..0000000 --- a/snip/after/ftplugin/javascript_snips.vim +++ /dev/null @@ -1,37 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_js_snips') - fini -en -let s:did_js_snips = 1 - -" Prototype -exe "Snipp proto ${1:class_name}.prototype.${2:method_name} =\nfunction(${3:first_argument}) {\n\t${4:// body...}\n};" -" Function -exe "Snipp fun function ${1:function_name} (${2:argument}) {\n\t${3:// body...}\n}" -" Anonymous Function -exe 'Snipp f function(${1}) {${2}};' -" if -exe 'Snipp if if (${1:true}) {${2}};' -" if ... else -exe "Snipp ife if (${1:true}) {${2}}\nelse{${3}};" -" tertiary conditional -exe 'Snipp t ${1:/* condition */} ? ${2:a} : ${3:b}' -" switch -exe "Snipp switch switch(${1:expression}) {\n\tcase '${3:case}':\n\t\t${4:// code}\n\t\tbreak;\n\t${5}\n\tdefault:\n\t\t${2:// code}\n}" -" case -exe "Snipp case case '${1:case}':\n\t${2:// code}\n\tbreak;\n${3}" -" for (...) {...} -exe "Snipp for for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3:++}) {\n\t${4:$1[$2]}\n};" -" for (...) {...} (Improved Native For-Loop) -exe "Snipp forr for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3:--}) {\n\t${4:$1[$2]}\n};" -" while (...) {...} -exe "Snipp wh while (${1:/* condition */}) {\n\t${2:/* code */}\n}" -" do...while -exe "Snipp do do {\n\t${2:/* code */}\n} while (${1:/* condition */});" -" Object Method -exe "Snipp :f ${1:method_name}: function(${2:attribute}) {\n\t${4}\n}${3:,}" -" setTimeout function -exe 'Snipp timeout setTimeout(function() {${3}}${2}, ${1:10};' -" Get Elements -exe "Snipp get getElementsBy${1:TagName}('${2}')${3}" -" Get Element -exe "Snipp gett getElementBy${1:Id}('${2}')${3}" diff --git a/snip/after/ftplugin/objc_snips.vim b/snip/after/ftplugin/objc_snips.vim deleted file mode 100644 index 6a04b71..0000000 --- a/snip/after/ftplugin/objc_snips.vim +++ /dev/null @@ -1,54 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_objc_snips') - fini -en -let s:did_objc_snips = 1 - -" #import <...> -exe 'Snipp imp #import <${1:Cocoa/Cocoa.h}>${2}' -" #import "..." -exe 'Snipp Imp #import "${1:`Filename()`.h}"${2}' -" @selector(...) -exe 'Snipp sel @selector(${1:method}:)${3}' -" NSLog(...) -exe 'Snipp log NSLog(@"${1}"${2});${3}' -" Class -exe "Snipp objc @interface ${1:`Filename('', 'object')`} : ${2:NSObject}\n{\n}\n@end\n\n@implementation $1\n- (id) init\n{\n\tif (self = [super init])" -\."\n\t{${3}\n\t}\n\treturn self\n}\n@end" -" Class Interface -exe "Snipp clh @interface ${1:ClassName} : ${2:NSObject}\n{${3}\n}\n${4}\n@end" -exe 'Snipp ibo IBOutlet ${1:NSSomeClass} *${2:$1};' -" Category -exe "Snipp cat @interface ${1:NSObject} (${2:Category})\n@end\n\n@implementation $1 ($2)\n${3}\n@end" -" Category Interface -exe "Snipp cath @interface ${1:NSObject} (${2:Category})\n${3}\n@end" -" NSArray -exe 'Snipp array NSMutableArray *${1:array} = [NSMutable array];${2}' -" NSDictionary -exe 'Snipp dict NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2}' -" NSBezierPath -exe 'Snipp bez NSBezierPath *${1:path} = [NSBezierPath bezierPath];${2}' -" Method -exe "Snipp m - (${1:id})${2:method}\n{\n\t${3:return self;}\n}" -" Method declaration -exe "Snipp md - (${1:id})${2:method};${3}" -" Class Method -exe "Snipp M + (${1:id})${2:method}\n{${3}\n\treturn nil;\n}" -" Sub-method (Call super) -exe "Snipp sm - (${1:id})${2:method}\n{\n\t[super $2];${3}\n\treturn self;\n}" -" Method: Initialize -exe "Snipp I + (void) initialize\n{\n\t[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWIthObjectsAndKeys:\n\t\t${1}@\"value\", @\"key\",\n\t\tnil]];\n}" -" Accessor Methods For: -" Object -exe "Snipp objacc - (${1:id})${2:thing}\n{\n\treturn $2;\n}\n\n- (void) set$2:($1)\n{\n\t$1 old$2 = $2;\n\t$2 = [aValue retain];\n\t[old$2 release];\n}" -exe "Snipp forarray unsigned int\t${1:object}Count = [${2:array} count];\n\nfor (unsigned int index = 0; index < $1Count; index++)\n{\n\t${3:id}\t$1 = [$2 $1AtIndex:index];\n\t${4}\n}" -" IBOutlet -" @property (Objective-C 2.0) -exe "Snipp prop @property (${1:retain}) ${2:NSSomeClass} *${3:$2};${4}" -" @synthesize (Objective-C 2.0) -exe "Snipp syn @synthesize ${1:NSSomeClass};${2}" -" [[ alloc] init] -exe 'Snipp alloc [[${1:foo} alloc] init]${2};${3}' -" retain -exe 'Snipp ret [${1:foo} retain];${2}' -" release -exe 'Snipp rel [${1:foo} release];${2}' diff --git a/snip/after/ftplugin/perl_snips.vim b/snip/after/ftplugin/perl_snips.vim deleted file mode 100644 index 1a0e230..0000000 --- a/snip/after/ftplugin/perl_snips.vim +++ /dev/null @@ -1,37 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_perl_snips') - fini -en -let s:did_perl_snips = 1 - -" Hash Pointer -exe 'Snipp . =>' -" Function -exe "Snipp sub sub ${1:function_name} {\n\t${2:#body ...}\n}" -" Conditional -exe "Snipp if if (${1}) {\n\t${2:# body...}\n}" -" Conditional if..else -exe "Snipp ife if (${1}) {\n\t${2:# body...}\n} else {\n\t${3:# else...}\n}" -" Conditional if..elsif..else -exe "Snipp ifee if (${1}) {\n\t${2:# body...}\n} elsif (${3}) {\n\t${4:# elsif...}\n} else {\n\t${5:# else...}\n}" -" Conditional One-line -exe 'Snipp xif ${1:expression} if ${2:condition};${3}' -" Unless conditional -exe "Snipp unless unless (${1}) {\n\t${2:# body...}\n}" -" Unless conditional One-line -exe 'Snipp xunless ${1:expression} unless ${2:condition};${3}' -" Try/Except -exe "Snipp eval eval {\n\t${1:# do something risky...}\n};\nif ($@) {\n\t${2:# handle failure...}\n}" -" While Loop -exe "Snipp wh while (${1}) {\n\t${2:# body...}\n}" -" While Loop One-line -exe "Snipp xwh ${1:expression} while ${2:condition};${3}" -" For Loop -exe "Snipp for for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) {\n\t${4:# body...}\n}" -" Foreach Loop -exe "Snipp fore foreach my $${1:x} (@${2:array}) {\n\t${3:# body...}\n}" -" Foreach Loop One-line -exe 'Snipp xfore ${1:expression} foreach @${2:array};${3}' -" Package -exe "Snipp cl package ${1:ClassName};\n\nuse base qw(${2:ParentClass});\n\nsub new {\n\tmy $class = shift;\n\t$class = ref $class if ref $class;\n\tmy $self = bless {}, $class;\n\t$self;\n}\n\n1;${3}" -" Read File -exe "Snipp slurp my $${1:var};\n{ local $/ = undef; local *FILE; open FILE, \"<${2:file}\"; $$1 = ; close FILE }${2}" diff --git a/snip/after/ftplugin/php_snips.vim b/snip/after/ftplugin/php_snips.vim deleted file mode 100644 index 7a87720..0000000 --- a/snip/after/ftplugin/php_snips.vim +++ /dev/null @@ -1,67 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_php_snips') - fini -en -let s:did_php_snips = 1 - -exe "Snipp php " -exe 'Snipp ec echo "${1:string}"${2};' -exe "Snipp inc include '${1:file}';${2}" -exe "Snipp inc1 include_once '${1:file}';${2}" -exe "Snipp req require '${1:file}';${2}" -exe "Snipp req1 require_once '${1:file}';${2}" -" $GLOBALS['...'] -exe "Snipp globals $GLOBALS['${1:variable}']${2: = }${3:something}${4:;}${5}" -exe "Snipp! $_ \"COOKIE['...']\" $_COOKIE['${1:variable}']${2}" -exe "Snipp! $_ \"ENV['...']\" $_ENV['${1:variable}']${2}" -exe "Snipp! $_ \"FILES['...']\" $_FILES['${1:variable}']${2}" -exe "Snipp! $_ \"Get['...']\" $_GET['${1:variable}']${2}" -exe "Snipp! $_ \"POST['...']\" $_POST['${1:variable}']${2}" -exe "Snipp! $_ \"REQUEST['...']\" $_REQUEST['${1:variable}']${2}" -exe "Snipp! $_ \"SERVER['...']\" $_SERVER['${1:variable}']${2}" -exe "Snipp! $_ \"SESSION['...']\" $_SESSION['${1:variable}']${2}" -" Start Docblock -exe "Snipp /* /**\n * ${1}\n **/" -" Class - post doc -exe "Snipp doc_cp /**\n * ${1:undocumented class}\n *\n * @package ${2:default}\n * @author ${3:`g:snips_author`}\n**/${4}" -" Class Variable - post doc -exe "Snipp doc_vp /**\n * ${1:undocumented class variable}\n *\n * @var ${2:string}\n **/${3}" -" Class Variable -exe "Snipp doc_v /**\n * ${3:undocumented class variable}\n *\n * @var ${4:string}\n **/\n${1:var} $${2};${5}" -" Class -exe "Snipp doc_c /**\n * ${3:undocumented class}\n *\n * @packaged ${4:default}\n * @author ${5:`g:snips_author`}\n **/\n${1:}class ${2:}\n{${6}\n} // END $1class $2" -" Constant Definition - post doc -exe "Snipp doc_dp /**\n * ${1:undocumented constant}\n **/${2}" -" Constant Definition -exe "Snipp doc_d /**\n * ${3:undocumented constant}\n **/\ndefine(${1}, ${2});${4}" -" Function - post doc -exe "Snipp doc_fp /**\n * ${1:undocumented function}\n *\n * @return ${2:void}\n * @author ${3:`g:snips_author`}\n **/${4}" -" Function signature -exe "Snipp doc_s /**\n * ${4:undocumented function}\n *\n * @return ${5:void}\n * @author ${6:`g:snips_author`}\n **/\n${1}function ${2}(${3});${7}" -" Function -exe "Snipp doc_f /**\n * ${4:undocumented function}\n *\n * @return ${5:void}\n * @author ${6:`g:snips_author`}\n **/\n${1}function ${2}(${3})\n{${7}\n}" -" Header -exe "Snipp doc_h /**\n * ${1}\n *\n * @author ${2:`g:snips_author`}\n * @version ${3:$Id$}\n * @copyright ${4:$2}, `strftime('%d %B, %Y')`\n * @package ${5:default}\n **/\n\n/**\n * Define DocBlock\n *//" -" Interface -exe "Snipp doc_i /**\n * ${2:undocumented class}\n *\n * @package ${3:default}\n * @author ${4:`g:snips_author`}\n **/\ninterface ${1:}\n{${5}\n} // END interface $1" -" class ... -exe "Snipp class /**\n * ${1}\n **/\nclass ${2:ClassName}\n{\n\t${3}\n\tfunction ${4:__construct}(${5:argument})\n\t{\n\t\t${6:// code...}\n\t}\n}" -" define(...) -exe "Snipp def define('${1}'${2});${3}" -" defined(...) -exe "Snipp def? ${1}defined('${2}')${3}" -exe "Snipp wh while (${1:/* condition */}) {\n\t${2:// code...}\n}" -" do ... while -exe "Snipp do do {\n\t${2:// code... }\n} while (${1:/* condition */});" -exe "Snipp if if (${1:/* condition */}) {\n\t${2:// code...}\n}" -exe "Snipp ife if (${1:/* condition */}) {\n\t${2:// code...}\n} else {\n\t${3:// code...}\n}\n${4}" -exe "Snipp else else {\n\t${1:// code...}\n}" -exe "Snipp elseif elseif (${1:/* condition */}) {\n\t${2:// code...}\n}" -" Tertiary conditional -exe "Snipp t $${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5}" -exe "Snipp switch switch ($${1:variable}) {\n\tcase '${2:value}':\n\t\t${3:// code...}\n\t\tbreak;\n\t${5}\n\tdefault:\n\t\t${4:// code...}\n\t\tbreak;\n}" -exe "Snipp case case '${1:value}':\n\t${2:// code...}\n\tbreak;${3}" -exe "Snipp for for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) {\n\t${4: // code...}\n}" -exe "Snipp foreach foreach ($${1:variable} as $${2:key}) {\n\t${3:// code...}\n}" -exe "Snipp fun ${1:public }function ${2:FunctionName}(${3})\n{\n\t${4:// code...}\n}" -" $... = array (...) -exe "Snipp array $${1:arrayName} = array('${2}' => ${3});${4}" diff --git a/snip/after/ftplugin/python_snips.vim b/snip/after/ftplugin/python_snips.vim deleted file mode 100644 index e663039..0000000 --- a/snip/after/ftplugin/python_snips.vim +++ /dev/null @@ -1,28 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_python_snips') - fini -en -let s:did_python_snips = 1 - -" New Class -exe "Snipp cl class ${1:ClassName}(${2:object}):\n\t\"\"\"${3:docstring for $1}\"\"\"\n\tdef __init__(self, ${4:arg}):\n\t\t${5:super($1, self).__init__()}\n\t\tself.$4 = $4\n\t\t${6}" -" New Function -exe "Snipp def def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):\n\t\"\"\"${3:docstring for $1}\"\"\"\n\t${4:pass}" -" New Method -exe "Snipp defs def ${1:mname}(self, ${2:arg})):\n\t${3:pass}" -" New Property -exe "Snipp property def ${1:foo}():\n\tdoc = \"${2:The $1 property.}\"\n\tdef fget(self):\n\t\t\t${3:return self._$1}\n\tdef fset(self, value):\n\t\t" -\."${4:self._$1 = value}\n\tdef fdel(self):\n\t\t\t${5:del self._$1}\n\treturn locals()\n$1 = property(**$1())${6}" -" Self -exe 'Snipp . self.' -" Try/Except -exe "Snipp try try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}" -" Try/Except/Else -exe "Snipp trye try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nelse:\n\t${5:pass}" -" Try/Except/Finally -exe "Snipp tryf try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nfinally:\n\t${5:pass}" -" Try/Except/Else/Finally -exe "Snipp tryef try:\n\t${1:pass}\nexcept ${2:Exception}, ${3:e}:\n\t${4:raise $3}\nelse:\n\t${5:pass}\nfinally:\n\t${6:pass}" -" if __name__ == '__main__': -exe "Snipp ifmain if __name__ == '__main__':\n\t${1:main()}" -" __magic__ -exe 'Snipp _ __${1:init}__${2}' diff --git a/snip/after/ftplugin/ruby_snips.vim b/snip/after/ftplugin/ruby_snips.vim deleted file mode 100644 index de16c6e..0000000 --- a/snip/after/ftplugin/ruby_snips.vim +++ /dev/null @@ -1,167 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_ruby_snips') - fini -en -let s:did_ruby_snips = 1 - -" New Block -exe "Snipp =b =begin rdoc\n\t${1}\n=end" -exe "Snipp y :yields: ${1:arguments}" -exe "Snipp rb #!/usr/bin/env ruby -wKU\n" -exe 'Snipp req require "${1}"${2}' -exe 'Snipp # # =>' -exe 'Snipp end __END__' -exe "Snipp case case ${1:object}\nwhen ${2:condition}\n\t${3}\nend" -exe "Snipp when when ${1:condition}\n\t${2}" -exe "Snipp def def ${1:method_name}\n\t${2}\nend" -exe "Snipp deft def test_${1:case_name}\n\t${2}\nend" -exe "Snipp if if ${1:condition}\n\t${2}\nend" -exe "Snipp ife if ${1:condition}\n\t${2}\nelse\n\t${3}\nend" -exe "Snipp elsif elsif ${1:condition}\n\t${2}" -exe "Snipp unless unless ${1:condition}\n\t${2}\nend" -exe "Snipp while while ${1:condition}\n\t${2}\nend" -exe "Snipp until until ${1:condition}\n\t${2}\nend" -exe "Snipp! cla \"class .. end\" class ${1:`substitute(Filename(), '^.', '\\u&', '')`}\n\t${2}\nend" -exe "Snipp! cla \"class .. initialize .. end\" class ${1:`substitute(Filename(), '^.', '\\u&', '')`}\n\tdef initialize(${2:args})\n\t\t${3}\n\tend\n\n\nend" -exe "Snipp! cla \"class .. < ParentClass .. initialize .. end\" class ${1:`substitute(Filename(), '^.', '\\u&', '')`} < ${2:ParentClass}\n\tdef initialize(${3:args})\n\t\t${4}\n\tend\n\n\nend" -exe "Snipp! cla \"ClassName = Struct .. do .. end\" ${1:`substitute(Filename(), '^.', '\\u&', '')`} = Struct.new(:${2:attr_names}) do\n\tdef ${3:method_name}\n\t\t${4}\n\tend\n\n\nend" -exe "Snipp! cla \"class BlankSlate .. initialize .. end\" class ${1:BlankSlate}\n\tinstance_methods.each { |meth| undef_method(meth) unless meth =~ /\A__/ }" -\ ."\n\n\tdef initialize(${2:args})\n\t\t@${3:delegate} = ${4:$3_object}\n\n\t\t${5}\n\tend\n\n\tdef method_missing(meth, *args, &block)\n\t\t@$3.send(meth, *args, &block)\n\tend\n\n\nend" -exe "Snipp! cla \"class << self .. end\" class << ${1:self}\n\t${2}\nend" -" class .. < DelegateClass .. initialize .. end -exe "Snipp cla- class ${1:`substitute(Filename(), '^.', '\\u&', '')`} < DelegateClass(${2:ParentClass})\n\tdef initialize(${3:args})\n\t\tsuper(${4:del_obj})\n\n\t\t${5}\n\tend\n\n\nend" -exe "Snipp! mod \"module .. end\" module ${1:`substitute(Filename(), '^.', '\\u&', '')`}\n\t${2}\nend" -exe "Snipp! mod \"module .. module_function .. end\" module ${1:`substitute(Filename(), '^.', '\\u&', '')`}\n\tmodule_function\n\n\t${2}\nend" -exe "Snipp! mod \"module .. ClassMethods .. end\" module ${1:`substitute(Filename(), '^.', '\\u&', '')`}\n\tmodule ClassMethods\n\t\t${2}\n\tend\n\n\t" -\."module InstanceMethods\n\n\tend\n\n\tdef self.included(receiver)\n\t\treceiver.extend ClassMethods\n\t\treseiver.send :include, InstanceMethods\n\tend\nend" -" attr_reader -exe 'Snipp r attr_reader :${1:attr_names}' -" attr_writer -exe 'Snipp w attr_writer :${1:attr_names}' -" attr_accessor -exe 'Snipp rw attr_accessor :${1:attr_names}' -" include Enumerable -exe "Snipp Enum include Enumerable\n\ndef each(&block)\n\t${1}\nend" -" include Comparable -exe "Snipp Comp include Comparable\n\ndef <=>(other)\n\t${1}\nend" -" extend Forwardable -exe 'Snipp Forw- extend Forwardable' -" def self -exe "Snipp defs def self.${1:class_method_name}\n\t${2}\nend" -" def method_missing -exe "Snipp defmm def method_missing(meth, *args, &blk)\n\t${1}\nend" -exe 'Snipp defd def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}' -exe 'Snipp defds def_delegators :${1:@del_obj}, :${2:del_methods}' -exe 'Snipp am alias_method :${1:new_name}, :${2:old_name}' -exe "Snipp app if __FILE__ == $PROGRAM_NAME\n\t${1}\nend" -" usage_if() -exe "Snipp usai if ARGV.${1}\n\tabort \"Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}\"${3}\nend" -" usage_unless() -exe "Snipp usau unless ARGV.${1}\n\tabort \"Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}\"${3}\nend" -exe 'Snipp array Array.new(${1:10}) { |${2:i}| ${3} }' -exe 'Snipp hash Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }' -exe 'Snipp! file "File.foreach() { |line| .. }" File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }' -exe 'Snipp! file "File.read()" File.read(${1:"path/to/file"})${2}' -exe 'Snipp! Dir "Dir.global() { |file| .. }" Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }' -exe 'Snipp! Dir "Dir[''..'']" Dir[${1:"glob/**/*.rb"}]${2}' -exe 'Snipp dir Filename.dirname(__FILE__)' -exe 'Snipp deli delete_if { |${1:e}| ${2} }' -exe 'Snipp fil fill(${1:range}) { |${2:i}| ${3} }' -" flatten_once() -exe 'Snipp flao inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}' -exe 'Snipp zip zip(${1:enums}) { |${2:row}| ${3} }' -" downto(0) { |n| .. } -exe 'Snipp dow downto(${1:0}) { |${2:n}| ${3} }' -exe 'Snipp ste step(${1:2}) { |${2:n}| ${3} }' -exe 'Snipp tim times { |${1:n}| ${2} }' -exe 'Snipp upt upto(${1:1.0/0.0}) { |${2:n}| ${3} }' -exe 'Snipp loo loop { ${1} }' -exe 'Snipp ea each { |${1:e}| ${2} }' -exe 'Snipp eab each_byte { |${1:byte}| ${2} }' -exe 'Snipp! eac- "each_char { |chr| .. }" each_char { |${1:chr}| ${2} }' -exe 'Snipp! eac- "each_cons(..) { |group| .. }" each_cons(${1:2}) { |${2:group}| ${3} }' -exe 'Snipp eai each_index { |${1:i}| ${2} }' -exe 'Snipp eak each_key { |${1:key}| ${2} }' -exe 'Snipp eal each_line { |${1:line}| ${2} }' -exe 'Snipp eap each_pair { |${1:name}, ${2:val}| ${3} }' -exe 'Snipp eas- each_slice(${1:2}) { |${2:group}| ${3} }' -exe 'Snipp eav each_value { |${1:val}| ${2} }' -exe 'Snipp eawi each_with_index { |${1:e}, ${2:i}| ${3} }' -exe 'Snipp reve reverse_each { |${1:e}| ${2} }' -exe 'Snipp inj inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }' -exe 'Snipp map map { |${1:e}| ${2} }' -exe 'Snipp mapwi- enum_with_index.map { |${1:e}, ${2:i}| ${3} }' -exe 'Snipp sor sort { |a, b| ${1} }' -exe 'Snipp sorb sort_by { |${1:e}| ${2} }' -exe 'Snipp ran sort_by { rand }' -exe 'Snipp all all? { |${1:e}| ${2} }' -exe 'Snipp any any? { |${1:e}| ${2} }' -exe 'Snipp cl classify { |${1:e}| ${2} }' -exe 'Snipp col collect { |${1:e}| ${2} }' -exe 'Snipp det detect { |${1:e}| ${2} }' -exe 'Snipp fet fetch(${1:name}) { |${2:key}| ${3} }' -exe 'Snipp fin find { |${1:e}| ${2} }' -exe 'Snipp fina find_all { |${1:e}| ${2} }' -exe 'Snipp gre grep(${1:/pattern/}) { |${2:match}| ${3} }' -exe 'Snipp sub ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }' -exe 'Snipp sca scan(${1:/pattern/}) { |${2:match}| ${3} }' -exe 'Snipp max max { |a, b|, ${1} }' -exe 'Snipp min min { |a, b|, ${1} }' -exe 'Snipp par partition { |${1:e}|, ${2} }' -exe 'Snipp rej reject { |${1:e}|, ${2} }' -exe 'Snipp sel select { |${1:e}|, ${2} }' -exe 'Snipp lam lambda { |${1:args}| ${2} }' -exe "Snipp do do |${1:variable}|\n\t${2}\nend" -exe 'Snipp : :${1:key} => ${2:"value"}${3}' -exe 'Snipp ope open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }' -" path_from_here() -exe 'Snipp patfh File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}' -" unix_filter {} -exe "Snipp unif ARGF.each_line${1} do |${2:line}|\n\t${3}\nend" -" option_parse {} -exe "Snipp optp require \"optparse\"\n\noptions = {${1:default => \"args\"}}\n\nARGV.options do |opts|\n\topts.banner = \"Usage: #{File.basename($PROGRAM_NAME)}" -\."[OPTIONS] ${2:OTHER_ARGS}\"\n\n\topts.separator \"\"\n\topts.separator \"Specific Options:\"\n\n\t${3}\n\n\topts.separator \"Common Options:\"\n\n\t" -\."opts.on( \"-h\", \"--help\",\n \"Show this message.\" ) do\n\t\tputs opts\n\t\texit\n\tend\n\n\tbegin\n\t\topts.parse!\n\trescue\n\t\tputs opts\n\t\texit\n\tend\nend" -exe "Snipp opt opts.on( \"-${1:o}\", \"--${2:long-option-name}\", ${3:String},\n \"${4:Option description.}\") do |${5:opt}|\n\t${6}\nend" -exe "Snipp tc require \"test/unit\"\n\nrequire \"${1:library_file_name}\"\n\nclass Test${2:$1} < Test::Unit::TestCase\n\tdef test_${3:case_name}\n\t\t${4}\n\tend\nend" -exe "Snipp ts require \"test/unit\"\n\nrequire \"tc_${1:test_case_file}\"\nrequire \"tc_${2:test_case_file}\"${3}" -exe 'Snipp as assert(${1:test}, \"${2:Failure message.}\")${3}' -exe 'Snipp ase assert_equal(${1:expected}, ${2:actual})${3}' -exe 'Snipp asne assert_not_equal(${1:unexpected}, ${2:actual})${3}' -exe 'Snipp asid assert_in_delta(${1:expected_float}, ${2:actual_float}, ${3:2 ** -20})${4}' -exe 'Snipp asio assert_instance_of(${1:ExpectedClass}, ${2:actual_instance})${3}' -exe 'Snipp asko assert_kind_of(${1:ExpectedKind}, ${2:actual_instance})${3}' -exe 'Snipp asn assert_nil(${1:instance})${2}' -exe 'Snipp asnn assert_not_nil(${1:instance})${2}' -exe 'Snipp asm assert_match(/${1:expected_pattern}/, ${2:actual_string})${3}' -exe 'Snipp asnm assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})${3}' -exe 'Snipp aso assert_operator(${1:left}, :${2:operator}, ${3:right})${4}' -exe 'Snipp asr assert_raise(${1:Exception}) { ${2} }' -exe 'Snipp asnr assert_nothing_raised(${1:Exception}) { ${2} }' -exe 'Snipp asrt assert_respond_to(${1:object}, :${2:method})${3}' -exe 'Snipp! ass "assert_same(..)" assert_same(${1:expected}, ${2:actual})${3}' -exe 'Snipp! ass "assert_send(..)" assert_send([${1:object}, :${2:message}, ${3:args}])${4}' -exe 'Snipp asns assert_not_same(${1:unexpected}, ${2:actual})${3}' -exe 'Snipp ast assert_throws(:${1:expected}) { ${2} }' -exe 'Snipp asnt assert_nothing_thrown { ${1} }' -exe 'Snipp fl flunk("${1:Failure message.}")${2}' -" Benchmark.bmbm do .. end -exe "Snipp bm- TESTS = ${1:10_000}\nBenchmark.bmbm do |results|\n\t${2}\nend" -exe 'Snipp rep results.report("${1:name}:") { TESTS.times { ${2} }}' -" Marshal.dump(.., file) -exe 'Snipp Md File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}' -" Mashal.load(obj) -exe 'Snipp Ml File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}' -" deep_copy(..) -exe 'Snipp deec Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}' -exe 'Snipp Pn- PStore.new(${1:"file_name.pstore"})${2}' -exe 'Snipp tra transaction(${1:true}) { ${2} }' -" xmlread(..) -exe 'Snipp xml- REXML::Document.new(File.read(${1:"path/to/file"}))${2}' -" xpath(..) { .. } -exe "Snipp xpa elements.each(${1:\"//Xpath\"}) do |${2:node}|\n\t${3}\nend" -" class_from_name() -exe 'Snipp clafn split("::").inject(Object) { |par, const| par.const_get(const) }' -" singleton_class() -exe 'Snipp sinc class << self; self end' -exe "Snipp nam namespace :${1:`Filename()`} do\n\t${2}\nend" -exe "Snipp tas desc \"${1:Task description\}\"\ntask :${2:task_name => [:dependent, :tasks]} do\n\t${3}\nend" diff --git a/snip/after/ftplugin/sh_snips.vim b/snip/after/ftplugin/sh_snips.vim deleted file mode 100644 index a7794da..0000000 --- a/snip/after/ftplugin/sh_snips.vim +++ /dev/null @@ -1,11 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_sh_snips') - fini -en -let s:did_sh_snips = 1 - -exe "Snipp if if [[ ${1:condition} ]]; then\n\t${2:#statements}\nfi" -exe "Snipp elif elif [[ ${1:condition} ]]; then\n\t${2:#statements}" -exe "Snipp for for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do\n\t${3:#statements}\ndone" -exe "Snipp wh while [[ ${1:condition} ]]; do\n\t${2:#statements}\ndone" -exe "Snipp until [[ ${1:condition} ]]; do\n\t${2:#statements}\ndone" -exe "Snipp case case ${1:word} in\n\t${2:pattern})\n\t\t${3};;\nesac" diff --git a/snip/after/ftplugin/tex_snips.vim b/snip/after/ftplugin/tex_snips.vim deleted file mode 100644 index b912802..0000000 --- a/snip/after/ftplugin/tex_snips.vim +++ /dev/null @@ -1,49 +0,0 @@ -if !exists('loaded_snips') || exists('s:did_tex_snips') - fini -en -let s:did_tex_snips = 1 - -" \begin{}...\end{} -exe "Snipp begin \\begin{${1:env}}\n\t${2}\n\\end{$1}" -" Tabular -exe "Snipp tab \\begin{${1:tabular}}{${2:c}}\n${3}\n\\end{$1}" -" Align(ed) -exe "Snipp ali \\begin{align${1:ed}}\n\t${2}\n\\end{align$1}" -" Gather(ed) -exe "Snipp gat \\begin{gather${1:ed}}\n\t${2}\n\\end{gather$1}" -" Equation -exe "Snipp eq \\begin{equation}\n\t${1}\n\\end{equation}" -" Unnumbered Equation -exe "Snipp \\ \\\\[\n\t${1}\n\\\\]" -" Enumerate -exe "Snipp enum \\begin{enumerate}\n\t\\item ${1}\n\\end{enumerate}" -" Itemize -exe "Snipp item \\begin{itemize}\n\t\\item ${1}\n\\end{itemize}" -" Description -exe "Snipp desc \\begin{description}\n\t\\item[${1}] ${2}\n\\end{description}" -" Matrix -exe "Snipp mat \\begin{${1:p/b/v/V/B/small}matrix}\n\t${2}\n\\end{$1matrix}" -" Cases -exe "Snipp cas \\begin{cases}\n\t${1:equation}, &\\text{ if }${2:case}\\\\\n\t${3}\n\\end{cases}" -" Split -exe "Snipp spl \\begin{split}\n\t${1}\n\\end{split}" -" Part -exe "Snipp part \\part{${1:part name}} % (fold)\n\\label{prt:${2:$1}}\n${3}\n% part $2 (end)" -" Chapter -exe "Snipp cha \\chapter{${1:chapter name}} % (fold)\n\\label{cha:${2:$1}}\n${3}\n% chapter $2 (end)" -" Section -exe "Snipp sec \\section{${1:section name}} % (fold)\n\\label{sec:${2:$1}}\n${3}\n% section $2 (end)" -" Sub Section -exe "Snipp sub \\subsection{${1:subsection name}} % (fold)\n\\label{sub:${2:$1}}\n${3}\n% subsection $2 (end)" -" Sub Sub Section -exe "Snipp subs \\subsubsection{${1:subsubsection name}} % (fold)\n\\label{ssub:${2:$1}}\n${3}\n% subsubsection $2 (end)" -" Paragraph -exe "Snipp par \\paragraph{${1:paragraph name}} % (fold)\n\\label{par:${2:$1}}\n${3}\n% paragraph $2 (end)" -" Sub Paragraph -exe "Snipp subp \\subparagraph{${1:subparagraph name}} % (fold)\n\\label{subp:${2:$1}}\n${3}\n% subparagraph $2 (end)" -exe 'Snipp itd \item[${1:description}] ${2:item}' -exe 'Snipp figure ${1:Figure}~\ref{${2:fig:}}${3}' -exe 'Snipp table ${1:Table}~\ref{${2:tab:}}${3}' -exe 'Snipp listing ${1:Listing}~\ref{${2:list}}${3}' -exe 'Snipp section ${1:Section}~\ref{${2:sec:}}${3}' -exe 'Snipp page ${1:page}~\pageref{${2}}${3}' diff --git a/snip/after/ftplugin/vim_snips.vim b/snip/after/ftplugin/vim_snips.vim deleted file mode 100644 index e5b4c9c..0000000 --- a/snip/after/ftplugin/vim_snips.vim +++ /dev/null @@ -1,16 +0,0 @@ -if !exists('g:loaded_snips') || exists('s:did_vim_snips') - fini -en -let s:did_vim_snips = 1 - -" snippets for making snippets :) -exe 'Snipp snip exe "Snipp ${1:trigger}"${2}' -exe "Snipp snipp exe 'Snipp ${1:trigger}'${2}" -exe 'Snipp gsnip exe "GlobalSnip ${1:trigger}"${2}' -exe "Snipp gsnipp exe 'GlobalSnip ${1:trigger}'${2}" - -exe "Snipp f fun ${1:function_name}()\n\t${2:\" code}\nendfun" -exe "Snipp for for ${1:needle} in ${2:haystack}\n\t${3:\" code}\nendfor" -exe "Snipp wh wh ${1:condition}\n\t${2:\" code}\nendw" -exe "Snipp if if ${1:condition}\n\t${2:\" code}\nendif" -exe "Snipp ife if ${1:condition}\n\t${2}\nelse\n\t${3}\nendif" diff --git a/snip/after/plugin/global_snips.vim b/snip/after/plugin/global_snips.vim deleted file mode 100644 index ba1ff9b..0000000 --- a/snip/after/plugin/global_snips.vim +++ /dev/null @@ -1,8 +0,0 @@ -if !exists('g:loaded_snips') || exists('s:did_snips') - fini -en -let s:did_snips = 1 - -" (c) holds no legal value ;) -exe 'GlobalSnip c) '.(&enc[:2] == 'utf' ? '©' : '(c)').' Copyright `strftime("%Y")` ${1:`g:snips_author`}. All Rights Reserved.${2}' -exe 'GlobalSnip date `strftime("%Y-%m-%d")`' diff --git a/snip/after/plugin/snipMate.vim b/snip/after/plugin/snipMate.vim deleted file mode 100644 index 96027bc..0000000 --- a/snip/after/plugin/snipMate.vim +++ /dev/null @@ -1,23 +0,0 @@ -" These are the mappings for snipMate.vim. Putting it here ensures that it -" will be mapped after other plugins such as supertab.vim. -if exists('s:did_snips_mappings') || &cp || version < 700 - fini -en -let s:did_snips_mappings = 1 - -ino =TriggerSnippet() -snor i=TriggerSnippet() -snor b -snor ' b' -snor a -snor bi - -" By default load snippets in ~/.vim/snippets/ -if isdirectory($HOME.'/.vim/snippets') - if isdirectory($HOME.'/.vim/snippets/_') - cal ExtractSnips($HOME.'/.vim/snippets/_', '_') - en - au FileType * if !exists('s:did_'.&ft) && - \ isdirectory($HOME.'/.vim/snippets/'.&ft) - \| cal ExtractSnips($HOME.'/.vim/snippets/'.&ft, &ft) | en -en diff --git a/snip/doc/snipMate.txt b/snip/doc/snipMate.txt deleted file mode 100644 index a3e63ff..0000000 --- a/snip/doc/snipMate.txt +++ /dev/null @@ -1,258 +0,0 @@ -*snipMate.txt* Plugin for using TextMate-style snippets in Vim. - -Snippets *snippet* *snippets* *snipMate* -Last Change: February 21, 2009 - -|snipMate-description| Description -|snipMate-usage| Usage -|snipMate-syntax| Snippet syntax -|snipMate-features| Features -|snipMate-disadvantages| Disadvantages to TextMate -|snipMate-contact| Contact - -For Vim version 7.0 or later. -This plugin only works if 'compatible' is not set. -{Vi does not have any of these features} - -============================================================================== -DESCRIPTION *snipMate-description* - -snipMate.vim implements some of TextMate's snippets features in -Vim. A snippet is a piece of often-typed text that you can -insert into your document using a trigger word followed by a . - -For instance, in a C file using the default installation of -snipMate.vim, if you type "for" in insert mode, -it will expand a typical for loop in C: > - - for (i = 0; i < count; i++) { - - } - - -To go to the next item in the loop, simply -over to it; if there is repeated code, such as the "i" variable -in this example, you can simply start typing once it's -highlighted and all the matches specified in the snippet will -be updated. - -============================================================================== -USAGE *snipMate-usage* - -There are two ways to make snippets: file-based and command-based. File-based -snippets are simply plain text files named after the trigger of the snippet -and placed in the directory of the filetype (/.snippet); -command-based snippets are snippets defined using the |Snipp| and |GlobalSnip| -commands. File-based snippets have the advantage of being easier to read, but -do not support some special characters in snippet triggers, while -command-based snippets are obviously convenient for short snippets but can -quickly get unreadable. - - *file-snippets* *'snippets'* -File-based snippets by default are looked for in the 'snippets' directory -inside your home '.vim' directory, typically located in -'~/.vim/snippets/'. To change that location or add another one, -edit '~/.vim/after/plugin/snipMate.vim' and use the |ExtractSnips()|function. - -ExtractSnips({directory}, {filetype}) *ExtractSnips()* - -ExtractSnips() extracts *.snippet files from the specified directory and -defines them as snippets for the given filetype; to define a global snippet, -use '_' for the {filetype} argument. - - *ResetSnips()* -The ResetSnips() function removes all snippets from memory. This is useful to -put at the top of a snippet setup file if you would like to :source it -multiple times. - - *command-snippets* -Command-based should be installed in the 'after' directory, usually located in -'~/.vim/after'. Filetype specific snippets should be installed in -'after/ftplugin', such as 'after/ftplugin/_snips.vim'. -See |ftplugins|. Global snippets should be installed in 'after/plugin'. -To ensure user snippets are not lost when upgrading the plugin, name them -using an ending other than "snips" such as "_mysnips.vim" - - *Snipp* *GlobalSnip* -Snipp and GlobalSnip Commands~ - -Snippets are added via the "Snipp" and "GlobalSnip" commands. The syntax for -these are "Snipp "; e.g.: > - - exe "Snipp trigger The cursor will be placed here." - exe "GlobalSnip another_trigger foo" - -"Snipp" creates snippets local to the buffer, while "GlobalSnip" creates -global snippets. "Snipp" is used instead of "Snip" to avoid conflicts with the -imaps.vim script that uses that command name. - -These commands are conveniently bound to snippets themselves; "snip" and -"gsnip", respectively. So to expand a Snipp command with double quotes, -type snip. Single quote Snipp and GlobalSnip commands are bound -to the snippets "snipp" and "gsnipp". See |literal-string| for the -difference between single and double quotes. - - *multi_snip* *Snipp!* *GlobalSnip!* -To specify that a snippet can have multiple matches, use the Snipp or -GlobalSnip command followed by a bang (!). The syntax for these are -'Snipp! "" '. (Note that the name must be -enclosed in double quotes). E.g.: > - - exe 'Snip! trigger "Snippet name #1" expand_this_text' - exe 'Snip! trigger "Snippet name #2" expand_THIS_text!' - -In this example, when "trigger" is typed, a numbered menu containing all -of the names for the "trigger" will be shown; when the user presses the -corresponding number, that snippet will then be expanded. - -To ensure snipMate.vim is loaded and 'compatible' is not set, make sure -to add: > - - if !exists('g:loaded_snips') - fini - en - -to the top of your snippets files. - - *snipMate-expandtab* *snipMate-indenting* -If you would like your snippets to use spaces instead of tabs, just enable -'expandtab' and set 'softtabstop' to your preferred amount of spaces. If -'softtabstop' is not set, 'shiftwidth' is used instead. - -============================================================================== -SYNTAX *snipMate-syntax* *snipMate-${#}* - -Tab stops ~ - -By default, the cursor is placed at the end of a snippet. To specify where the -cursor is to be placed next, use "${#}", where the # is the number of the tab -stop. E.g., to place the cursor first on the id of a
tag, and then allow -the user to to the middle of it: - > - exe "Snipp div
\n\t${2}\n
" -< - *snipMate-placeholders* *snipMate-${#:}* *snipMate-$#* -Placeholders ~ - -Placeholder text can be supplied using "${#:text}", where # is the number of -the tab stop. This text then can be copied throughout the snippet using "$#", -given # is the same number as used before. So, to make a C for loop: > - - exe "Snipp for for (${2:i}; $2 < ${1:count}; $1++) {\n\t${4}\n}" - -This will cause "count" to first be selected and change if the user starts -typing. When is pressed, the "i" in ${2}'s position will be selected; -all $2 variables will default to "i" and automatically be updated if the user -starts typing. -NOTE: "$#" syntax is used only for variables, not for tab stops as in TextMate. - -Variables within variables are also possible. For instance: > - - exe 'Snipp opt ' - -Will, as usual, cause "option" to first be selected and update all the $1 -variables if the user starts typing. Since one of these variables is inside of -${2}, this text will then be used as a placeholder for the next tab stop, -allowing the user to change it if he wishes. - -To copy a value throughout a snippet without supplying default text, simply -use the "${#:}" construct without the text; e.g.: > - - exe 'Snipp foo${1:}bar$1' -< *snipMate-commands* -Interpolated Vim Script ~ - -Snippets can also contain Vim script commands that are executed (via |eval()|) -when the snippet is inserted. Commands are given inside backticks (`...`); for -TextMates's functionality, use the |system()| function. E.g.: > - - exe 'Snipp date `system("date +%Y-%m-%d")`' - -will insert the current date, assuming you are on a Unix system. Note you can -also (and should) use |strftime()| for this example. - -Filename([{expr}, {defaultText}]) *snipMate-filename* *Filename()* - -Since the current filename is used often in snippets, a default function -has been defined for it in snipMate.vim, appropriately called Filename(). - -With no arguments, the default filename without an extension is returned; -the first argument specifies what to place before or after the filename, -and the second argument supplies the default text to be used if the file -has not been named. "$1" in the first argument is replaced with the filename; -if you only want the filename to be returned, the first argument can be left -blank. Examples: > - - exe 'Snipp filename `Filename()`' - exe 'Snipp filename_with_default `Filename("", "name")`' - exe 'Snipp filename_foo `Filename("$1_foo")`' - - -The first example returns the filename if it the file has been named, and an -empty string if it hasn't. The second returns the filename if it's been named, -and "name" if it hasn't. The third returns the filename followed by "_foo" if -it has been named, and an empty string if it hasn't. - - *snipMate-settings* *g:snips_author* -The g:snips_author string (similar to $TM_FULLNAME in TextMate) should be set -to your name; it can then be used in snippets to automatically add it. E.g.: > - - let g:snips_author = 'Hubert Farnsworth' - exe 'Snipp name `g:snips_author`' -< - *snipMate-remap* -snipMate does not come with a setting to customize the trigger key, but you -can remap it easily in the two lines it's defined in -'~/.vim/after/plugin/snipMate.vim'. For instance, to change the trigger key -to shift-tab, just change this: > - ino =ExpandSnippet() - snor i=ExpandSnippet() - -to this: > - ino =ExpandSnippet() - snor i=ExpandSnippet() - -============================================================================== -FEATURES *snipMate-features* - -snipMate.vim has the following features among others: - - The syntax of snippets is very similar to TextMate's, allowing - easy conversion. - - The position of the snippet is kept transparently (i.e. it does not use - markers/placeholders written to the buffer), which allows you to escape - out of an incomplete snippet, something particularly useful in Vim. - - Variables in snippets are updated as-you-type. - - Snippets can have multiple matches. - - Snippets can be out of order. For instance, in a do...while loop, the - condition can be added before the code. - -============================================================================== -DISADVANTAGES *snipMate-disadvantages* - -snipMate.vim currently has the following disadvantages to TextMate's snippets: - - There is no way to go back a tab stop, like shift-tab in TextMate. - - There is no $0; the order of tab stops must be explicitly stated. - - Placeholders within placeholders are not possible. E.g.: > - - '${3}
' -< - In TextMate this would first highlight ' id="some_id"', and if - you hit delete it would automatically skip ${2} and go to ${3} - on the next , but if you didn't delete it it would highlight - "some_id" first. You cannot do this in snipMate.vim. - - Regex cannot be performed on variables, such as "${1/.*/\U&}" - - Placeholders cannot span multiple lines. - - Activating snippets in different scopes of the same file is - not possible. - -Perhaps some of these features will be added in a later release. - -============================================================================== -CONTACT *snipMate-contact* *snipMate-author* - -To contact the author (Michael Sanders), please email: - msanders42+snipmate gmail com - -I greatly appreciate any suggestions or improvements offered for the script. - -vim:tw=78:ts=8:ft=help:norl: diff --git a/snip/plugin/snipMate.vim b/snip/plugin/snipMate.vim deleted file mode 100644 index b3116ce..0000000 --- a/snip/plugin/snipMate.vim +++ /dev/null @@ -1,557 +0,0 @@ -" File: snipMate.vim -" Author: Michael Sanders -" Version: 0.7 -" Description: snipMate.vim implements some of TextMate's snippets features in -" Vim. A snippet is a piece of often-typed text that you can -" insert into your document using a trigger word followed by a "". -" -" For more help see snipMate.txt; you can do this by using: -" :helptags ~/.vim/doc -" :h snipMate.txt -" Last Modified: February 25, 2009. - -if exists('loaded_snips') || &cp || version < 700 - finish -endif -let loaded_snips = 1 -if !exists('snips_author') | let snips_author = 'Me' | endif - -com! -nargs=+ -bang Snipp call s:MakeSnippet(, &ft, 0) -com! -nargs=+ -bang GlobalSnip call s:MakeSnippet(, '_', 0) - -let s:snippets = {} | let s:multi_snips = {} - -fun! Filename(...) - let filename = expand('%:t:r') - if filename == '' | return a:0 == 2 ? a:2 : '' | endif - return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') -endf - -" escapes special characters in snippet triggers -fun s:Hash(text) - return substitute(a:text, '\W', '\="_".char2nr(submatch(0))."_"', 'g') -endf - -fun s:MakeSnippet(text, ft, multisnip) - let space = stridx(a:text, ' ') - let trigger = s:Hash(strpart(a:text, 0, space)) - if a:multisnip - let space += 2 - let quote = stridx(a:text, '"', space) - let name = strpart(a:text, space, quote-space) - let space = stridx(a:text, ' ', quote) - let var = 's:multi_snips' - else " evaluating a regular snippet - let var = 's:snippets' - endif - if !has_key({var}, a:ft) | let {var}[a:ft] = {} | endif - let end = strpart(a:text, space+1) - - if end == '' || space == '' || (a:multisnip && name == '') - echom 'Error in snipMate.vim: Snippet '.a:text.' is undefined.' - elseif !has_key({var}[a:ft], trigger) - let {var}[a:ft][trigger] = a:multisnip ? [[name, end]] : end - elseif a:multisnip | let {var}[a:ft][trigger] += [[name, end]] - else - echom 'Warning in snipMate.vim: Snippet '.strpart(a:text, 0, stridx(a:text, ' ')) - \ .' is already defined. See :h multi_snip for help on snippets' - \ .' with multiple matches.' - endif -endf - -fun! ExtractSnips(dir, ft) - let s:slash = has('win16') || has('win32') || has('win64') ? '\\' : '/' - for path in split(globpath(a:dir, '*'), '\n') - if isdirectory(path) - for snipFile in split(globpath(path, '*.snippet'), '\n') - call s:ProcessFile(snipFile, a:ft, strpart(path, strridx(path, s:slash)+1)) - endfor - continue - endif - call s:ProcessFile(path, a:ft) - endfor - unl s:slash - let s:did_{a:ft} = 1 -endf - -" Processes a snippet file; optionally add the name of the parent directory -" for a snippet with multiple matches. -fun s:ProcessFile(file, ft, ...) - let keyword = matchstr(a:file, '.*'.s:slash.'\zs.*\ze\.snippet') - if keyword == '' | return | endif - try - let text = join(readfile(a:file), '\n') - catch /E484/ - echom "Error in snipMate.vim: couldn't read file: ".a:file - endtry - return a:0 ? s:MakeSnippet(a:1.' "'.keyword.'" '.text, a:ft, 1) - \ : s:MakeSnippet(keyword.' '.text, a:ft, 0) -endf - -fun! ResetSnippets() - let s:snippets = {} | let s:multi_snips = {} -endf - -fun s:RemoveSnippet() - unl s:snipPos s:curPos s:snipLen s:endSnip s:endSnipLine s:prevLen -endf - -fun s:ChooseSnippet(ft, trigger) - let snippet = [] - let i = 1 - for snip in s:multi_snips[a:ft][a:trigger] - let snippet += [i.'. '.snip[0]] - let i += 1 - endfor - if i == 2 | return s:multi_snips[a:ft][a:trigger][0][1] | endif - let num = inputlist(snippet)-1 - return num < i-1 ? s:multi_snips[a:ft][a:trigger][num][1] : '' -endf - -fun! TriggerSnippet() - if pumvisible() " update snippet if completion is used, or deal with supertab - if exists('s:sid') | return "\" | endif - call feedkeys("\a", 'n') | call s:UpdateChangedSnip(0) - endif - - if !exists('s:snipPos') " don't expand snippets within snippets - if !exists('s:sid') && exists('g:SuperTabMappingForward') - \ && g:SuperTabMappingForward == "" - call s:GetSuperTabSID() - endif - let word = s:GetSnippet() - - if exists('s:snippet') - if s:snippet == '' - return unl s:snippet " if user cancelled multi snippet, quit - endif - let col = col('.')-len(word) - " if word is a trigger for a snippet, delete the trigger & expand - " the snippet - exe 'sil s/'.word.'\%#//' - return s:ExpandSnippet(col) - endif - return exists('s:sid') ? {s:sid}_SuperTab('n') : "\" - endif - return s:JumpTabStop() -endf - -" Check if word under cursor is snippet trigger; if it isn't, try checking if -" the text after non-word characters is (e.g. check for "foo" in "bar.foo") -fun s:GetSnippet() - let origWord = matchstr(getline('.'), '\S\+\%'.col('.').'c') - wh !exists('s:snippet') - let word = s:Hash(origWord) - if exists('s:snippets["'.&ft.'"]["'.word.'"]') - let s:snippet = s:snippets[&ft][word] - elseif exists('s:snippets["_"]["'.word.'"]') - let s:snippet = s:snippets['_'][word] - elseif exists('s:multi_snips["'.&ft.'"]["'.word.'"]') - let s:snippet = s:ChooseSnippet(&ft, word) - elseif exists('s:multi_snips["_"]["'.word.'"]') - let s:snippet = s:ChooseSnippet('_', word) - en - if match(origWord, '\W') == -1 | break | en - let origWord = substitute(origWord, '.\{-}\W', '', '') - endw - return origWord -endf - -fun s:GetSuperTabSID() - let old = @a - redir @a | exe 'sil fun /SuperTab$' | redir END - let s:sid = matchstr(@a, '\d\+\ze_SuperTab(command)') - let @a = old -endf - -fun s:ExpandSnippet(col) - let lnum = line('.') | let col = a:col - let afterCursor = strpart(getline('.'), col-1) - if afterCursor != "\t" && afterCursor != ' ' - sil exe 's/\%'.col.'c.*//' - else | let afterCursor = '' | endif - - call s:ProcessSnippet() - if s:snippet == '' - return unl s:snippet " avoid an error if the snippet is now empty - endif - - let snip = split(substitute(s:snippet, '$\d\|${\d.\{-}}', '', 'g'), "\n", 1) - if afterCursor != '' | let snip[-1] .= afterCursor | endif - let line = getline(lnum) - call setline(lnum, line.snip[0]) - - " for some reason the cursor needs to move one right after this - if line != '' && col == 1 && afterCursor == '' && &ve !~ 'all\|onemore' - let col += 1 - endif - " autoindent snippet according to previous indentation - let indent = matchend(line, '^.\{-}\ze\(\S\|$\)')+1 - if !indent - call append(lnum, snip[1:]) - else - call append(lnum, map(snip[1:], "'".strpart(line, 0, indent-1)."'.v:val")) - endif - - let snipLen = s:BuildTabStops(lnum, col-indent, indent) - unl s:snippet - - if snipLen - let s:curPos = 0 - let s:snipLen = snipLen - let s:endSnip = s:snipPos[0][1] - let s:endSnipLine = s:snipPos[s:curPos][0] - - call cursor(s:snipPos[0][0], s:snipPos[0][1]) - let s:prevLen = [line('$'), col('$')] - if s:snipPos[0][2] != -1 | return s:SelectWord() | endif - else - " place cursor at end of snippet if no tab stop is given - unl s:snipPos | let newlines = len(snip)-1 - call cursor(lnum + newlines, tab + len(snip[-1]) - len(afterCursor) - \ + (newlines ? 0: col)) - endif - return '' -endf - -fun s:ProcessSnippet() - " evaluate eval (`...`) expressions - " Using a loop here instead of a regex fixes a bug with nested "\=" - if stridx(s:snippet, '`') != -1 - wh match(s:snippet, '`.\{-}`') != -1 - let s:snippet = substitute(s:snippet, '`.\{-}`', - \ substitute(eval(matchstr(s:snippet, '`\zs.\{-}\ze`')), - \ "\n\\%$", '', ''), '') - endw - let s:snippet = substitute(s:snippet, "\r", "\n", 'g') - endif - - " place all text after a colon in a tab stop after the tab stop - " (e.g. "${#:foo}" becomes "${:foo}foo") - " this helps tell the position of the tab stops later. - let s:snippet = substitute(s:snippet, '${\d:\(.\{-}\)}', '&\1', 'g') - - " update the s:snippet so that all the $# become - " the text after the colon in their associated ${#} - " (e.g. "${1:foo}" turns all "$1"'s into "foo") - let i = 1 - wh stridx(s:snippet, '${'.i) != -1 - let s = matchstr(s:snippet, '${'.i.':\zs.\{-}\ze}') - if s != '' - let s:snippet = substitute(s:snippet, '$'.i, '&'.s, 'g') - endif - let i += 1 - endw - if &et " expand tabs to spaces if 'expandtab' is set - let s:snippet = substitute(s:snippet, '\t', - \ repeat(' ', &sts ? &sts : &sw), 'g') - endif -endf - -fun s:Count(haystack, needle) - let counter = 0 - let index = stridx(a:haystack, a:needle) - wh index != -1 - let index = stridx(a:haystack, a:needle, index+1) - let counter += 1 - endw - return counter -endf - -" Sorry, this next section is a bit convoluted... -" This function builds a list of a list of each tab stop in the snippet -" containing: -" 1.) The number of the current line plus the number of "\n"s (line -" breaks) before the tab stop -" 2.) The current column plus the position of the next "${#}" on -" the line by getting the length of the string between the last "\n" -" and the "${#}" tab stop, -" 3.) The length of the text after the colon for the current tab stop -" (e.g. "${#:foo}" would returnrn 3). If there is no text, -1 is returnrned. -" 4.) If the "${#:}" construct is given, the fourth part of the list -" is another list containing all the matches of "$#", to be replaced -" with the variable. This list is composed the same way as the parent: -" the first part is the number of "\n"s before the tab stop, and -" second is the position (column) of the "$#" tab stop on the line. -" If there are none of these tab stop, an empty list ([]) is returnrned -fun s:BuildTabStops(lnum, col, indent) - let s:snipPos = [] - let i = 1 - " temporarily delete placeholders - let cut_snip = substitute(s:snippet, '$\d', '', 'g') - wh stridx(s:snippet, '${'.i) != -1 - let s:snipPos += [[a:lnum+s:Count(matchstr(cut_snip, '^.*\ze${'.i), "\n"), - \ a:indent+len(matchstr(substitute(cut_snip, '${'.i.'\@!\d.\{-}}', '', 'g'), - \ "^.*\\(\n\\|^\\)\\zs.*\\ze${".i.'.\{-}}')), -1]] - if s:snipPos[i-1][0] == a:lnum - let s:snipPos[i-1][1] += a:col - endif - - " get all $# matches in another list, if ${#:name} is given - if stridx(cut_snip, '${'.i.':') != -1 - let j = i-1 - let s:snipPos[j][2] = len(matchstr(cut_snip, '${'.i.':\zs.\{-}\ze}')) - let s:snipPos[j] += [[]] - " temporarily delete all other tab stops/placeholders - let tempstr = substitute(s:snippet, '$'.i.'\@!\d\|${\d.\{-}}', '', 'g') - wh stridx(tempstr, '$'.i) != -1 - let beforeMark = matchstr(tempstr, '^.\{-}\ze$'.i) - let linecount = a:lnum+s:Count(beforeMark, "\n") - let s:snipPos[j][3] += [[linecount, - \ a:indent+(linecount > a:lnum ? - \ len(matchstr(beforeMark, "^.*\n\\zs.*")) - \ : a:col+len(beforeMark))]] - let tempstr = substitute(tempstr, '$'.i, '', '') - endw - endif - let i += 1 - endw - return i-1 -endf - -fun s:JumpTabStop() - if exists('s:update') - call s:UpdatePlaceholderTabStops() - let changeLine = 0 | let changeCol = 0 - else - let changeLine = s:endSnipLine - s:snipPos[s:curPos][0] - let changeCol = s:endSnip - s:snipPos[s:curPos][1] - if exists('s:origWordLen') - let changeCol -= s:origWordLen | unl s:origWordLen - endif - endif - - let s:curPos += 1 - if s:curPos == s:snipLen - let sMode = s:endSnip == s:snipPos[s:curPos-1][1]+s:snipPos[s:curPos-1][2] - call s:RemoveSnippet() - return sMode ? "\" : TriggerSnippet() - endif - call s:UpdateTabStops(changeLine, changeCol) - - call cursor(s:snipPos[s:curPos][0], s:snipPos[s:curPos][1]) - - let s:endSnipLine = s:snipPos[s:curPos][0] - let s:endSnip = s:snipPos[s:curPos][1] - let s:prevLen = [line('$'), col('$')] - - return s:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord() -endf - -fun s:UpdatePlaceholderTabStops() - " update tab stops in snippet if text has been added via "$#", - " e.g. in "${1:foo}bar$1${2}" - if exists('s:origPos') - let changeLen = s:origWordLen - s:snipPos[s:curPos][2] - - " This could probably be more efficent... - if changeLen != 0 - let lnum = line('.') - let len = len(s:origPos) - for pos in s:snipPos[(s:curPos+1):] - let i = 0 | let j = 0 | let k = 0 - let endSnip = pos[2]+pos[1]-1 - wh i < len && s:origPos[i][0] <= pos[0] - if pos[0] == s:origPos[i][0] - if pos[1] > s:origPos[i][1] - \ || (pos[2] == -1 && pos[1] == s:origPos[i][1]) - let j += 1 - elseif s:origPos[i][1] < endSnip " parse variables within placeholders - let k += 1 - endif - endif - let i += 1 - endw - if pos[0] == lnum && pos[1] > s:origSnipPos - let j += 1 - endif - let pos[1] -= changeLen*j - let pos[2] -= changeLen*k - - if pos[2] != -1 - for nPos in pos[3] - let i = 0 | let j = 0 - wh i < len && s:origPos[i][0] <= nPos[0] - if nPos[0] == s:origPos[i][0] && nPos[1] > s:origPos[i][1] - let j += 1 - endif - let i += 1 - endw - if nPos[0] == lnum && nPos[1] > s:origSnipPos - let j += 1 - endif - if nPos[0] > s:origPos[0][0] | break | endif - let nPos[1] -= changeLen*j - endfor - endif - endfor - endif - unl s:endSnip s:origPos s:origSnipPos - endif - unl s:startSnip s:origWordLen s:update -endf - -fun s:UpdateTabStops(changeLine, changeCol) - " there's probably a more efficient way to do this as well... - let lnum = s:snipPos[s:curPos-1][0] - let col = s:snipPos[s:curPos-1][1] - " update the line number of all proceeding tab stops if has - " been inserted - if a:changeLine != 0 - for pos in s:snipPos[(s:curPos):] - if pos[0] >= lnum - if pos[0] == lnum - let pos[1] += a:changeCol - endif - let pos[0] += a:changeLine - endif - if pos[2] != -1 - for nPos in pos[3] - if nPos[0] >= lnum - if nPos[0] == lnum - let nPos[1] += a:changeCol - endif - let nPos[0] += a:changeLine - endif - endfor - endif - endfor - elseif a:changeCol != 0 - " update the column of all proceeding tab stops if text has - " been inserted/deleted in the current line - for pos in s:snipPos[(s:curPos):] - if pos[1] >= col && pos[0] == lnum - let pos[1] += a:changeCol - endif - if pos[2] != -1 - for nPos in pos[3] - if nPos[0] > lnum | break | endif - if nPos[0] == lnum && nPos[1] >= col - let nPos[1] += a:changeCol - endif - endfor - endif - endfor - en -endf - -fun s:SelectWord() - let s:origWordLen = s:snipPos[s:curPos][2] - let s:oldWord = strpart(getline('.'), s:snipPos[s:curPos][1]-1, - \ s:origWordLen) - let s:prevLen[1] -= s:origWordLen - if !empty(s:snipPos[s:curPos][3]) - let s:update = 1 - let s:endSnip = -1 - let s:startSnip = s:snipPos[s:curPos][1]-1 - en - if !s:origWordLen | return '' | en - let l = col('.') != 1 ? 'l' : '' - if &sel == 'exclusive' | return "\".l.'v'.s:origWordLen."l\" | en - return s:origWordLen == 1 ? "\".l.'gh' - \ : "\".l.'v'.(s:origWordLen-1)."l\" -endf - -" This updates the snippet as you type when text needs to be inserted -" into multiple places (e.g. in "${1:default text}foo$1bar$1", -" "default text" would be highlighted, and if the user types something, -" UpdateChangedSnip() would be called so that the text after "foo" & "bar" -" are updated accordingly) -" -" It also automatically quits the snippet if the cursor is moved out of it -" while in insert mode. -au CursorMovedI * call s:UpdateChangedSnip(0) -au InsertEnter * call s:UpdateChangedSnip(1) -fun s:UpdateChangedSnip(entering) - if exists('s:update') - if !exists('s:origPos') && s:curPos+1 < s:snipLen - " save the old snippet & word length before it's updated - " s:startSnip must be saved too, in case text is added - " before the snippet (e.g. in "foo$1${2}bar${1:foo}") - let s:origSnipPos = s:startSnip - let s:origPos = deepcopy(s:snipPos[s:curPos][3]) - endif - let col = col('.')-1 - - if s:endSnip != -1 - let changeLen = col('$') - s:prevLen[1] - let s:endSnip += changeLen - else " when being updated the first time, after leaving select mode - if a:entering | return | endif - let s:endSnip = col-1 - endif - - " if the cursor moves outside the snippet, quit it - if line('.') != s:snipPos[s:curPos][0] || col < s:startSnip || - \ col-1 > s:endSnip - unl! s:startSnip s:origWordLen s:origPos s:update - return s:RemoveSnippet() - endif - - call s:UpdateSnip() - let s:prevLen[1] = col('$') - elseif exists('s:snipPos') - let col = col('.') - let lnum = line('.') - let changeLine = line('$') - s:prevLen[0] - - if lnum == s:endSnipLine - let s:endSnip += col('$') - s:prevLen[1] - let s:prevLen = [line('$'), col('$')] - endif - if changeLine != 0 - let s:endSnipLine += changeLine - let s:endSnip = col - endif - - " delete snippet if cursor moves out of it in insert mode - if (lnum == s:endSnipLine && (col > s:endSnip || col < s:snipPos[s:curPos][1])) - \ || lnum > s:endSnipLine || lnum < s:snipPos[s:curPos][0] - call s:RemoveSnippet() - endif - endif -endf - -fun s:UpdateSnip() - " using strpart() here avoids a bug if s:endSnip is negative that would - " happen with the getline('.')[(s:startSnip):(s:endSnip)] syntax - let newWordLen = s:endSnip - s:startSnip + 1 - let newWord = strpart(getline('.'), s:startSnip, newWordLen) - if newWord != s:oldWord - let changeLen = s:snipPos[s:curPos][2] - newWordLen - let curLine = line('.') - let startCol = col('.') - let oldStartSnip = s:startSnip - let updateSnip = changeLen != 0 - let i = 0 - - for pos in s:snipPos[s:curPos][3] - if updateSnip - let start = s:startSnip - if pos[0] == curLine && pos[1] <= start - let s:startSnip -= changeLen - let s:endSnip -= changeLen - en - for nPos in s:snipPos[s:curPos][3][(i):] - if nPos[0] == pos[0] - if nPos[1] > pos[1] || (nPos == [curLine, pos[1]] && - \ nPos[1] > start) - let nPos[1] -= changeLen - en - elseif nPos[0] > pos[0] | break | en - endfor - let i += 1 - en - - call setline(pos[0], substitute(getline(pos[0]), '\%'.pos[1].'c'. - \ s:oldWord, newWord, '')) - endfor - if oldStartSnip != s:startSnip - call cursor('.', startCol + s:startSnip - oldStartSnip) - en - - let s:oldWord = newWord - let s:snipPos[s:curPos][2] = newWordLen - en -endf -" vim:noet:sw=4:ts=4:ft=vim