開発環境をRubyMineからEmacsに移した話

初めまして、moai (@moaeee) です。普段は人事労務freeeの開発をやっています。

この記事は freee Developers Advent Calendar の 5日目です。

この記事の目的

私がIDEからEmacsに移ったきっかけ、移行にかかった時間、どのように移行していったのかを書いていきます。 この記事をきっかけにEmacsを始めてみようかなーと思う人が増えるといいなと思います。

この記事を書こうと思った理由

  • やっぱり、Emacsって少数派。(少なくとも私の周辺では。)
  • IDEと違って、それ単体ではインストールしたら、全部整う世界ではない。
    • 色々なパッケージを自分でカスタマイズして、どんどん使いやすいeditorになる。(Vimもそうだと思う。)
    • 便利パッケージは各々使い方や、キーバインドが各々有って、適宜覚えていく必要がある。
  • キーバインドはデフォルトから、便利パッケージのものも含めて、全部を覚えなきゃいけないので、結局全てを一辺には覚えられない。
  • じゃあ、自分の生活の一部として、小さく試すのにはどのようにするのが良いのか、どのタイミングから仕事に使える状態できるようになるんや。っていう導入ロードマップみたいなのが有ったら便利だったなーと思うことがある。
  • 今、Emacsが好き。

初期状態

当時の作業毎に使っていたツールたちはこんな感じ。

作業 ツール
Rubyのコーディング RubyMine(+IdeaVim)
Rubyの起動 terminal
Rubyのデバッグ binding.pryを仕込む
Git操作(差分表示以外) terminal + Git command
差分表示 RubyMine(差分表示が綺麗だった)
日報とかメモ Vim
DBのデータを見る terminal+MySQL console
terminal作業 iTerm2 + tmux

RubyMineを使っているのでにterminalは別とかIDEの本領が活かしきれていない状態でした。 (ちなみに今でもRubyMineはいいIDEだと思います。なんでもあるし、自分で個別設定いらなくて、便利です。)

画像で見るとこんな感じの見栄えです。

f:id:moaieee:20171203221320p:plain

現在状態

作業 ツール
Rubyのコーディング emacs-nw
Rubyの起動 terminal
Rubyのデバッグ binding.pryを仕込む
Git操作(差分表示以外) terminal + Git command
差分表示 emacs-nw + magit or git diff
日報とかメモ emacs-nw
DBのデータを見る terminal+MySQL console
terminal作業 iTerm2 + tmux

画像で見るとこんな感じの見栄えです。

f:id:moaieee:20171203221431p:plain

いい感じにすべてterminal上で完結するようになっています。 ちなみに、現在の私のEmacsの設定はこちらです。参考にどうぞ。

github.com

きっかけ

  1. terminalで生活が統一できると、そのうちcloudに開発環境が移るったときもsshで開発できて便利だよなー。
  2. なんかコンピュータのロジックを基本からやっていったほうが良いかも
  3. SICPやってみるか。
  4. Schemeで書くのね
  5. SchemeのIDEとか情報出てこないな。(その後racketにはideがあるということを知ったが当時はググり力が足らず出てこなかった)
  6. Emacsで環境構築する例は結構出てくるな。
  7. よし、さくっとEmacsで環境構築して見るか

こんな感じで私のEmacs生活は始まりました。

移行の時期とやっていたこと

こんな感じでRubyMineからの以降をやっていきました。 こうやって見ると、新しい言語をはじめて、環境構築の再現性が確認できるところまで1年近くかかっているので、だいぶのんびりした移行です。 移行はほとんど土日にやっていたので、こんなもんかなと言う気もします。

時期 やっていたこと
2016/9 Emacs環境つくり始め
2016/11 本業が忙しくなりすぎて、Emacs移行を一旦ストップ
2017/1 Emacsの移行を再度開始
2017/3 業務の開発を完全にEmacsに移す
2017/4 RubyMineがやってくれていたことをEmacsに移す
2017/6 Emacsでの開発環境ほぼfix。以降はほとんどファイル分割とかしかやっていない
2017/10 Ruby以外の言語(go)で環境構築もやってみる

移行時期とそれぞれの時期にやっていたこと

以下ではやっていたことをそれぞれのフェーズに分けて記載していきます。

Emacsの環境つくり始め

この期間は、主に2フェーズくらいに分かれていました。

  1. とにかく色々雑多に情報を集める
  2. 処理できない量の情報量である時期であることを悟って、どうやって処理していこうか考えた時期
  3. 順番にEmacsに慣れさせようと計画立てていた時期

とにかく色々雑多に情報を集める

とにかく色々情報を集めた時期でした。 最終目標は『Rubyの開発とSICPの勉強が出来るEmacs環境を整える』だったので、これに必要そうな情報を集めて、手当たり次第試していました。

