3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-10-09

概要

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

3
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?