fancy_irb 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.swp
2
+ *~
3
+ doc
4
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jan Lelis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,114 @@
1
+ FancyIrb patches your IRB to create a smooth output experience.
2
+
3
+ == Features
4
+ * Use fancy colors! You can colorize the prompts, irb errors, +stderr+ and +stdout+
5
+ * Output results as Ruby comment
6
+ * Enhance your output value, using procs
7
+
8
+ == Motivation
9
+ I really like the {irb_rocket}[https://github.com/genki/irb_rocket] gem, which outputs the evaluation result as comment and colorizes errors. Unfortunately, the implementation leads to bugs, because it tries to run the whole command before printing anything to +stdout+. For this reason, I've rewritten (and extended) it.
10
+
11
+ This plugin is compatible with other great gems like {hirb}[https://github.com/cldwalker/hirb], {interactive_editor}[https://github.com/jberkel/interactive_editor], etc.
12
+
13
+ == Usage
14
+
15
+ require 'fancy_irb'
16
+ FancyIrb.start
17
+
18
+ You can pass an options hash. These are the default values:
19
+
20
+ default_options = {
21
+ :rocket_mode => true, # activate or deactivate #=> rocket output
22
+ :rocket_prompt => '#=> ', # prompt to use for the rocket
23
+ :result_prompt => '=> ', # prompt to use for normal output
24
+ :colorize => { # colors hash. Set to nil to deactivate colorizing
25
+ :rocket_prompt => :blue,
26
+ :result_prompt => :blue,
27
+ :input_prompt => nil,
28
+ :irb_errors => :red,
29
+ :stderr => :light_red,
30
+ :stdout => :dark_gray,
31
+ :input => nil,
32
+ :output => true, # wirble's output colorization
33
+ },
34
+ :result_proc => default_result_proc, # how to get the output result (see below)
35
+ :output_procs => [default_colorizer_proc], # you can modify/enhance/log your output
36
+ }
37
+
38
+ === Rocket mode
39
+
40
+ Rocket mode means: Output result as comment if there is enough space left on the terminal line.
41
+
42
+ === Available colors
43
+ >> Wirble::Colorize::Color::COLORS.keys
44
+ => [:light_purple, :yellow, :light_gray, :white, :black, :dark_gray, :red, :green, :light_green, :brown, :light_blue, :light_red, :cyan, :blue, :light_cyan, :purple, :nothing]
45
+
46
+ === Modify your output
47
+
48
+ You can modify how to get and display the input. The <tt>result_proc</tt> is a proc which takes the irb context object and should return the value. You can change it with <tt>FancyIrb.set_result_proc do (your code) end</tt>. After that, each proc in <tt>output_procs</tt> gets triggered. They take the value and can return a modified one. You can use the <tt>FancyIrb.add_output_proc</tt> method for adding new output filter procs.
49
+
50
+ ===== default_result_proc
51
+
52
+ default_result_proc = proc{ |context|
53
+ if context.inspect?
54
+ context.last_value.inspect
55
+ else
56
+ context.last_value
57
+ end
58
+ }
59
+
60
+ ===== default_colorizer_proc
61
+
62
+ default_colorizer_proc = proc{ |value|
63
+ FancyIrb.real_lengths[:output] = value.size
64
+ if defined?(Wirble) && FancyIrb[:colorize, :output]
65
+ Wirble::Colorize.colorize value
66
+ else
67
+ value
68
+ end
69
+ }
70
+
71
+ == Example configurations
72
+
73
+ === Default
74
+ FancyIrb.start
75
+
76
+ === No colorization
77
+ FancyIrb.start :colorize => nil
78
+
79
+ === Use awesome_print for inspecting
80
+ require 'ap'
81
+ FancyIrb.start :rocket_mode => false,
82
+ :colorize => { :output => false,
83
+ :result_prompt => :yellow },
84
+ :result_proc => proc{ |context|
85
+ context.last_value.awesome_inspect
86
+ }
87
+
88
+ === Smileyfy output
89
+ FancyIrb.start
90
+ FancyIrb.add_output_proc do |value|
91
+ value + ' :)'
92
+ end
93
+
94
+ == TODO
95
+ === Known bugs
96
+ * If stdout of the current command scrolls, the rocket is displayed not higher than the first terminal line
97
+ * Something is wrong with input-newline when colorizing input
98
+ * Not all input methods are patched properly (to work with the rocket) --> focusing on the often used ones
99
+
100
+ === Features, maybe
101
+ * Count string lengths without ansi escape sequences (would be more flexible than remembering)
102
+ * "Always rocket"-mode
103
+ * Allow custom ansi escape strings
104
+ * Refactor some code duplications
105
+
106
+ Feel free to fix a bug or implement a todo ;)
107
+
108
+ == Copyright / Credits
109
+
110
+ Inspired by the irb_rocket gem from genki.
111
+
112
+ Copyright (c) 2010 Jan Lelis, http://rbjl.net, released under the MIT license.
113
+
114
+ J-_-L
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "fancy_irb"
8
+ gem.summary = %q{FancyIrb patches your IRB to create a smooth output experience.}
9
+ gem.description = %q{FancyIrb patches your IRB to create a smooth output experience.
10
+ * Use fancy colors! You can colorize the prompts, irb errors, +stderr+ and +stdout+
11
+ * Output results as Ruby comment #=> (rocket)
12
+ * Enhance your output value, using procs}
13
+ gem.email = "mail@janlelis.de"
14
+ gem.homepage = "http://github.com/janlelis/fancy_irb"
15
+ gem.authors = ["Jan Lelis"]
16
+ gem.add_dependency 'wirble'
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/rdoctask'
24
+ Rake::RDocTask.new do |rdoc|
25
+ version = File.exist?('VERSION') ? File.read('VERSION').chomp : ""
26
+
27
+ rdoc.rdoc_dir = 'doc'
28
+ rdoc.title = "FancyIrb #{version}"
29
+ rdoc.rdoc_files.include('README*')
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.6.0
data/fancy_irb.gemspec ADDED
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fancy_irb}
8
+ s.version = "0.6.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jan Lelis"]
12
+ s.date = %q{2010-11-10}
13
+ s.description = %q{FancyIrb patches your IRB to create a smooth output experience.
14
+ * Use fancy colors! You can colorize the prompts, irb errors, +stderr+ and +stdout+
15
+ * Output results as Ruby comment #=> (rocket)
16
+ * Enhance your output value, using procs}
17
+ s.email = %q{mail@janlelis.de}
18
+ s.extra_rdoc_files = [
19
+ "LICENSE",
20
+ "README"
21
+ ]
22
+ s.files = [
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "fancy_irb.gemspec",
29
+ "lib/fancy_irb.rb",
30
+ "lib/fancy_irb/irb_ext.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/janlelis/fancy_irb}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.7}
36
+ s.summary = %q{FancyIrb patches your IRB to create a smooth output experience.}
37
+
38
+ if s.respond_to? :specification_version then
39
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<wirble>, [">= 0"])
44
+ else
45
+ s.add_dependency(%q<wirble>, [">= 0"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<wirble>, [">= 0"])
49
+ end
50
+ end
51
+
@@ -0,0 +1,163 @@
1
+ module IRB
2
+ class Irb
3
+ def colorize(string, color)
4
+ if defined?(Wirble) && color && color_string = Wirble::Colorize::Color.escape( color.to_sym )
5
+ color_string + string.to_s + Wirble::Colorize::Color.escape( :nothing )
6
+ else
7
+ # if defined? Wirble
8
+ # Wirble::Colorize::Color.escape( :nothing ) + string.to_s
9
+ # else
10
+ string.to_s
11
+ # end
12
+ end
13
+ end
14
+
15
+ def output_value
16
+ # prepare prompts
17
+ rocket = colorize FancyIrb[:rocket_prompt], FancyIrb[:colorize, :rocket_prompt]
18
+ no_rocket = colorize FancyIrb[:result_prompt], FancyIrb[:colorize, :result_prompt]
19
+
20
+ # get_result and pass it into every format_output_proc
21
+ result = FancyIrb[:result_proc][ @context ]
22
+
23
+ output = Array( FancyIrb[:output_procs] ).
24
+ inject( result.to_s ){ |output, formatter|
25
+ formatter[ output ].to_s
26
+ }
27
+
28
+ # reset color
29
+ print Wirble::Colorize::Color.escape( :nothing )
30
+
31
+ # try to output in rocket mode (depending on rocket_mode setting)
32
+ if FancyIrb[:rocket_mode]
33
+ # get lengths
34
+ last_input = @scanner.instance_variable_get( :@line )
35
+ last_line_without_prompt = last_input.split("\n").last
36
+ offset = last_line_without_prompt.size + FancyIrb.real_lengths[:input_prompt] + 1
37
+ screen_length = `tput cols`.to_i
38
+ output_length = FancyIrb.real_lengths[:output]
39
+ rocket_length = FancyIrb[:rocket_prompt].size
40
+ stdout_lines = FancyIrb.get_height
41
+
42
+ # auto rocket mode
43
+ if FancyIrb[:rocket_mode] && screen_length > offset + rocket_length + output_length
44
+ print `tput sc` + # save current cursor position
45
+ `tput cuu1`*stdout_lines + # move cursor upwards to the original input line
46
+ `tput cuf1`*offset + # move cursor rightwards to the original input offset
47
+ rocket + # draw rocket prompt
48
+ output + # draw output
49
+ `tput rc` # return to normal cursor position
50
+ return
51
+ end
52
+ end
53
+ # normal output mode
54
+ puts no_rocket + output
55
+ end
56
+
57
+ # colorize prompt & input
58
+ alias prompt_non_fancy prompt
59
+ def prompt(*args, &block)
60
+ print Wirble::Colorize::Color.escape(:nothing)
61
+
62
+ prompt = prompt_non_fancy(*args, &block)
63
+ FancyIrb.real_lengths[:input_prompt] = prompt.size
64
+ colorized_prompt = colorize prompt, FancyIrb[:colorize, :input_prompt]
65
+ if input_color = FancyIrb[:colorize, :input]
66
+ colorized_prompt + Wirble::Colorize::Color.escape( input_color ) # NOTE: No reset, relies on next one
67
+ # TODO buggy
68
+ else
69
+ colorized_prompt
70
+ end
71
+ end
72
+
73
+ # track height and capture irb errors (part 2)
74
+ alias signal_status_non_fancy signal_status
75
+ def signal_status(name, *args, &block)
76
+ FancyIrb.reset_height
77
+ signal_status_non_fancy(name, *args, &block)
78
+ ensure
79
+ if name == :IN_EVAL
80
+ if FancyIrb.capture_irb_errors
81
+ errors = FancyIrb.capture_irb_errors.string
82
+
83
+ $stdout = FancyIrb.original_stdout
84
+ FancyIrb.capture_irb_errors = nil
85
+ FancyIrb.original_stdout = nil
86
+
87
+ unless errors.empty?
88
+ warn colorize( errors.chomp, FancyIrb[:colorize, :irb_errors] )
89
+ end
90
+ end
91
+ end#if
92
+ end#def
93
+ end#class
94
+
95
+ class Context
96
+ alias evaluate_non_fancy evaluate
97
+
98
+ # capture irb errors (part 1)
99
+ def evaluate(*args)
100
+ FancyIrb.stdout_colorful = true
101
+ evaluate_non_fancy(*args)
102
+ FancyIrb.stdout_colorful = false
103
+ rescue Exception => err
104
+ FancyIrb.stdout_colorful = false
105
+ FancyIrb.capture_irb_errors = StringIO.new
106
+ FancyIrb.original_stdout, $stdout = $stdout, FancyIrb.capture_irb_errors
107
+ raise err
108
+ end
109
+ end
110
+ end
111
+
112
+ # hook into streams to count lines and colorize
113
+ class << $stdout
114
+ alias write_non_fancy write
115
+ def write(data)
116
+ FancyIrb.track_height data
117
+ FancyIrb.write_stream $stdout, data, FancyIrb[:colorize, :stdout]
118
+ end
119
+ end
120
+
121
+ class << $stderr
122
+ alias write_non_fancy write
123
+ def write(data)
124
+ FancyIrb.track_height data
125
+ FancyIrb.write_stream $stderr, data, FancyIrb[:colorize, :stderr]
126
+ rescue Exception # catch fancy_irb errors
127
+ write_non_fancy data
128
+ end
129
+ end
130
+
131
+
132
+ # patch some input methods to track height
133
+ alias gets_non_fancy gets
134
+ def gets(*args)
135
+ res = gets_non_fancy *args
136
+ FancyIrb.track_height res
137
+ res
138
+ end
139
+
140
+ # TODO testing and improving, e.g. getc does not contain "\n"
141
+ class << $stdin
142
+ stdin_hooks = %w[binread read gets getc getbyte readbyte readchar readline readlines readpartial sysread]
143
+ # TODO: each_byte, each_char, each_codepoint, each
144
+
145
+ stdin_hooks.each{ |m|
146
+ msym = m.to_sym
147
+ malias = (m+'_non_fancy').to_sym
148
+
149
+ if $stdin.respond_to? msym
150
+ alias_method malias, msym
151
+ define_method msym do |*args|
152
+ res = send malias, *args
153
+ FancyIrb.track_height res
154
+ res
155
+ end
156
+ end
157
+ }
158
+ end
159
+
160
+ # reset everything (e.g. colors) when exiting
161
+ END{
162
+ print `tput sgr0`
163
+ }
data/lib/fancy_irb.rb ADDED
@@ -0,0 +1,123 @@
1
+ require 'stringio'
2
+ require 'wirble'
3
+
4
+ module FancyIrb
5
+ VERSION = ( File.read File.expand_path( '../VERSION', File.dirname(__FILE__)) ).chomp
6
+ end
7
+
8
+ class << FancyIrb
9
+ # setup instance variable accessors
10
+ attr_reader :options
11
+ def [](key, key2 = nil)
12
+ if key2
13
+ @options[key][key2]
14
+ else
15
+ @options[key]
16
+ end
17
+ end
18
+
19
+ attr_accessor :original_stdout
20
+ attr_accessor :capture_irb_errors
21
+ attr_accessor :real_lengths
22
+ attr_accessor :stdout_colorful
23
+
24
+ def start(user_options = {})
25
+ # track some irb stuff
26
+ @height_counter = []
27
+ @real_lengths = { :output => 1, :input_prompt => 9999 } # or whatever
28
+ @stdout_colorful = false
29
+
30
+ # set defaults and parse user options
31
+ default_result_proc = proc{ |context|
32
+ if context.inspect?
33
+ context.last_value.inspect
34
+ else
35
+ context.last_value
36
+ end
37
+ }
38
+
39
+ default_colorizer_proc = proc{ |value|
40
+ FancyIrb.real_lengths[:output] = value.size
41
+ if defined?(Wirble) && FancyIrb[:colorize, :output]
42
+ Wirble::Colorize.colorize value
43
+ else
44
+ value
45
+ end
46
+ }
47
+
48
+ default_options = {
49
+ :rocket_mode => true, # activate or deactivate #=> rocket output
50
+ :rocket_prompt => '#=> ', # prompt to use for the rocket
51
+ :result_prompt => '=> ', # prompt to use for normal output
52
+ :colorize => { # colors hash. Set to nil to deactivate colorizing
53
+ :rocket_prompt => :blue,
54
+ :result_prompt => :blue,
55
+ :input_prompt => nil,
56
+ :irb_errors => :red,
57
+ :stderr => :light_red,
58
+ :stdout => :dark_gray,
59
+ :input => nil,
60
+ :output => true, # wirble's output colorization
61
+ },
62
+ :result_proc => default_result_proc, # how to get the output result
63
+ :output_procs => [default_colorizer_proc], # you can modify/enhance/log your output
64
+ }
65
+
66
+ @options = default_options
67
+
68
+ default_options.each{ |key, value|
69
+ # (ugly) 1 level deep merge, maybe refactor
70
+ if key == :colorize
71
+ if user_options.has_key?(:colorize) && user_options[:colorize].nil?
72
+ @options[:colorize] = {}
73
+ else
74
+ value.each{ |key2, _|
75
+ if user_options[key] && user_options[key].has_key?(key2)
76
+ @options[:colorize][key2] = user_options[key][key2]
77
+ end
78
+ }
79
+ end
80
+ else
81
+ @options[key] = user_options.has_key?(key) ? user_options[key] : default_options[key]
82
+ end
83
+ }
84
+
85
+ # hook code into IRB
86
+ require 'fancy_irb/irb_ext'
87
+
88
+ "Enjoy your FancyIrb :)"
89
+ end
90
+
91
+ def add_output_proc(prepend = false, &proc)
92
+ action = prepend ? :unshift : :push
93
+ @options[:output_procs].send action, proc
94
+ end
95
+
96
+ def set_result_proc(&proc)
97
+ @options[:result_proc] = proc
98
+ end
99
+
100
+ def reset_height
101
+ @height_counter = []
102
+ end
103
+
104
+ def track_height(data)
105
+ lines = data.to_s.count("\n")
106
+ long_lines = data.to_s.split("\n").inject(0){ |sum, line| line.size / `tput cols`.to_i }
107
+ @height_counter << lines + long_lines
108
+ end
109
+
110
+ def get_height
111
+ 1 + ( @height_counter == [0] ? 0 : @height_counter.reduce(:+) || 0 )
112
+ end
113
+
114
+ def write_stream(stream, data, color = nil)
115
+ stream.write_non_fancy(
116
+ if defined?(Wirble) && FancyIrb.stdout_colorful && color
117
+ Wirble::Colorize::Color.escape( color ) + data.to_s + Wirble::Colorize::Color.escape(:nothing)
118
+ else
119
+ data.to_s
120
+ end
121
+ )
122
+ end
123
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fancy_irb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
10
+ platform: ruby
11
+ authors:
12
+ - Jan Lelis
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-10 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: wirble
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: |-
34
+ FancyIrb patches your IRB to create a smooth output experience.
35
+ * Use fancy colors! You can colorize the prompts, irb errors, +stderr+ and +stdout+
36
+ * Output results as Ruby comment #=> (rocket)
37
+ * Enhance your output value, using procs
38
+ email: mail@janlelis.de
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README
46
+ files:
47
+ - .gitignore
48
+ - LICENSE
49
+ - README
50
+ - Rakefile
51
+ - VERSION
52
+ - fancy_irb.gemspec
53
+ - lib/fancy_irb.rb
54
+ - lib/fancy_irb/irb_ext.rb
55
+ has_rdoc: true
56
+ homepage: http://github.com/janlelis/fancy_irb
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --charset=UTF-8
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: FancyIrb patches your IRB to create a smooth output experience.
87
+ test_files: []
88
+