如何用vimscript包装一段文本?

时间:2013-01-07 14:30:30

标签: vim

我正在编写一个vimscript函数来将当前选定的行(可视模式)包装在Ruby开始 - 救援块中。我有一些奇怪的行为。这是我的功能:

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

几乎有效 - 由于某种原因它只产生头部和尾部的两个副本。例如,在选择此文本时运行该函数:

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

生成此输出:

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

我不关心缩进(以后可以修复)。请注意,有一个外包装,包括一个空的内包装,后面是目标线。我做错了什么?

1 个答案:

答案 0 :(得分:4)

问题是Vim会执行两次你的方法,因为你选择了2行。如果您将range参数添加到方法中,它将只执行一次,您将获得所需的效果:

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

请注意,尽管如此,这样的映射可能会更简洁:

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

,q的此映射会删除当前选定的文本,写入begin语句,然后放入刚删除的内容,然后写下结尾。