#!/usr/bin/env ruby require 'reline' require 'optparse' require_relative 'termination_checker' opt = OptionParser.new opt.on('--prompt-list-cache-timeout VAL') { |v| Reline::LineEditor.__send__(:remove_const, :PROMPT_LIST_CACHE_TIMEOUT) Reline::LineEditor::PROMPT_LIST_CACHE_TIMEOUT = v.to_f } opt.on('--dynamic-prompt') { Reline.prompt_proc = proc { |lines| lines.each_with_index.map { |l, i| '[%04d]> ' % i } } } opt.on('--broken-dynamic-prompt') { Reline.prompt_proc = proc { |lines| range = lines.size > 1 ? (0..(lines.size - 2)) : (0..0) lines[range].each_with_index.map { |l, i| '[%04d]> ' % i } } } opt.on('--dynamic-prompt-returns-empty') { Reline.prompt_proc = proc { |l| [] } } opt.on('--auto-indent') { AutoIndent.new } opt.on('--simple-dialog') { Reline.add_dialog_proc(:simple_dialog, lambda { contents = <<~RUBY.split("\n") Ruby is... A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. RUBY Reline::DialogRenderInfo.new(pos: cursor_pos, contents: contents) }) } opt.on('--complete') { Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| %w{String ScriptError SyntaxError Signal} } } opt.on('--autocomplete') { Reline.autocompletion = true Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| %w{String Struct Symbol ScriptError SyntaxError Signal} } } opt.on('--autocomplete-long') { Reline.autocompletion = true Reline.completion_proc = lambda { |target, preposing = nil, postposing = nil| %w{String Struct Symbol StopIteration SystemCallError SystemExit SystemStackError ScriptError SyntaxError Signal SizedQueue Set SecureRandom Socket StringIO StringScanner Shellwords Syslog Singleton SDBM} } } opt.parse!(ARGV) begin stty_save = `stty -g`.chomp rescue end begin prompt = ENV['RELINE_TEST_PROMPT'] || 'prompt> ' puts 'Multiline REPL.' checker = TerminationChecker.new while code = Reline.readmultiline(prompt, true) { |code| checker.terminated?(code) } case code.chomp when 'exit', 'quit', 'q' exit 0 when '' # NOOP else begin result = eval(code) puts "=> #{result.inspect}" rescue ScriptError, StandardError => e puts "Traceback (most recent call last):" e.backtrace.reverse_each do |f| puts " #{f}" end puts e.message end end end rescue Interrupt puts '^C' `stty #{stty_save}` if stty_save exit 0 ensure `stty #{stty_save}` if stty_save end begin puts rescue Errno::EIO # Maybe the I/O has been closed. end