Help us understand the problem. What is going on with this article?

RubyでRubyのコード一括フォーマット(自動でインデント綺麗にする)するの作った

More than 3 years have passed since last update.

概要

EclipseとかVisual Studioみたいな、全選択してボタン押すと一括でインデント綺麗にしてくれるのが欲しかった。
需要ありそうだからググればすぐ見つかるかと思ったら、あまりにも良い感じのが見つからなかったから自作してみた。探し方が悪いんだろうか。

本当はエディタ側で設定した方が理想的な動作になるんだろうけど、色々プラグイン入れたりとかの面倒なことはあんまりしたくなった。

コード

gist参照
https://gist.github.com/sensq/dc302c9185cb260104a581cc39c656bd
ちょっと改造すればたぶん他の言語でも使える。

使い方

以下のコマンドを実行

ruby formatter.rb 'file_path'

ざっくりした処理の説明

  • ファイル読み込む
  • 上記ファイルと同階層にバックアップ作成(フォーマット失敗したときや比較用)
  • フォーマット処理
    • 予約語を定義(defとかifとか、インデント変えるキーになる文字列)
    • 最初にインデントを全部消去
    • 一行ずつ探索し、予約語が存在する行が出てきたら、インデントを一つずらす
    • コメント行は無視
    • 探索中の行の頭に、インデントの深さに応じたスペースを追加
  • 上書き保存

実行例

適当にインデントがめちゃくちゃなコードを書いてフォーマットしてみる。

class Test
  attr_accessor :pub
  def initialize
@pub = 0
  end
  # loopのサンプル
  def loop
    (0..10).each do |i|
    (0..10).each do |j|
    (0..10).each do |k|
      if k%2
      p i
      elsif k%3
      p j
      else
      p k
      end
    end
    end
    end
    end
# caseのサンプル
def case_sample
    case @pub
    when 1
    p "hoge"
    when 2
    p "fuga"
  end
  end
end

test = Test.new
#if true
  test.pub = 2
#end
test.case_sample

これをフォーマットすると・・・

class Test
  attr_accessor :pub
  def initialize
    @pub = 0
  end
  # loopのサンプル
  def loop
    (0..10).each do |i|
      (0..10).each do |j|
        (0..10).each do |k|
          if k%2
            p i
          elsif k%3
            p j
          else
            p k
          end
        end
      end
    end
  end
  # caseのサンプル
  def case_sample
    case @pub
    when 1
      p "hoge"
    when 2
      p "fuga"
    end
  end
end

test = Test.new
#if true
test.pub = 2
#end
test.case_sample

キレイ!!

バグ

  • do~endではなく、{}で書いてるコードには使えない
    • インライン展開"#{}"とか、{}を1行で書いてる場合とかの判定が面倒そうだった
    • ↑直しました
  • 文字列として"\sdo\s"の含まれる行があると、次の行からインデントされてしまう
    • 「doが"や'で囲まれている場合は無視する」ってのが面倒そうだった
    • 「前後が\sのdo」という条件にしているので、あまり起こらないバグのはず

自分で書いたコードが想定通りにフォーマットされることしか確認していないので、汎用的に使えるかどうかは自信ありません。
たぶんだいたいのコードには使えるんじゃないかと思います。

追記

いまいち使い勝手悪かったので、Mery(エディタ)のマクロにしてみた。
https://gist.github.com/sensq/589de2764297e22d9b5a99acebca4684

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away