Emacsだけに絞ると、こんなkeywordが僕の頭に飛び込んでいきました。 editorの機能なんてものはほとんど気にしたことなかった僕の目にはほとんど新しいものに移りました。

当初、Emacs で Ruby の開発環境をさらにめちゃガチャパワーアップしたまとめ この記事を見ながら、順番に入れていこうとしたのですが、全体像が分からず入れていったので、結構右往左往しながら、入れていきました。

その時、目にしたキーワードはこの辺です。この辺のキーワードが余りどういう立ち位置なのか、カテゴリ分けも理解出来ず、一気に目に入ってきたので、うげげってなったのを覚えています。

  • Emacsのturorial(デフォルトのkeybindを覚えるもの)
  • helm, anything
  • auto-complete, company-mode
  • cask, package-install
  • dired
  • flycheck, flymake
  • syntax-highlight
  • rubocop
  • ctags, gtags(この辺の設定が一番時間かかった記憶があります。)
  • projectile
  • ruby-mode, minor-mode, major-mode
  • hook
  • Emacs Lisp

処理できない量の情報量である時期であることを悟って、どうやって処理していこうか考えた時期

兎にも角にも、上記の記事を参考に必要そうなものは一通り、入れていったのですが、どうにもRubyの開発に使える気がしなくて、結局使いものにならないと判断して、ゆっくりやらなければならないと思いました。

  1. 当時これがなければ、RubyMineから移行はできないと思った点

    特に、どの辺りがその当時、足りなかったと思っていた点はこのあたりです。

    • ディレクトリ移動
      • どうやってファイル移動したら良いのか。いちいち ファイルを開くのに、完全なpathを保管させながら入力して、探すのは厳しい。
    • コードジャンプ
      • コードリーディングの質に関わるので、コードジャンプは必要だった。
    • プロジェクト内のファイル検索
      • RubyMineのプロジェクト内のファイル、methodをすべて検索するもの(Shift 2回)代替
      • プロジェクト内grep(⌘ + Shift + f)
    • syntax-highlight
      • 単純に見づらい。こちらもコードリーディングの質に関わる。
    • コーディングルールの適用
      • そもそもrubocopかけてなかった。
  2. この辺はすんなり移行できた点

    逆によく分からなくても適当にどうにかなったのは、このあたりです。

    • デフォルトのkeybind
      • 完全に慣れの問題。チュートリアルを1回やれば、後は触れる回数を増やしていくだけだったので、そんなに恐怖感は無かった。
      • Mac, terminal上ではEmacsのkeybindが使えるので、寧ろ慣れると便利。
      • terminal上でctrl + pとかすると、一個戻れたりする。
      • MacのkeybindがEmacsに親しいことに気づいた段階で私は長い間お世話になったvimのキーバインドからはおさらばし、Emacsのキーバインドとともに生きていくことを決めました。
    • 補完
      • companyを入れたら、どうにかなったのと、Rubyではほとんど補完使っていなかった。
    • Emacsのパッケージ管理
      • caskを入れると決めてしまえば、あんまり気にならなかった。
  3. ちゃんとは理解していなかったけど、なんとかなったもの

    • modeなんかファイル名で自動的に立ち上がってくれるらしいもの。

順番にEmacsに慣れさせようと計画立てていた時期

このままでは、絶対に移行できないと思って、こんな計画で、移行することにしました。 ちなみに、上であげた移行できなかった理由などはまだ、全体像には気づいていなかったです。 そのため、この時点では最終型にないものもあります。

こんなマイルストーンにしました。

  1. 日報など、メモがEmacsでかけるようになり、キーバインドに慣れる
  2. コードリーディング出来るようになる
    1. コードジャンプ
    2. プロジェクト内検索
    3. 開きたいファイルをいい感じに開けるようになる
    4. syntax heighlight
  3. RubyMineと同じくらいの生産性でコードが書けるようになる
    1. ここはあんまりプラン無かったです。ゆっくり便利なものが有ったら、入れていくくらいのスタンスでした。

本業が忙しくなりすぎて、Emacs移行を一旦ストップ

この時、本業が忙しくなりすぎたので、移行を一旦ストップしました。 この時期何にもやっていないです。

業務の開発を完全にEmacsに移す

うまく、いかなかった問題に対して、各々のライブラリを手に入れて、業務の開発をEmacsに移しました。

コードジャンプ

このあたりを入れるようにして、対応しました。 この対応するのに結局1ヶ月位かかっていると思います。

  • ripper-tags
    • これはどちらかと言うと、システムに exuberant-ctags, gtagsを比較して、導入をやめることを決めるまでです。
      • ripper-tagsにした理由
        • Rubyの構文解析をしてくれるため、ctagと比較して、ジャンプの精度が良い。
      • gtagsの導入をやめた理由。
        • 便利そうだったけど、ctags-updateにいい感じに連携することを始めていたら、無限に時間を食いそうだったこと
        • ctags + company-modeでジャンプの精度は結構良かったため
  • ctags-update
    • これは、タグファイルをプロジェクトのファイルが保存されると同時にアップデートしてほしかったので、そのために導入しました。
    • ctagsファイルをripper-tagsで更新する用にフックを仕込む部分が一番手間がかかったと思います。
  • helm-etags-plus
    • 複数ジャンプの候補先が有ったときに、自動でインクリメンタルサーチを導入するために入れました。便利です。

