lang/ruby: major refactor
+ Robe is now to be started manually. + Adds more keybindings for robe (including <localleader> ' for robe-start). + Use ruby-mode if ruby isn't available (e.g. editing ruby files on remote systems), enh-ruby-mode otherwise. + Added rake, bundler, rvm, rbenv and minitest packages + Added $RBENV_ROOT/shims to exec-path. This should fix rbenv support for the ruby version display in the modeline.
This commit is contained in:
parent
b91a8f0d2f
commit
8bdb42fe15
3 changed files with 150 additions and 92 deletions
|
@ -1,5 +1,8 @@
|
|||
;;; lang/ruby/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +ruby-version-cache (make-hash-table :test 'equal)
|
||||
"TODO")
|
||||
|
||||
;;;###autoload
|
||||
(defun +ruby|cleanup-robe-servers ()
|
||||
"Clean up dangling inf robe processes if there are no more `enh-ruby-mode'
|
||||
|
@ -22,11 +25,28 @@ ruby executable found in your PATH).
|
|||
This is not necessarily aware of env management tools like virtualenv, pyenv or
|
||||
pipenv, unless those tools have modified the PATH that Emacs picked up when you
|
||||
started it."
|
||||
(unless (executable-find "ruby")
|
||||
(user-error "Couldn't find ruby executable in PATH"))
|
||||
(with-temp-buffer
|
||||
(let ((p (call-process "ruby" nil (current-buffer) nil "--version"))
|
||||
(output (string-trim (buffer-string))))
|
||||
(unless (zerop p)
|
||||
(user-error "ruby --version failed: %s" output))
|
||||
(nth 1 (split-string output " " t)))))
|
||||
(condition-case _
|
||||
(let ((version-str (car (process-lines "ruby" "--version"))))
|
||||
(puthash (doom-project-root)
|
||||
(format "Ruby %s" (cadr (split-string version-str " ")))
|
||||
+ruby-version-cache))
|
||||
(error "Ruby")))
|
||||
|
||||
|
||||
;;
|
||||
;; Hooks
|
||||
|
||||
;;;###autoload
|
||||
(defun +ruby|update-version (&rest _)
|
||||
"Update `+ruby--version' by consulting `+ruby-version' function."
|
||||
(setq +ruby--version
|
||||
(or (gethash (doom-project-root) +python-version-cache)
|
||||
(+ruby-version))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ruby|update-version-in-all-buffers ()
|
||||
"Update `+ruby--version' in all `enh-ruby-mode' buffers."
|
||||
(dolist (buffer (doom-buffers-in-mode 'enh-ruby-mode))
|
||||
(setq +ruby-version-cache (clrhash +ruby-version-cache))
|
||||
(with-current-buffer buffer
|
||||
(+ruby|update-version))))
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
;;; lang/ruby/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +ruby-mode-line-indicator
|
||||
'("Ruby" (+ruby-version (" " +ruby-version)))
|
||||
(defvar +ruby-mode-line-indicator '("" +ruby--version)
|
||||
"Format for the ruby version/env indicator in the mode-line.")
|
||||
|
||||
(defvar-local +ruby-version nil
|
||||
(defvar-local +ruby--version nil
|
||||
"The ruby version in the current buffer.")
|
||||
|
||||
|
||||
|
@ -12,33 +11,66 @@
|
|||
;; Packages
|
||||
|
||||
(def-package! enh-ruby-mode
|
||||
:mode "\\.rb\\'"
|
||||
:mode "\\.rake\\'"
|
||||
:mode "\\.gemspec\\'"
|
||||
:mode "\\.\\(?:pry\\|irb\\)rc\\'"
|
||||
:mode "/\\(?:Gem\\|Cap\\|Vagrant\\|Rake\\|Pod\\|Puppet\\|Berks\\)file\\'"
|
||||
:mode ("\\.\\(?:pry\\|irb\\)rc\\'" . +ruby|init)
|
||||
:mode ("\\.\\(?:rb\\|rake\\|rabl\\|ru\\|builder\\|gemspec\\|jbuilder\\|thor\\)\\'" . +ruby|init)
|
||||
:mode ("/\\(?:Berks\\|Cap\\|Gem\\|Guard\\|Pod\\|Puppet\\|Rake\\|Thor\\|Vagrant\\)file\\'" . +ruby|init)
|
||||
:preface
|
||||
(after! ruby-mode (require 'enh-ruby-mode))
|
||||
(defun +ruby|init ()
|
||||
"Enable `enh-ruby-mode' if ruby is available, otherwise `ruby-mode'."
|
||||
(if (executable-find "ruby")
|
||||
(enh-ruby-mode)
|
||||
(ruby-mode)))
|
||||
:config
|
||||
(set-electric! 'enh-ruby-mode :words '("else" "end" "elsif"))
|
||||
(set-repl-handler! 'enh-ruby-mode #'inf-ruby) ; `inf-ruby'
|
||||
(set-env! "RBENV_ROOT")
|
||||
(set-electric! '(ruby-mode enh-ruby-mode) :words '("else" "end" "elsif"))
|
||||
(set-repl-handler! '(ruby-mode enh-ruby-mode) #'inf-ruby)
|
||||
|
||||
(after! company-dabbrev-code
|
||||
(add-to-list 'company-dabbrev-code-modes 'enh-ruby-mode nil #'eq)
|
||||
(add-to-list 'company-dabbrev-code-modes 'ruby-mode nil #'eq))
|
||||
|
||||
(after! dtrt-indent
|
||||
;; `dtrt-indent' supports ruby-mode. Make it aware of enh-ruby-mode
|
||||
(add-to-list 'dtrt-indent-hook-mapping-list '(enh-ruby-mode ruby enh-ruby-indent-level)))
|
||||
|
||||
;; so class and module pairs work
|
||||
(setq-hook! 'enh-ruby-mode-hook sp-max-pair-length 6)
|
||||
(setq-hook! (ruby-mode enh-ruby-mode) sp-max-pair-length 6)
|
||||
|
||||
;; Add ruby version string to the major mode in the modeline
|
||||
(defun +ruby|adjust-mode-line ()
|
||||
(setq mode-name +ruby-mode-line-indicator))
|
||||
(add-hook 'enh-ruby-mode-hook #'+ruby|adjust-mode-line)
|
||||
|
||||
(defun +ruby|update-version (&rest _)
|
||||
(setq +ruby-version (+ruby-version)))
|
||||
(+ruby|update-version)
|
||||
(add-hook 'enh-ruby-mode-hook #'+ruby|update-version))
|
||||
|
||||
|
||||
(def-package! yard-mode :hook enh-ruby-mode)
|
||||
(def-package! robe
|
||||
:hook (enh-ruby-mode . robe-mode)
|
||||
:config
|
||||
(set-repl-handler! 'enh-ruby-mode #'robe-start)
|
||||
(set-company-backend! 'enh-ruby-mode 'company-robe)
|
||||
(set-lookup-handlers! 'enh-ruby-mode
|
||||
:definition #'robe-jump
|
||||
:documentation #'robe-doc)
|
||||
(map! :localleader
|
||||
:map robe-mode-map
|
||||
:n "'" #'robe-start
|
||||
;; robe mode specific
|
||||
:n "h" #'robe-doc
|
||||
:n "rr" #'robe-rails-refresh
|
||||
;; inf-enh-ruby-mode
|
||||
:prefix "s"
|
||||
:n "f" #'ruby-send-definition
|
||||
:n "F" #'ruby-send-definition-and-go
|
||||
:n "r" #'ruby-send-region
|
||||
:n "R" #'ruby-send-region-and-go
|
||||
:n "i" #'ruby-switch-to-inf))
|
||||
|
||||
|
||||
;; NOTE Must be loaded before `robe-mode'
|
||||
(def-package! yard-mode
|
||||
:hook (ruby-mode enh-ruby-mode))
|
||||
|
||||
|
||||
(def-package! rubocop
|
||||
|
@ -52,22 +84,45 @@
|
|||
:nv "P" #'rubocop-autocorrect-project))
|
||||
|
||||
|
||||
(def-package! robe
|
||||
:hook (enh-ruby-mode . robe-mode)
|
||||
:init
|
||||
;; robe-start errors if you hit no.
|
||||
(defun +ruby|init-robe ()
|
||||
(when (executable-find "ruby")
|
||||
(cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
|
||||
(save-window-excursion
|
||||
(with-demoted-errors "ROBE ERROR: %s"
|
||||
(robe-start)))
|
||||
(when (robe-running-p)
|
||||
(add-hook 'kill-buffer-hook #'+ruby|cleanup-robe-servers nil t)))))
|
||||
(add-hook 'enh-ruby-mode-hook #'+ruby|init-robe)
|
||||
:config
|
||||
(set-company-backend! 'robe-mode 'company-robe))
|
||||
;;
|
||||
;; Package & Ruby version management
|
||||
|
||||
(def-package! rake
|
||||
:defer t
|
||||
:init
|
||||
(setq rake-cache-file (concat doom-cache-dir "rake.cache"))
|
||||
(map! :after enh-ruby-mode
|
||||
:localleader
|
||||
:map enh-ruby-mode-map
|
||||
:prefix "k"
|
||||
:n "k" #'rake
|
||||
:n "r" #'rake-rerun
|
||||
:n "R" #'rake-regenerate-cache
|
||||
:n "f" #'rake-find-task))
|
||||
|
||||
(def-package! bundler
|
||||
:defer t
|
||||
:init
|
||||
(map! :after enh-ruby-mode
|
||||
:localleader
|
||||
:map enh-ruby-mode-map
|
||||
:prefix "b"
|
||||
:n "c" #'bundle-check
|
||||
:n "C" #'bundle-console
|
||||
:n "i" #'bundle-install
|
||||
:n "u" #'bundle-update
|
||||
:n "e" #'bundle-exec
|
||||
:n "o" #'bundle-open))
|
||||
|
||||
;; `rvm'
|
||||
(setq rspec-use-rvm t)
|
||||
|
||||
(after! rbenv
|
||||
(add-to-list 'exec-path (expand-file-name "shims" rbenv-installation-dir)))
|
||||
|
||||
|
||||
;;
|
||||
;; Testing frameworks
|
||||
|
||||
(def-package! rspec-mode
|
||||
:mode ("/\\.rspec\\'" . text-mode)
|
||||
|
@ -80,64 +135,41 @@
|
|||
;; Rake
|
||||
(("task" "namespace") () "end")))
|
||||
|
||||
(unless (featurep! :feature evil)
|
||||
(if (featurep! :feature evil)
|
||||
(add-hook 'rspec-mode-hook #'evil-normalize-keymaps)
|
||||
(setq rspec-verifiable-mode-keymap (make-sparse-keymap)
|
||||
rspec-mode-keymap (make-sparse-keymap)))
|
||||
|
||||
(defun +ruby*init-appropriate-rspec-mode ()
|
||||
"TODO"
|
||||
(cond ((rspec-buffer-is-spec-p)
|
||||
(rspec-mode +1))
|
||||
((let ((proot (doom-project-root 'nocache)))
|
||||
(or (file-directory-p (expand-file-name "spec" proot))
|
||||
(file-exists-p (expand-file-name ".rspec" proot))))
|
||||
(rspec-verifiable-mode +1))))
|
||||
(advice-add #'rspec-enable-appropriate-mode :override #'+ruby*init-appropriate-rspec-mode)
|
||||
:config
|
||||
(map! :map (rspec-mode-map rspec-verifiable-mode-map)
|
||||
(map! :map rspec-mode-map
|
||||
:localleader
|
||||
:prefix "t"
|
||||
:n "r" #'rspec-rerun
|
||||
:n "a" #'rspec-verify-all
|
||||
:n "s" #'rspec-verify-single
|
||||
:n "v" #'rspec-verify)
|
||||
:n "v" #'rspec-verify
|
||||
:n "c" #'rspec-verify-continue
|
||||
:n "e" #'rspec-toggle-example-pendingness
|
||||
:n "f" #'rspec-verify-method
|
||||
:n "l" #'rspec-run-last-failed
|
||||
:n "m" #'rspec-verify-matching
|
||||
:n "t" #'rspec-toggle-spec-and-target-find-example
|
||||
:n "T" #'rspec-toggle-spec-and-target))
|
||||
|
||||
|
||||
(def-package! bundler
|
||||
:after enh-ruby-mode
|
||||
(def-package! minitest
|
||||
:defer t
|
||||
:config
|
||||
(map! :localleader
|
||||
:map enh-ruby-mode-map
|
||||
:prefix "b"
|
||||
:n "c" #'bundle-check
|
||||
:n "C" #'bundle-console
|
||||
:n "i" #'bundle-install
|
||||
:n "u" #'bundle-update
|
||||
:n "e" #'bundle-exec
|
||||
:n "o" #'bundle-open))
|
||||
|
||||
;; Evil integration
|
||||
(when (featurep! :feature evil +everywhere)
|
||||
(add-hook! '(rspec-mode-hook rspec-verifiable-mode-hook)
|
||||
#'evil-normalize-keymaps)))
|
||||
(when (featurep! :feature evil)
|
||||
(add-hook 'minitest-mode-hook #'evil-normalize-keymaps))
|
||||
(map! :map minitest-mode-map
|
||||
:localleader
|
||||
:prefix "t"
|
||||
:n "r" #'minitest-rerun
|
||||
:n "a" #'minitest-verify-all
|
||||
:n "s" #'minitest-verify-single
|
||||
:n "v" #'minitest-verify))
|
||||
|
||||
|
||||
(def-package! company-inf-ruby
|
||||
:when (featurep! :completion company)
|
||||
:after inf-ruby
|
||||
:config (set-company-backend! 'inf-ruby-mode 'company-inf-ruby))
|
||||
|
||||
|
||||
;;
|
||||
;; Version managers
|
||||
|
||||
(def-package! rbenv
|
||||
:when (featurep! +rbenv)
|
||||
:after enh-ruby-mode
|
||||
:config (set-env! "RBENV_ROOT"))
|
||||
|
||||
|
||||
(def-package! rvm
|
||||
:when (featurep! +rvm)
|
||||
:after enh-ruby-mode)
|
||||
|
||||
;; Evil integration
|
||||
(when (featurep! :feature evil +everywhere)
|
||||
(add-hook! 'rspec-mode-hook #'evil-normalize-keymaps))
|
||||
|
|
|
@ -4,18 +4,24 @@
|
|||
;; requires ruby ruby-lint
|
||||
|
||||
(package! enh-ruby-mode)
|
||||
(package! rubocop)
|
||||
(package! inf-ruby)
|
||||
(package! rspec-mode)
|
||||
(package! yard-mode)
|
||||
(package! rake)
|
||||
(package! inf-ruby)
|
||||
(package! robe)
|
||||
(package! bundler)
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-inf-ruby))
|
||||
|
||||
;; Project tools
|
||||
(package! bundler)
|
||||
(package! rake)
|
||||
(package! rubocop)
|
||||
|
||||
;; Version management
|
||||
(when (featurep! +rbenv)
|
||||
(package! rbenv))
|
||||
(when (featurep! +rvm)
|
||||
(package! rvm))
|
||||
|
||||
;; Testing frameworks
|
||||
(package! rspec-mode)
|
||||
(package! minitest)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue