As a Rails developer, every time we work on a Rails project we heavily use rails console for development. I love the rails console as much as any Rails developer. It is the best place to experiment or validate your logic but...!
There are some of my personal nit-picks:
- When we are playing around with multiple rails projects and end up opening rails console for multiple projects, then it becomes difficult to identify which rails console belong to which project.
- Another problem with these plain rails console is identifying the rails environment in which we are. Until you run
Rails.env
you can't be sure. - But the biggest issue with the plain old rails console is; it is BORING! It's the same old screen every time I open.
Your rails console should be more declartive
Enter the Dotfiles
A little while ago I came to know about dotfiles by Rails conf talk by @bradurani. So basically the dotfiles are the configuration for Unix-y systems. In our daily dev life we use .bashrc, .bash_profile etc.
To my surprise ruby's IRB also has dotfile based configuration .irbrc and rails console is based on IRB so this config does apply to rails console too.
In this blog post, we will explore .irbrc prompt configuration and tackle the issues mentioned above.
IRB provides many prompt modes out of the box, these are NULL, DEFAULT, CLASSIC, SIMPLE, etc.
To switch between these prompt-modes, edit your .irbrc (located in HOME directory, if it's not present, create it.)
# .irbrc | |
IRB.conf[:PROMPT_MODE] = :SIMPLE # default is :DEFAULT | |
# Or, invoke irb with the prompt mode by | |
# terminal | |
❱ irb --prompt simple |
There's a lot we need to understand before the above configuration starts making sense.
1 . Specific format for the irb prompt is used:
{ | |
PROMPT_I => "" # Simple prompt | |
PROMPT_S => "" # Prompt for continued strings | |
PROMPT_C => "" # Prompt for continued statement | |
RETURN => "" # Format to return value | |
} |
2 . Special strings are provided in irb as prompt-helpers:
%N # command name which is running | |
%m # to_s of main object (self) | |
%l # type of string(", ', /, ]), `]' is inner %w[...] | |
%NNi # indent level. NN is digits and means as same as printf("%NNd"). | |
%NNn # line number. |
Now, let's take a look at how IRB defines Classic mode & Simple mode.
# IRB Classic prompt | |
IRB.conf[:PROMPT_MODE][:CLASSIC] = { | |
:PROMPT_I => "%N(%m):%03n:%i> ", # irb(main):001:0> | |
:PROMPT_S => "%N(%m):%03n:%i%l ", # irb(main):003:0" | |
:PROMPT_C => "%N(%m):%03n:%i* ", # irb(main):005:0* | |
:RETURN => "%s\n" # used to printf # | |
} | |
vs | |
# IRB Simple prompt | |
IRB.conf[:PROMPT_MODE][:CLASSIC] = { | |
:PROMPT_I => ">> ", # >> | |
:PROMPT_C => "?> ", # ?> | |
:RETURN: => "%s" | |
} |
Hurray!!, we completed the basic guide, now lets start tweaking with our .irbrc
Let's target our first issue, "How to inform the developer about the rails application name in the rails console?"
The first step, get the application name in rails.
We can find our rails app name in config/application.rb
Note: We will be using meetup rails app for examples
# config/application.rb
module Meetup
class Application < Rails::Application
....
end
end
Notice that our application name is the module name for rails application class, now let's get it programmatically.
# We can get application class by | |
>> Rails.application.class.name | |
# => "Meetup::Application" | |
## Since we are only interested in application name, we can get it by | |
>> Rails.application.class.module_parent.name | |
# => "Meetup" | |
# Caveat: In previous versions of ruby, rails it can be acheived by | |
>> Rails.application.class.parent.name | |
# => "Meetup" |
Now let's tackle the second issue, Rails environment information in rails console this is straightforward...
# We can get rails environment by simply calling | |
>> Rails.env | |
# => "development" |
Now let's glue these together with .irbrc
def application_name | |
Rails.application.class.module_parent.name | |
end | |
def rails_environment | |
Rails.env | |
end | |
# Checking if we are in rails console | |
if defined?(Rails) | |
prompt = "#{application_name}[#{rails_environment}]" | |
# defining custom prompt | |
IRB.conf[:PROMPT][:RAILS] = { | |
:PROMPT_I => "#{prompt}>> ", | |
:PROMPT_N => "#{prompt}> ", | |
:PROMPT_S => "#{prompt}* ", | |
:PROMPT_C => "#{prompt}? ", | |
:RETURN => " => %s\n" | |
} | |
# Setting our custom prompt as prompt mode | |
IRB.conf[:PROMPT_MODE] = :RAILS | |
end |
Oh! Wait we still haven't solved the important issue. Its still BOORING plain rails console.
Since irbrc is just ruby, your imagination is only the limitation for making it interesting. Following are my version of rails console's
- Colorful rails console using Rainbow gem or ANSI escape codes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
# This gem needs to installed require 'rainbow' def app_prompt rails_klass = Rails.application.class app_name = if rails_klass.respond_to? :module_parent rails_klass.module_parent else rails_klass.parent end Rainbow("#{app_name.name}").blue end # target log path for irb history def log_path rails_root = Rails.root "#{rails_root}/log/.irb-save-history" end def env_prompt case Rails.env when "development" Rainbow("development").green when "production" Rainbow("production").red else Rainbow("#{Rails.env}").yellow end end if defined?(Rails) IRB.conf[:HISTORY_FILE] = FileUtils.touch(log_path).join IRB.conf[:PROMPT] ||= {} prompt = "#{app_prompt}[#{env_prompt}]:%03n " IRB.conf[:PROMPT][:RAILS] = { :PROMPT_I => "#{prompt}>> ", :PROMPT_N => "#{prompt}> ", :PROMPT_S => "#{prompt}* ", :PROMPT_C => "#{prompt}? ", :RETURN => " => %s\n" } IRB.conf[:PROMPT_MODE] = :RAILS end - Rails console with emojis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
# This gem needs to installed require 'rainbow' def app_prompt rails_klass = Rails.application.class app_name = if rails_klass.respond_to? :module_parent rails_klass.module_parent else rails_klass.parent end Rainbow("#{app_name.name}").blue end # target log path for irb history def log_path rails_root = Rails.root "#{rails_root}/log/.irb-save-history" end def env_prompt case Rails.env when "development" Rainbow("development").green when "production" Rainbow("production").red else Rainbow("#{Rails.env}").yellow end end if defined?(Rails) IRB.conf[:HISTORY_FILE] = FileUtils.touch(log_path).join IRB.conf[:PROMPT] ||= {} prompt = "#{app_prompt}[#{env_prompt}]:%03n " IRB.conf[:PROMPT][:RAILS_EMOJI] = { :PROMPT_I => "#{prompt}\u{1F601} >", :PROMPT_N => "#{prompt}\u{1F609} >", :PROMPT_S => "#{prompt}\u{1F606} >", :PROMPT_C => "#{prompt}\u{1F605} >", :RETURN => " => %s\n" } IRB.conf[:PROMPT_MODE] = :RAILS_EMOJI end
Thank you for reading!!
Top comments (5)
What font are you using for the emoji icons?
I am using fonts pulled by oh-my-zsh & powerline.
Nice. I’m still a Ruby newb so this looks pretty cool. Also, congrats on your first post!
Thank you! Nick.
Nice one. I was unknown about the dotfiles for IRB. Great!