Sean Mackesey
Sean Mackesey

Reputation: 10939

How do I wrap a block of text with vimscript?

I am writing a vimscript function to wrap the currently selected lines (visual mode) in a Ruby begin-rescue block. I am getting some strange behavior. Here is my function:

function! BeginRescueWrap()
  execute "normal! gvd"
  let head = "begin\<CR>"
  let body = @"
  let tail = "rescue StandardError =>e\<CR>binding.pry\<CR>end\<CR>"
  execute "normal! i" . head . "\<CR>" . body . "\<CR>" . tail
endfunction

It almost works-- it just produces two copies of the head and tail for some reason. For example, running the function when this text is selected:

Oh lord won't you buy me a Mercedes Benz
My friends all drive Porsches, I must make amends

Produces this output:

begin

  begin

  rescue StandardError =>e
  binding.pry
  end

  Oh lord won't you buy me a Mercedes Benz
  My friends all drive Porsches, I must make amends

  rescue StandardError =>e
  binding.pry
  end

I don't care about the indentation (can fix that later). Just notice that there is an outer wrapping that includes an empty inner wrapping followed by the target lines. What am I doing wrong?

Upvotes: 0

Views: 225

Answers (1)

Daan Bakker
Daan Bakker

Reputation: 6332

The problem is that Vim will execute your method twice, because you selected 2 lines. If you add the range parameter to the method it will only be executed once, and you will have your desired effect:

function! BeginRescueWrap() range
  execute "normal! gvd"
  let head = "begin\<CR>"
  let body = @"
  let tail = "rescue StandardError =>e\<CR>binding.pry\<CR>end\<CR>"
  execute "normal! i" . head . "\<CR>" . body . "\<CR>" . tail
endfunction

Note though that for this specific purpose, a mapping like this would probably be more concise:

vnoremap ,q sbegin<cr><C-R>1rescue StandardError =>e<cr>binding.pry<cr>end<cr>

This mapping for ,q removes the currently selected text, writes the begin statement, then puts what was just deleted, then writes your ending ending.

Upvotes: 4

Related Questions