diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/irb/xmp.rb |
Fresh start
Diffstat (limited to 'jni/ruby/lib/irb/xmp.rb')
-rw-r--r-- | jni/ruby/lib/irb/xmp.rb | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/jni/ruby/lib/irb/xmp.rb b/jni/ruby/lib/irb/xmp.rb new file mode 100644 index 0000000..395a562 --- /dev/null +++ b/jni/ruby/lib/irb/xmp.rb @@ -0,0 +1,169 @@ +# +# xmp.rb - irb version of gotoken xmp +# $Release Version: 0.9$ +# $Revision: 47266 $ +# by Keiju ISHITSUKA(Nippon Rational Inc.) +# +# -- +# +# +# + +require "irb" +require "irb/frame" + +# An example printer for irb. +# +# It's much like the standard library PrettyPrint, that shows the value of each +# expression as it runs. +# +# In order to use this library, you must first require it: +# +# require 'irb/xmp' +# +# Now, you can take advantage of the Object#xmp convenience method. +# +# xmp <<END +# foo = "bar" +# baz = 42 +# END +# #=> foo = "bar" +# #==>"bar" +# #=> baz = 42 +# #==>42 +# +# You can also create an XMP object, with an optional binding to print +# expressions in the given binding: +# +# ctx = binding +# x = XMP.new ctx +# x.puts +# #=> today = "a good day" +# #==>"a good day" +# ctx.eval 'today # is what?' +# #=> "a good day" +class XMP + + # Creates a new XMP object. + # + # The top-level binding or, optional +bind+ parameter will be used when + # creating the workspace. See WorkSpace.new for more information. + # + # This uses the +:XMP+ prompt mode, see IRB@Customizing+the+IRB+Prompt for + # full detail. + def initialize(bind = nil) + IRB.init_config(nil) + + IRB.conf[:PROMPT_MODE] = :XMP + + bind = IRB::Frame.top(1) unless bind + ws = IRB::WorkSpace.new(bind) + @io = StringInputMethod.new + @irb = IRB::Irb.new(ws, @io) + @irb.context.ignore_sigint = false + + IRB.conf[:MAIN_CONTEXT] = @irb.context + end + + # Evaluates the given +exps+, for example: + # + # require 'irb/xmp' + # x = XMP.new + # + # x.puts '{:a => 1, :b => 2, :c => 3}' + # #=> {:a => 1, :b => 2, :c => 3} + # # ==>{:a=>1, :b=>2, :c=>3} + # x.puts 'foo = "bar"' + # # => foo = "bar" + # # ==>"bar" + def puts(exps) + @io.puts exps + + if @irb.context.ignore_sigint + begin + trap_proc_b = trap("SIGINT"){@irb.signal_handle} + catch(:IRB_EXIT) do + @irb.eval_input + end + ensure + trap("SIGINT", trap_proc_b) + end + else + catch(:IRB_EXIT) do + @irb.eval_input + end + end + end + + # A custom InputMethod class used by XMP for evaluating string io. + class StringInputMethod < IRB::InputMethod + # Creates a new StringInputMethod object + def initialize + super + @exps = [] + end + + # Whether there are any expressions left in this printer. + def eof? + @exps.empty? + end + + # Reads the next expression from this printer. + # + # See IO#gets for more information. + def gets + while l = @exps.shift + next if /^\s+$/ =~ l + l.concat "\n" + print @prompt, l + break + end + l + end + + # Concatenates all expressions in this printer, separated by newlines. + # + # An Encoding::CompatibilityError is raised of the given +exps+'s encoding + # doesn't match the previous expression evaluated. + def puts(exps) + if @encoding and exps.encoding != @encoding + enc = Encoding.compatible?(@exps.join("\n"), exps) + if enc.nil? + raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one" + else + @encoding = enc + end + else + @encoding = exps.encoding + end + @exps.concat exps.split(/\n/) + end + + # Returns the encoding of last expression printed by #puts. + attr_reader :encoding + end +end + +# A convenience method that's only available when the you require the IRB::XMP standard library. +# +# Creates a new XMP object, using the given expressions as the +exps+ +# parameter, and optional binding as +bind+ or uses the top-level binding. Then +# evaluates the given expressions using the +:XMP+ prompt mode. +# +# For example: +# +# require 'irb/xmp' +# ctx = binding +# xmp 'foo = "bar"', ctx +# #=> foo = "bar" +# #==>"bar" +# ctx.eval 'foo' +# #=> "bar" +# +# See XMP.new for more information. +def xmp(exps, bind = nil) + bind = IRB::Frame.top(1) unless bind + xmp = XMP.new(bind) + xmp.puts exps + xmp +end |