This really was a lark to see if I could change ALL the files using woccur and a regular expression. Quite please with how simple that was.
7.2 KiB
Programming in Ruby
A literate programming file for configuring Emacs to support the Ruby programming language.
Getting Started
Ruby is probably already installed on the system, and if not, we certainly can download it from ruby-lang.org, but since I need to juggle different versions for each project, I use direnv and ruby-install:
brew install ruby-install
And then install one or more versions:
ruby-install -U
ruby-install ruby 3
Per Project
While we could use a large project templating system, I keep it simple. For each project, create the following directory structure:
├── Gemfile ├── Rakefile ├── lib │ └── hello_world.rb └── test └── hello_world_test.rb
For instance:
mkdir ~/other/ruby-xp # Change me
cd ~/other/ruby-xp
mkdir lib test
Now, do the following steps.
-
Create a
.envrc
file with the Ruby you want to use:use ruby 2.6.8
-
Next, get Bundler:
gem install bundle
-
Create a minimal
Gemfile
:source 'https://rubygems.org' gem 'rake', group: :development gem 'rubocop', group: :development gem 'solargraph', group: :development
-
Grab all the dependencies:
bundle install
-
Create a minimal
Rakefile
:task default: %w[test] task :run do ruby 'lib/hello_world.rb' end task :test do ruby 'test/hello_world_test.rb' end
-
Create the first program:
class HelloWorld attr_reader :name def initialize(name = nil) @name = name end def greeting if @name "Hello there, #{@name}" else 'Hello World!' end end end puts HelloWorld.new.greeting
-
Create the first test:
require 'test/unit' require_relative '../lib/hello_world' class TestHelloWorld < Test::Unit::TestCase def test_default assert_equal 'Hello World!', HelloWorld.new.greeting end def test_name assert_equal 'Hello there, Bob', HelloWorld.new('Bob').greeting end end
Or something like that.
Configuration
Ruby-specific commands are attached to the ha-ruby-leader
, bound to SPC m
:
(general-create-definer ha-ruby-leader
:states '(normal visual motion)
:keymaps 'ruby-mode-map
:prefix "SPC m"
:global-prefix "<f17>"
:non-normal-prefix "S-SPC")
While Emacs supplies a Ruby editing environment, we’ll still use use-package
to grab the latest:
(use-package ruby-mode
:after projectile
:mode (rx ".rb" eos)
:mode (rx "Rakefile" eos)
:mode (rx "Gemfile" eos)
:mode (rx "Berksfile" eos)
:mode (rx "Vagrantfile" eos)
:interpreter "ruby"
:init
(setq ruby-indent-level 2
ruby-indent-tabs-mode nil)
:hook (ruby-mode . superword-mode))
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:
(use-package inf-ruby
:config
(ha-ruby-leader
"R" '("REPL" . inf-ruby)))
Electric Ruby
The ruby-electric project is a minor mode that aims to add the extra syntax when typing Ruby code.
(use-package ruby-electric
:hook (ruby-mode . ruby-electric-mode))
Testing
The ruby-test-mode project aims a running Ruby test from Emacs seemless:
(use-package ruby-test-mode
:hook (ruby-mode . ruby-test-mode)
:config
(ha-ruby-leader
"t" '(:ignore t :which-key "test")
"t t" '("test one" . ruby-test-run-at-point)
"t g" '("toggle code/test" . ruby-test-toggle-implementation-and-specification)
"t A" '("test all" . ruby-test-run)
"t a" '("retest" . ruby-test-rerun)))
Rubocop?
The lint-like style checker of choice for Ruby is Rubocop. The rubocop.el mode should work with Flycheck. First install it with:
gem install rubocop
And then we may or may not need to enable the rubocop-mode
:
(use-package rubocop
:hook (ruby-mode . rubocop-mode))
Auxiliary Support
Cucumber
Seems that to understand and edit Cucumber feature definitions, you need cucumber.el:
(use-package feature-mode)
LSP
Need to install Solargraph for the LSP server experience:
gem install solargraph
Or add it to your Gemfile
:
gem 'solargraph', group: :development