0

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

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

我不在乎缩进(以后可以解决)。请注意,有一个外包装,其中包括一个空的内包装,后跟目标行。我究竟做错了什么?

4

1 回答 1

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语句,然后放入刚刚删除的内容,然后写入您的结尾结尾。

于 2013-01-07T15:04:49.287 回答