Changing the case within Snipmate.vim snippets?
Asked Answered
W

3

7

Is it possible to change the case of variable values within Snipmate snippets?

For example:

snippet dc
  def create
    @${1} = $1.new
  end

Should output:

def create
  @product = Product.new
end

I tried to use backticks to call a custom function:

snippet dc
  def create
    @${1} = `ToUpperCase('$1')`.new
  end

And defined this function in Vim:

function! ToUpperCase(str)
    let result = substitute(a:str, '\(\w\)', '\u\1', '')
    return result
endfunction

This doesn't work as it seems that Snipmate expands its $n variables after it has executed the backticks.

Wellthoughtof answered 21/2, 2011 at 9:49 Comment(0)
W
2

I made a little hack to snipMate to allow the functionality I was looking for.

Put this code in autoload/snipMate.vim to the end of the s:RemoveSnippet() function (after the line #14):

let linecount = len(getline("1", "$"))
for linenum in range(1, linecount)
    let line = getline(linenum)
    let line = substitute(line, '\v\%uc\(([^)]+)\)', '\U\1\E', 'g')
    let line = substitute(line, '\v\%ucfirst\(([^)]+)\)', '\u\1', 'g')
    call setline(linenum, line)
endfor

Now you can define snippets like this:

snippet dc
  def create
    @${1:product} = %ucfirst($1).new
    %uc($1) = "This is Ruby %uc(constant) example."
  end

Output:

def create
  @product = Product.new
  PRODUCT = "This is Ruby CONSTANT example."
end

Notice that the replacement is not done in real time but after you "quit" the snippet.

Wellthoughtof answered 21/2, 2011 at 21:44 Comment(1)
SnipMate.vim fork, which includes this functionality, is now at GitHub: github.com/jarijokinen/snipmate.vimWellthoughtof
N
10

Disclaimer: I am the main author of UltiSnips.

For your interest and rollin-the-drum purposes, I present two snippet definitions for UltiSnips which has been mentioned here before. Both do what the OP wants. The first one uses transformations (TextMate syntax):

snippet dc "create" b
def create
   @$1 = ${1/.*/\u$0/}.new
end
endsnippet

The second uses python code interpolation. For my tastes this is easier to read but it is a little more verbose.

snippet dc "create" b
def create
   @$1 = `!p snip.rv = t[1].title()`.new
end
endsnippet

Since version 1.3 UltiSnips comes with a script that can convert snipMate snippets, switching should therefore be easy.

Nicolasanicolau answered 27/7, 2011 at 5:36 Comment(0)
D
3

The current release of snipMate is not capable of performing transformations on the mirrored text. Look up :help snipMate-disadvantages where it says:

Regex cannot be performed on variables, such as "${1/.*/\U&}"

If you really want this feature, you might want to try one of the other snippet plugins out there. UltiSnips uses the same syntax for defining snippets, and claims to have all of the same features as TextMate.

Discontinuity answered 21/2, 2011 at 13:25 Comment(1)
Thanks for the help. I tried UltiSnips once but it was missing something (don't remember what) and that's why I started to use snipMate. I think the hack below is enough for now.Wellthoughtof
W
2

I made a little hack to snipMate to allow the functionality I was looking for.

Put this code in autoload/snipMate.vim to the end of the s:RemoveSnippet() function (after the line #14):

let linecount = len(getline("1", "$"))
for linenum in range(1, linecount)
    let line = getline(linenum)
    let line = substitute(line, '\v\%uc\(([^)]+)\)', '\U\1\E', 'g')
    let line = substitute(line, '\v\%ucfirst\(([^)]+)\)', '\u\1', 'g')
    call setline(linenum, line)
endfor

Now you can define snippets like this:

snippet dc
  def create
    @${1:product} = %ucfirst($1).new
    %uc($1) = "This is Ruby %uc(constant) example."
  end

Output:

def create
  @product = Product.new
  PRODUCT = "This is Ruby CONSTANT example."
end

Notice that the replacement is not done in real time but after you "quit" the snippet.

Wellthoughtof answered 21/2, 2011 at 21:44 Comment(1)
SnipMate.vim fork, which includes this functionality, is now at GitHub: github.com/jarijokinen/snipmate.vimWellthoughtof

© 2022 - 2024 — McMap. All rights reserved.