プロジェクト内検索

この3つさえあれば、困らないです。 後は適当にキーバインドを探して、使うだけです。 見つけるだけなら、3日くらいでしょうか。慣れも含めて、1週間くらいだったと思います。 helm-projectileを見つけた後は、とても幸せになりました。

  • projectile
    • ファイルを開く
    • プロジェクト内を検索する
  • helm-projectile

    • 絞込窓をインクリメンタルサーチするのに使っています。一番helmの威力を感じるところです。
  • ag

    • Silver Searcherのインストールしました。

git-grepは余り使っていないです。

開きたいファイルをいい感じに開けるようにする

これはデフォルトの機能でなんとかなりました。 チュートリアルを読んで、なるほどと思って1日くらい。3日もあれば慣れると思います。

  • dired
    • デフォルトのディレクトリ移動のパッケージですが、便利です。

RubyMineがやってくれていたことをEmacsに移す

最後はRubyMineが知らず知らずのうちにやっていたことを見つけて、都度Emacsに移すということをやっていました。 これは少しずつ移していったので、期間だけは地味に2ヶ月くらいはかかっているかと思います。

RubyMineが知らず知らずのうちにやってくれていて、便利だった機能は以下の2つです。

  • syntax heighlight and color theme
  • 静的解析 and 静的解析の結果を 表示に反映する

syntax heighlight and color theme

madhat2rを導入して落ち着きました。 でも、結局2日くらいしかかかっていないような気がします。

これを選んだ理由は、こんな感じです。

  • terminal上でEmacsを表示してもいい感じだった
  • helmなどが考慮されているため、インクリメンタルサーチの表示も綺麗だった。

静的解析 and 静的解析の結果を 表示に反映する

ここは結構時間がかかりました。2, 3週間かかっているイメージです。 そもそもRubyMineで静的解析がかかって、表示に影響されていると言う意識が希薄だったため、そもそも静的解析ツールをどのように導入するのか? 現在どのように動いているのかなどが分かっていなかったためです。

下記のようなことを行いました。

  • flycheckの導入
    • これはすんなり。
  • rubocopをflycheckからフックするようにする
    • ここは結構時間がかかりました。
    • globalにインストールされているrubocopでflycheckをかける
    • project毎に導入されているrubocopに対応させる

Ruby以外の言語(Go)で環境構築も成功

最近、仕事でGoを書くようになったので、それ用に環境を構築しました。 当初は余り意識しなかったですが、ざっと情報を集めて、言語自体の環境構築を含めてもほとんど2週間ほどで開発開始できたと思います。 あと、Goで書くためのツールがほとんどGo言語をインストールしたら、大体ついてきたというのもデカイと思います。 結構驚きました。

ほとんど5パッケージだけで済む上に、独特な設定は殆どいらなかったです。

  • go-mode
    • ジャンプ, syntax heighlight 等基本的なことはやってくれる。
  • company-go
    • 補完
  • go-eldoc
    • ドキュメント参照。でもほとんどソース見てるから、必要ないかも
  • go-rename
    • renameツール
  • go-guru
    • 関数を呼んでいるところの一覧を表示したり

終わりに

こんな感じで、私のEmacs移行計画は終了しました。 移行当初はこんなに時間がかかると思っていなかったです。かなり手間でした。IDE(RubyMine)は偉大です。お金払う価値あると思います。 一方で、良いことも幾つか有りました。(月並みですが)エディターを構成する要素を分解して一つずつ理解できたこと、エディターのプラグインを調べていくうちに、OSSのコードを前よりは見るようになったこと、です。

IDEを使っている時代はエディターが構成される要素がハイライトとか、補完とかそういう小さい機能の集合であることを意識したことは無かったです。 現在では、それらが1つずつ分解できて、自分が全体像を理解できるようになりました。(機能の細かいところは理解できていませんが)

Emacsのプラグインはそこまで、ドキュメントが充実していないことも有って、結構OSSのコードを追っていって、機能を理解することも有りました。 その作業の途中で、良いコードをGitHubで探して来るということが私の引き出しの中に入りました。とても勉強になります。 GitHub便利です。ありがとうGitHub。

で、結局SICPやってんの?

やってないです。Scheme勉強したいですが、今はどっちかっていうとモデリングの方が興味あります。

次の人は?

明日は freeeが誇るsupportを支える asai さんの記事です。私もどんな記事になるか楽しみにしています。お楽しみに。