Skip to content

Commit

Permalink
Reline::ANSI is general io. Reline::GeneralIO is not.
Browse files Browse the repository at this point in the history
Reline::ANSI has a partial non-tty supporting code. It should be a general io.
Reline::GeneralIO should be renamed because it is actually not a general io but an unusable io only for test usage.
  • Loading branch information
tompng committed May 22, 2024
1 parent a5b5298 commit 2779c89
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 42 deletions.
45 changes: 15 additions & 30 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
raise ArgumentError.new('#readmultiline needs block to confirm multiline termination')
end

Reline.update_iogate
io_gate.with_raw_input do
inner_readline(prompt, add_hist, true, &confirm_multiline_termination)
end
Expand All @@ -286,7 +285,6 @@ def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)

def readline(prompt = '', add_hist = false)
@mutex.synchronize do
Reline.update_iogate
io_gate.with_raw_input do
inner_readline(prompt, add_hist, false)
end
Expand Down Expand Up @@ -336,7 +334,7 @@ def readline(prompt = '', add_hist = false)
line_editor.auto_indent_proc = auto_indent_proc
line_editor.dig_perfect_match_proc = dig_perfect_match_proc
pre_input_hook&.call
unless Reline::IOGate == Reline::GeneralIO
unless Reline::IOGate == Reline::TestDumbIO
@dialog_proc_list.each_pair do |name_sym, d|
line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context)
end
Expand Down Expand Up @@ -473,7 +471,7 @@ def ambiguous_width
end

private def may_req_ambiguous_char_width
@ambiguous_width = 2 if io_gate == Reline::GeneralIO or !STDOUT.tty?
@ambiguous_width = 2 if io_gate == Reline::TestDumbIO || !STDIN.tty? || !STDOUT.tty?
return if defined? @ambiguous_width
io_gate.move_cursor_column(0)
begin
Expand Down Expand Up @@ -567,38 +565,25 @@ def self.ungetc(c)
def self.line_editor
core.line_editor
end

def self.update_iogate
return if core.config.test_mode

# Need to change IOGate when `$stdout.tty?` change from false to true by `$stdout.reopen`
# Example: rails/spring boot the application in non-tty, then run console in tty.
if ENV['TERM'] != 'dumb' && core.io_gate == Reline::GeneralIO && $stdout.tty?
require 'reline/ansi'
remove_const(:IOGate)
const_set(:IOGate, Reline::ANSI)
end
end
end

require 'reline/general_io'
io = Reline::GeneralIO
unless ENV['TERM'] == 'dumb'
case RbConfig::CONFIG['host_os']
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
require 'reline/windows'
tty = (io = Reline::Windows).msys_tty?
else
tty = $stdout.tty?
end
require 'reline/test_dumb_io'
Reline::GeneralIO = Reline::TestDumbIO
Reline.deprecate_constant :GeneralIO

if ENV['TERM'] == 'dumb'
io = Reline::TestDumbIO
elsif /mswin|msys|mingw|cygwin|bccwin|wince|emc/.match?(RbConfig::CONFIG['host_os'])
require 'reline/windows'
io = Reline::Windows unless Reline::Windows.msys_tty?
end
Reline::IOGate = if tty
unless io
require 'reline/ansi'
Reline::ANSI
else
io
io = Reline::ANSI
end

Reline::IOGate = io

Reline::Face.load_initial_configs

Reline::HISTORY = Reline::History.new(Reline.core.config)
10 changes: 4 additions & 6 deletions lib/reline/ansi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,10 @@ def self.inner_getc(timeout_second)
Reline.core.line_editor.handle_signal
end
c = @@input.getbyte
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
(c == 0x16 && @@input.tty? && @@input.raw(min: 0, time: 0, &:getbyte)) || c
rescue Errno::EIO
# Maybe the I/O has been closed.
nil
rescue Errno::ENOTTY
nil
end

START_BRACKETED_PASTE = String.new("\e[200~", encoding: Encoding::ASCII_8BIT)
Expand Down Expand Up @@ -242,12 +240,12 @@ def self.get_screen_size
def self.set_screen_size(rows, columns)
@@input.winsize = [rows, columns]
self
rescue Errno::ENOTTY
rescue Errno::ENOTTY, Errno::ENODEV
self
end

def self.cursor_pos
begin
if @@input.tty? && @@output.tty?
res = +''
m = nil
@@input.raw do |stdin|
Expand All @@ -266,7 +264,7 @@ def self.cursor_pos
end
column = m[:column].to_i - 1
row = m[:row].to_i - 1
rescue Errno::ENOTTY
else
begin
buf = @@output.pread(@@output.pos, 0)
row = buf.count("\n")
Expand Down
2 changes: 2 additions & 0 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ def update_dialogs(key = nil)
def render_finished
clear_rendered_lines
render_full_content
@output.flush
end

def clear_rendered_lines
Expand Down Expand Up @@ -553,6 +554,7 @@ def render_differential
Reline::IOGate.move_cursor_column wrapped_cursor_x
Reline::IOGate.move_cursor_down y - cursor_y
@rendered_screen.cursor_y = y
@output.flush
new_lines.size - y
end

Expand Down
2 changes: 1 addition & 1 deletion lib/reline/general_io.rb → lib/reline/test_dumb_io.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require 'io/wait'

class Reline::GeneralIO
class Reline::TestDumbIO
RESET_COLOR = '' # Do not send color reset sequence

def self.reset(encoding: nil)
Expand Down
8 changes: 4 additions & 4 deletions test/reline/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class <<self
def test_mode(ansi: false)
@original_iogate = IOGate
remove_const('IOGate')
const_set('IOGate', ansi ? Reline::ANSI : Reline::GeneralIO)
const_set('IOGate', ansi ? Reline::ANSI : Reline::TestDumbIO)
if ENV['RELINE_TEST_ENCODING']
encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
else
Expand All @@ -34,7 +34,7 @@ def test_mode(ansi: false)
def IOGate.get_screen_size
[24, 80]
end
Reline::GeneralIO.reset(encoding: encoding) unless ansi
Reline::TestDumbIO.reset(encoding: encoding) unless ansi
core.config.instance_variable_set(:@test_mode, true)
core.config.reset
end
Expand All @@ -44,7 +44,7 @@ def test_reset
IOGate.define_singleton_method(:get_screen_size, @original_get_screen_size)
remove_const('IOGate')
const_set('IOGate', @original_iogate)
Reline::GeneralIO.reset
Reline::TestDumbIO.reset
Reline.instance_variable_set(:@core, nil)
end

Expand Down Expand Up @@ -146,7 +146,7 @@ def assert_byte_pointer_size(expected)
expected.bytesize, byte_pointer,
<<~EOM)
<#{expected.inspect} (#{expected.encoding.inspect})> expected but was
<#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::GeneralIO.encoding.inspect}>
<#{chunk.inspect} (#{chunk.encoding.inspect})> in <Terminal #{Reline::TestDumbIO.encoding.inspect}>
EOM
end

Expand Down
2 changes: 1 addition & 1 deletion test/reline/test_reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ def test_read_io
def test_dumb_terminal
lib = File.expand_path("../../lib", __dir__)
out = IO.popen([{"TERM"=>"dumb"}, Reline.test_rubybin, "-I#{lib}", "-rreline", "-e", "p Reline.core.io_gate"], &:read)
assert_equal("Reline::GeneralIO", out.chomp)
assert_equal("Reline::TestDumbIO", out.chomp)
end

def test_require_reline_should_not_trigger_winsize
Expand Down

0 comments on commit 2779c89

Please sign in to comment.