0

現在選択されている行(ビジュアルモード)をRubyのbegin-rescueブロックでラップするvimscript関数を作成しています。奇妙な振る舞いをしています。これが私の関数です:

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

それはほとんど機能します-それは何らかの理由で頭と尾の2つのコピーを生成するだけです。たとえば、このテキストが選択されているときに関数を実行すると、次のようになります。

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

問題は、2行を選択したため、Vimがメソッドを2回実行することです。メソッドにパラメーターを追加すると、rangeパラメーターは1回だけ実行され、目的の効果が得られます。

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 に答える