vim-users.jp

Hack #141: 引数の順序を入れ替える

Posted at 2010/04/22
このエントリーをはてなブックマークに追加

問題

いくつかのプログラミング言語における関数呼び出しないしメソッド呼び出しは、以下のような書き方をすることが多いです。

aaa(bbb, ccc)

引数部分に大抵の式を書くことができ、

aaa(bbb(ccc, ddd), eee())

のように書くことができる場合も多いです。

さて、上記関数aaaに与える引数の順序が実は間違っていたことに気づいたとします。どのように引数の順序を入れ替えるのがラクでなおかつ確実でしょうか。

aaa(bbb(ccc, ddd), eee())

まず0f(などで引数のリストの手前の括弧に飛び、df,で削除…、おっとコンマは既に途中で使われていました。df)ならば今回はうまくいきますが、しかしこれも汎用的ではありません。%を使うにも、うまく個別の引数を指定できません。

解決法

flipperというスクリプトを使います。

まず、以下のスクリプトを環境変数$PATHの通った位置に配置し、実行権限を与えます。

#!/usr/bin/env ruby
# flip('(aaa, bbb)') #=> '(bbb, aaa)'
def flip(str)
  stack = []
  tmp = ''
  tokens = []
  str.each_char.to_a[1..-2].each do |c|
    case c
    when '('
      stack << ')'
    when ')'
      stack.pop == ')' or abort 'Syntax Error'
    when '"'
      if stack.last == '"'
        stack.pop
      else
        stack << '"'
      end
    when "'"
      if stack.last == "'"
        stack.pop
      else
        stack << "'"
      end
    when ','
      if stack.empty?
        tokens << tmp
        tmp = ''
        next
      end
    when ' '
      if tmp.empty?
        next
      end
    end
    tmp << c
  end
  tokens << tmp
  '(' + tokens.reverse.join(', ') + ')'
end

if __FILE__ == $0
  puts flip(ARGV.shift)
end

つづいて、~/.vimrcに以下を記述します。

" Flip Arguments {{{
"   f(a, b) to f(b, a) when your cursol is on '('.
function! FlipArguments()
  normal! y%
  let @" = split(system('flipper "' . @" . '"'), "\n")[0]
  execute "normal! %p\<C-o>d%"
endfunction
" }}}

これで、:call FlipArguments()とすることでカーソル位置の引数リストの順番を逆順にすることができます。

入力を楽にするために、例えば以下のような設定をします。

nnoremap <space>flip :<C-u>call FlipArguments()<Cr>

<space>flipで同様の処理ができます。この作業はそれほど頻繁に行なうわけではないので、多少長いキーストロークでも問題ないのではないかと思います。

ujihisa

もどる
blog comments powered by Disqus