Skip to content

Instantly share code, notes, and snippets.

@brand-it
Last active November 7, 2023 06:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brand-it/5299e7b9d923caa8d204e2dcf31afdc6 to your computer and use it in GitHub Desktop.
Save brand-it/5299e7b9d923caa8d204e2dcf31afdc6 to your computer and use it in GitHub Desktop.
.irbrc with a bunch of stuff I found useful. This is all sort of hacky but that kinda of the point. Do what you want take what you need. no need to be perfect
# frozen_string_literal: true
MAX_COLUMNS_FOR_TABLE = 15 unless defined?(MAX_COLUMNS_FOR_TABLE)
DEFAULT_EDITOR = 'code' unless defined?(DEFAULT_EDITOR)
class PrettyString < String
# https://no-color.org/
NO_COLOR = ENV.key?('NO_COLOR') || `tput colors`.chomp.to_i < 8 unless defined?(NO_COLOR)
unless defined?(ANSI_COLORS)
ANSI_COLORS = {
red: 31,
green: 32,
yellow: 33,
blue: 34,
magenta: 35
}.freeze
end
ANSI_COLORS.each do |name, code|
define_method(name) { NO_COLOR ? self : "\e[#{code}m#{self}\e[0m" }
end
end
class PrintTable
attr_reader :data
def initialize(data)
@data = data
end
def print
return false if fields.size <= 1 || fields.length > MAX_COLUMNS_FOR_TABLE || total_width > IO.console.winsize[1]
puts border
puts title_row
puts border
data_to_a.each do |item|
puts '| ' + fields.map { |f| format("%-#{max_len[f]}s", read_attribute(item, f)) }.join(' | ') + ' |'
end
puts border
puts "#{data_to_a.length} rows in set\n"
true
rescue StandardError => e
puts e.message
puts e.backtrace.join("\n")
false
end
private
# Calulate the total lenght of the table
def total_width
fields.map { |f| max_len[f] }.sum + fields.length * 3 + 1
end
def attributes_keys(data = self.data)
@attributes_keys ||= if data.respond_to?(:attributes_keys)
data.attributes_keys
elsif data.respond_to?(:keys)
data.keys
elsif data.respond_to?(:attributes) && data.attributes.respond_to?(:keys)
data.attributes.keys
elsif data.respond_to?(:members)
data.members
end
end
def data_to_a
if data.class == Array || data.class == Enumerable
data
else
[data]
end
end
def border
'+-' + fields.map { |f| '-' * max_len[f] }.join('-+-') + '-+'
end
def title_row
'| ' + fields.map { |f| format("%-#{max_len[f]}s", PrettyString.new(f.to_s).yellow) }.join(' | ') + ' |'
end
def max_len
return @max_len if @max_len
@max_len = Hash[*fields.map { |f| [f, f.to_s.length] }.flatten]
data_to_a.each do |item|
fields.each do |field|
len = read_attribute(item, field).length
@max_len[field] = len if len > @max_len[field]
end
end
@max_len
end
def fields
@fields ||= attributes_keys || []
end
def read_attribute(item, attribute)
if item.respond_to?(:read_attribute)
item.read_attribute(attribute).to_s
elsif item.respond_to?(attribute.to_sym, false)
item.public_send(attribute.to_sym).to_s
elsif item.is_a?(Hash)
item[attribute.to_sym].to_s || item[attribute.to_s].to_s
else
raise "Can't read attribute #{attribute} from #{item.class}"
end
end
end
puts PrettyString.new('loading .irbrc...').blue
require 'tempfile'
# /Users/brandit/.asdf/installs/ruby/3.2.1/lib/ruby/gems/3.2.0/gems/actioncable-7.0.4.2/lib
def require_custom(gem_name, require_name = nil)
@libs ||= Dir["#{File.expand_path("~/.asdf/installs/ruby/#{RUBY_VERSION}")}/**/lib"].sort
gems = @libs.select { _1.include?(gem_name) }
if gems.any?
gems.each { $LOAD_PATH.unshift(_1.gsub("/lib/#{gem_name}", '/lib')) }
puts PrettyString.new("require #{require_name || gem_name}").green
require require_name || gem_name
end
rescue LoadError => e
puts PrettyString.new(e.message).red
end
require_custom 'awesome_print'
require_custom 'benchmark', 'benchmark/ips'
require_custom 'rbzip2'
require_custom 'memoist'
require_custom 'kalibera'
require_custom 'json'
# require_custom 'hirb'
IRB.conf[:PROMPT][:CUSTOM_PROMPT] = {
PROMPT_I: "#{PrettyString.new('[%n]').green} #{PrettyString.new(Dir.pwd).blue}> ",
PROMPT_N: "#{PrettyString.new('[%n]').green} #{PrettyString.new(Dir.pwd).blue}> ",
PROMPT_S: "#{PrettyString.new('[%n]').green} #{PrettyString.new(Dir.pwd).blue}> ",
PROMPT_C: "#{PrettyString.new('[%n]').green} #{PrettyString.new(Dir.pwd).blue}> ",
RETURN: "=> %s\n"
}
if defined?(Rails)
env = Rails.env
env_color = if env.acceptance?
PrettyString.new(env).green
elsif env.staging?
PrettyString.new(env).yellow
elsif env.production?
PrettyString.new(env).red
else
PrettyString.new(env).blue
end
IRB.conf[:PROMPT][:RAILS_APP] = {
PROMPT_I: "#{PrettyString.new('[%n]').green} #{Rails.application.class.module_parent_name} (#{env_color}) > ",
PROMPT_N: "#{PrettyString.new('[%n]').green} #{Rails.application.class.module_parent_name} (#{env_color}) > ",
PROMPT_S: "#{PrettyString.new('[%n]').green} #{Rails.application.class.module_parent_name} (#{env_color}) > ",
PROMPT_C: "#{PrettyString.new('[%n]').green} #{Rails.application.class.module_parent_name} (#{env_color}) > ",
RETURN: "=> %s\n"
}
IRB.conf[:PROMPT_MODE] = :RAILS_APP
else
IRB.conf[:PROMPT_MODE] = :CUSTOM_PROMPT
end
IRB.conf[:BACK_TRACE_LIMIT] = 20
# ActiveRecord::Base.logger.level = 1 if defined?(ActiveRecord)
IRB.conf[:SAVE_HISTORY] = 1000
# IRB.conf[:USE_AUTOCOMPLETE] = false # can be slow rather use tab or lm
# Overriding Object class
class Object
def types
self.class.ancestors.select { |a| a.to_s =~ /^[A-Z]/ }.sort_by(&:to_s)
end
def named
respond_to?(:name) ? name : self.class
end
# Easily print methods local to an object's class
def lm(scan = nil)
sorted_methods = (methods - Object.instance_methods).sort
scan ? sorted_methods.select { |m| m.to_s.include?(scan.to_s) } : sorted_methods
end
# look up source location of a method
def sl(method_name)
method(method_name).source_location
rescue StandardError
"#{method_name} not found"
end
# open particular method in vs code
def ocode(method_name)
file, line = sl(method_name)
if file && line
`#{DEFAULT_EDITOR} -g '#{file}:#{line}'`
else
"'#{method_name}' not found :( Try #{named}.lm to see available methods"
end
end
# display method source in rails console
def ds(method_name)
method(method_name).source.display
end
# open json object in VS Code Editor
def oj
file = Tempfile.new([named.to_s, '.json'])
file.write(JSON.pretty_generate(as_json))
file.close
system("#{DEFAULT_EDITOR} #{file.path}")
rescue NoMethodError => e
puts PrettyString.new("Can't open #{named} because it doesn't respond to #as_json").red
end
end
# history command
def hist(count = 0)
# Get history into an array
history_array = Reline::HISTORY.to_a
# if count is > 0 we'll use it.
# otherwise set it to 0
count = count.positive? ? count : 0
if count.positive?
from = history_array.length - count
history_array = history_array[from..]
end
history_array
end
# copy a string to the clipboard
def cp(string)
`echo "#{string}" | pbcopy`
puts 'copied in clipboard'
end
# reloads the irb console can be useful for debugging .irbrc
def reload_irb
load File.expand_path('~/.irbrc')
# will reload rails env if you are running ./script/console
reload! if @script_console_running
puts 'Console Reloaded!'
end
# opens irbrc in vscode
def edit_irb
`#{DEFAULT_EDITOR} ~/.irbrc` if system('code')
end
def hirb_on
Hirb.enable
end
def hirb_off
Hirb.disable
end
def disable_active_record_logging
ActiveRecord::Base.logger.level = 1
end
def enable_active_record_logging
ActiveRecord::Base.logger.level = 0
end
def bm
# From http://blog.evanweaver.com/articles/2006/12/13/benchmark/
# Call benchmark { } with any block and you get the wallclock runtime
# as well as a percent change + or - from the last run
cur = Time.zone.now
result = yield
print "#{cur = Time.zone.now - cur} seconds"
begin
puts " (#{(cur / $last_benchmark * 100).to_i - 100}% change)"
rescue StandardError
puts ''
end
$last_benchmark = cur
result
end
module IRB
class Irb
def output_value(omit = false) # :nodoc:
PrintTable.new(@context.last_value).print || original_output_value(omit)
end
# pulled this code from irb source to override the output_value method
# https://github.com/ruby/irb/blob/457502a7468399ba3a176e5769c63a49c0e69e95/lib/irb.rb#L824
def original_output_value(omit = false) # :nodoc:
str = @context.inspect_last_value
multiline_p = str.include?("\n")
if omit
winwidth = @context.io.winsize.last
if multiline_p
first_line = str.split("\n").first
result = @context.newline_before_multiline_output? ? (@context.return_format % first_line) : first_line
output_width = Reline::Unicode.calculate_width(result, true)
diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
if diff_size.positive? && (output_width > winwidth)
lines, = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
str = '%s...' % lines.first
str += "\e[0m" if Color.colorable?
multiline_p = false
else
str = str.gsub(/(\A.*?\n).*/m, '\\1...')
str += "\e[0m" if Color.colorable?
end
else
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
diff_size = output_width - Reline::Unicode.calculate_width(str, true)
if diff_size.positive? && (output_width > winwidth)
lines, = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
str = '%s...' % lines.first
str += "\e[0m" if Color.colorable?
end
end
end
if multiline_p && @context.newline_before_multiline_output?
printf @context.return_format, "\n#{str}"
else
printf @context.return_format, str
end
end
end
end
# exit using `q`
alias q exit
# all available methods explaination
def ll
puts '============================================================================================================='
puts 'Welcome to console. Here are few list of pre-defined methods you can use.'
puts '============================================================================================================='
puts 'bm(&block) ------------> benchmarking for block passed as an argument e.g bm { Lead.all.pluck(:stage);0 }'
puts 'cp(str) ---------------> copy string in clipboard e.g cp(lead.name)'
puts 'edit_gemfile ----------> edit gemfile'
puts 'edit_irb --------------> edit irbrc file'
puts 'hist(n) ---------------> command history e.g hist(10)'
puts 'obj.dispsoc(:method) --> display method source in rails console e.g lead.dispsoc(:name)'
puts 'obj.ocode(:method) ----> open method in vs code e.g lead.ocode(:name)'
puts 'obj.oj ----------------> open object json in vs code e.g lead.oo'
puts 'obj.sl(:method) -------> source location e.g lead.sl(:name)'
puts 'obj.types -------------> list of all types'
puts 'reload_irb ------------> reload irb console'
puts '============================================================================================================='
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment