blackwinter-wirble 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/COPYING +20 -0
  2. data/ChangeLog +29 -0
  3. data/README +433 -0
  4. data/wirble.rb +519 -0
  5. metadata +63 -0
data/COPYING ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2002-2006 Paul Duncan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies of the Software, its documentation and marketing & publicity
12
+ materials, and acknowledgment shall be given in the documentation, materials
13
+ and software packages that this Software was used.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/ChangeLog ADDED
@@ -0,0 +1,29 @@
1
+
2
+ * Wed Sep 06 00:01:21 2006, pabs <pabs@pablotron.org>
3
+ * initial import
4
+
5
+ * Wed Sep 06 00:10:13 2006, pabs <pabs@pablotron.org>
6
+ * wirble.rb: remove symbol hackery to prevent
7
+ ri/rdoc from barfing
8
+
9
+ * Wed Sep 6 02:49:02 EDT 2006, Paul Duncan <pabs@pablotron.org>
10
+ * wirble.rb: fix typo
11
+ * re-release 0.1.0
12
+
13
+ * Fri Sep 8 04:01:40 EDT 2006, Paul Duncan <pabs@pablotron.org>
14
+ * README: updated version to 0.1.1
15
+ * wirble.gemspec: ditto
16
+ * wirble.rb: ditto
17
+ * wirble.rb: wrap colorize in an exception (just in case)
18
+
19
+ * Fri Sep 08 13:11:05 2006, pabs <pabs@pablotron.org>
20
+ * increment version to 0.1.2
21
+ * wirble.gemspec: remove rubilicious dependency
22
+
23
+ * Fri Sep 8 13:17:29 EDT 2006, Paul Duncan <pabs@pablotron.org>
24
+ * README: increment version to 0.1.2
25
+ * wirble.gemspec: ditto
26
+ * wirble.rb: ditto
27
+
28
+ * Fri Sep 08 13:18:15 2006, pabs <pabs@pablotron.org>
29
+ * releasing 0.1.2
data/README ADDED
@@ -0,0 +1,433 @@
1
+ Wirble 0.1.2 README
2
+ ===================
3
+
4
+ This document was last updated on Fri Sep 08 13:16:55 2006. See the
5
+ file COPYING for licensing and warranty information. The latest version
6
+ of this software is available at the following URL:
7
+
8
+ http://pablotron.org/software/wirble/
9
+
10
+ Table of Contents
11
+ =================
12
+ * Introduction to Wirble
13
+ * Installing Wirble
14
+ o Via RubyGems
15
+ o Via a Tarball
16
+ o As a User
17
+ * Using Wirble
18
+ o Editing Your ~/.irbrc
19
+ o Enabling Color
20
+ * Configuring Wirble
21
+ * Color Settings
22
+ o Color Keys
23
+ o Color Values
24
+ o Default Color Map
25
+ * Frequently Asked Questions (FAQ)
26
+ * Reporting Bugs
27
+ * About the Author
28
+
29
+
30
+ Introduction to Wirble
31
+ ======================
32
+ Wirble is a set of enhancements to Irb all included together in one
33
+ easy-to-use package. Specifically, Wirble adds a saved history, a
34
+ couple of useful shortcuts, and color to Irb. Wirble also enables a
35
+ Irb's built-in tab-completion and a simpler prompt.
36
+
37
+ Before we begin, I should mention that several of Wirble's features were
38
+ shamelessly inspired (read: borrowed with extreme prejudice) from the
39
+ "Irb Tips and Tricks" page of the Ruby Garden Wiki, which you can find
40
+ at the following URL:
41
+
42
+ http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
43
+
44
+ In particular, the Irb history and ri features bear a striking
45
+ resemblence to their Ruby Garden counterparts.
46
+
47
+
48
+ Installing Wirble
49
+ =================
50
+ The easiest way to install Wirble is via RubyGems
51
+ (http://rubygems.org/). If you've already got RubyGems installed,
52
+ simply do the following, then skip to the "Using Wirble" section below:
53
+
54
+ # install wirble via RubyGems
55
+ sudo gem install wirble
56
+
57
+ If you don't have RubyGems, you can also install the Wirble library
58
+ this:
59
+
60
+ # install wirble to library directory
61
+ sudo cp -v wirble.rb $(ruby -e 'puts $LOAD_PATH[0]')
62
+
63
+ Or, if you don't use sudo, you can do the same thing with su, like so:
64
+
65
+ # install wirble to library directory
66
+ su -c "cp -v wirble.rb $(ruby -e 'puts $LOAD_PATH[0]')"
67
+
68
+ Finally, if you don't have an administrator account, you can still
69
+ install Wirble in your local home directory like so:
70
+
71
+ # create local ruby library directory
72
+ mkdir ~/.ruby && chmod 700 ~/.ruby
73
+ cp -v wirble.rb ~/.ruby
74
+
75
+ Then add the following line at the _top_ of your ~/.irbrc file:
76
+
77
+ # add ~/.ruby to the library search path
78
+ $LOAD_PATH << File.expand_path('~/.ruby')
79
+
80
+
81
+ Using Wirble
82
+ ============
83
+ Using Wirble is easy: just add the following lines to your ~/.irbrc
84
+ file:
85
+
86
+ # load rubygems and wirble
87
+ require 'rubygems' rescue nil
88
+ require 'wirble'
89
+
90
+ # load wirble
91
+ Wirble.init
92
+
93
+ A lot of people really don't like colors, so I've kept the color
94
+ disabled by default. To enable it, add the following bit to your
95
+ ~/.irbrc file after "Wirble.init":
96
+
97
+ # enable color
98
+ Wirble.colorize
99
+
100
+ If you want to terrify your grandmother and impress your buddies, your
101
+ entire ~/.irbrc can also be written like so:
102
+
103
+ %w{rubygems wirble}.each { |lib| require lib rescue nil }
104
+ %w{init colorize}.each { |str| Wirble.send(str.intern) }
105
+
106
+ Configuring Wirble
107
+ ==================
108
+ You can pass a hash of options to Wirble.init in order to adjust the
109
+ behavior of Wirble. Here's a full list of options and a brief
110
+ description of each one:
111
+
112
+ * :skip_internals
113
+
114
+ Don't load the internal Irb features. Equivalent to setting both
115
+ :skip_libraries and :skip_prompt (see below).
116
+
117
+ * :skip_libraries
118
+
119
+ Don't load any libraries. At the moment, Wirble attempts to load
120
+ the following libraries: "pp", "irb/completion", and "rubygems".
121
+
122
+ * :skip_prompt
123
+
124
+ Down't load the simple prompt. Shouldn't ever be necessary, but
125
+ I've included it for the sake of completeness. Wirble's default
126
+ behavior is to the prompt setting before making any changes. If the
127
+ prompt is anything other than :DEFAULT, Wirble won't override it.
128
+
129
+ * :skip_history
130
+
131
+ Don't load the Irb history. There are a few additional history
132
+ options as well; see :history_path, :history_size, and
133
+ :history_perms below.
134
+
135
+ * :history_path
136
+
137
+ Set the path to the Irb history file. Defaults to "~/.irb_history".
138
+ If an environment variable named IRB_HISTORY_FILE is set, Wirble
139
+ will use that instead of the default value.
140
+
141
+ * :history_size
142
+
143
+ Set the size (in lines) of the Irb history file. Defaults to 1000
144
+ lines. If an environment variable named IRB_HISTORY_SIZE is set,
145
+ Wirble will use that instead of the default value.
146
+
147
+ * :history_perms
148
+
149
+ Set the permissions of the Irb history file. Defaults to
150
+ File::WRONLY.
151
+
152
+ * :skip_shortcuts
153
+
154
+ Don't load any shortcut methods. at the moment there are three
155
+ shortcut methods: "ri", "po", and "poc". The first calls the "ri"
156
+ command on the specified value -- you"ll need to use proper quoting
157
+ to pass the name properly. As for "po" and "poc": the former lists
158
+ an object's instance methods (excluding methods that belong to
159
+ Object), sorted by name, and the latter lists an object's constants,
160
+ sorted by name.
161
+
162
+ * :init_colors
163
+
164
+ Enable colors. Equivalent to calling Wirble.colorize directly.
165
+
166
+ * :colors
167
+
168
+ A hash of colors. Only makes sense in conjunction with the
169
+ :init_colors option. See below for additional information on
170
+ customizing color settings.
171
+
172
+ Here's an example of passing a list of options to Wirble.init():
173
+
174
+ wirble_opts = {
175
+ # skip shortcuts
176
+ :skip_shortcuts => true,
177
+
178
+ # don't set the prompt
179
+ :skip_prompt => true,
180
+
181
+ # override some of the default colors
182
+ :colors => {
183
+ :open_hash => :green.
184
+ :close_hash => :green.
185
+ :string => :blue,
186
+ },
187
+
188
+ # enable color
189
+ :init_color => true,
190
+ }
191
+
192
+ # initialize wirble with options above
193
+ Wirble.init(wirble_opts)
194
+
195
+ For a full description of the color options, see the next section.
196
+
197
+
198
+ Color Settings
199
+ ==============
200
+ You can set colors in Wirble by passing a hash of color options via
201
+ Wirble.init (see the :color option for Wirble.init above), or by setting
202
+ Wirble::Colorize.color directly. For example:
203
+
204
+ # get the default colors and add in your own
205
+ colors = Wirble::Colorize.colors.merge({
206
+ # set the comma color to blue
207
+ :comma => :blue,
208
+ })
209
+
210
+ # set the colors used by Wirble
211
+ Wirble::Colorize.colors = colors
212
+
213
+ Below is a list of all the recognized color keys.
214
+
215
+ * :comma (',')
216
+
217
+ A comma character. The element delimiter in arrays and hashes.
218
+
219
+ * :refers ('=>')
220
+
221
+ The hash reference operator. The key/value delimiter in hashes.
222
+
223
+ * :open_hash ('{')
224
+
225
+ The opening curly brace for a hash.
226
+
227
+ * :close_hash ('}')
228
+
229
+ The opening curly brace for a hash.
230
+
231
+ * :open_array ('[')
232
+
233
+ The opening brace for a array.
234
+
235
+ * :close_array (']')
236
+
237
+ The opening brace for a array.
238
+
239
+ * :open_object ('#<')
240
+
241
+ The opening delimiter for an object.
242
+
243
+ * :close_object ('>')
244
+
245
+ The closing delimiter for an object inspection.
246
+
247
+ * :object_class
248
+
249
+ The class attribute of an object inspection. For example, in the
250
+ string "#<Proc:0xb7be4968@(irb):8>", the string "Proc" is the class
251
+ attribute.
252
+
253
+ * :object_addr_prefix (':')
254
+
255
+ The colon prefixing the address attribute of an object inspection.
256
+ For example, in the string "#<Proc:0xb7be4968@(irb):8>", the string
257
+ "0xb7be4968" is the memory address attribute, so the ':' is the
258
+ address prefix.
259
+
260
+ * :object_addr
261
+
262
+ The memory address attribute of an object inspection. For example,
263
+ in the string "#<Proc:0xb7be4968@(irb):8>", the string "0xb7be4968"
264
+ is the memory address attribute.
265
+
266
+ * :object_addr_prefix ('@')
267
+
268
+ The at symbol prefixing the line attribute of an object inspection.
269
+ For example, in the string "#<Proc:0xb7be4968@(irb):8>", the string
270
+ "(irb):8" is the line attribute, so the '@' is the line attribute
271
+ prefix.
272
+
273
+ * :object_line
274
+
275
+ The line number attribute of an object inspection. For example,
276
+ in the string "#<Proc:0xb7be4968@(irb):8>", the string "(irb):8"
277
+ is the line number attribute.
278
+
279
+ * :symbol_prefix (':')
280
+
281
+ The colon prefix for a symbol object.
282
+
283
+ * :symbol
284
+
285
+ The string of a symbol object.
286
+
287
+ * :open_string ('"')
288
+
289
+ The opening quote of a string object.
290
+
291
+ * :close_string ('"')
292
+
293
+ The closing quote of a string object.
294
+
295
+ * :number
296
+
297
+ A number (integer or float).
298
+
299
+ * :range ('..')
300
+
301
+ The delimeter of a range object.
302
+
303
+ * :keyword
304
+
305
+ A built-in Ruby keyword. This includes values like "true", "false",
306
+ and "nil".
307
+
308
+ * :class
309
+
310
+ A class. This includes strings like "Class" and "Object".
311
+
312
+ * :whitespace
313
+
314
+ Whitespace character (i.e. space, newline, tab, etc).
315
+
316
+ The highlighting is implemented with a simple hand-rolled state-based
317
+ tokenizer (wow, that was a mouthful). This should be adequate most of
318
+ the time, but since it's not a actual LALR parser, Wirble can get
319
+ confused in a few specific instances. If you find a serious
320
+ highlighting problem, please let me know. Oh yeah, before I forget,
321
+ here's a list of the valid color codes:
322
+
323
+ :nothing :green :light_purple
324
+ :black :light_blue :purple
325
+ :blue :light_cyan :red
326
+ :brown :light_gray :white
327
+ :cyan :light_green :yellow
328
+ :dark_gray :light_red
329
+
330
+ Note that I'm not a designer, and I also use a terminal with a dark
331
+ background. I've also been accused of having a Vim color scheme that
332
+ looks like "a beat up clown". With those caveats in mind, here's the
333
+ default color scheme for Wirble:
334
+
335
+ #
336
+ # Default Wirble color scheme.
337
+ #
338
+ DEFAULT_COLORS = {
339
+ # delimiter colors
340
+ :comma => :blue,
341
+ :refers => :blue,
342
+
343
+ # container colors (hash and array)
344
+ :open_hash => :green,
345
+ :close_hash => :green,
346
+ :open_array => :green,
347
+ :close_array => :green,
348
+
349
+ # object colors
350
+ :open_object => :light_red,
351
+ :object_class => :white,
352
+ :object_addr_prefix => :blue,
353
+ :object_line_prefix => :blue,
354
+ :close_object => :light_red,
355
+
356
+ # symbol colors
357
+ :symbol => :yellow,
358
+ :symbol_prefix => :yellow,
359
+
360
+ # string colors
361
+ :open_string => :red,
362
+ :string => :cyan,
363
+ :close_string => :red,
364
+
365
+ # misc colors
366
+ :number => :cyan,
367
+ :keyword => :green,
368
+ :class => :light_green,
369
+ :range => :red,
370
+ }
371
+
372
+ This map is also available via programmatically via
373
+ Wirble::Colorize::DEFAULT_COLORS.
374
+
375
+
376
+ Frequently Asked Questions (FAQ)
377
+ ================================
378
+ Q. Where did the name come from?
379
+ A. Beats me. It's the only thing I could find in the dictionary, and
380
+ the only name I came up with that I could pronounce.
381
+
382
+ Q. How do I use color in my Irb prompts?
383
+ A. You can use standard color escape codes in the format string used by
384
+ Irb. For example, to set the user prompt to cyan, you could do
385
+ something like this:
386
+
387
+ ctx = IRB.CurrentContext
388
+ ctx.prompt_i = Wirble::Colorize.colorize_string(ctx.prompt_i, :cyan)
389
+
390
+ Q. How can I do syntax highlighting as I type?
391
+ A. I don't know. If there is an answer, I suspect it's not very
392
+ portable and probably requires some modification to Irb. There's a
393
+ sneaky hack called eval.rb that seems to do a little bit of
394
+ highlight, but it doesn't use Irb, and it doesn't really do what
395
+ you're asking. That said, you can find it here:
396
+
397
+ http://www.rubyist.net/~slagell/ruby/eval.txt
398
+
399
+ Incidentally, part of the problem is that there's no real easy way
400
+ to do the following:
401
+
402
+ 1. Access to the token stream or parser state incrementally.
403
+ 2. Process partial strings in readline.
404
+
405
+ A bit more about #1: both Irb and the internal Ruby lexer kind of
406
+ muddle the traditionally separate concepts of lexer and parser, so
407
+ it's difficult to, say, parse a string into components and do syntax
408
+ highlighting on them. Vim and Emacs both handle this with sneaky
409
+ regular expressions, and a simple Ruby parser, respectively. Wirble
410
+ and Irb both roll their own (albeit limited) Ruby lexers.
411
+
412
+
413
+ Reporting Bugs
414
+ ==============
415
+ Have a bug to report or a feature you'd like me to add to Wirble?
416
+ Feel free to email me at the address below. Alternatively, you can
417
+ submit your feature request or bug directly to my bug-tracking web
418
+ interface at the following URL:
419
+
420
+ http://bugs.pablotron.org/
421
+
422
+ Note: you'll need to create an account in order to submit a feature
423
+ request or a bug report via the web interface. Also, I'm a busy guy! I
424
+ make every effort to respond quickly to bug reports, but detailed
425
+ descriptions and or patches really do make my life a whole lot easier.
426
+
427
+
428
+ About the Author
429
+ ================
430
+ Paul Duncan <pabs@pablotron.org>
431
+ http://pablotron.org/
432
+
433
+ And of course, all the fine folks from the Ruby Garden Wiki. :)
data/wirble.rb ADDED
@@ -0,0 +1,519 @@
1
+ require 'ostruct'
2
+
3
+ #
4
+ # Wirble: A collection of useful Irb features.
5
+ #
6
+ # To use, add the following to your ~/.irbrc:
7
+ #
8
+ # require 'rubygems'
9
+ # require 'wirble'
10
+ # Wirble.init
11
+ #
12
+ # If you want color in Irb, add this to your ~/.irbrc as well:
13
+ #
14
+ # Wirble.colorize
15
+ #
16
+ # Note: I spent a fair amount of time documenting this code in the
17
+ # README. If you've installed via RubyGems, root around your cache a
18
+ # little bit (or fire up gem_server) and read it before you tear your
19
+ # hair out sifting through the code below.
20
+ #
21
+ module Wirble
22
+ VERSION = '0.1.2'
23
+
24
+ #
25
+ # Load internal Ruby features, including tab-completion, rubygems,
26
+ # and a simple prompt.
27
+ #
28
+ module Internals
29
+ # list of internal libraries to automatically load
30
+ LIBRARIES = %w{pp irb/completion rubygems}
31
+
32
+ #
33
+ # load tab completion and rubygems
34
+ #
35
+ def self.init_libraries
36
+ LIBRARIES.each { |lib| require lib rescue nil }
37
+ end
38
+
39
+ #
40
+ # Set a simple prompt, unless a custom one has been specified.
41
+ #
42
+ def self.init_prompt
43
+ # set the prompt
44
+ if IRB.conf[:PROMPT_MODE] == :DEFAULT
45
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
46
+ end
47
+ end
48
+
49
+ #
50
+ # Load all Ruby internal features.
51
+ #
52
+ def self.init(opt = nil)
53
+ init_libraries unless opt && opt[:skip_libraries]
54
+ init_prompt unless opt && opt[:skip_prompt]
55
+ end
56
+ end
57
+
58
+ #
59
+ # Basic IRB history support. This is based on the tips from
60
+ # http://wiki.rubygarden.org/Ruby/page/show/Irb/TipsAndTricks
61
+ #
62
+ class History
63
+ DEFAULTS = {
64
+ :history_path => ENV['IRB_HISTORY_FILE'] || "~/.irb_history",
65
+ :history_size => (ENV['IRB_HISTORY_SIZE'] || 1000).to_i,
66
+ :history_perms => File::WRONLY | File::CREAT | File::TRUNC,
67
+ }
68
+
69
+ private
70
+
71
+ def say(*args)
72
+ puts *args if @verbose
73
+ end
74
+
75
+ def cfg(key)
76
+ @opt["history_#{key}".intern]
77
+ end
78
+
79
+ def save_history
80
+ path, max_size, perms = %w{path size perms}.map { |v| cfg(v) }
81
+
82
+ # read lines from history, and truncate the list (if necessary)
83
+ lines = Readline::HISTORY.to_a.uniq
84
+ lines = lines[-max_size, -1] if lines.size > max_size
85
+
86
+ # write the history file
87
+ real_path = File.expand_path(path)
88
+ File.open(real_path, perms) { |fh| fh.puts lines }
89
+ say 'Saved %d lines to history file %s.' % [lines.size, path]
90
+ end
91
+
92
+ def load_history
93
+ # expand history file and make sure it exists
94
+ real_path = File.expand_path(cfg('path'))
95
+ unless File.exist?(real_path)
96
+ say "History file #{real_path} doesn't exist."
97
+ return
98
+ end
99
+
100
+ # read lines from file and add them to history
101
+ lines = File.readlines(real_path).map { |line| line.chomp }
102
+ Readline::HISTORY.push(*lines)
103
+
104
+ say 'Read %d lines from history file %s' % [lines.size, cfg('path')]
105
+ end
106
+
107
+ public
108
+
109
+ def initialize(opt = nil)
110
+ @opt = DEFAULTS.merge(opt || {})
111
+ return unless defined? Readline::HISTORY
112
+ load_history
113
+ Kernel.at_exit { save_history }
114
+ end
115
+ end
116
+
117
+ #
118
+ # Add color support to IRB.
119
+ #
120
+ module Colorize
121
+ #
122
+ # Tokenize an inspection string.
123
+ #
124
+ module Tokenizer
125
+ def self.tokenize(str)
126
+ raise 'missing block' unless block_given?
127
+ chars = str.split(//)
128
+
129
+ # $stderr.puts "DEBUG: chars = #{chars.join(',')}"
130
+
131
+ state, val, i, lc = [], '', 0, nil
132
+ while i <= chars.size
133
+ repeat = false
134
+ c = chars[i]
135
+
136
+ # $stderr.puts "DEBUG: state = #{state}"
137
+
138
+ case state[-1]
139
+ when nil
140
+ case c
141
+ when ':' then state << :symbol
142
+ when '"' then state << :string
143
+ when '#' then state << :object
144
+ when /[a-z]/i
145
+ state << :keyword
146
+ repeat = true
147
+ when /[0-9-]/
148
+ state << :number
149
+ repeat = true
150
+ when '{' then yield :open_hash, '{'
151
+ when '[' then yield :open_array, '['
152
+ when ']' then yield :close_array, ']'
153
+ when '}' then yield :close_hash, '}'
154
+ when /\s/ then yield :whitespace, c
155
+ when ',' then yield :comma, ','
156
+ when '>'
157
+ yield :refers, '=>' if lc == '='
158
+ when '.'
159
+ yield :range, '..' if lc == '.'
160
+ when '='
161
+ # ignore these, they're used elsewhere
162
+ nil
163
+ else
164
+ # $stderr.puts "DEBUG: ignoring char #{c}"
165
+ end
166
+ when :symbol
167
+ case c
168
+ # XXX: should have =, but that messes up foo=>bar
169
+ when /[a-z0-9_!?]/
170
+ val << c
171
+ else
172
+ yield :symbol_prefix, ':'
173
+ yield state[-1], val
174
+ state.pop; val = ''
175
+ repeat = true
176
+ end
177
+ when :string
178
+ case c
179
+ when '"'
180
+ if lc == "\\"
181
+ val[-1] = ?"
182
+ else
183
+ yield :open_string, '"'
184
+ yield state[-1], val
185
+ state.pop; val = ''
186
+ yield :close_string, '"'
187
+ end
188
+ else
189
+ val << c
190
+ end
191
+ when :keyword
192
+ case c
193
+ when /[a-z0-9_]/i
194
+ val << c
195
+ else
196
+ # is this a class?
197
+ st = val =~ /^[A-Z]/ ? :class : state[-1]
198
+
199
+ yield st, val
200
+ state.pop; val = ''
201
+ repeat = true
202
+ end
203
+ when :number
204
+ case c
205
+ when /[0-9e-]/
206
+ val << c
207
+ when '.'
208
+ if lc == '.'
209
+ val[/\.$/] = ''
210
+ yield state[-1], val
211
+ state.pop; val = ''
212
+ yield :range, '..'
213
+ else
214
+ val << c
215
+ end
216
+ else
217
+ yield state[-1], val
218
+ state.pop; val = ''
219
+ repeat = true
220
+ end
221
+ when :object
222
+ case c
223
+ when '<'
224
+ yield :open_object, '#<'
225
+ state << :object_class
226
+ when ':'
227
+ state << :object_addr
228
+ when '@'
229
+ state << :object_line
230
+ when '>'
231
+ yield :close_object, '>'
232
+ state.pop; val = ''
233
+ end
234
+ when :object_class
235
+ case c
236
+ when ':'
237
+ yield state[-1], val
238
+ state.pop; val = ''
239
+ repeat = true
240
+ else
241
+ val << c
242
+ end
243
+ when :object_addr
244
+ case c
245
+ when '>'
246
+ when '@'
247
+ yield :object_addr_prefix, ':'
248
+ yield state[-1], val
249
+ state.pop; val = ''
250
+ repeat = true
251
+ else
252
+ val << c
253
+ end
254
+ when :object_line
255
+ case c
256
+ when '>'
257
+ yield :object_line_prefix, '@'
258
+ yield state[-1], val
259
+ state.pop; val = ''
260
+ repeat = true
261
+ else
262
+ val << c
263
+ end
264
+ else
265
+ raise "unknown state #{state}"
266
+ end
267
+
268
+ unless repeat
269
+ i += 1
270
+ lc = c
271
+ end
272
+ end
273
+ end
274
+ end
275
+
276
+ #
277
+ # Terminal escape codes for colors.
278
+ #
279
+ module Color
280
+ COLORS = {
281
+ :nothing => '0;0',
282
+ :black => '0;30',
283
+ :red => '0;31',
284
+ :green => '0;32',
285
+ :brown => '0;33',
286
+ :blue => '0;34',
287
+ :cyan => '0;36',
288
+ :purple => '0;35',
289
+ :light_gray => '0;37',
290
+ :dark_gray => '1;30',
291
+ :light_red => '1;31',
292
+ :light_green => '1;32',
293
+ :yellow => '1;33',
294
+ :light_blue => '1;34',
295
+ :light_cyan => '1;36',
296
+ :light_purple => '1;35',
297
+ :white => '1;37',
298
+ }
299
+
300
+ #
301
+ # Return the escape code for a given color.
302
+ #
303
+ def self.escape(key)
304
+ COLORS.key?(key) && "\033[#{COLORS[key]}m"
305
+ end
306
+ end
307
+
308
+ #
309
+ # Default Wirble color scheme.
310
+ #
311
+ DEFAULT_COLORS = {
312
+ # delimiter colors
313
+ :comma => :blue,
314
+ :refers => :blue,
315
+
316
+ # container colors (hash and array)
317
+ :open_hash => :green,
318
+ :close_hash => :green,
319
+ :open_array => :green,
320
+ :close_array => :green,
321
+
322
+ # object colors
323
+ :open_object => :light_red,
324
+ :object_class => :white,
325
+ :object_addr_prefix => :blue,
326
+ :object_line_prefix => :blue,
327
+ :close_object => :light_red,
328
+
329
+ # symbol colors
330
+ :symbol => :yellow,
331
+ :symbol_prefix => :yellow,
332
+
333
+ # string colors
334
+ :open_string => :red,
335
+ :string => :cyan,
336
+ :close_string => :red,
337
+
338
+ # misc colors
339
+ :number => :cyan,
340
+ :keyword => :green,
341
+ :class => :light_green,
342
+ :range => :red,
343
+ }
344
+
345
+ #
346
+ # Fruity testing colors.
347
+ #
348
+ TESTING_COLORS = {
349
+ :comma => :red,
350
+ :refers => :red,
351
+ :open_hash => :blue,
352
+ :close_hash => :blue,
353
+ :open_array => :green,
354
+ :close_array => :green,
355
+ :open_object => :light_red,
356
+ :object_class => :light_green,
357
+ :object_addr => :purple,
358
+ :object_line => :light_purple,
359
+ :close_object => :light_red,
360
+ :symbol => :yellow,
361
+ :symbol_prefix => :yellow,
362
+ :number => :cyan,
363
+ :string => :cyan,
364
+ :keyword => :white,
365
+ :range => :light_blue,
366
+ }
367
+
368
+ #
369
+ # Set color map to hash
370
+ #
371
+ def self.colors=(hash)
372
+ @colors = hash
373
+ end
374
+
375
+ #
376
+ # Get current color map
377
+ #
378
+ def self.colors
379
+ @colors ||= {}.update(DEFAULT_COLORS)
380
+ end
381
+
382
+ #
383
+ # Return a string with the given color.
384
+ #
385
+ def self.colorize_string(str, color)
386
+ col, nocol = [color, :nothing].map { |key| Color.escape(key) }
387
+ col ? "#{col}#{str}#{nocol}" : str
388
+ end
389
+
390
+ #
391
+ # Colorize the results of inspect
392
+ #
393
+ def self.colorize(str)
394
+ begin
395
+ ret, nocol = '', Color.escape(:nothing)
396
+ Tokenizer.tokenize(str) do |tok, val|
397
+ # c = Color.escape(colors[tok])
398
+ ret << colorize_string(val, colors[tok])
399
+ end
400
+ ret
401
+ rescue
402
+ # catch any errors from the tokenizer (just in case)
403
+ str
404
+ end
405
+ end
406
+
407
+ #
408
+ # Enable colorized IRB results.
409
+ #
410
+ def self.enable(custom_colors = nil)
411
+ # if there's a better way to do this, I'm all ears.
412
+ ::IRB::Irb.class_eval do
413
+ alias :non_color_output_value :output_value
414
+
415
+ def output_value
416
+ if @context.inspect?
417
+ val = Colorize.colorize(@context.last_value.inspect)
418
+ printf @context.return_format, val
419
+ else
420
+ printf @context.return_format, @context.last_value
421
+ end
422
+ end
423
+ end
424
+
425
+ colors = custom_colors if custom_colors
426
+ end
427
+
428
+ #
429
+ # Disable colorized IRB results.
430
+ #
431
+ def self.disable
432
+ ::IRB::Irb.class_eval do
433
+ alias :output_value :non_color_output_value
434
+ end
435
+ end
436
+ end
437
+
438
+ #
439
+ # Convenient shortcut methods.
440
+ #
441
+ module Shortcuts
442
+ #
443
+ # Print object methods, sorted by name. (excluding methods that
444
+ # exist in the class Object) .
445
+ #
446
+ def po(o)
447
+ o.methods.sort - Object.methods
448
+ end
449
+
450
+ #
451
+ # Print object constants, sorted by name.
452
+ #
453
+ def poc(o)
454
+ o.constants.sort
455
+ end
456
+ end
457
+
458
+ #
459
+ # Convenient shortcut for ri
460
+ #
461
+ module RiShortcut
462
+ def self.init
463
+ Kernel.class_eval {
464
+ def ri(arg)
465
+ puts `ri '#{arg}'`
466
+ end
467
+ }
468
+
469
+ Module.instance_eval {
470
+ def ri(meth=nil)
471
+ if meth
472
+ if instance_methods(false).include? meth.to_s
473
+ puts `ri #{self}##{meth}`
474
+ else
475
+ super
476
+ end
477
+ else
478
+ puts `ri #{self}`
479
+ end
480
+ end
481
+ }
482
+ end
483
+ end
484
+
485
+
486
+
487
+ #
488
+ # Enable color results.
489
+ #
490
+ def self.colorize(custom_colors = nil)
491
+ Colorize.enable(custom_colors)
492
+ end
493
+
494
+ #
495
+ # Load everything except color.
496
+ #
497
+ def self.init(opt = nil)
498
+ # make sure opt isn't nil
499
+ opt ||= {}
500
+
501
+ # load internal irb/ruby features
502
+ Internals.init(opt) unless opt && opt[:skip_internals]
503
+
504
+ # load the history
505
+ History.new(opt) unless opt && opt[:skip_history]
506
+
507
+ # load shortcuts
508
+ unless opt && opt[:skip_shortcuts]
509
+ # load ri shortcuts
510
+ RiShortcut.init
511
+
512
+ # include common shortcuts
513
+ Object.class_eval { include Shortcuts }
514
+ end
515
+
516
+ colorize(opt[:colors]) if opt && opt[:init_colors]
517
+ end
518
+ end
519
+
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blackwinter-wirble
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Paul Duncan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-05 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: 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.
17
+ email: pabs@pablotron.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - wirble.rb
26
+ - README
27
+ - ChangeLog
28
+ - COPYING
29
+ has_rdoc: true
30
+ homepage: http://pablotron.org/software/wirble/
31
+ post_install_message:
32
+ rdoc_options:
33
+ - --webcvs
34
+ - http://cvs.pablotron.org/cgi-bin/viewcvs.cgi/wirble/
35
+ - --title
36
+ - Wirble API Documentation
37
+ - wirble.rb
38
+ - README
39
+ - ChangeLog
40
+ - COPYING
41
+ require_paths:
42
+ - .
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements:
56
+ - Ruby, version 1.8.0 (or newer)
57
+ rubyforge_project: wirble
58
+ rubygems_version: 1.2.0
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Handful of common Irb features, made easy.
62
+ test_files: []
63
+