Rubyの高速フォーマッタ－"Rufo"を使ってみる【18/09/30更新】

普段はVisualStudioCodeでRailsのコードを書いているのですが、Rubyのフォーマッターがほしいと常々思っていました。

そこで、[週間Railsウォッチ](https://techracho.bpsinc.jp/hachi8833/2017_07_07/42697)で紹介されていた[Rufo](https://github.com/ruby-formatter/rufo)というRubyフォーマッターを使ってみたところ、非常に使いやすく、自分の使い方にもマッチしていたので紹介します。

# 変更点

## 2018/09/30

[Setting.md](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md)に合わせて**設定**の内容を更新しました。
設定できる項目が減り、いずれ設定をする必要がなくなるようです。
細かく設定したい人にはうれしくない話かもしれませんが、フォーマットは統一できればさほど問題ないので、細かく設定できて差分が生じるより良い話かと思います。


# フォーマッターに求めること
自分がフォーマッターに求めることは主に以下の4つです。

- 保存時に自動でフォーマットがかかること
- フォーマット設定が容易で、共有できること
- ストレスなく使えること
- 自分の好きなエディタで使えること

簡単に説明します。

## 保存時に自動でフォーマットがかかること
Rails自体は個人の趣味の範囲でしか開発していないので、自分がフォーマットを気をつければ良いだけなのですが、集中して書いているとちょっとしたずれがあるので、保存時に自動的にフォーマットがかけられたり、コマンドで任意に呼び出せたりすると便利です。

## フォーマット設定が容易で、共有できること
複数の環境での開発や、複数人での開発となった際は統一したフォーマットの設定が必須なので、簡単にフォーマットの設定ができる必要があります。

## ストレスなく使えること
フォーマットの適用に数秒待たされるとなると集中も途切れてしまうので、ある程度ストレス無く使える必要があります。(個人差はあると思いますが、個人的には0.5秒以内が理想)

## 自分の好きなエディタで使えること
上記3つに比べればさほど重要ではありませんが、いつも使用しているエディタで使えることが望ましいです。

# Rufo
**Ru**by **fo**rmatterこと`Rufo`は上記の自分のフォーマッターに対する要望にしっかり応えてくれます。
フォーマットの適用タイミングはエディタ毎に異なりますが、設定が可能です。
フォーマットの設定に関しては`.rufo`というドットファイルを用意することで自動的に読み込んで適用してくれます。`.rufo`で設定できる項目は後述します。
速度に関してはGithubの説明にもある通り高速に動作し、ノンストレスで使用できます。(公式では3000行程度で290ms, 500行程度では180msとなっています。)

## インストール
インストールには以下のコマンドを実行するだけです。

```shell
$ gem install rufo
```

## 使用方法
コマンドラインからフォーマットをかける場合は下記になります。

```shell
$ rufo file names or dir names
```

※ `.rufo`を置いていない場合はデフォルト設定でのフォーマットが実行されます。

下記リンク先に各種エディタでのサポートもありますので、確認してみてください。

[Editor support - Github](https://github.com/ruby-formatter/rufo#editor-support)

## 設定
メインとなる`.rufo`の設定となります。

設定を反映する場合は`.rufo`ファイルをプロジェクトに配置することで自動的に読み込んでくれます。また、複数のプロジェクトで共有したい場合は親のディレクトリに配置すれば読み込んでくれます。

以下、[Settings - Github](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md)を日本語で説明したものとなります。元のWikiから説明の補足や間違いの修正をしています。おかしな箇所があったらコメントでご連絡ください。



### [align_case_when](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md#align_case_when)

case文の中のwhen句で縦位置を合わせるかどうか

- `false`: (デフォルト) 縦位置を合わせない(既存のコードはそのまま保存される)
- `true`: 縦位置を合わせる

コード例

```ruby
case exp
when foo then 2
when barbaz then 3
end
```

`true`の場合、フォーマットをかけると以下のようになる

```ruby
case exp
when foo    then 2
when barbaz then 3
end
```

`false`の場合は何も変更されない


### [align_chained_calls](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md#align_chained_calls)

メソッドチェインの`.`の縦位置を合わせるかどうか

- `false`: (デフォルト) 縦位置を合わせない(既存のコードはそのまま保存される)
- `true`: 縦位置を合わせる

コード例

```ruby
foo.bar
   .baz

foo.bar
  .baz
```

`true`の場合、フォーマットをかけると以下のようになる

```ruby
foo.bar
   .baz

foo.bar
   .baz
```

`false`の場合は何も変更されない

メモ: `false`の時にすでに縦位置がそろっている場合は、その状態が維持される


### [parens_in_def](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md#parens_in_def)

メソッド定義で引数の括弧を使用するかどうか

- `:dynamic`: (デフォルト) 現状のまま変更しない
- `:yes`: 常に括弧を付与する

コード例

```ruby
def foo x, y
end

def bar(x, y)
end
```

`:yes`の場合、フォーマットをかけると以下のようになる

```ruby
def foo(x, y)
end

def bar(x, y)
end
```

`:dynamic`の場合は何も変更されない



### [trailing_commas](https://github.com/ruby-formatter/rufo/blob/master/docs/settings.md#trailing_commas)

「配列やハッシュにおけるケツカンマ」のフォーマット方法

- `:dynamic`: (デフォルト) 現状のまま変更しない
- `:always`: 常にケツカンマがあるようにフォーマットする
- `:never`: 常にケツカンマがないようにフォーマットする

コード例

```ruby
[
  1,
  2
]

[
  1,
  2,
]

{
  foo: 1,
  bar: 2
}

{
  foo: 1,
  bar: 2,
}

foo(
  x: 1,
  y: 2
)

foo(
  x: 1,
  y: 2,
)
```

`:always`の場合、以下のようになる

```ruby
[
  1,
  2,
]

[
  1,
  2,
]

{
  foo: 1,
  bar: 2,
}

{
  foo: 1,
  bar: 2,
}

foo(
  x: 1,
  y: 2,
)

foo(
  x: 1,
  y: 2,
)
```

`:never`の場合、以下のようになる

```ruby
[
  1,
  2
]

[
  1,
  2
]

{
  foo: 1,
  bar: 2
}

{
  foo: 1,
  bar: 2
}

foo(
  x: 1,
  y: 2
)

foo(
  x: 1,
  y: 2
)
```

`:dynamic`の場合は何も変更されない


## 自分の`.rufo`

自分の設定している`.rufo`はこんな感じです。

```ruby
parens_in_def :yes
trailing_commas :always
```