Search code examples
vimsnipmate

Changing the case within Snipmate.vim snippets?


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.


Solution

  • 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.