HOME

Ruby

Still my favorite language.

Ruby Mode Keybindings

Key-Chord Command
C-c C-z Switch to IRB REPL
C-c C-l Load current buffer into the REPL
C-' Convert Symbol->String
C-: Convert String->Symbol

Start-up

(setq rbenv-installation-dir (concat (getenv "HOME") "/.rbenv"))
(require-package 'ruby-mode)
(autoload 'ruby-mode "ruby-mode" "Major mode for Ruby" t)

(setenv "PATH"
        (string-join (list
                      (concat rbenv-installation-dir "/shims")
                      (concat rbenv-installation-dir "/bin")
                      (getenv "PATH"))
                     ":"))

(setenv "PATH" (concat (getenv "PATH") ":" ))
(add-to-list 'exec-path (concat rbenv-installation-dir "/shims"))

(require-package 'enh-ruby-mode)
(autoload 'enh-ruby-mode "enh-ruby-mode" "Major mode for ruby files" t)
(setq enh-ruby-program (concat rbenv-installation-dir "/shims/ruby"))

(eval-after-load 'ruby-mode
  '(progn
     (require-package 'smartparens)
     (require-package 'inf-ruby)
     (require-package 'rbenv)
     (require-package 'rspec-mode)
     (autoload 'rspec-mode "rspec-mode" "Minor mode for RSpec specs" t)
     (require-package 'minitest)
     (autoload 'minitest-mode "minitest-mode" "Minor mode for Minitest specs" t)
     (require-package 'enh-ruby-mode)
     (autoload 'enh-ruby-mode "enh-ruby-mode" "Major mode for ruby files" t)
     (require-package 'column-marker)
     (require-package 'flyspell)
     (require-package 'ruby-tools)))

;; (require-package 'robe)
;; (eval-after-load 'company
;;   '(push 'company-robe company-backends))

;; Hide-show settings
(add-to-list 'hs-special-modes-alist
             '(ruby-mode
               "\\(class\\|def\\|do\\|if\\)" "\\(end\\)" "#"
               (lambda (arg) (ruby-end-of-block)) nil))

(add-to-list 'hs-special-modes-alist
             '(enh-ruby-mode
               "\\(class\\|def\\|do\\|if\\)" "\\(end\\)" "#"
               (lambda (arg) (enh-ruby-end-of-block)) nil))

(add-hook 'after-init-hook    'inf-ruby-switch-setup)
(add-hook 'ruby-mode-hook     'toby/add-prettified-symbols)
(add-hook 'enh-ruby-mode-hook 'toby/add-prettified-symbols)

(defun toby/ruby-prettify ()
  (setq prettify-symbols-alist
        '(("lambda" . 955)
          ("->"     . (?→ (Br . Bl)))
          ("=>"     . 10233)
          )))

(defun toby/ruby-init ()
  (set (make-local-variable 'indent-tabs-mode) 'nil)
  (set (make-local-variable 'tab-width) 2)

  (toby/ruby-prettify)

  (column-marker-1 80)
  (whitespace-mode t)

  ;; Doesn't work in the terminal, unfortunately…
  (define-key ruby-mode-map (kbd "C-=") 'insert-rocket)
  (define-key ruby-mode-map (kbd "C-c =") 'insert-rocket)
  (define-key ruby-mode-map (kbd "C-c c") 'compile)

  (if (boundp 'enh-ruby-mode-map)
      (progn
        (define-key enh-ruby-mode-map (kbd "C-c =") 'insert-rocket)
        (define-key enh-ruby-mode-map (kbd "C-c c") 'compile)))

  (hs-minor-mode 1) ;; Code folding

  (flyspell-prog-mode)
  (eldoc-mode)

  (require 'ruby-tools)

  (global-rbenv-mode)
  (rbenv-use-corresponding)

  ;; (robe-mode)
  ;; (yard-mode)

  (require 'smartparens-config)
  ;; (smartparens-strict-mode)
  (smartparens-mode)
  (show-smartparens-mode t)

  (setq buffer-save-without-query t)

  ;; (require 'rspec-mode)
  ;; (require 'minitest-mode)

  (local-set-key (kbd "M-r")            'rspec-verify)
  (local-set-key (kbd "M-S-r")          'rspec-verify-single)
  (local-set-key [f12]                  'rspec-verify)
  (local-set-key [f11]                  'rspec-verify-single)
  (local-set-key (kbd "S-<f12>")        'rspec-rerun)
  (local-set-key [f13]                  'rspec-rerun)
  (local-set-key [f10]                  'next-error))

(add-to-list 'auto-mode-alist        '("\\.rb$" . ruby-mode))
(add-to-list 'interpreter-mode-alist '("ruby" . enh-ruby-mode))

(add-hook 'ruby-mode-hook     'toby/ruby-init)
(add-hook 'enh-ruby-mode-hook 'toby/ruby-init)
(add-hook 'enh-ruby-mode-hook (lambda () (electric-pair-mode 0)))

Inf-Ruby

(eval-after-load 'inf-ruby
  '(define-key inf-ruby-minor-mode-map
     (kbd "C-c C-s") 'inf-ruby-console-auto))

(defun toby/inf-ruby-hooks ()
  (color-identifiers-mode -1)
  (linum-mode -1))

(add-hook 'inf-ruby-mode-hook 'toby/inf-ruby-hooks)

RSpec

(defun toby/rspec-init ())

(defun toby/rspec-compile-init ()
  (linum-mode -1)
  (local-set-key (kbd "r") 'inf-ruby-switch-from-compilation)
  )

(add-hook 'rspec-compilation-mode-hook 'toby/rspec-compile-init)

Rbenv

(require-package 'rbenv)

(let ((rbenv-home
       (replace-regexp-in-string "[^[:word:]]*$" ""
                                 (shell-command-to-string "brew --prefix rbenv"))))
  (setenv "PATH"
          (concat rbenv-home "/shims:"
                  rbenv-home "/bin:"
                  (getenv "PATH")))
  (setq exec-path
      (cons (concat rbenv-home "/shims")
            (cons (concat rbenv-home "/bin")
                  exec-path)))

  (setq rbenv-installation-dir rbenv-home))

Cucumber

(require-package 'feature-mode)
(add-to-list 'auto-mode-alist '("\.feature$" . feature-mode))
(when (and (featurep 'yasnippet)
           feature-snippet-directory
           (file-exists-p feature-snippet-directory))
  (yas-load-directory feature-snippet-directory))

(add-hook 'feature-mode-hook
          (lambda ()
            (local-set-key (kbd "M-r")   'feature-verify-all-scenarios-in-buffer)
            (local-set-key [f12]         'feature-verify-all-scenarios-in-buffer)
            (local-set-key (kbd "M-S-r") 'feature-verify-scenario-at-pos)
            (local-set-key [f11]         'feature-verify-scenario-at-pos)))

Rails

(add-to-list 'auto-mode-alist '("\\.rabl$" . enh-ruby-mode))
(add-to-list 'auto-mode-alist '("\\.rake$" . enh-ruby-mode))

(require-package 'web-mode)
(autoload 'web-mode "web-mode" "Web Mode" t)
(add-to-list 'auto-mode-alist '("\\.html.erb$" . web-mode))

Lining Up Data Structures

(require 'align)
(add-hook 'align-load-hook
          (lambda ()
            (add-to-list 'align-rules-list
                         '(ruby-comma-delimiter
                           (regexp . ",\\(\\s-*\\)[^# \t\n]")
                           (repeat . t)
                           (modes  . '(ruby-mode))))
            (add-to-list 'align-rules-list
                         '(ruby-hash-literal
                           (regexp . "\\(\\s-*\\)=>\\s-*[^# \t\n]")
                           (repeat . t)
                           (modes  . '(ruby-mode))))
            (add-to-list 'align-rules-list
                         '(ruby-assignment-literal
                           (regexp . "\\(\\s-*\\)=\\s-*[^# \t\n]")
                           (repeat . t)
                           (modes  . '(ruby-mode))))
            (add-to-list 'align-rules-list
                         '(ruby-xmpfilter-mark
                           (regexp . "\\(\\s-*\\)# => [^#\t\n]")
                           (repeat . nil)
                           (modes  . '(ruby-mode))))))

TODO Make sure this hack is still necessary:

It used to prevent a strange start-up error on inf-ruby, but I should check if it's still needed.

(defalias 'inf-ruby-keys 'inf-ruby-setup-keybindings)

Cleaning Up Sloppy Code

Add Useful White-Space

Here's a function to add some helpful white-space:

(defun add-pride ()
  (interactive)
  (fix-parens)
  (decompress-hash-rockets)
  (untabify-buffer)
  (delete-trailing-whitespace))

Break-up Long Hashes

Sometimes, people spew massive hashes onto a single line without bothering to break it up for readability. This function will break the hash up on commas.

It will detect the bounds of the hash and set a region to its bounds. Then it moves through the hash injecting line-breaks after the commas.

(defun break-ruby-hash ()
  "Break the ruby hash around point into multiple lines at commas"
  (interactive)
  (let ((chars "^{}") p1 p2)
    (save-excursion
      (skip-chars-backward chars)
      (setq p1 (point))
      (skip-chars-forward chars)
      (setq p2 (point))

      (goto-char p1) (insert "\n")
      (goto-char p2) (forward-char 1) (insert "\n")
      (replace-in ", " ",\n" p1 p2)
      (indent-region p1 (+ 2 p2)))))
(provide 'ruby-init)

Author: Toby Tripp

Created: 2018-02-09 Fri 15:38

Validate