virb 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/
2
+ .virb
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Virb
2
+
3
+ Virb is an interactive Vim mode for IRB, Rails console, and Pry.
4
+
5
+ ## Motivation
6
+
7
+ The IRB is Ruby's interactive REPL. IRB is a very handy tool, but its
8
+ text-editing capabilities are limited. Virb wraps an IRB session in a Vim
9
+ session and gives you convenient ways to evaluate Ruby code from Vim.
10
+
11
+ Virb inverts the approach taken by
12
+ the [interactive_editor](https://github.com/jberkel/interactive_editor) gem and
13
+ similar solutions which let you pop out into Vim from IRB and come back to IRB
14
+ to see the results. Virb keeps you in Vim at all times, calling IRB behind the
15
+ scenes and fetching IBR's output to display inside Vim.
16
+
17
+ ## Install
18
+
19
+ gem install virb
20
+
21
+ Virb requires Ruby 1.9 and Vim 7.2 or above. Virb has been tested only on OS X
22
+ 10.8 and Ubuntu Linux.
23
+
24
+
25
+ ## Using Virb
26
+
27
+ Start up Virb with the command
28
+
29
+ virb [file]
30
+
31
+ The optional `file` is a text file that contains Ruby code that you
32
+ would like to run interactively.
33
+
34
+ Virb opens 2 Vim buffers. The bottom buffer is the interactive buffer,
35
+ where you can edit Ruby code and then send it to the underlying interactive
36
+ Ruby session for evaluation. The top buffer is the output buffer, where you
37
+ can see the IRB session you are controlling from the interactive buffer.
38
+
39
+ To evaluate code in the interactive buffer:
40
+
41
+ To evaluate a line of code, put the cursor on it, and press ENTER in normal mode.
42
+
43
+ To evaluate several lines of code, you can either
44
+
45
+ 1. select the lines in Vim's visual mode, and press ENTER to evaluate them;
46
+ 2. use an ed-style range command: `:[range]Virb`
47
+
48
+ If IRB takes too long (more than about half a second) to evaluate your code,
49
+ you may need to manually force the session buffer to update itself. You can
50
+ force an update by pressing SPACE in normal mode.
51
+
52
+
53
+ ## Using Virb with Pry
54
+
55
+ Make sure you have the `pry` gem installed. Then you can run this:
56
+
57
+ virb-pry [file]
58
+
59
+ When virb opens, you should be able to send your code for evaluation to Pry and
60
+ get Pry output in the virb session buffer.
61
+
62
+ ## How to wrap Rails console with Virb
63
+
64
+ If you want to use Virb with the standard Rails console:
65
+
66
+ Put this in your Gemfile:
67
+
68
+ group :development do
69
+ gem 'virb'
70
+ end
71
+
72
+ and start Rails console as you do normally. You should see the Virb interface
73
+ open, where you can interact with the Ralis console through a Vim buffer and
74
+ see its output in the other Vim buffer.
75
+
76
+ If you want to use Virb with Pry and Rails console:
77
+
78
+ Put this in your Gemfile:
79
+
80
+ group :development do
81
+ gem 'pry'
82
+ gem 'virb'
83
+ end
84
+
85
+ and start Rails console like this:
86
+
87
+ VIRB=pry rails c
88
+
89
+
90
+ ## Caveats
91
+
92
+ The normal command line options for `irb` and `pry` do not work with `virb`.
93
+
94
+
95
+ ## Author
96
+
97
+ Virb was written by [Daniel Choi](http://danielchoi.com/software), an independent software developer based in Cambridge, Massachusetts.
98
+
99
+ * [GitHub](http://github.com/danchoi)
100
+ * [Twitter](http://twitter.com/danchoi)
101
+ * I am available for short to medium-term consulting projects: [Email](mailto:dhchoi@gmail.com)
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ desc "release and build and push new website"
7
+ task :push => [:release, :web]
8
+
9
+ desc "build and push website"
10
+ task :web => :build_webpage do
11
+ puts "Building and pushing website"
12
+ Dir.chdir "../project-webpages" do
13
+ `scp out/virb.html zoe2@instantwatcher.com:~/danielchoi.com/public/software/`
14
+ `rsync -avz out/images-virb zoe2@instantwatcher.com:~/danielchoi.com/public/software/`
15
+ `rsync -avz out/stylesheets zoe2@instantwatcher.com:~/danielchoi.com/public/software/`
16
+ `rsync -avz out/lightbox2 zoe2@instantwatcher.com:~/danielchoi.com/public/software/`
17
+ end
18
+ `open http://danielchoi.com/software/virb.html`
19
+ end
20
+
21
+ desc "build webpage"
22
+ task :build_webpage do
23
+ `cp README.md ../project-webpages/src/virb.README.markdown`
24
+ require "./lib/virb/version"
25
+ version = Virb::VERSION
26
+ puts "Version detected: #{version}"
27
+ Dir.chdir "../project-webpages" do
28
+ puts `ruby gen.rb virb #{version}`
29
+ `open out/virb.html`
30
+ end
31
+ end
32
+
33
+ task :default => :test
34
+
data/bin/virb ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if %w{ -h --help --version -v }.include?(ARGV[0])
4
+ require 'virb/version'
5
+ puts <<END
6
+ virb #{Virb::VERSION}
7
+
8
+ For instructions, please visit http://github.com/danchoi/virb
9
+ Author: Daniel Choi
10
+ License: MIT
11
+ END
12
+ exit
13
+ end
14
+ require 'virb/default'
15
+ IRB.start
data/bin/virb-pry ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if %w{ -h --help --version -v }.include?(ARGV[0])
4
+ require 'virb/version'
5
+ puts <<END
6
+ virb #{Virb::VERSION}
7
+
8
+ For instructions, please visit http://github.com/danchoi/virb
9
+ Author: Daniel Choi
10
+ License: MIT
11
+ END
12
+ exit
13
+ end
14
+ require 'virb/pry'
15
+ Virb::Pry.start
data/images/virb1.png ADDED
Binary file
data/images/virb2.png ADDED
Binary file
data/images/virb3.png ADDED
Binary file
@@ -0,0 +1,459 @@
1
+ #
2
+ # irb.rb - irb main module
3
+ # $Release Version: 0.9.6 $
4
+ # $Revision: 31641 $
5
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
6
+ #
7
+ # Modified for virb by Daniel Choi dhchoi@gmail.com
8
+ # --
9
+ #
10
+ #
11
+ #
12
+ require "e2mmap"
13
+
14
+ require 'stringio'
15
+
16
+ require "irb/init"
17
+ require "irb/context"
18
+ require "irb/extend-command"
19
+ #require "irb/workspace"
20
+
21
+ require "irb/ruby-lex"
22
+ require "irb/input-method"
23
+ require "irb/locale"
24
+
25
+ `rm -rf .virb`
26
+ `mkdir -p .virb`
27
+ unless File.exist?('.virb/fifo')
28
+ `mkfifo .virb/fifo`
29
+ end
30
+ `touch .virb/session`
31
+
32
+ STDOUT.sync = true
33
+
34
+ $outfile = '.virb/session'
35
+ STDERR.reopen "/dev/null" # this prevent logging to cursor location in rails c
36
+ $infifo = '.virb/fifo'
37
+
38
+ module IRB
39
+ class StdioInputMethod < InputMethod
40
+ def initialize
41
+ super
42
+ @line_no = 0
43
+ @line = []
44
+ @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
45
+ @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-")
46
+ end
47
+
48
+ def gets
49
+ print @prompt
50
+ line = @stdin.gets
51
+ print line # this is added by dan choi to ensure echoing of executed code in session window
52
+ @line[@line_no += 1] = line
53
+ end
54
+
55
+ def eof?
56
+ @stdin.eof?
57
+ end
58
+
59
+ def readable_atfer_eof?
60
+ true
61
+ end
62
+
63
+ def line(line_no)
64
+ @line[line_no]
65
+ end
66
+
67
+ def encoding
68
+ @stdin.external_encoding
69
+ end
70
+ end
71
+ end
72
+
73
+ module IRB
74
+
75
+ class Abort < Exception;end
76
+
77
+ #
78
+ @CONF = {}
79
+
80
+ def IRB.conf
81
+ @CONF
82
+ end
83
+
84
+ # IRB version method
85
+ def IRB.version
86
+ if v = @CONF[:VERSION] then return v end
87
+
88
+ require "irb/version"
89
+ rv = @RELEASE_VERSION.sub(/\.0/, "")
90
+ @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
91
+ end
92
+
93
+ def IRB.CurrentContext
94
+ IRB.conf[:MAIN_CONTEXT]
95
+ end
96
+
97
+ # initialize IRB and start TOP_LEVEL irb
98
+ def IRB.start(ap_path = nil)
99
+
100
+ vimscript = File.join(File.dirname(__FILE__), '..', 'virb.vim')
101
+
102
+ # strip args so IRB doesn't think it's loading a file
103
+ args = ARGV.dup
104
+ while ARGV.shift
105
+ # pass
106
+ end
107
+
108
+
109
+ fork do
110
+ original_start ap_path
111
+ end
112
+
113
+ exec("vim -S #{vimscript} #{args.join(' ')} && rm -rf .virb && kill 0")
114
+ end
115
+
116
+ def IRB.original_start(ap_path = nil)
117
+ $0 = File::basename(ap_path, ".rb") if ap_path
118
+
119
+ IRB.setup(ap_path)
120
+
121
+ if @CONF[:SCRIPT]
122
+ irb = Irb.new(nil, @CONF[:SCRIPT])
123
+ else
124
+ irb = Irb.new
125
+ end
126
+
127
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
128
+ @CONF[:MAIN_CONTEXT] = irb.context
129
+
130
+ trap("SIGINT") do
131
+ irb.signal_handle
132
+ end
133
+
134
+ begin
135
+ catch(:IRB_EXIT) do
136
+ irb.eval_input
137
+ end
138
+ ensure
139
+ irb_at_exit
140
+ end
141
+ # print "\n"
142
+
143
+
144
+ end
145
+
146
+ def IRB.irb_at_exit
147
+ @CONF[:AT_EXIT].each{|hook| hook.call}
148
+ end
149
+
150
+ def IRB.irb_exit(irb, ret)
151
+ throw :IRB_EXIT, ret
152
+ end
153
+
154
+ def IRB.irb_abort(irb, exception = Abort)
155
+ if defined? Thread
156
+ irb.context.thread.raise exception, "abort then interrupt!"
157
+ else
158
+ raise exception, "abort then interrupt!"
159
+ end
160
+ end
161
+
162
+ #
163
+ # irb interpreter main routine
164
+ #
165
+ class Irb
166
+ def initialize(workspace = nil, input_method = StdioInputMethod.new , output_method = nil)
167
+
168
+ # input_method is hard to override
169
+
170
+ @context = Context.new(self, workspace, input_method, output_method)
171
+ @context.main.extend ExtendCommandBundle
172
+ @signal_status = :IN_IRB
173
+
174
+ @scanner = RubyLex.new
175
+ @scanner.exception_on_syntax_error = false
176
+
177
+ @outfile = File.open($outfile, 'w')
178
+ $stderr = @outfile
179
+ $stdout = @outfile
180
+ end
181
+ attr_reader :context
182
+ attr_accessor :scanner
183
+
184
+ def eval_input
185
+ @scanner.set_prompt do
186
+ |ltype, indent, continue, line_no|
187
+ if ltype
188
+ f = @context.prompt_s
189
+ elsif continue
190
+ f = @context.prompt_c
191
+ elsif indent > 0
192
+ f = @context.prompt_n
193
+ else
194
+ f = @context.prompt_i
195
+ end
196
+ f = "" unless f
197
+ if @context.prompting?
198
+ @context.io.prompt = p = prompt(f, ltype, indent, line_no)
199
+ else
200
+ @context.io.prompt = p = ""
201
+ end
202
+ if @context.auto_indent_mode
203
+ unless ltype
204
+ ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
205
+ indent * 2 - p.size
206
+ ind += 2 if continue
207
+ @context.io.prompt = p + " " * ind if ind > 0
208
+ end
209
+ end
210
+ end
211
+
212
+ # puts @context.io.inspect
213
+ fd = IO.sysopen($infifo)
214
+ @newio = IO.new(fd)
215
+ @context.io.instance_variable_set(:@stdin, @newio)
216
+ #@context.io.instance_variable_set(:@stdout, @outfile)
217
+
218
+ @scanner.set_input(@context.io) do
219
+ signal_status(:IN_INPUT) do
220
+
221
+ if @newio.nil? || @newio.eof?
222
+ fd = IO.sysopen($infifo)
223
+ @newio = IO.new(fd)
224
+ @context.io.instance_variable_set(:@stdin, @newio)
225
+ end
226
+
227
+ if l = @context.io.gets
228
+ print l if @context.verbose?
229
+ else
230
+ if @context.ignore_eof? and @context.io.readable_after_eof?
231
+ l = "\n"
232
+ if @context.verbose?
233
+ printf "Use \"exit\" to leave %s\n", @context.ap_name
234
+ end
235
+ else
236
+ print "\n"
237
+ end
238
+ end
239
+ l
240
+ end
241
+ end
242
+
243
+ @scanner.each_top_level_statement do |line, line_no|
244
+ signal_status(:IN_EVAL) do
245
+ begin
246
+ line.untaint
247
+
248
+ # This is to handle puts etc which print to stdout instead
249
+ # of returning a value
250
+ stringio = StringIO.new
251
+ $stdout = stringio
252
+ @context.evaluate(line, line_no)
253
+ $stdout = @outfile
254
+
255
+ stringio.rewind
256
+ print stringio.read
257
+ output_value if @context.echo?
258
+
259
+ exc = nil
260
+ rescue Interrupt => exc
261
+ rescue SystemExit, SignalException
262
+ raise
263
+ rescue Exception => exc
264
+ end
265
+ if exc
266
+ print exc.class, ": ", exc, "\n"
267
+ if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ &&
268
+ !(SyntaxError === exc)
269
+ irb_bug = true
270
+ else
271
+ irb_bug = false
272
+ end
273
+
274
+ messages = []
275
+ lasts = []
276
+ levels = 0
277
+ for m in exc.backtrace
278
+ m = @context.workspace.filter_backtrace(m) unless irb_bug
279
+ if m
280
+ if messages.size < @context.back_trace_limit
281
+ messages.push "\tfrom "+m
282
+ else
283
+ lasts.push "\tfrom "+m
284
+ if lasts.size > @context.back_trace_limit
285
+ lasts.shift
286
+ levels += 1
287
+ end
288
+ end
289
+ end
290
+ end
291
+ print messages.join("\n"), "\n"
292
+ unless lasts.empty?
293
+ printf "... %d levels...\n", levels if levels > 0
294
+ print lasts.join("\n")
295
+ end
296
+ print "Maybe IRB bug!\n" if irb_bug
297
+ end
298
+ if $SAFE > 2
299
+ abort "Error: irb does not work for $SAFE level higher than 2"
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ # DANCHOI
306
+ def print *s
307
+ @outfile.print *s
308
+ @outfile.flush
309
+ end
310
+
311
+ def suspend_name(path = nil, name = nil)
312
+ @context.irb_path, back_path = path, @context.irb_path if path
313
+ @context.irb_name, back_name = name, @context.irb_name if name
314
+ begin
315
+ yield back_path, back_name
316
+ ensure
317
+ @context.irb_path = back_path if path
318
+ @context.irb_name = back_name if name
319
+ end
320
+ end
321
+
322
+ def suspend_workspace(workspace)
323
+ @context.workspace, back_workspace = workspace, @context.workspace
324
+ begin
325
+ yield back_workspace
326
+ ensure
327
+ @context.workspace = back_workspace
328
+ end
329
+ end
330
+
331
+ def suspend_input_method(input_method)
332
+ back_io = @context.io
333
+ @context.instance_eval{@io = input_method}
334
+ begin
335
+ yield back_io
336
+ ensure
337
+ @context.instance_eval{@io = back_io}
338
+ end
339
+ end
340
+
341
+ def suspend_context(context)
342
+ @context, back_context = context, @context
343
+ begin
344
+ yield back_context
345
+ ensure
346
+ @context = back_context
347
+ end
348
+ end
349
+
350
+ def signal_handle
351
+ unless @context.ignore_sigint?
352
+ print "\nabort!\n" if @context.verbose?
353
+ exit
354
+ end
355
+
356
+ case @signal_status
357
+ when :IN_INPUT
358
+ print "^C\n"
359
+ raise RubyLex::TerminateLineInput
360
+ when :IN_EVAL
361
+ IRB.irb_abort(self)
362
+ when :IN_LOAD
363
+ IRB.irb_abort(self, LoadAbort)
364
+ when :IN_IRB
365
+ # ignore
366
+ else
367
+ # ignore other cases as well
368
+ end
369
+ end
370
+
371
+ def signal_status(status)
372
+ return yield if @signal_status == :IN_LOAD
373
+
374
+ signal_status_back = @signal_status
375
+ @signal_status = status
376
+ begin
377
+ yield
378
+ ensure
379
+ @signal_status = signal_status_back
380
+ end
381
+ end
382
+
383
+ def prompt(prompt, ltype, indent, line_no)
384
+ p = prompt.dup
385
+ p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
386
+ case $2
387
+ when "N"
388
+ @context.irb_name
389
+ when "m"
390
+ @context.main.to_s
391
+ when "M"
392
+ @context.main.inspect
393
+ when "l"
394
+ ltype
395
+ when "i"
396
+ if $1
397
+ format("%" + $1 + "d", indent)
398
+ else
399
+ indent.to_s
400
+ end
401
+ when "n"
402
+ if $1
403
+ format("%" + $1 + "d", line_no)
404
+ else
405
+ line_no.to_s
406
+ end
407
+ when "%"
408
+ "%"
409
+ end
410
+ end
411
+ p
412
+ end
413
+
414
+ def output_value
415
+ # printf @context.return_format, @context.inspect_last_value
416
+ r = sprintf @context.return_format, @context.inspect_last_value
417
+ print r
418
+ end
419
+
420
+ def inspect
421
+ ary = []
422
+ for iv in instance_variables
423
+ case (iv = iv.to_s)
424
+ when "@signal_status"
425
+ ary.push format("%s=:%s", iv, @signal_status.id2name)
426
+ when "@context"
427
+ ary.push format("%s=%s", iv, eval(iv).__to_s__)
428
+ else
429
+ ary.push format("%s=%s", iv, eval(iv))
430
+ end
431
+ end
432
+ format("#<%s: %s>", self.class, ary.join(", "))
433
+ end
434
+ end
435
+
436
+ # Singleton method
437
+ def @CONF.inspect
438
+ IRB.version unless self[:VERSION]
439
+
440
+ array = []
441
+ for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
442
+ case k
443
+ when :MAIN_CONTEXT, :__TMP__EHV__
444
+ array.push format("CONF[:%s]=...myself...", k.id2name)
445
+ when :PROMPT
446
+ s = v.collect{
447
+ |kk, vv|
448
+ ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
449
+ format(":%s=>{%s}", kk.id2name, ss.join(", "))
450
+ }
451
+ array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
452
+ else
453
+ array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
454
+ end
455
+ end
456
+ array.join("\n")
457
+ end
458
+ end
459
+
data/lib/virb/pry.rb ADDED
@@ -0,0 +1,81 @@
1
+ `rm -rf .virb`
2
+ `mkdir -p .virb`
3
+ unless File.exist?('.virb/fifo')
4
+ `mkfifo .virb/fifo`
5
+ end
6
+ `touch .virb/session`
7
+
8
+ module Virb
9
+ class Pry
10
+ class Fifo
11
+ def initialize
12
+ reinit_fifo
13
+ end
14
+ def reinit_fifo
15
+ fd = IO.sysopen(".virb/fifo")
16
+ @io = IO.new(fd, 'r')
17
+ end
18
+ def readline(current_prompt)
19
+ $stdout.print current_prompt
20
+ if @io.eof?
21
+ reinit_fifo
22
+ end
23
+ x = @io.gets
24
+ $stdout.print x
25
+ x
26
+ end
27
+ def rewind
28
+ end
29
+ end
30
+
31
+ # fakes a tty stdout
32
+ class Output
33
+ def initialize
34
+ @out = File.open(".virb/session", "w")
35
+ @out.sync = true
36
+ end
37
+ def print s
38
+ @out.print s
39
+ end
40
+ def puts s
41
+ @out.puts s
42
+ end
43
+ def write s
44
+ @out.write s
45
+ end
46
+ def flush
47
+ @out.flush
48
+ end
49
+ def tty?
50
+ true
51
+ end
52
+ end
53
+
54
+ def self.start
55
+ pgid = Process.getpgid(Process.pid())
56
+
57
+ pid = fork do
58
+ ENV['TERM'] = 'dumb'
59
+ require 'pry'
60
+
61
+ out = Virb::Pry::Output.new
62
+ $stdout = out
63
+ $stderr = out
64
+
65
+ ::Pry.cli = true
66
+ ::Pry.color = false
67
+ ::Pry.config.pager = false
68
+ ::Pry.config.print = ::Pry::SIMPLE_PRINT
69
+ ::Pry.config.auto_indent = false # turns off ansi control escape sequences
70
+ input = Fifo.new
71
+ ::Pry.input = input
72
+ ::Pry.config.output = out
73
+ ::Pry.start(TOPLEVEL_BINDING.eval('self'))
74
+ end
75
+
76
+ args = ARGV.dup
77
+ vimscript = File.join(File.dirname(__FILE__), '..', 'virb.vim')
78
+ exec("vim -S #{vimscript} #{args.join(' ')} && rm -rf .virb && kill 0")
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,205 @@
1
+ module PryRails
2
+ Commands = Pry::CommandSet.new do
3
+ create_command "show-routes", "Print out all defined routes in match order, with names." do
4
+ group "Rails"
5
+
6
+ def options(opt)
7
+ opt.banner unindent <<-USAGE
8
+ Usage: show-routes [-G]
9
+
10
+ show-routes displays the current Rails app's routes.
11
+ USAGE
12
+
13
+ opt.on :G, "grep", "Filter output by regular expression", :argument => true
14
+ end
15
+
16
+ def process
17
+ Rails.application.reload_routes!
18
+ all_routes = Rails.application.routes.routes
19
+
20
+ all_routes = begin
21
+ begin
22
+ # rails 4
23
+ require 'action_dispatch/routing/inspector'
24
+ inspector = ActionDispatch::Routing::RoutesInspector.new
25
+ rescue LoadError => e
26
+ # rails 3.2
27
+ require 'rails/application/route_inspector'
28
+ inspector = Rails::Application::RouteInspector.new
29
+ end
30
+ inspector.format(all_routes)
31
+ rescue LoadError => e
32
+ # rails 3.0 and 3.1. cribbed from
33
+ # https://github.com/rails/rails/blob/3-1-stable/railties/lib/rails/tasks/routes.rake
34
+ routes = all_routes.collect do |route|
35
+
36
+ reqs = route.requirements.dup
37
+ reqs[:to] = route.app unless route.app.class.name.to_s =~ /^ActionDispatch::Routing/
38
+ reqs = reqs.empty? ? "" : reqs.inspect
39
+
40
+ {:name => route.name.to_s, :verb => route.verb.to_s, :path => route.path, :reqs => reqs}
41
+ end
42
+
43
+ # Skip the route if it's internal info route
44
+ routes.reject! { |r| r[:path] =~ %r{/rails/info/properties|^/assets} }
45
+
46
+ name_width = routes.map{ |r| r[:name].length }.max
47
+ verb_width = routes.map{ |r| r[:verb].length }.max
48
+ path_width = routes.map{ |r| r[:path].length }.max
49
+
50
+ routes.map do |r|
51
+ "#{r[:name].rjust(name_width)} #{r[:verb].ljust(verb_width)} #{r[:path].ljust(path_width)} #{r[:reqs]}"
52
+ end
53
+ end
54
+
55
+ output.puts all_routes.grep(Regexp.new(opts[:G] || ".")).join "\n"
56
+ end
57
+ end
58
+
59
+ create_command "show-models", "Print out all defined models, with attribrutes." do
60
+ group "Rails"
61
+
62
+ def options(opt)
63
+ opt.banner unindent <<-USAGE
64
+ Usage: show-models
65
+
66
+ show-models displays the current Rails app's models.
67
+ USAGE
68
+
69
+ opt.on :G, "grep", "Color output red by regular expression", :argument => true
70
+ end
71
+
72
+ def process
73
+ Rails.application.eager_load!
74
+
75
+ if defined?(ActiveRecord::Base)
76
+ models = ActiveRecord::Base.descendants.map do |mod|
77
+ model_string = mod.to_s + "\n"
78
+ if mod.table_exists?
79
+ model_string << mod.columns.map { |col| " #{col.name}: #{col.type.to_s}" }.join("\n")
80
+ else
81
+ model_string << " Table doesn't exist"
82
+ end
83
+ mod.reflections.each do |model,ref|
84
+ model_string << "\n #{ref.macro.to_s} #{model}"
85
+ model_string << " through #{ref.options[:through]}" unless ref.options[:through].nil?
86
+ end
87
+ model_string
88
+ end.join("\n")
89
+ elsif defined?(Mongoid::Document)
90
+ models = get_files.map do |path|
91
+ mod = extract_class_name(path)
92
+ model_string = "\033[1;34m#{mod.to_s}\033[0m\n"
93
+ begin
94
+ if mod.constantize.included_modules.include?(Mongoid::Document)
95
+ model_string << mod.constantize.fields.values.sort_by(&:name).map { |col|
96
+ " #{col.name}: \033[1;33m#{col.options[:type].to_s.downcase}\033[0m"
97
+ }.join("\n")
98
+ mod.constantize.relations.each do |model,ref|
99
+ model_string << "\n #{kind_of_relation(ref.relation.to_s)} \033[1;34m#{model}\033[0m"
100
+ model_string << ", autosave" if ref.options[:autosave]
101
+ model_string << ", autobuild" if ref.options[:autobuild]
102
+ model_string << ", validate" if ref.options[:validate]
103
+ model_string << ", dependent-#{ref.options[:dependent]}" if ref.options[:dependent]
104
+ end
105
+ else
106
+ model_string << " Collection doesn't exist"
107
+ end
108
+ model_string
109
+
110
+ rescue Exception
111
+ STDERR.puts "Warning: exception #{$!} raised while trying to load model class #{path}"
112
+ end
113
+ end.join("\n")
114
+ end
115
+
116
+ models.gsub!(Regexp.new(opts[:G] || ".", Regexp::IGNORECASE)) { |s| text.red(s) } unless opts[:G].nil?
117
+ output.puts models
118
+ end
119
+
120
+ def get_files(prefix ='')
121
+ Dir.glob(prefix << "app/models/**/*.rb")
122
+ end
123
+
124
+ def extract_class_name(filename)
125
+ filename.split('/')[2..-1].collect { |i| i.camelize }.join('::').chomp(".rb")
126
+ end
127
+
128
+ def kind_of_relation(string)
129
+ case string.gsub('Mongoid::Relations::', '')
130
+ when 'Referenced::Many' then 'has_many'
131
+ when 'Referenced::One' then 'has_one'
132
+ when 'Referenced::In' then 'belongs_to'
133
+ when 'Embedded::Many' then 'embeds_many'
134
+ when 'Embedded::One' then 'embeds_one'
135
+ when 'Embedded::In' then 'embedded_in'
136
+ end
137
+ end
138
+ end
139
+
140
+ create_command "show-middleware" do
141
+ group "Rails"
142
+
143
+ def options(opt)
144
+ opt.banner unindent <<-USAGE
145
+ Usage: show-middleware [-G]
146
+
147
+ show-middleware shows the Rails app's middleware.
148
+
149
+ If this pry REPL is attached to a Rails server, the entire middleware
150
+ stack is displayed. Otherwise, only the middleware Rails knows about is
151
+ printed.
152
+ USAGE
153
+
154
+ opt.on :G, "grep", "Filter output by regular expression", :argument => true
155
+ end
156
+
157
+ def process
158
+ # assumes there is only one Rack::Server instance
159
+ server = nil
160
+ ObjectSpace.each_object(Rack::Server) do |object|
161
+ server = object
162
+ end
163
+
164
+ middlewares = []
165
+
166
+ if server
167
+ stack = server.instance_variable_get("@wrapped_app")
168
+ middlewares << stack.class.to_s
169
+
170
+ while stack.instance_variable_defined?("@app") do
171
+ stack = stack.instance_variable_get("@app")
172
+ # Rails 3.0 uses the Application class rather than the application
173
+ # instance itself, so we grab the instance.
174
+ stack = Rails.application if stack == Rails.application.class
175
+ middlewares << stack.class.to_s if stack != Rails.application
176
+ end
177
+ else
178
+ middleware_names = Rails.application.middleware.map do |middleware|
179
+ # After Rails 3.0, the middleware are wrapped in a special class
180
+ # that responds to #name.
181
+ if middleware.respond_to?(:name)
182
+ middleware.name
183
+ else
184
+ middleware.inspect
185
+ end
186
+ end
187
+ middlewares.concat middleware_names
188
+ end
189
+ middlewares << Rails.application.class.to_s
190
+ print_middleware middlewares.grep(Regexp.new(opts[:G] || "."))
191
+ end
192
+
193
+ def print_middleware(middlewares)
194
+ middlewares.each do |middleware|
195
+ string = if middleware == Rails.application.class.to_s
196
+ "run #{middleware}.routes"
197
+ else
198
+ "use #{middleware}"
199
+ end
200
+ output.puts string
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ module Virb
4
+ class Railtie < Rails::Railtie
5
+ if ENV['VIRB'] == 'pry'
6
+ require 'pry'
7
+ require 'virb/pry'
8
+ console do
9
+ if Rails::VERSION::MAJOR == 3
10
+ Rails::Console::IRB = Virb::Pry
11
+ unless defined? Virb::Pry::ExtendCommandBundle
12
+ Virb::Pry::ExtendCommandBundle = Module.new
13
+ end
14
+ end
15
+ if Rails::VERSION::MAJOR == 4
16
+ Rails.application.config.console = Virb::Pry
17
+ end
18
+
19
+ if (Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR >= 2) || Rails::VERSION::MAJOR == 4
20
+ require 'rails/console/app'
21
+ require 'rails/console/helpers'
22
+ TOPLEVEL_BINDING.eval('self').extend ::Rails::ConsoleMethods
23
+ end
24
+ end
25
+ require "virb/pry_commands"
26
+ ::Pry.commands.import PryRails::Commands
27
+
28
+ # do this to prevent the sql output from going to vim interactive buffer
29
+ STDERR.reopen("/dev/null")
30
+
31
+ else
32
+ require 'virb/default'
33
+ console do
34
+ if Rails::VERSION::MAJOR == 3
35
+ Rails::Console::IRB = IRB
36
+ end
37
+ if Rails::VERSION::MAJOR == 4
38
+ Rails.application.config.console = IRB
39
+ end
40
+
41
+ if (Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR >= 2) || Rails::VERSION::MAJOR == 4
42
+ require 'rails/console/app'
43
+ require 'rails/console/helpers'
44
+ TOPLEVEL_BINDING.eval('self').extend ::Rails::ConsoleMethods
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Virb
2
+ VERSION = '0.0.2'
3
+ end
data/lib/virb.rb ADDED
@@ -0,0 +1,6 @@
1
+
2
+
3
+ if defined?(Rails)
4
+ require 'virb/railtie'
5
+ end
6
+
data/lib/virb.vim ADDED
@@ -0,0 +1,84 @@
1
+ "=================================================
2
+ " File: virb.vim
3
+ " Description: A Vim shell for irb and rails console
4
+ " Author: Daniel Choi <dhchoi@gmail.com>
5
+ " ================================================
6
+
7
+ if exists("g:loaded_virb") || &cp
8
+ finish
9
+ endif
10
+ let g:loaded_virb = 1
11
+
12
+ let s:fifo = ".virb/fifo"
13
+
14
+ " split into two windows: a session buffer and a interactive buffer
15
+
16
+ function! s:focus_virb_output_window()
17
+ if bufwinnr(s:virb_output_bufnr) == winnr()
18
+ return
19
+ end
20
+ let winnr = bufwinnr(s:virb_output_bufnr)
21
+ if winnr == -1
22
+ " create window
23
+ split! .virb/session
24
+ exec "buffer" . s:virb_output_bufnr
25
+ else
26
+ exec winnr . "wincmd w"
27
+ endif
28
+ endfunc
29
+
30
+ function! VirbStatusLine()
31
+ let line = "%<*virb interactive buffer* %r%=%-14.(%l,%c%V%)\ %P"
32
+ return line
33
+ endfunc
34
+
35
+ split! .virb/session
36
+ setlocal autoread
37
+ let s:virb_output_bufnr = bufnr('%')
38
+ setlocal nomodifiable
39
+ setlocal nu
40
+
41
+ " in interactive buffer
42
+ wincmd p
43
+ setlocal nu
44
+ setlocal statusline=%!VirbStatusLine()
45
+ command! -bar -range Virb :<line1>,<line2>call Virb()
46
+
47
+ " main execution function
48
+ func! Virb() range
49
+ let s:mtime = getftime(".virb/session")
50
+ let cmd = ":".a:firstline.",".a:lastline."w >> .virb/fifo"
51
+ exec cmd
52
+ if $VIRB == 'pry'
53
+ " a little slower
54
+ :sleep 600m
55
+ else
56
+ :sleep 400m
57
+ endif
58
+ :call VirbRefresh()
59
+ endfunc
60
+
61
+ func! VirbRefresh()
62
+ :call s:focus_virb_output_window()
63
+ ":exec ":checktime ".s:virb_output_bufnr
64
+ :e!
65
+ :normal G
66
+ syn match irbprompt /^irb\S\+\(>\|\*\).*$/
67
+ " [2] pry(main)>
68
+ syn match irbprompt /^\[\d\+\] pry.*$/
69
+ hi def link irbprompt Comment
70
+ :wincmd p
71
+ endfunc
72
+
73
+ if !hasmapto('<Plug>VirbRun')
74
+ " this is global
75
+ nnoremap <cr> :call Virb()<cr>
76
+ vnoremap <cr> :call Virb()<cr>
77
+ endif
78
+
79
+ if !hasmapto('<Plug>VirbRefresh')
80
+ " this is global
81
+ nnoremap <space> :checkt<CR>
82
+ endif
83
+
84
+
data/notes ADDED
@@ -0,0 +1,42 @@
1
+ todo
2
+ - Virb command
3
+
4
+
5
+ Pry
6
+
7
+
8
+ See pry.rb for start of Pry integration
9
+
10
+
11
+ def redirect_pry_io(new_in, new_out = StringIO.new)
12
+ old_in = Pry.input
13
+ old_out = Pry.output
14
+
15
+ Pry.input = new_in
16
+ Pry.output = new_out
17
+ begin
18
+ yield
19
+ ensure
20
+ Pry.input = old_in
21
+ Pry.output = old_out
22
+ end
23
+ end
24
+
25
+ InputTester.new("exit-all")
26
+
27
+
28
+
29
+ class InputTester
30
+ def initialize(*actions)
31
+ @orig_actions = actions.dup
32
+ @actions = actions
33
+ end
34
+
35
+ def readline(*)
36
+ @actions.shift
37
+ end
38
+
39
+ def rewind
40
+ @actions = @orig_actions.dup
41
+ end
42
+ end
data/virb.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require 'virb/version'
5
+ Gem::Specification.new do |s|
6
+ s.name = "virb"
7
+ s.version = Virb::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.required_ruby_version = '>= 1.9.0'
10
+
11
+ s.authors = ["Daniel Choi"]
12
+ s.email = ["dhchoi@gmail.com"]
13
+ s.homepage = "http://danielchoi.com/software/virb.html"
14
+ s.summary = %q{A Vim shell for irb and rails console}
15
+ s.description = %q{A Vim shell for irb and rails console}
16
+
17
+ s.rubyforge_project = "virb"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.executables = ['virb', 'virb-pry']
21
+ # s.require_paths = ["lib"]
22
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: virb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Choi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-24 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A Vim shell for irb and rails console
15
+ email:
16
+ - dhchoi@gmail.com
17
+ executables:
18
+ - virb
19
+ - virb-pry
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - README.md
25
+ - Rakefile
26
+ - bin/virb
27
+ - bin/virb-pry
28
+ - images/virb1.png
29
+ - images/virb2.png
30
+ - images/virb3.png
31
+ - lib/virb.rb
32
+ - lib/virb.vim
33
+ - lib/virb/default.rb
34
+ - lib/virb/pry.rb
35
+ - lib/virb/pry_commands.rb
36
+ - lib/virb/railtie.rb
37
+ - lib/virb/version.rb
38
+ - notes
39
+ - virb.gemspec
40
+ homepage: http://danielchoi.com/software/virb.html
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: 1.9.0
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project: virb
60
+ rubygems_version: 1.8.23
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: A Vim shell for irb and rails console
64
+ test_files: []