blackwinter-wirble 0.1.2

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.
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
+