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 Apr 3, 2024
1 parent 3debb0a commit bd69658
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 40 deletions.
45 changes: 15 additions & 30 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,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 @@ -279,7 +278,6 @@ def readmultiline(prompt = '', add_hist = false, &confirm_multiline_termination)
end

def readline(prompt = '', add_hist = false)
Reline.update_iogate
io_gate.with_raw_input do
inner_readline(prompt, add_hist, false)
end
Expand Down Expand Up @@ -324,7 +322,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 @@ -468,7 +466,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 @@ -562,38 +560,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)
8 changes: 4 additions & 4 deletions lib/reline/ansi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,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

@@in_bracketed_paste_mode = false
Expand Down Expand Up @@ -263,6 +261,8 @@ def self.cursor_pos
begin
res = +''
m = nil
raise Errno::ENOTTY unless @@input.tty? && @@output.tty?

@@input.raw do |stdin|
@@output << "\e[6n"
@@output.flush
Expand All @@ -284,7 +284,7 @@ def self.cursor_pos
buf = @@output.pread(@@output.pos, 0)
row = buf.count("\n")
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
rescue Errno::ESPIPE
rescue Errno::ESPIPE, IOError
# Just returns column 1 for ambiguous width because this I/O is not
# tty and can't seek.
row = 0
Expand Down
3 changes: 3 additions & 0 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,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 @@ -538,6 +539,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 Expand Up @@ -1110,6 +1112,7 @@ def input_key(key)
end
end
if key.char.nil?
process_insert(force: true)
if @first_char
@eof = true
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 get_reline_encoding
Expand Down

0 comments on commit bd69658

Please sign in to comment.