Skip to content

Latest commit

 

History

History
260 lines (190 loc) · 8.7 KB

emacs-ruby.org

File metadata and controls

260 lines (190 loc) · 8.7 KB

Ruby Configuration for Emacs

We begin by stealing a typical Ruby environment from Prelude.

Ruby Installation

I like having everything Ruby controlled by RVM:

curl -sSL https://get.rvm.io | bash -s stable

And then install a Ruby version and set it to be used globally:

rvm install 1.9.3-p550
rvm use 1.9.3-p550

See the Ruby Virtual Manager section below.

Supporting Packages

Starting to collect the Ruby packages that make the most sense for my work-flow and development style:

(packages-install '( ruby-tools
                     inf-ruby
                     rvm
                     yari
                     robe
                     rubocop
                     smartparens ))

Notice that I’m not using enh-ruby-mode, as I have found that the updated ruby-mode that is standard in Emacs 24.4 is quite good.

Ruby Mode and File Extensions

Many odd files need to associated with any Ruby mode:

(when (require 'ruby-mode nil t)
  (add-to-list 'auto-mode-alist '("\\.rb$"          . ruby-mode))
  (add-to-list 'interpreter-mode-alist '("ruby"     . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.rake\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("Rakefile\\'"     . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.gemspec\\'"   . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.ru\\'"        . ruby-mode))
  (add-to-list 'auto-mode-alist '("Gemfile\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("Guardfile\\'"    . ruby-mode))
  (add-to-list 'auto-mode-alist '("Capfile\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.thor\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.rabl\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("Thorfile\\'"     . ruby-mode))
  (add-to-list 'auto-mode-alist '("Vagrantfile\\'"  . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.jbuilder\\'"  . ruby-mode))
  (add-to-list 'auto-mode-alist '("Podfile\\'"      . ruby-mode))
  (add-to-list 'auto-mode-alist '("\\.podspec\\'"   . ruby-mode))
  (add-to-list 'auto-mode-alist '("Puppetfile\\'"   . ruby-mode))
  (add-to-list 'auto-mode-alist '("Berksfile\\'"    . ruby-mode))
  (add-to-list 'auto-mode-alist '("Appraisals\\'"   . ruby-mode)))

Use web-mode for dealing with ERB templates:

(when (require 'web-mode nil t)
  (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode)))

Customizations

Create a function that will set the default values for the ruby-mode, and tie that to the ruby-mode-hoook:

(defun ha/ruby-mode-defaults ()
  ;; It hate subwords
  (superword-mode +1)
  (ruby-tools-mode +1)

  (setq-default ruby-indent-level 2)
  (setq-default ruby-indent-tabs-mode nil)

  ;; Using =expand-regions= and send a region to REPLs:
  (local-set-key (kbd "C-c i") 'ruby-send-region))

(add-hook 'ruby-mode-hook 'ha/ruby-mode-defaults)

Better Keyboard Movement

Each language that I use, I like to bind the sexp movement:

(define-key ruby-mode-map (kbd "M-<down>") 'ruby-forward-sexp)
(define-key ruby-mode-map (kbd "M-<up>") 'ruby-backward-sexp)

Other keystrokes to remember:

C-M-p / C-M-n
Move to the beginning and end of a block
C-M-a / C-M-e
Move to the beginning and end of a function

Ruby Virtual Manager

Using RVM integration for Emacs:

(when (require 'rvm nil t)
  (rvm-use-default))

When jumping from project to project, need to run the command: rvm-use … which must be done before starting an Eshell (that is, if you’re into that sort of thing).

Ruby Functional Doc

The Yari project attempts to hook Ruby calls to the ri project.

(when (require 'yari nil t)
  (add-hook 'ruby-mode-hook
            (lambda ()
              (local-set-key [f1] 'yari))))

Now, place point on some function, and hit F1 to see the glory. In order for this to work, we need to generate the missing docs:

gem rdoc --all --ri --no-rdoc
rvm docs generate all

And we may have to do this for every change to RVM. Seems that dash-at-point is more effective (C-c d), however.

Ruby REPL

I am not sure I can learn a new language without a REPL connected to my editor, and for Ruby, this is inf-ruby:

(require 'inf-ruby)
(add-hook 'ruby-mode-hook 'inf-ruby-minor-mode)

To start eval-ing, do: M-x inf-ruby … or: C-c C-s

Smart Parens

Can I get the same wonder from paredit and Lisp in my Ruby using smartparens? Not really, as it isn’t as pedantic as paredit. Still, it may be good enough for Ruby:

(when (require 'smartparens-config nil t)
      (require 'smartparens-ruby)

  (add-hook 'ruby-mode-hook 'smartparens-mode))

Rubocop

The lint-like style checker of choice for Ruby is Rubocop. The rubocop.el mode should just work with Flycheck.

(when (require 'rubocop nil t)
  (add-hook 'ruby-mode-hook 'rubocop-mode))

Install it with: gem install rubocop

Robe

Robe is a “code assistance” tool, that pretty much only works with methods (and doesn’t seem to work well with direct functions). One must install the following before this will work:

gem install pry pry-doc

Once started with robe-start, we should get code completion:

(when (require 'robe nil t)
  (add-hook 'ruby-mode-hook 'robe-mode)
  (eval-after-load 'company '(push 'company-robe company-backends))

  ;; Don't care to have to start up Ruby if I'm just jumping around
  (define-key robe-mode-map (kbd "M-.") 'xref-find-definitions)
  (define-key robe-mode-map (kbd "C-M-.") 'robe-jump)

  (defadvice inf-ruby-console-auto (before activate-rvm-for-robe activate)
    (rvm-activate-corresponding-ruby)))

With a complex Ruby project, one should evaluate the entire Ruby file (C-c C-l), and then run:

  • robe-jump to go to the method’s definition
  • robe-ask will act like jump, but asks for the method first
  • robe-doc displays the method documentation (doesn’t seem to be as useful as dash-at-point).

Ruby Tools

The little refactoring available with Ruby Tools looks interesting.

(when (require 'ruby-tools nil t)
  (add-hook 'ruby-mode-hook 'ruby-tools-mode))

The primary key-bindings operate on the thing the cursor is on, e.g. a string, a symbol, etc.

  • C-‘ converts the thing into a single-quoted string
  • C-“ converts the thing into a double-quoted string
  • C-: converts the thing into a symbol

Other options:

  • C-; clears the string
  • Inside a string the # key will insert a variable interpolation if the string is double-quoted (this is actually what I use this package the most)

Technical Artifacts

Make sure that we can simply require this library.

(provide 'init-ruby)

Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: C-c C-c