From 5527548d63c0e8992086ba1e06b20447dc4757bd Mon Sep 17 00:00:00 2001 From: Michael Sanders Date: Sun, 15 Mar 2009 18:52:29 -0400 Subject: [PATCH] added support for buffer-only snippets --- after/ftplugin/vim_snips.vim | 2 ++ doc/snipMate.txt | 46 +++++++++++++++++++----------------- plugin/snipMate.vim | 31 ++++++++++++------------ 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/after/ftplugin/vim_snips.vim b/after/ftplugin/vim_snips.vim index 997e0e7..c4d2974 100644 --- a/after/ftplugin/vim_snips.vim +++ b/after/ftplugin/vim_snips.vim @@ -7,6 +7,8 @@ let snippet_filetype = 'vim' " snippets for making snippets :) exe 'Snipp snip exe "Snipp ${1:trigger}"${2}' exe "Snipp snipp exe 'Snipp ${1:trigger}'${2}" +exe 'Snipp bsnip exe "BufferSnip ${1:trigger}"${2}' +exe "Snipp bsnipp exe 'BufferSnip ${1:trigger}'${2}" exe 'Snipp gsnip exe "GlobalSnip ${1:trigger}"${2}' exe "Snipp gsnipp exe 'GlobalSnip ${1:trigger}'${2}" exe "Snipp guard if !exists('g:loaded_snips') || exists('s:did_". diff --git a/doc/snipMate.txt b/doc/snipMate.txt index aa23a4d..a8623eb 100644 --- a/doc/snipMate.txt +++ b/doc/snipMate.txt @@ -1,7 +1,7 @@ *snipMate.txt* Plugin for using TextMate-style snippets in Vim. snipMate *snippet* *snippets* *snipMate* -Last Change: March 8, 2009 +Last Change: March 15, 2009 |snipMate-description| Description |snipMate-usage| Usage @@ -43,10 +43,10 @@ There are currently two ways to make snippets: file-based and command-based. File-based snippets are simply *.snippet files named after the trigger of the snippet 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 special characters in -snippet triggers, while command-based snippets are obviously convenient for -short snippets but can quickly get unreadable. +using the |Snipp| , |BufferSnip|, and |GlobalSnip| commands. File-based +snippets have the advantage of being easier to read, but do not support +special characters in snippet triggers, while command-based snippets are +obviously convenient for short snippets but can quickly get unreadable. *command-snippets* ------------------------------------------------------------------------------ @@ -69,33 +69,35 @@ snipMate: > This ensures dotted filetypes (see 'filetype') are dealt with correctly. - *Snipp* *GlobalSnip* -Snipp and GlobalSnip Commands~ + *Snipp* *BufferSnip* *GlobalSnip* +Snipp, BufferSnip, 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 at the end of this sentence." exe "GlobalSnip another_trigger foo" + exe "BufferSnip bar This snippet only works for the current buffer." -"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 vim script that uses that command name. +"Snipp" creates snippets for the current filetype, "GlobalSnip" creates global +snippets, and "BufferSnip" creates snippets for the current buffer. "Snipp" +is used instead of "Snip" to avoid conflicts with the imaps.vim 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, -just 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. +These commands are conveniently bound to snippets themselves; "snip", "bsnip", +and "gsnip", respectively (in vim files). So to expand a Snipp command with +double quotes, just type snip. Single quote Snipp and GlobalSnip +commands are bound to the snippets "snipp", "bsnipp" 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.: > + *multi_snip* *Snipp!* *BufferSnip!* *GlobalSnip!* +To specify that a snippet can have multiple matches, use the Snipp, +BufferSnip, 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!' + exe 'Snipp! trigger "Snippet name #1" expand_this_text' + exe 'Snipp! 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 diff --git a/plugin/snipMate.vim b/plugin/snipMate.vim index 15a1958..af16fab 100644 --- a/plugin/snipMate.vim +++ b/plugin/snipMate.vim @@ -16,6 +16,7 @@ let loaded_snips = 1 if !exists('snips_author') | let snips_author = 'Me' | endif com! -nargs=+ -bang Snipp call s:MakeSnippet(, snippet_filetype, 0) +com! -nargs=+ -bang BufferSnip call s:MakeSnippet(, bufnr('%'), 0) com! -nargs=+ -bang GlobalSnip call s:MakeSnippet(, '_', 0) let s:snippets = {} | let s:multi_snips = {} @@ -26,7 +27,7 @@ fun! Filename(...) return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') endf -fun s:MakeSnippet(text, ft, multisnip) +fun s:MakeSnippet(text, scope, multisnip) let space = stridx(a:text, ' ') let trigger = strpart(a:text, 0, space) if a:multisnip @@ -38,14 +39,14 @@ fun s:MakeSnippet(text, ft, multisnip) else let var = 's:snippets' endif - if !has_key({var}, a:ft) | let {var}[a:ft] = {} | endif + if !has_key({var}, a:scope) | let {var}[a:scope] = {} | 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]] + elseif !has_key({var}[a:scope], trigger) + let {var}[a:scope][trigger] = a:multisnip ? [[name, end]] : end + elseif a:multisnip | let {var}[a:scope][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' @@ -90,16 +91,16 @@ fun s:RemoveSnippet() unl s:snipPos s:curPos s:snipLen s:endSnip s:endSnipLine s:prevLen endf -fun s:ChooseSnippet(ft, trigger) +fun s:ChooseSnippet(scope, trigger) let snippet = [] let i = 1 - for snip in s:multi_snips[a:ft][a:trigger] + for snip in s:multi_snips[a:scope][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 + if i == 2 | return s:multi_snips[a:scope][a:trigger][0][1] | endif let num = inputlist(snippet) - 1 - return num < i-1 ? s:multi_snips[a:ft][a:trigger][num][1] : '' + return num < i-1 ? s:multi_snips[a:scope][a:trigger][num][1] : '' endf fun! TriggerSnippet() @@ -117,7 +118,7 @@ fun! TriggerSnippet() endif let word = matchstr(getline('.'), '\S\+\%'.col('.').'c') - for filetype in split(&ft, '\.') + ['_'] " Deal with dotted file-types + for filetype in [bufnr('%')] + split(&ft, '\.') + ['_'] let trigger = s:GetSnippet(word, filetype) if exists('s:snippet') | break | endif endfor @@ -144,13 +145,13 @@ 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(word, ft) +fun s:GetSnippet(scope, ft) let word = a:word wh !exists('s:snippet') - if exists('s:snippets["'.a:ft.'"]["'.word.'"]') - let s:snippet = s:snippets[a:ft][word] - elseif exists('s:multi_snips["'.a:ft.'"]["'.word.'"]') - let s:snippet = s:ChooseSnippet(a:ft, word) + if exists('s:snippets["'.a:scope.'"]["'.word.'"]') + let s:snippet = s:snippets[a:scope][word] + elseif exists('s:multi_snips["'.a:scope.'"]["'.word.'"]') + let s:snippet = s:ChooseSnippet(a:scope, word) else if match(word, '\W') == -1 | break | endif let word = substitute(word, '.\{-}\W', '', '')