Quantcast
Channel: Futurismo
Viewing all articles
Browse latest Browse all 91

EmacsでRubyの開発環境をさらにめちゃガチャパワーアップしたまとめ

$
0
0

はじめに

Ruby開発環境を整えようとおもったが、普段よく使っているEclipseを出すにはスクリプト言語は大げさだ。

スクリプト言語はコンソール端末で書くに限る。

というわけで、Emacs使いなあたしとしては、EmacsでのRuby環境を整えようとおもった。

いろんなサイトを参考にしつつ、導入したものを列挙していく。

準備

elip取得に必要な package.elやel-get.el、gitやwgetなどのツールはインストール済みのこと。

環境

  • Emacs 24.3.1
  • Ruby 2.1.0

入力支援

ruby-mode/enhanced-ruby-mode

まずはともあれ、Emacsのruby-modeを使う。 .emacsの設定。拡張子.rbと接頭語Capfile,GemfileをRubyファイルと認識させる。

(autoload 'ruby-mode "ruby-mode"
  "Mode for editing ruby source files" t)
(add-to-list 'auto-mode-alist '("\\.rb$latex " . ruby-mode))
(add-to-list 'auto-mode-alist '("Capfile$" . ruby-mode))
(add-to-list 'auto-mode-alist '("Gemfile$" . ruby-mode))

今は、enhanced-ruby-modeというものもあるらしい。

以下の機能を強化。

  • インデント
  • シンタックスハイライト
  • リアルタイムの文法チェック

MELPAに入っているので、package.elやel-get.elでインストールできる。

githubの元のリポジトリは開発が止まっているようで、自分はfork版を入れる。

enh-rubu-modeという名前を探してインストールした。

あとは、既存の設定で、ruby-mode-hock/ruby-mode-mapとなっているところを enh-ruby-mode-hock enh-ruby-mode-mapで置換する。

ruby-electric

ruby-electricはかっこやdo endなどの対応関係を自動で補正してくれる。

(require 'ruby-electric)
(add-hook 'ruby-mode-hook '(lambda () (ruby-electric-mode t)))
(setq ruby-electric-expand-delimiters-list nil)

ruby-block

ruby-blockを導入すると、end に対応する行をハイライトしてくれる。

;; ruby-block.el --- highlight matching block
(require 'ruby-block)
(ruby-block-mode t)
(setq ruby-block-highlight-toggle t)

コードリーディング

ctags/ripper-tags

タグジャンプを利用するためには、ctagsがRubyに対応しているようだ。

まずは、ctagsをインストール。linux mintでは以下で入る。

sudo apt-get install ctags

Exuberant Ctagsというものがctagsの代わにインストールされた?まあいいや。

ルートディレクトリで以下を実行。

ctags-exuberant -a -e -f TAGS --tag-relative -R *

TAGSが生成される。これをemacsからつかえばよい。試しに M-x find-tagsを入力して、タグジャンプが発動すればOK。

  • M-. find-tags タグジャンプ
  • M-* ジャンプ元に戻る。

さらに改善。ctagsよりも高速なripper-tagsというものを見つけた。Emacsにも対応しているよう。

ripper-tagsは ctagsデータをより高速に生成するツール。

gem install ripper-tags

ルートディレクトリで以下を実行。

ripper-tags -e -R -f TAGS

さらにさらに改善するには、helm-etags-selectがいいかも。helmインターフェースで飛び先を絞り込み。M-x c e で発動。

rcodetools( xmpfilter )

rcodertoolsとは、Ruby開発のためのツール群。emacs界で有名な、rubikichi 氏の作品。

以下のような機能をゆうしている。

xmpfilter: Test::Unit assert* / RSpec should* 自動生成、コード注釈
rct-complete: 高精度メソッド名・クラス名・定数名等補完
rct-doc: ドキュメント参照・コードナビゲーター
rct-meth-args: 高精度メソッド情報リスト、TAGS ファイル作成
rct-fork: Rails 等重いライブラリを予めロードし、補完を高速化する(サーバ)
rct-fork-client: rct-fork サーバが保持する状態から Ruby スクリプトを実行する
ruby-toggle-file: テストスクリプトと実装スクリプトを切り換える
rbtest: 小規模スクリプトのための埋め込み Test::Unit

まずは、rcodertoolsをダウンロードする。gemコマンドで入る。

$ gem install rcodetools

gem environmentコマンドでインストールされた場所を調べて、rcodetools.elをload-pathが通った場所にコピーする。

$ gem environment
$ cp /usr/lib/ruby/gems/1.9.1/gems/rcodetools-0.8.5.0/rcodetools.el .

最後に、rcodetools/binにパスを通す(ここがハマりポイント!)このページに助けられた。

.zshenvとかに、

export PATH=$PATH:$HOME/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/rcodetools-0.8.5.0/bin

.emacsへの設定例は以下。

;; rcodetools
(require 'rcodetools)
(setq rct-find-tag-if-available nil)
(defun ruby-mode-hook-rcodetools ()
  (define-key ruby-mode-map "\M-\C-i" 'rct-complete-symbol)
  (define-key ruby-mode-map "\C-c\C-t" 'ruby-toggle-buffer)
  (define-key ruby-mode-map "\C-c\C-f" 'rct-ri))
(add-hook 'ruby-mode-hook 'ruby-mode-hook-rcodetools)

xmprilterを使うとRuby コードの行末に「# =>」を入れて xmpfilter を実行するとその行の返り値を見ることができる。

rct-completeを使うと、コードの自動補完が使える。

また、ruby-toggle-bufferはテストコードとソースコードを切り替えることができる。

切り替えたり、メソッドを補完しながらTDDする方法をTDCと名づけている。(Test Driven Completion)README.TDCを読むと面白い。

たくさん機能があるので、いろいろ調べるとよい。ちょっとまだつかいこなせてない。詳しくはREADMEを参照。

rdefs

rdefsはソースコードのclassやmodule、defといった宣言のラインを引っ張り出してくれるツール。

gem install rdefs

anything I/Fを経由して、Emacsから利用することができる。helmは見つからなかった。

wget https://raw2.github.com/mori-dev/anything-rdefs/master/anything-rdefs.el

.emacsの設定は以下。

(require 'anything)
(require 'anything-rdefs)
(add-hook 'enh-ruby-mode-hook
          (lambda ()
            (define-key enh-ruby-mode (kbd "C-@") 'anything-rdefs)))

これはなかなかよいツールだ。

リファクタリング

Rubyリファクタリング環境は以外に貧弱だった。なんとかならないものか・・・。

anzu

リファクタリングのリネーム機能を探していたら、これが良さそう。

置換や検索をおしゃれに実行するElisp。詳しくは、以下。

(require 'anzu)
(global-anzu-mode +1)

(set-face-attribute 'anzu-mode-line nil
                    :foreground "yellow" :weight 'bold)
(custom-set-variables
 '(anzu-mode-lighter "")
 '(anzu-deactivate-region t)
 '(anzu-search-threshold 1000)
 '(anzu-use-mimego t)
 '(anzu-replace-to-string-separator " => "))

ruby-refactor

ruby-refactorは、Rubyでリファクタリングをするためのツール。

githubからとってくる。

.emacsにも設定を追加。

(require 'ruby-refactor)
(add-hook 'ruby-mode-hook 'ruby-refactor-mode-launch)

こんなことができる。


    Extract to Method (C-c C-r e)
    Extract Local Variable (C-c C-r v)
    Extract Constant (C-c C-r c)
    Add Parameter (C-c C-r p)
    Extract to Let (C-c C-r l)

個人的にはExtract MethodとRenameができればよいが、Renameはできない。

また、Extract Methodは変数を抽出してはくれないのであまり賢くない。

コーディング支援

inf-ruby

Emacsのバッファからirbを起動する。

(autoload 'inf-ruby "inf-ruby" "Run an inferior Ruby process" t)
(add-hook 'ruby-mode-hook 'inf-ruby-minor-mode)

M-x inf-rubyでバッファが起動。これだけ。

SmartCompile

SmaprtCompleを入れることで、Emacs編集中に”C+c, C+c”でRubyを実行することができる。

.emacsにも設定を追加。

;; smart-compile
(require 'smart-compile)
(define-key ruby-mode-map (kbd "C-c c") 'smart-compile)
(define-key ruby-mode-map (kbd "C-c C-c") (kbd "C-c c C-m"))
(setq compilation-window-height 15) ;; default window height is 15

また、このままだと、コードチェックまでで、実行してくれないので、このサイトを参考にしてelispを編集した。

;;  ("\\.rb\\'"         . "ruby -cw %f")
  ("\\.rb\\'"         . "ruby %f")

auto-complite-ruby/RSense

Ruby用の補完をする。補完はauto-completeという有名なelispがある。

もっと賢いのがオムニ補完と呼ばれるもの。これは文法を解析して補完してくれる。以下の2つが使えそう。

  • RSense
  • auto-complete-ruby

しかし、・・・どちらも自分の環境では動かなかった。。。ruby2.0だと駄目なのかな?そのうち頑張る。とりあえず、auto-completeで我慢。

yasnippet-ruby

Emacsのスニペット挿入機能といえば、yasnippetだが、そのRuby用テンプレート群をいれる。

ここからダウンロードして、yasnippetのスニペット一覧に突っ込む!

いちおう、yasnippetsの設定も載せておく。ここでは、~/.emacs.d/snippetsにいれた。

(require 'yasnippet)
(yas/load-directory "~/.emacs.d/snippets")
(yas-global-mode 1)

;; 既存スニペットを挿入する
(define-key yas-minor-mode-map (kbd "C-x i i") 'yas-insert-snippet)
;; 新規スニペットを作成するバッファを用意する
(define-key yas-minor-mode-map (kbd "C-x i n") 'yas-new-snippet)
;; 既存スニペットを閲覧・編集する
(define-key yas-minor-mode-map (kbd "C-x i v") 'yas-visit-snippet-file)

静的解析

flycheckが熱いことが分かった。

flymake-ruby

文法を静的解析するために、flymake-rubyを入れる。

(require 'flymake-ruby)
(add-hook 'ruby-mode-hook 'flymake-ruby-load)

入れると、文法的におかしいところに色がつく。単純ミスしか指摘してくれない。

flycheck

flymakeのかわりに、flycheckというものがある。機能は似ているが、こっちの方が新しく拡張性がある。

両者の比較には、以下のエントリが参考になる。

(require 'flycheck)
(setq flycheck-check-syntax-automatically '(mode-enabled save))
(add-hook 'ruby-mode-hook 'flycheck-mode)

とりあえず、新しいflycheckをつかうことにする。

ついでに、flycheckをカラフルにする flycheck-color-mode-lineも入れた。どうも、MELPAやel-getで取得できなかったので、直接git cloneした。

git clone https://github.com/flycheck/flycheck-color-mode-line.git

設定は以下。

この拡張性を利用して、ruby-lintとrobocopを入れてみる。

rubocop

コーディングスタイルをチェックするために、rubocopを入れてみる。 以下を参考にした。

まずは、gemでrobocopをインストール。

gem install rubocop

.emacsの設定は以下。

(require 'rubocop)
(add-hook 'ruby-mode-hook 'rubocop-mode)

標準だと、Rubyコーディングスタイルガイドにしたがっているかチェックできる。

カスタマイズは徐々にしていこう。

さらに、前述のflycheckのcheckツールにrubocopを組み込むことができる。

flycheck-list-errorsで、flycheckが検出したエラーと一緒にチェックできる。I/Fの共通化。

(flycheck-define-checker ruby-rubocop
  "A Ruby syntax and style checker using the RuboCop tool."
  :command ("rubocop" "--format" "emacs" "--silent"
            (config-file "--config" flycheck-rubocoprc)
            source)
  :error-patterns
  ((warning line-start
            (file-name) ":" line ":" column ": " (or "C" "W") ": " (message)
            line-end)
   (error line-start
          (file-name) ":" line ":" column ": " (or "E" "F") ": " (message)
          line-end))
   :modes (enh-ruby-mode motion-mode))

ruby-lint

flymakeよりももう少し頭のいい解析をする。semantic(文法解析)的に解析してくれるらしい。

rubocopとの違いについても、githubのreadmeにかかれている。

gemでインストール。

gem install ruby-lint

これも、flycheckのインタフェースを利用してチェックさせる。

;; definition for flycheck
(flycheck-define-checker ruby-rubylint
  "A Ruby syntax and style checker using the rubylint tool."
  :command ("ruby-lint" source)
  :error-patterns
  ((warning line-start
            (file-name) ":" line ":" column ": " (or "C" "W") ": " (message)
            line-end)
   (error line-start
          (file-name) ":" line ":" column ": " (or "E" "F") ": " (message)
          line-end))
  :modes (enh-ruby-mode ruby-mode))

Viewing all articles
Browse latest Browse all 91

Trending Articles