1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/lib/reline.rb
aycabta cafa7904e7
Backport lib/reline, and lib/irb for 3.0.1 4th (#4349)
* [ruby/irb] Update help message for next context-mode of 4

While here, fixing tab/space issues in help message, and sync
rdoc for IRB class to match the help message.

https://github.com/ruby/irb/commit/ef8e3901cc

* [ruby/irb] Do not continue line if last expression is an endless range

Fixes [Bug #14824]

https://github.com/ruby/irb/commit/63414f8465

* [ruby/irb] Add a test for not continuing when endless range at eol

https://github.com/ruby/irb/commit/1020ac9c65

* [ruby/irb] Make save-history extension safe for concurrent use

This makes the save-history extension check for modifications to
the history file before saving it.  If the history file was modified
after the history was loaded and before it was saved, append only
the new history lines to the history file.

This can result in more lines in the history file than SAVE_HISTORY
allows.  However, that will be fixed the next time irb is run and
the history is saved.

Fixes [Bug #13654]

https://github.com/ruby/irb/commit/041ef53845

* Fix errors when XDG_CONFIG_HOME points to non-writable directory

`$HOME/.config` is not writable on CI
because I think tests should not corrupt user's data.

And GitHub Actions CI sets `XDG_CONFIG_HOME`
since `Version: 20210309.1`.

https://github.com/ruby/actions/runs/2130811016?check_suite_focus=true#step:16:301
```
Errno::EACCES: Permission denied @ dir_s_mkdir - /home/runner/.config/irb
```

* Try to fix errors in TestIRB::TestHistory too

https://github.com/ruby/actions/runs/2137935523?check_suite_focus=true#step:9:562
```
  1) Error:
TestIRB::TestHistory#test_history_concurrent_use:
Errno::EACCES: Permission denied @ dir_s_mkdir - /home/runner/.config/irb
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:253:in `mkdir'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:253:in `fu_mkdir'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:231:in `block (2 levels) in mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:229:in `reverse_each'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:229:in `block in mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:211:in `each'
    /home/runner/work/actions/actions/ruby/lib/fileutils.rb:211:in `mkdir_p'
    /home/runner/work/actions/actions/ruby/lib/irb/init.rb:355:in `rc_file_generators'
    /home/runner/work/actions/actions/ruby/lib/irb/init.rb:330:in `rc_file'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:170:in `block in assert_history'
    /home/runner/work/actions/actions/ruby/lib/tmpdir.rb:96:in `mktmpdir'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:168:in `assert_history'
    /home/runner/work/actions/actions/ruby/test/irb/test_history.rb:133:in `test_history_concurrent_use'
```

* [ruby/irb] Define "measure" command without forced override

https://github.com/ruby/irb/commit/9587ba13b5

* [ruby/irb] Add all lib files automatically

https://github.com/ruby/irb/commit/ecc82336b7

* [ruby/irb] Don't call Ruby 2.4+'s String#pretty_print

https://github.com/ruby/irb/commit/89bcf107be

* [ruby/irb] Implement ls command

https://github.com/ruby/irb/commit/19b6c20604

* [ruby/irb] Add whereami command

https://github.com/ruby/irb/commit/bc822e4aac

* [ruby/irb] Fix column overflow on ls output

https://github.com/ruby/irb/commit/6115754623

* [ruby/irb] Fix step's argument

cols.size was calling Integer#size, which returns 8.

Fixing a bug of https://github.com/ruby/irb/pull/209

https://github.com/ruby/irb/commit/c93ae4be71

* [ruby/irb] Deal with different screen sizes

e.g. http://rubyci.s3.amazonaws.com/centos8/ruby-master/log/20210321T063003Z.fail.html.gz

https://github.com/ruby/irb/commit/ddb3472ba2

* [ruby/irb] Have some right padding

instead of filling out an entire line

https://github.com/ruby/irb/commit/6ac8f45f5f

* Suppress verbose messages

Get rid of warnings in the parallel test.

```
unknown command: "Switch to inspect mode."
```

* [ruby/irb] Change ripper_lex_without_warning to a class method

https://github.com/ruby/irb/commit/d9f8abc17e

* [ruby/irb] Complete require and require_relative

https://github.com/ruby/irb/commit/1c61178b4c

* [ruby/reline] Add Reline.ungetc to control buffer

https://github.com/ruby/reline/commit/43ac03c624

* [ruby/reline] Reline.delete_text removes the current line in multiline

https://github.com/ruby/reline/commit/da90c094a1

* [ruby/reline] Support preposing and postposing for Reline.completion_proc

https://github.com/ruby/reline/commit/1f469de90c

* [ruby/reline] Suppress crashing when completer_{quote,word_break}_characters is empty

https://github.com/ruby/reline/commit/c6f1164942

* [ruby/irb] fix completion test when out-of-place build

* [ruby/irb] Cache completion files to require

https://github.com/ruby/irb/commit/612ebcb311

* [ruby/irb] Always add input method when calling Irb.new in tests

When passes input method as nil to Context.new through Irb.new,
ReidlineInputMethod.new is executed and the global internal state of Reline is
rewritten, therefore other tests are failed in the Ruby repository. This
commit changes to use TestInputMethod.

https://github.com/ruby/irb/commit/010dce9210

* [ruby/irb] Prevent the completion from crashing if rdoc is missing

There are cases where ruby is installed without rdoc and e.g.
lib/irb/cmd/help.rb also handles the LoadError

Here is how to replicate the issue:

```
$ docker run -it alpine:3.13.3 sh

/ # apk add ruby ruby-irb ruby-io-console

/ # irb

irb(main):001:0> Class[TAB][TAB]
```

And you end up with something like:

```
irb(main):001:0> ClassTraceback (most recent call last):
        34: from /usr/bin/irb:23:in `<main>'
        33: from /usr/bin/irb:23:in `load'
        32: from /usr/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
        31: from /usr/lib/ruby/2.7.0/irb.rb:400:in `start'
        30: from /usr/lib/ruby/2.7.0/irb.rb:471:in `run'
        29: from /usr/lib/ruby/2.7.0/irb.rb:471:in `catch'
        28: from /usr/lib/ruby/2.7.0/irb.rb:472:in `block in run'
        27: from /usr/lib/ruby/2.7.0/irb.rb:537:in `eval_input'
        26: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `each_top_level_statement'
        25: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `catch'
        24: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `block in each_top_level_statement'
        23: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:151:in `loop'
        22: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:154:in `block (2 levels) in each_top_level_statement'
        21: from /usr/lib/ruby/2.7.0/irb/ruby-lex.rb:182:in `lex'
        20: from /usr/lib/ruby/2.7.0/irb.rb:518:in `block in eval_input'
        19: from /usr/lib/ruby/2.7.0/irb.rb:704:in `signal_status'
        18: from /usr/lib/ruby/2.7.0/irb.rb:519:in `block (2 levels) in eval_input'
        17: from /usr/lib/ruby/2.7.0/irb/input-method.rb:294:in `gets'
        16: from /usr/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
        15: from /usr/lib/ruby/2.7.0/forwardable.rb:235:in `readmultiline'
        14: from /usr/lib/ruby/2.7.0/reline.rb:175:in `readmultiline'
        13: from /usr/lib/ruby/2.7.0/reline.rb:238:in `inner_readline'
        12: from /usr/lib/ruby/2.7.0/reline.rb:238:in `loop'
        11: from /usr/lib/ruby/2.7.0/reline.rb:239:in `block in inner_readline'
        10: from /usr/lib/ruby/2.7.0/reline.rb:270:in `read_io'
         9: from /usr/lib/ruby/2.7.0/reline.rb:270:in `loop'
         8: from /usr/lib/ruby/2.7.0/reline.rb:311:in `block in read_io'
         7: from /usr/lib/ruby/2.7.0/reline.rb:240:in `block (2 levels) in inner_readline'
         6: from /usr/lib/ruby/2.7.0/reline.rb:240:in `each'
         5: from /usr/lib/ruby/2.7.0/reline.rb:241:in `block (3 levels) in inner_readline'
         4: from /usr/lib/ruby/2.7.0/reline/line_editor.rb:820:in `input_key'
         3: from /usr/lib/ruby/2.7.0/reline/line_editor.rb:608:in `complete'
         2: from /usr/lib/ruby/2.7.0/irb/completion.rb:269:in `block in <module:InputCompletor>'
         1: from /usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require'
/usr/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb:92:in `require': cannot load such file -- rdoc (LoadError)
```

https://github.com/ruby/irb/commit/a2d299c2ac

* [ruby/irb] Suppress verbose messages in the parallel test

`:VERBOSE` flag needs to be set prior to `IRB::Irb.new`.

https://github.com/ruby/irb/commit/78604682d9

* [ruby/irb] SIGINT should raise Interrupt after IRB session

https://github.com/ruby/irb/commit/5832cfe75b

* [ruby/irb] Colorize `__END__` as keyword

https://github.com/ruby/irb/commit/9b84018311

* [ruby/irb] Add show_source command

https://github.com/ruby/irb/commit/108cb04352

* [ruby/reline] Reset @rest_height when clear screen

https://github.com/ruby/reline/commit/3a7019b0d5

* [ruby/irb] process multi-line pastes as a single entity

this allows pasting leading-dot chained methods correctly:

```ruby
class A
  def a; self; end
  def b; true; end
end

a = A.new

a
 .a
 .b
```

will properly return `true` instead of erroring on the `.a` line:

```
irb(main):001:1*     class A
irb(main):002:1*       def a; self; end
irb(main):003:0>     end
irb(main):004:0*
irb(main):005:0>     a = A.new
irb(main):006:0*
irb(main):007:0>     a
irb(main):008:0>      .a
irb(main):009:0>      .a
=> #<A:0x00007f984211fbe8>
```

https://github.com/ruby/irb/commit/45aeb52575

* [ruby/irb] Add yamatanooroti test example

https://github.com/ruby/irb/commit/279155fcee

* [ruby/irb] Add test for multiline paste

https://github.com/ruby/irb/commit/e93c9cb54d

* [ruby/irb] Evaluate each toplevel statement

https://github.com/ruby/irb/commit/bc1b1d8bc3

* [ruby/irb] Version 1.3.5

https://github.com/ruby/irb/commit/22e2ddf715

* [ruby/reline] Version 0.2.5

https://github.com/ruby/reline/commit/22ce5651e5

Co-authored-by: Jeremy Evans <code@jeremyevans.net>
Co-authored-by: Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Aleksandar Ivanov <aivanov92@gmail.com>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
Co-authored-by: Cody Cutrer <cody@instructure.com>
2021-04-03 18:26:46 +09:00

471 lines
14 KiB
Ruby

require 'io/console'
require 'timeout'
require 'forwardable'
require 'reline/version'
require 'reline/config'
require 'reline/key_actor'
require 'reline/key_stroke'
require 'reline/line_editor'
require 'reline/history'
require 'rbconfig'
module Reline
FILENAME_COMPLETION_PROC = nil
USERNAME_COMPLETION_PROC = nil
Key = Struct.new('Key', :char, :combined_char, :with_meta)
CursorPos = Struct.new(:x, :y)
class Core
ATTR_READER_NAMES = %i(
completion_append_character
basic_word_break_characters
completer_word_break_characters
basic_quote_characters
completer_quote_characters
filename_quote_characters
special_prefixes
completion_proc
output_modifier_proc
prompt_proc
auto_indent_proc
pre_input_hook
dig_perfect_match_proc
).each(&method(:attr_reader))
attr_accessor :config
attr_accessor :key_stroke
attr_accessor :line_editor
attr_accessor :last_incremental_search
attr_reader :output
def initialize
self.output = STDOUT
yield self
@completion_quote_character = nil
@bracketed_paste_finished = false
end
def encoding
Reline::IOGate.encoding
end
def completion_append_character=(val)
if val.nil?
@completion_append_character = nil
elsif val.size == 1
@completion_append_character = val.encode(Reline::IOGate.encoding)
elsif val.size > 1
@completion_append_character = val[0].encode(Reline::IOGate.encoding)
else
@completion_append_character = nil
end
end
def basic_word_break_characters=(v)
@basic_word_break_characters = v.encode(Reline::IOGate.encoding)
end
def completer_word_break_characters=(v)
@completer_word_break_characters = v.encode(Reline::IOGate.encoding)
end
def basic_quote_characters=(v)
@basic_quote_characters = v.encode(Reline::IOGate.encoding)
end
def completer_quote_characters=(v)
@completer_quote_characters = v.encode(Reline::IOGate.encoding)
end
def filename_quote_characters=(v)
@filename_quote_characters = v.encode(Reline::IOGate.encoding)
end
def special_prefixes=(v)
@special_prefixes = v.encode(Reline::IOGate.encoding)
end
def completion_case_fold=(v)
@config.completion_ignore_case = v
end
def completion_case_fold
@config.completion_ignore_case
end
def completion_quote_character
@completion_quote_character
end
def completion_proc=(p)
raise ArgumentError unless p.respond_to?(:call) or p.nil?
@completion_proc = p
end
def output_modifier_proc=(p)
raise ArgumentError unless p.respond_to?(:call) or p.nil?
@output_modifier_proc = p
end
def prompt_proc=(p)
raise ArgumentError unless p.respond_to?(:call) or p.nil?
@prompt_proc = p
end
def auto_indent_proc=(p)
raise ArgumentError unless p.respond_to?(:call) or p.nil?
@auto_indent_proc = p
end
def pre_input_hook=(p)
@pre_input_hook = p
end
def dig_perfect_match_proc=(p)
raise ArgumentError unless p.respond_to?(:call) or p.nil?
@dig_perfect_match_proc = p
end
def input=(val)
raise TypeError unless val.respond_to?(:getc) or val.nil?
if val.respond_to?(:getc)
if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
Reline::ANSI.input = val
elsif Reline::IOGate == Reline::GeneralIO
Reline::GeneralIO.input = val
end
end
end
def output=(val)
raise TypeError unless val.respond_to?(:write) or val.nil?
@output = val
if defined?(Reline::ANSI) and Reline::IOGate == Reline::ANSI
Reline::ANSI.output = val
end
end
def vi_editing_mode
config.editing_mode = :vi_insert
nil
end
def emacs_editing_mode
config.editing_mode = :emacs
nil
end
def vi_editing_mode?
config.editing_mode_is?(:vi_insert, :vi_command)
end
def emacs_editing_mode?
config.editing_mode_is?(:emacs)
end
def get_screen_size
Reline::IOGate.get_screen_size
end
def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
unless confirm_multiline_termination
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
end
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
whole_buffer = line_editor.whole_buffer.dup
whole_buffer.taint if RUBY_VERSION < '2.7'
if add_hist and whole_buffer and whole_buffer.chomp("\n").size > 0
Reline::HISTORY << whole_buffer
end
line_editor.reset_line if line_editor.whole_buffer.nil?
whole_buffer
end
def readline(prompt = '', add_hist = false)
inner_readline(prompt, add_hist, false)
line = line_editor.line.dup
line.taint if RUBY_VERSION < '2.7'
if add_hist and line and line.chomp("\n").size > 0
Reline::HISTORY << line.chomp("\n")
end
line_editor.reset_line if line_editor.line.nil?
line
end
private def inner_readline(prompt, add_hist, multiline, &confirm_multiline_termination)
if ENV['RELINE_STDERR_TTY']
if Reline::IOGate.win?
$stderr = File.open(ENV['RELINE_STDERR_TTY'], 'a')
else
$stderr.reopen(ENV['RELINE_STDERR_TTY'], 'w')
end
$stderr.sync = true
$stderr.puts "Reline is used by #{Process.pid}"
end
otio = Reline::IOGate.prep
may_req_ambiguous_char_width
line_editor.reset(prompt, encoding: Reline::IOGate.encoding)
if multiline
line_editor.multiline_on
if block_given?
line_editor.confirm_multiline_termination_proc = confirm_multiline_termination
end
else
line_editor.multiline_off
end
line_editor.output = output
line_editor.completion_proc = completion_proc
line_editor.completion_append_character = completion_append_character
line_editor.output_modifier_proc = output_modifier_proc
line_editor.prompt_proc = prompt_proc
line_editor.auto_indent_proc = auto_indent_proc
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
line_editor.pre_input_hook = pre_input_hook
unless config.test_mode
config.read
config.reset_default_key_bindings
Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
config.add_default_key_binding(key, func)
end
end
line_editor.rerender
begin
prev_pasting_state = false
loop do
prev_pasting_state = Reline::IOGate.in_pasting?
read_io(config.keyseq_timeout) { |inputs|
line_editor.set_pasting_state(Reline::IOGate.in_pasting?)
inputs.each { |c|
line_editor.input_key(c)
line_editor.rerender
}
if @bracketed_paste_finished
line_editor.rerender_all
@bracketed_paste_finished = false
end
}
if prev_pasting_state == true and not Reline::IOGate.in_pasting? and not line_editor.finished?
line_editor.set_pasting_state(false)
prev_pasting_state = false
line_editor.rerender_all
end
break if line_editor.finished?
end
Reline::IOGate.move_cursor_column(0)
rescue Errno::EIO
# Maybe the I/O has been closed.
rescue StandardError => e
line_editor.finalize
Reline::IOGate.deprep(otio)
raise e
end
line_editor.finalize
Reline::IOGate.deprep(otio)
end
# Keystrokes of GNU Readline will timeout it with the specification of
# "keyseq-timeout" when waiting for the 2nd character after the 1st one.
# If the 2nd character comes after 1st ESC without timeout it has a
# meta-property of meta-key to discriminate modified key with meta-key
# from multibyte characters that come with 8th bit on.
#
# GNU Readline will wait for the 2nd character with "keyseq-timeout"
# milli-seconds but wait forever after 3rd characters.
private def read_io(keyseq_timeout, &block)
buffer = []
loop do
c = Reline::IOGate.getc
if c == -1
result = :unmatched
@bracketed_paste_finished = true
else
buffer << c
result = key_stroke.match_status(buffer)
end
case result
when :matched
expanded = key_stroke.expand(buffer).map{ |expanded_c|
Reline::Key.new(expanded_c, expanded_c, false)
}
block.(expanded)
break
when :matching
if buffer.size == 1
begin
succ_c = nil
Timeout.timeout(keyseq_timeout / 1000.0) {
succ_c = Reline::IOGate.getc
}
rescue Timeout::Error # cancel matching only when first byte
block.([Reline::Key.new(c, c, false)])
break
else
if key_stroke.match_status(buffer.dup.push(succ_c)) == :unmatched
if c == "\e".ord
block.([Reline::Key.new(succ_c, succ_c | 0b10000000, true)])
else
block.([Reline::Key.new(c, c, false), Reline::Key.new(succ_c, succ_c, false)])
end
break
else
Reline::IOGate.ungetc(succ_c)
end
end
end
when :unmatched
if buffer.size == 1 and c == "\e".ord
read_escaped_key(keyseq_timeout, c, block)
else
expanded = buffer.map{ |expanded_c|
Reline::Key.new(expanded_c, expanded_c, false)
}
block.(expanded)
end
break
end
end
end
private def read_escaped_key(keyseq_timeout, c, block)
begin
escaped_c = nil
Timeout.timeout(keyseq_timeout / 1000.0) {
escaped_c = Reline::IOGate.getc
}
rescue Timeout::Error # independent ESC
block.([Reline::Key.new(c, c, false)])
else
if escaped_c.nil?
block.([Reline::Key.new(c, c, false)])
elsif escaped_c >= 128 # maybe, first byte of multi byte
block.([Reline::Key.new(c, c, false), Reline::Key.new(escaped_c, escaped_c, false)])
elsif escaped_c == "\e".ord # escape twice
block.([Reline::Key.new(c, c, false), Reline::Key.new(c, c, false)])
else
block.([Reline::Key.new(escaped_c, escaped_c | 0b10000000, true)])
end
end
end
def ambiguous_width
may_req_ambiguous_char_width unless defined? @ambiguous_width
@ambiguous_width
end
private def may_req_ambiguous_char_width
@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.is_a?(File)
return if @ambiguous_width
Reline::IOGate.move_cursor_column(0)
begin
output.write "\u{25bd}"
rescue Encoding::UndefinedConversionError
# LANG=C
@ambiguous_width = 1
else
@ambiguous_width = Reline::IOGate.cursor_pos.x
end
Reline::IOGate.move_cursor_column(0)
Reline::IOGate.erase_after_cursor
end
end
extend Forwardable
extend SingleForwardable
#--------------------------------------------------------
# Documented API
#--------------------------------------------------------
(Core::ATTR_READER_NAMES).each { |name|
def_single_delegators :core, "#{name}", "#{name}="
}
def_single_delegators :core, :input=, :output=
def_single_delegators :core, :vi_editing_mode, :emacs_editing_mode
def_single_delegators :core, :readline
def_single_delegators :core, :completion_case_fold, :completion_case_fold=
def_single_delegators :core, :completion_quote_character
def_instance_delegators self, :readline
private :readline
#--------------------------------------------------------
# Undocumented API
#--------------------------------------------------------
# Testable in original
def_single_delegators :core, :get_screen_size
def_single_delegators :line_editor, :eof?
def_instance_delegators self, :eof?
def_single_delegators :line_editor, :delete_text
def_single_delegator :line_editor, :line, :line_buffer
def_single_delegator :line_editor, :byte_pointer, :point
def_single_delegator :line_editor, :byte_pointer=, :point=
def self.insert_text(*args, &block)
line_editor.insert_text(*args, &block)
self
end
# Untestable in original
def_single_delegator :line_editor, :rerender, :redisplay
def_single_delegators :core, :vi_editing_mode?, :emacs_editing_mode?
def_single_delegators :core, :ambiguous_width
def_single_delegators :core, :last_incremental_search
def_single_delegators :core, :last_incremental_search=
def_single_delegators :core, :readmultiline
def_instance_delegators self, :readmultiline
private :readmultiline
def self.encoding_system_needs
self.core.encoding
end
def self.core
@core ||= Core.new { |core|
core.config = Reline::Config.new
core.key_stroke = Reline::KeyStroke.new(core.config)
core.line_editor = Reline::LineEditor.new(core.config, Reline::IOGate.encoding)
core.basic_word_break_characters = " \t\n`><=;|&{("
core.completer_word_break_characters = " \t\n`><=;|&{("
core.basic_quote_characters = '"\''
core.completer_quote_characters = '"\''
core.filename_quote_characters = ""
core.special_prefixes = ""
}
end
def self.ungetc(c)
Reline::IOGate.ungetc(c)
end
def self.line_editor
core.line_editor
end
end
if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/
require 'reline/windows'
if Reline::Windows.msys_tty?
require 'reline/ansi'
Reline::IOGate = Reline::ANSI
else
Reline::IOGate = Reline::Windows
end
else
require 'reline/ansi'
Reline::IOGate = Reline::ANSI
end
Reline::HISTORY = Reline::History.new(Reline.core.config)
require 'reline/general_io'