Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit.

  • Loading branch information...
commit 4b1b0d5ef42cdea4481f0110f424b3d9b02ac3ce 0 parents
@blackwinter blackwinter authored
Showing with 1,049 additions and 0 deletions.
  1. +20 −0 COPYING
  2. +29 −0 ChangeLog
  3. +5 −0 MANIFEST
  4. +433 −0 README
  5. +43 −0 wirble.gemspec
  6. +519 −0 wirble.rb
20 COPYING
@@ -0,0 +1,20 @@
+Copyright (C) 2002-2006 Paul Duncan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies of the Software, its documentation and marketing & publicity
+materials, and acknowledgment shall be given in the documentation, materials
+and software packages that this Software was used.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 ChangeLog
@@ -0,0 +1,29 @@
+
+* Wed Sep 06 00:01:21 2006, pabs <pabs@pablotron.org>
+ * initial import
+
+* Wed Sep 06 00:10:13 2006, pabs <pabs@pablotron.org>
+ * wirble.rb: remove symbol hackery to prevent
+ ri/rdoc from barfing
+
+* Wed Sep 6 02:49:02 EDT 2006, Paul Duncan <pabs@pablotron.org>
+ * wirble.rb: fix typo
+ * re-release 0.1.0
+
+* Fri Sep 8 04:01:40 EDT 2006, Paul Duncan <pabs@pablotron.org>
+ * README: updated version to 0.1.1
+ * wirble.gemspec: ditto
+ * wirble.rb: ditto
+ * wirble.rb: wrap colorize in an exception (just in case)
+
+* Fri Sep 08 13:11:05 2006, pabs <pabs@pablotron.org>
+ * increment version to 0.1.2
+ * wirble.gemspec: remove rubilicious dependency
+
+* Fri Sep 8 13:17:29 EDT 2006, Paul Duncan <pabs@pablotron.org>
+ * README: increment version to 0.1.2
+ * wirble.gemspec: ditto
+ * wirble.rb: ditto
+
+* Fri Sep 08 13:18:15 2006, pabs <pabs@pablotron.org>
+ * releasing 0.1.2
5 MANIFEST
@@ -0,0 +1,5 @@
+./ChangeLog
+./COPYING
+./wirble.rb
+./README
+./wirble.gemspec
433 README
@@ -0,0 +1,433 @@
+Wirble 0.1.2 README
+===================
+
+This document was last updated on Fri Sep 08 13:16:55 2006. See the
+file COPYING for licensing and warranty information. The latest version
+of this software is available at the following URL:
+
+ http://pablotron.org/software/wirble/
+
+Table of Contents
+=================
+ * Introduction to Wirble
+ * Installing Wirble
+ o Via RubyGems
+ o Via a Tarball
+ o As a User
+ * Using Wirble
+ o Editing Your ~/.irbrc
+ o Enabling Color
+ * Configuring Wirble
+ * Color Settings
+ o Color Keys
+ o Color Values
+ o Default Color Map
+ * Frequently Asked Questions (FAQ)
+ * Reporting Bugs
+ * About the Author
+
+
+Introduction to Wirble
+======================
+Wirble is a set of enhancements to Irb all included together in one
+easy-to-use package. Specifically, Wirble adds a saved history, a
+couple of useful shortcuts, and color to Irb. Wirble also enables a
+Irb's built-in tab-completion and a simpler prompt.
+
+Before we begin, I should mention that several of Wirble's features were
+shamelessly inspired (read: borrowed with extreme prejudice) from the
+"Irb Tips and Tricks" page of the Ruby Garden Wiki, which you can find
+at the following URL:
+
+ http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
+
+In particular, the Irb history and ri features bear a striking
+resemblence to their Ruby Garden counterparts.
+
+
+Installing Wirble
+=================
+The easiest way to install Wirble is via RubyGems
+(http://rubygems.org/). If you've already got RubyGems installed,
+simply do the following, then skip to the "Using Wirble" section below:
+
+ # install wirble via RubyGems
+ sudo gem install wirble
+
+If you don't have RubyGems, you can also install the Wirble library
+this:
+
+ # install wirble to library directory
+ sudo cp -v wirble.rb $(ruby -e 'puts $LOAD_PATH[0]')
+
+Or, if you don't use sudo, you can do the same thing with su, like so:
+
+ # install wirble to library directory
+ su -c "cp -v wirble.rb $(ruby -e 'puts $LOAD_PATH[0]')"
+
+Finally, if you don't have an administrator account, you can still
+install Wirble in your local home directory like so:
+
+ # create local ruby library directory
+ mkdir ~/.ruby && chmod 700 ~/.ruby
+ cp -v wirble.rb ~/.ruby
+
+Then add the following line at the _top_ of your ~/.irbrc file:
+
+ # add ~/.ruby to the library search path
+ $LOAD_PATH << File.expand_path('~/.ruby')
+
+
+Using Wirble
+============
+Using Wirble is easy: just add the following lines to your ~/.irbrc
+file:
+
+ # load rubygems and wirble
+ require 'rubygems' rescue nil
+ require 'wirble'
+
+ # load wirble
+ Wirble.init
+
+A lot of people really don't like colors, so I've kept the color
+disabled by default. To enable it, add the following bit to your
+~/.irbrc file after "Wirble.init":
+
+ # enable color
+ Wirble.colorize
+
+If you want to terrify your grandmother and impress your buddies, your
+entire ~/.irbrc can also be written like so:
+
+ %w{rubygems wirble}.each { |lib| require lib rescue nil }
+ %w{init colorize}.each { |str| Wirble.send(str.intern) }
+
+Configuring Wirble
+==================
+You can pass a hash of options to Wirble.init in order to adjust the
+behavior of Wirble. Here's a full list of options and a brief
+description of each one:
+
+ * :skip_internals
+
+ Don't load the internal Irb features. Equivalent to setting both
+ :skip_libraries and :skip_prompt (see below).
+
+ * :skip_libraries
+
+ Don't load any libraries. At the moment, Wirble attempts to load
+ the following libraries: "pp", "irb/completion", and "rubygems".
+
+ * :skip_prompt
+
+ Down't load the simple prompt. Shouldn't ever be necessary, but
+ I've included it for the sake of completeness. Wirble's default
+ behavior is to the prompt setting before making any changes. If the
+ prompt is anything other than :DEFAULT, Wirble won't override it.
+
+ * :skip_history
+
+ Don't load the Irb history. There are a few additional history
+ options as well; see :history_path, :history_size, and
+ :history_perms below.
+
+ * :history_path
+
+ Set the path to the Irb history file. Defaults to "~/.irb_history".
+ If an environment variable named IRB_HISTORY_FILE is set, Wirble
+ will use that instead of the default value.
+
+ * :history_size
+
+ Set the size (in lines) of the Irb history file. Defaults to 1000
+ lines. If an environment variable named IRB_HISTORY_SIZE is set,
+ Wirble will use that instead of the default value.
+
+ * :history_perms
+
+ Set the permissions of the Irb history file. Defaults to
+ File::WRONLY.
+
+ * :skip_shortcuts
+
+ Don't load any shortcut methods. at the moment there are three
+ shortcut methods: "ri", "po", and "poc". The first calls the "ri"
+ command on the specified value -- you"ll need to use proper quoting
+ to pass the name properly. As for "po" and "poc": the former lists
+ an object's instance methods (excluding methods that belong to
+ Object), sorted by name, and the latter lists an object's constants,
+ sorted by name.
+
+ * :init_colors
+
+ Enable colors. Equivalent to calling Wirble.colorize directly.
+
+ * :colors
+
+ A hash of colors. Only makes sense in conjunction with the
+ :init_colors option. See below for additional information on
+ customizing color settings.
+
+Here's an example of passing a list of options to Wirble.init():
+
+ wirble_opts = {
+ # skip shortcuts
+ :skip_shortcuts => true,
+
+ # don't set the prompt
+ :skip_prompt => true,
+
+ # override some of the default colors
+ :colors => {
+ :open_hash => :green.
+ :close_hash => :green.
+ :string => :blue,
+ },
+
+ # enable color
+ :init_color => true,
+ }
+
+ # initialize wirble with options above
+ Wirble.init(wirble_opts)
+
+For a full description of the color options, see the next section.
+
+
+Color Settings
+==============
+You can set colors in Wirble by passing a hash of color options via
+Wirble.init (see the :color option for Wirble.init above), or by setting
+Wirble::Colorize.color directly. For example:
+
+ # get the default colors and add in your own
+ colors = Wirble::Colorize.colors.merge({
+ # set the comma color to blue
+ :comma => :blue,
+ })
+
+ # set the colors used by Wirble
+ Wirble::Colorize.colors = colors
+
+Below is a list of all the recognized color keys.
+
+ * :comma (',')
+
+ A comma character. The element delimiter in arrays and hashes.
+
+ * :refers ('=>')
+
+ The hash reference operator. The key/value delimiter in hashes.
+
+ * :open_hash ('{')
+
+ The opening curly brace for a hash.
+
+ * :close_hash ('}')
+
+ The opening curly brace for a hash.
+
+ * :open_array ('[')
+
+ The opening brace for a array.
+
+ * :close_array (']')
+
+ The opening brace for a array.
+
+ * :open_object ('#<')
+
+ The opening delimiter for an object.
+
+ * :close_object ('>')
+
+ The closing delimiter for an object inspection.
+
+ * :object_class
+
+ The class attribute of an object inspection. For example, in the
+ string "#<Proc:0xb7be4968@(irb):8>", the string "Proc" is the class
+ attribute.
+
+ * :object_addr_prefix (':')
+
+ The colon prefixing the address attribute of an object inspection.
+ For example, in the string "#<Proc:0xb7be4968@(irb):8>", the string
+ "0xb7be4968" is the memory address attribute, so the ':' is the
+ address prefix.
+
+ * :object_addr
+
+ The memory address attribute of an object inspection. For example,
+ in the string "#<Proc:0xb7be4968@(irb):8>", the string "0xb7be4968"
+ is the memory address attribute.
+
+ * :object_addr_prefix ('@')
+
+ The at symbol prefixing the line attribute of an object inspection.
+ For example, in the string "#<Proc:0xb7be4968@(irb):8>", the string
+ "(irb):8" is the line attribute, so the '@' is the line attribute
+ prefix.
+
+ * :object_line
+
+ The line number attribute of an object inspection. For example,
+ in the string "#<Proc:0xb7be4968@(irb):8>", the string "(irb):8"
+ is the line number attribute.
+
+ * :symbol_prefix (':')
+
+ The colon prefix for a symbol object.
+
+ * :symbol
+
+ The string of a symbol object.
+
+ * :open_string ('"')
+
+ The opening quote of a string object.
+
+ * :close_string ('"')
+
+ The closing quote of a string object.
+
+ * :number
+
+ A number (integer or float).
+
+ * :range ('..')
+
+ The delimeter of a range object.
+
+ * :keyword
+
+ A built-in Ruby keyword. This includes values like "true", "false",
+ and "nil".
+
+ * :class
+
+ A class. This includes strings like "Class" and "Object".
+
+ * :whitespace
+
+ Whitespace character (i.e. space, newline, tab, etc).
+
+The highlighting is implemented with a simple hand-rolled state-based
+tokenizer (wow, that was a mouthful). This should be adequate most of
+the time, but since it's not a actual LALR parser, Wirble can get
+confused in a few specific instances. If you find a serious
+highlighting problem, please let me know. Oh yeah, before I forget,
+here's a list of the valid color codes:
+
+ :nothing :green :light_purple
+ :black :light_blue :purple
+ :blue :light_cyan :red
+ :brown :light_gray :white
+ :cyan :light_green :yellow
+ :dark_gray :light_red
+
+Note that I'm not a designer, and I also use a terminal with a dark
+background. I've also been accused of having a Vim color scheme that
+looks like "a beat up clown". With those caveats in mind, here's the
+default color scheme for Wirble:
+
+ #
+ # Default Wirble color scheme.
+ #
+ DEFAULT_COLORS = {
+ # delimiter colors
+ :comma => :blue,
+ :refers => :blue,
+
+ # container colors (hash and array)
+ :open_hash => :green,
+ :close_hash => :green,
+ :open_array => :green,
+ :close_array => :green,
+
+ # object colors
+ :open_object => :light_red,
+ :object_class => :white,
+ :object_addr_prefix => :blue,
+ :object_line_prefix => :blue,
+ :close_object => :light_red,
+
+ # symbol colors
+ :symbol => :yellow,
+ :symbol_prefix => :yellow,
+
+ # string colors
+ :open_string => :red,
+ :string => :cyan,
+ :close_string => :red,
+
+ # misc colors
+ :number => :cyan,
+ :keyword => :green,
+ :class => :light_green,
+ :range => :red,
+ }
+
+This map is also available via programmatically via
+Wirble::Colorize::DEFAULT_COLORS.
+
+
+Frequently Asked Questions (FAQ)
+================================
+Q. Where did the name come from?
+A. Beats me. It's the only thing I could find in the dictionary, and
+ the only name I came up with that I could pronounce.
+
+Q. How do I use color in my Irb prompts?
+A. You can use standard color escape codes in the format string used by
+ Irb. For example, to set the user prompt to cyan, you could do
+ something like this:
+
+ ctx = IRB.CurrentContext
+ ctx.prompt_i = Wirble::Colorize.colorize_string(ctx.prompt_i, :cyan)
+
+Q. How can I do syntax highlighting as I type?
+A. I don't know. If there is an answer, I suspect it's not very
+ portable and probably requires some modification to Irb. There's a
+ sneaky hack called eval.rb that seems to do a little bit of
+ highlight, but it doesn't use Irb, and it doesn't really do what
+ you're asking. That said, you can find it here:
+
+ http://www.rubyist.net/~slagell/ruby/eval.txt
+
+ Incidentally, part of the problem is that there's no real easy way
+ to do the following:
+
+ 1. Access to the token stream or parser state incrementally.
+ 2. Process partial strings in readline.
+
+ A bit more about #1: both Irb and the internal Ruby lexer kind of
+ muddle the traditionally separate concepts of lexer and parser, so
+ it's difficult to, say, parse a string into components and do syntax
+ highlighting on them. Vim and Emacs both handle this with sneaky
+ regular expressions, and a simple Ruby parser, respectively. Wirble
+ and Irb both roll their own (albeit limited) Ruby lexers.
+
+
+Reporting Bugs
+==============
+Have a bug to report or a feature you'd like me to add to Wirble?
+Feel free to email me at the address below. Alternatively, you can
+submit your feature request or bug directly to my bug-tracking web
+interface at the following URL:
+
+ http://bugs.pablotron.org/
+
+Note: you'll need to create an account in order to submit a feature
+request or a bug report via the web interface. Also, I'm a busy guy! I
+make every effort to respond quickly to bug reports, but detailed
+descriptions and or patches really do make my life a whole lot easier.
+
+
+About the Author
+================
+Paul Duncan <pabs@pablotron.org>
+http://pablotron.org/
+
+And of course, all the fine folks from the Ruby Garden Wiki. :)
43 wirble.gemspec
@@ -0,0 +1,43 @@
+require 'rubygems'
+
+spec = Gem::Specification.new do |s|
+
+ #### Basic information.
+
+ s.name = 'wirble'
+ s.version = '0.1.2'
+ s.summary = <<-EOF
+ Handful of common Irb features, made easy.
+ EOF
+ s.description = <<-EOF
+ A handful of useful Irb features, including colorized results,
+ tab-completion, history, a simple prompt, and several helper
+ methods, all rolled into one easy to use package.
+ EOF
+
+ s.requirements << 'Ruby, version 1.8.0 (or newer)'
+
+ #### Which files are to be included in this gem? Everything! (Except CVS directories.)
+
+ s.files = Dir.glob("**/*").delete_if { |item| item.include?("CVS") }
+
+ #### C code extensions.
+
+ s.require_path = '.' # is this correct?
+ # s.extensions << "extconf.rb"
+
+ #### Load-time details: library and application (you will need one or both).
+ s.autorequire = 'wirble'
+ s.has_rdoc = true
+ s.rdoc_options = ['--webcvs',
+ 'http://cvs.pablotron.org/cgi-bin/viewcvs.cgi/wirble/', '--title',
+ 'Wirble API Documentation', 'wirble.rb', 'README', 'ChangeLog',
+ 'COPYING']
+
+ #### Author and project details.
+
+ s.author = 'Paul Duncan'
+ s.email = 'pabs@pablotron.org'
+ s.homepage = 'http://pablotron.org/software/wirble/'
+ s.rubyforge_project = 'wirble'
+end
519 wirble.rb
@@ -0,0 +1,519 @@
+require 'ostruct'
+
+#
+# Wirble: A collection of useful Irb features.
+#
+# To use, add the following to your ~/.irbrc:
+#
+# require 'rubygems'
+# require 'wirble'
+# Wirble.init
+#
+# If you want color in Irb, add this to your ~/.irbrc as well:
+#
+# Wirble.colorize
+#
+# Note: I spent a fair amount of time documenting this code in the
+# README. If you've installed via RubyGems, root around your cache a
+# little bit (or fire up gem_server) and read it before you tear your
+# hair out sifting through the code below.
+#
+module Wirble
+ VERSION = '0.1.2'
+
+ #
+ # Load internal Ruby features, including tab-completion, rubygems,
+ # and a simple prompt.
+ #
+ module Internals
+ # list of internal libraries to automatically load
+ LIBRARIES = %w{pp irb/completion rubygems}
+
+ #
+ # load tab completion and rubygems
+ #
+ def self.init_libraries
+ LIBRARIES.each { |lib| require lib rescue nil }
+ end
+
+ #
+ # Set a simple prompt, unless a custom one has been specified.
+ #
+ def self.init_prompt
+ # set the prompt
+ if IRB.conf[:PROMPT_MODE] == :DEFAULT
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
+ end
+ end
+
+ #
+ # Load all Ruby internal features.
+ #
+ def self.init(opt = nil)
+ init_libraries unless opt && opt[:skip_libraries]
+ init_prompt unless opt && opt[:skip_prompt]
+ end
+ end
+
+ #
+ # Basic IRB history support. This is based on the tips from
+ # http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
+ #
+ class History
+ DEFAULTS = {
+ :history_path => ENV['IRB_HISTORY_FILE'] || "~/.irb_history",
+ :history_size => (ENV['IRB_HISTORY_SIZE'] || 1000).to_i,
+ :history_perms => File::WRONLY | File::CREAT | File::TRUNC,
+ }
+
+ private
+
+ def say(*args)
+ puts *args if @verbose
+ end
+
+ def cfg(key)
+ @opt["history_#{key}".intern]
+ end
+
+ def save_history
+ path, max_size, perms = %w{path size perms}.map { |v| cfg(v) }
+
+ # read lines from history, and truncate the list (if necessary)
+ lines = Readline::HISTORY.to_a.uniq
+ lines = lines[-max_size, -1] if lines.size > max_size
+
+ # write the history file
+ real_path = File.expand_path(path)
+ File.open(real_path, perms) { |fh| fh.puts lines }
+ say 'Saved %d lines to history file %s.' % [lines.size, path]
+ end
+
+ def load_history
+ # expand history file and make sure it exists
+ real_path = File.expand_path(cfg('path'))
+ unless File.exist?(real_path)
+ say "History file #{real_path} doesn't exist."
+ return
+ end
+
+ # read lines from file and add them to history
+ lines = File.readlines(real_path).map { |line| line.chomp }
+ Readline::HISTORY.push(*lines)
+
+ say 'Read %d lines from history file %s' % [lines.size, cfg('path')]
+ end
+
+ public
+
+ def initialize(opt = nil)
+ @opt = DEFAULTS.merge(opt || {})
+ return unless defined? Readline::HISTORY
+ load_history
+ Kernel.at_exit { save_history }
+ end
+ end
+
+ #
+ # Add color support to IRB.
+ #
+ module Colorize
+ #
+ # Tokenize an inspection string.
+ #
+ module Tokenizer
+ def self.tokenize(str)
+ raise 'missing block' unless block_given?
+ chars = str.split(//)
+
+ # $stderr.puts "DEBUG: chars = #{chars.join(',')}"
+
+ state, val, i, lc = [], '', 0, nil
+ while i <= chars.size
+ repeat = false
+ c = chars[i]
+
+ # $stderr.puts "DEBUG: state = #{state}"
+
+ case state[-1]
+ when nil
+ case c
+ when ':': state << :symbol
+ when '"': state << :string
+ when '#': state << :object
+ when /[a-z]/i
+ state << :keyword
+ repeat = true
+ when /[0-9-]/
+ state << :number
+ repeat = true
+ when '{': yield :open_hash, '{'
+ when '[': yield :open_array, '['
+ when ']': yield :close_array, ']'
+ when '}': yield :close_hash, '}'
+ when /\s/: yield :whitespace, c
+ when ',': yield :comma, ','
+ when '>'
+ yield :refers, '=>' if lc == '='
+ when '.'
+ yield :range, '..' if lc == '.'
+ when '='
+ # ignore these, they're used elsewhere
+ nil
+ else
+ # $stderr.puts "DEBUG: ignoring char #{c}"
+ end
+ when :symbol
+ case c
+ # XXX: should have =, but that messes up foo=>bar
+ when /[a-z0-9_!?]/
+ val << c
+ else
+ yield :symbol_prefix, ':'
+ yield state[-1], val
+ state.pop; val = ''
+ repeat = true
+ end
+ when :string
+ case c
+ when '"'
+ if lc == "\\"
+ val[-1] = ?"
+ else
+ yield :open_string, '"'
+ yield state[-1], val
+ state.pop; val = ''
+ yield :close_string, '"'
+ end
+ else
+ val << c
+ end
+ when :keyword
+ case c
+ when /[a-z0-9_]/i
+ val << c
+ else
+ # is this a class?
+ st = val =~ /^[A-Z]/ ? :class : state[-1]
+
+ yield st, val
+ state.pop; val = ''
+ repeat = true
+ end
+ when :number
+ case c
+ when /[0-9e-]/
+ val << c
+ when '.'
+ if lc == '.'
+ val[/\.$/] = ''
+ yield state[-1], val
+ state.pop; val = ''
+ yield :range, '..'
+ else
+ val << c
+ end
+ else
+ yield state[-1], val
+ state.pop; val = ''
+ repeat = true
+ end
+ when :object
+ case c
+ when '<':
+ yield :open_object, '#<'
+ state << :object_class
+ when ':':
+ state << :object_addr
+ when '@':
+ state << :object_line
+ when '>'
+ yield :close_object, '>'
+ state.pop; val = ''
+ end
+ when :object_class
+ case c
+ when ':'
+ yield state[-1], val
+ state.pop; val = ''
+ repeat = true
+ else
+ val << c
+ end
+ when :object_addr
+ case c
+ when '>'
+ when '@'
+ yield :object_addr_prefix, ':'
+ yield state[-1], val
+ state.pop; val = ''
+ repeat = true
+ else
+ val << c
+ end
+ when :object_line
+ case c
+ when '>'
+ yield :object_line_prefix, '@'
+ yield state[-1], val
+ state.pop; val = ''
+ repeat = true
+ else
+ val << c
+ end
+ else
+ raise "unknown state #{state}"
+ end
+
+ unless repeat
+ i += 1
+ lc = c
+ end
+ end
+ end
+ end
+
+ #
+ # Terminal escape codes for colors.
+ #
+ module Color
+ COLORS = {
+ :nothing => '0;0',
+ :black => '0;30',
+ :red => '0;31',
+ :green => '0;32',
+ :brown => '0;33',
+ :blue => '0;34',
+ :cyan => '0;36',
+ :purple => '0;35',
+ :light_gray => '0;37',
+ :dark_gray => '1;30',
+ :light_red => '1;31',
+ :light_green => '1;32',
+ :yellow => '1;33',
+ :light_blue => '1;34',
+ :light_cyan => '1;36',
+ :light_purple => '1;35',
+ :white => '1;37',
+ }
+
+ #
+ # Return the escape code for a given color.
+ #
+ def self.escape(key)
+ COLORS.key?(key) && "\033[#{COLORS[key]}m"
+ end
+ end
+
+ #
+ # Default Wirble color scheme.
+ #
+ DEFAULT_COLORS = {
+ # delimiter colors
+ :comma => :blue,
+ :refers => :blue,
+
+ # container colors (hash and array)
+ :open_hash => :green,
+ :close_hash => :green,
+ :open_array => :green,
+ :close_array => :green,
+
+ # object colors
+ :open_object => :light_red,
+ :object_class => :white,
+ :object_addr_prefix => :blue,
+ :object_line_prefix => :blue,
+ :close_object => :light_red,
+
+ # symbol colors
+ :symbol => :yellow,
+ :symbol_prefix => :yellow,
+
+ # string colors
+ :open_string => :red,
+ :string => :cyan,
+ :close_string => :red,
+
+ # misc colors
+ :number => :cyan,
+ :keyword => :green,
+ :class => :light_green,
+ :range => :red,
+ }
+
+ #
+ # Fruity testing colors.
+ #
+ TESTING_COLORS = {
+ :comma => :red,
+ :refers => :red,
+ :open_hash => :blue,
+ :close_hash => :blue,
+ :open_array => :green,
+ :close_array => :green,
+ :open_object => :light_red,
+ :object_class => :light_green,
+ :object_addr => :purple,
+ :object_line => :light_purple,
+ :close_object => :light_red,
+ :symbol => :yellow,
+ :symbol_prefix => :yellow,
+ :number => :cyan,
+ :string => :cyan,
+ :keyword => :white,
+ :range => :light_blue,
+ }
+
+ #
+ # Set color map to hash
+ #
+ def self.colors=(hash)
+ @colors = hash
+ end
+
+ #
+ # Get current color map
+ #
+ def self.colors
+ @colors ||= {}.update(DEFAULT_COLORS)
+ end
+
+ #
+ # Return a string with the given color.
+ #
+ def self.colorize_string(str, color)
+ col, nocol = [color, :nothing].map { |key| Color.escape(key) }
+ col ? "#{col}#{str}#{nocol}" : str
+ end
+
+ #
+ # Colorize the results of inspect
+ #
+ def self.colorize(str)
+ begin
+ ret, nocol = '', Color.escape(:nothing)
+ Tokenizer.tokenize(str) do |tok, val|
+ # c = Color.escape(colors[tok])
+ ret << colorize_string(val, colors[tok])
+ end
+ ret
+ rescue
+ # catch any errors from the tokenizer (just in case)
+ str
+ end
+ end
+
+ #
+ # Enable colorized IRB results.
+ #
+ def self.enable(custom_colors = nil)
+ # if there's a better way to do this, I'm all ears.
+ ::IRB::Irb.class_eval do
+ alias :non_color_output_value :output_value
+
+ def output_value
+ if @context.inspect?
+ val = Colorize.colorize(@context.last_value.inspect)
+ printf @context.return_format, val
+ else
+ printf @context.return_format, @context.last_value
+ end
+ end
+ end
+
+ colors = custom_colors if custom_colors
+ end
+
+ #
+ # Disable colorized IRB results.
+ #
+ def self.disable
+ ::IRB::Irb.class_eval do
+ alias :output_value :non_color_output_value
+ end
+ end
+ end
+
+ #
+ # Convenient shortcut methods.
+ #
+ module Shortcuts
+ #
+ # Print object methods, sorted by name. (excluding methods that
+ # exist in the class Object) .
+ #
+ def po(o)
+ o.methods.sort - Object.methods
+ end
+
+ #
+ # Print object constants, sorted by name.
+ #
+ def poc(o)
+ o.constants.sort
+ end
+ end
+
+ #
+ # Convenient shortcut for ri
+ #
+ module RiShortcut
+ def self.init
+ Kernel.class_eval {
+ def ri(arg)
+ puts `ri '#{arg}'`
+ end
+ }
+
+ Module.instance_eval {
+ def ri(meth=nil)
+ if meth
+ if instance_methods(false).include? meth.to_s
+ puts `ri #{self}##{meth}`
+ else
+ super
+ end
+ else
+ puts `ri #{self}`
+ end
+ end
+ }
+ end
+ end
+
+
+
+ #
+ # Enable color results.
+ #
+ def self.colorize(custom_colors = nil)
+ Colorize.enable(custom_colors)
+ end
+
+ #
+ # Load everything except color.
+ #
+ def self.init(opt = nil)
+ # make sure opt isn't nil
+ opt ||= {}
+
+ # load internal irb/ruby features
+ Internals.init(opt) unless opt && opt[:skip_internals]
+
+ # load the history
+ History.new(opt) unless opt && opt[:skip_history]
+
+ # load shortcuts
+ unless opt && opt[:skip_shortcuts]
+ # load ri shortcuts
+ RiShortcut.init
+
+ # include common shortcuts
+ Object.class_eval { include Shortcuts }
+ end
+
+ colorize(opt[:colors]) if opt && opt[:init_colors]
+ end
+end
+
Please sign in to comment.
Something went wrong with that request. Please try again.