Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OMIT_ON_ASSIGNMENT #129

Merged
merged 3 commits into from
Sep 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ rvm:
before_install:
- yes | gem update --system

script: bundle exec rake test
script:
- bundle install
- bundle exec rake test
2 changes: 1 addition & 1 deletion irb.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Gem::Specification.new do |spec|

spec.required_ruby_version = Gem::Requirement.new(">= 2.5")

spec.add_dependency "reline", ">= 0.0.1"
spec.add_dependency "reline", ">= 0.1.5"
spec.add_development_dependency "bundler"
spec.add_development_dependency "rake"
end
36 changes: 34 additions & 2 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#
#
require "ripper"
require "reline"

require_relative "irb/init"
require_relative "irb/context"
Expand Down Expand Up @@ -538,7 +539,15 @@ def eval_input
begin
line.untaint if RUBY_VERSION < '2.7'
@context.evaluate(line, line_no, exception: exc)
output_value if @context.echo? && (@context.echo_on_assignment? || !assignment_expression?(line))
if @context.echo?
if assignment_expression?(line)
if @context.echo_on_assignment?
output_value(@context.omit_on_assignment?)
end
else
output_value
end
end
rescue Interrupt => exc
rescue SystemExit, SignalException
raise
Expand Down Expand Up @@ -737,9 +746,32 @@ def prompt(prompt, ltype, indent, line_no) # :nodoc:
p
end

def output_value # :nodoc:
def output_value(omit = false) # :nodoc:
str = @context.inspect_last_value
multiline_p = str.include?("\n")
if omit
winwidth = @context.io.winsize.last
if multiline_p
first_line = str.split("\n").first
result = @context.newline_before_multiline_output? ? (@context.return_format % first_line) : first_line
output_width = Reline::Unicode.calculate_width(result, true)
diff_size = output_width - Reline::Unicode.calculate_width(first_line, true)
if diff_size.positive? and output_width > winwidth
lines, _ = Reline::Unicode.split_by_width(first_line, winwidth - diff_size - 3)
str = "%s...\e[0m" % lines.first
multiline_p = false
else
str.gsub!(/(\A.*?\n).*/m, "\\1...")
end
else
output_width = Reline::Unicode.calculate_width(@context.return_format % str, true)
diff_size = output_width - Reline::Unicode.calculate_width(str, true)
if diff_size.positive? and output_width > winwidth
lines, _ = Reline::Unicode.split_by_width(str, winwidth - diff_size - 3)
str = "%s...\e[0m" % lines.first
end
end
end
if multiline_p && @context.newline_before_multiline_output?
printf @context.return_format, "\n#{str}"
else
Expand Down
28 changes: 24 additions & 4 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,12 @@ def initialize(irb, workspace = nil, input_method = nil)

@echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT]
if @echo_on_assignment.nil?
@echo_on_assignment = false
@echo_on_assignment = true
end

@omit_on_assignment = IRB.conf[:OMIT_ON_ASSIGNMENT]
if @omit_on_assignment.nil?
@omit_on_assignment = true
end

@newline_before_multiline_output = IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]
Expand Down Expand Up @@ -251,13 +256,27 @@ def main
attr_accessor :echo
# Whether to echo for assignment expressions
#
# Uses <code>IRB.conf[:ECHO_ON_ASSIGNMENT]</code> if available, or defaults to +false+.
# Uses <code>IRB.conf[:ECHO_ON_ASSIGNMENT]</code> if available, or defaults to +true+.
#
# a = "omg"
# IRB.CurrentContext.echo_on_assignment = true
# a = "omg"
# #=> omg
# IRB.CurrentContext.echo_on_assignment = false
# a = "omg"
attr_accessor :echo_on_assignment
# Whether to omit echo for assignment expressions
#
# Uses <code>IRB.conf[:OMIT_ON_ASSIGNMENT]</code> if available, or defaults to +true+.
#
# a = [1] * 10
# #=> [1, 1, 1, 1, 1, 1, 1, 1, ...
# [1] * 10
# #=> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
# IRB.CurrentContext.omit_on_assignment = false
# a = [1] * 10
# #=> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
# [1] * 10
# #=> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
attr_accessor :omit_on_assignment
# Whether a newline is put before multiline output.
#
# Uses <code>IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT]</code> if available,
Expand Down Expand Up @@ -306,6 +325,7 @@ def main
alias ignore_eof? ignore_eof
alias echo? echo
alias echo_on_assignment? echo_on_assignment
alias omit_on_assignment? omit_on_assignment
alias newline_before_multiline_output? newline_before_multiline_output

# Returns whether messages are displayed or not.
Expand Down
5 changes: 5 additions & 0 deletions lib/irb/init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def IRB.init_config(ap_path)
@CONF[:IGNORE_EOF] = false
@CONF[:ECHO] = nil
@CONF[:ECHO_ON_ASSIGNMENT] = nil
@CONF[:OMIT_ON_ASSIGNMENT] = nil
@CONF[:VERBOSE] = nil

@CONF[:EVAL_HISTORY] = nil
Expand Down Expand Up @@ -177,6 +178,10 @@ def IRB.parse_opts(argv: ::ARGV)
@CONF[:ECHO_ON_ASSIGNMENT] = true
when "--noecho-on-assignment"
@CONF[:ECHO_ON_ASSIGNMENT] = false
when "--omit-on-assignment"
@CONF[:OMIT_ON_ASSIGNMENT] = true
when "--noomit-on-assignment"
@CONF[:OMIT_ON_ASSIGNMENT] = false
when "--verbose"
@CONF[:VERBOSE] = true
when "--noverbose"
Expand Down
9 changes: 9 additions & 0 deletions lib/irb/input-method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require_relative 'src_encoding'
require_relative 'magic-file'
require_relative 'completion'
require 'io/console'
require 'reline'

module IRB
Expand All @@ -36,6 +37,14 @@ def gets
end
public :gets

def winsize
if instance_variable_defined?(:@stdout)
@stdout.winsize
else
[24, 80]
end
end

# Whether this input method is still readable when there is no more data to
# read.
#
Expand Down
161 changes: 157 additions & 4 deletions test/irb/test_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def encoding
def reset
@line_no = 0
end

def winsize
[10, 20]
end
end

def setup
Expand Down Expand Up @@ -213,6 +217,151 @@ def test_echo_on_assignment
assert_equal("", out)
end

def test_omit_on_assignment
input = TestInputMethod.new([
"a = [1] * 100\n",
"a\n",
])
value = [1] * 100
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
irb.context.return_format = "=> %s\n"

irb.context.echo = true
irb.context.echo_on_assignment = false
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> #{value.inspect}\n", out)

input.reset
irb.context.echo = true
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> #{value.inspect[0..(input.winsize.last - 9)]}...\e[0m\n=> #{value.inspect}\n", out)

input.reset
irb.context.echo = true
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = false
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> #{value.inspect}\n=> #{value.inspect}\n", out)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = false
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = false
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)
end

def test_omit_multiline_on_assignment
input = TestInputMethod.new([
"class A; def inspect; ([?* * 1000] * 3).join(%{\\n}); end; end; a = A.new\n",
"a\n"
])
value = ([?* * 1000] * 3).join(%{\n})
value_first_line = (?* * 1000).to_s
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)
irb.context.return_format = "=> %s\n"

irb.context.echo = true
irb.context.echo_on_assignment = false
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> \n#{value}\n", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)

input.reset
irb.context.echo = true
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> #{value_first_line[0..(input.winsize.last - 9)]}...\e[0m\n=> \n#{value}\n", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)

input.reset
irb.context.echo = true
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = false
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("=> \n#{value}\n=> \n#{value}\n", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = false
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = true
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)

input.reset
irb.context.echo = false
irb.context.echo_on_assignment = true
irb.context.omit_on_assignment = false
out, err = capture_io do
irb.eval_input
end
assert_empty err
assert_equal("", out)
irb.context.evaluate('A.remove_method(:inspect)', 0)
end

def test_echo_on_assignment_conf
# Default
IRB.conf[:ECHO] = nil
Expand All @@ -221,22 +370,26 @@ def test_echo_on_assignment_conf
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)

assert(irb.context.echo?, "echo? should be true by default")
refute(irb.context.echo_on_assignment?, "echo_on_assignment? should be false by default")
assert(irb.context.echo_on_assignment?, "echo_on_assignment? should be true by default")
assert(irb.context.omit_on_assignment?, "omit_on_assignment? should be true by default")

# Explicitly set :ECHO to false
IRB.conf[:ECHO] = false
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)

refute(irb.context.echo?, "echo? should be false when IRB.conf[:ECHO] is set to false")
refute(irb.context.echo_on_assignment?, "echo_on_assignment? should be false by default")
assert(irb.context.echo_on_assignment?, "echo_on_assignment? should be true by default")
assert(irb.context.omit_on_assignment?, "omit_on_assignment? should be true by default")

# Explicitly set :ECHO_ON_ASSIGNMENT to true
IRB.conf[:ECHO] = nil
IRB.conf[:ECHO_ON_ASSIGNMENT] = true
IRB.conf[:ECHO_ON_ASSIGNMENT] = false
IRB.conf[:OMIT_ON_ASSIGNMENT] = false
irb = IRB::Irb.new(IRB::WorkSpace.new(Object.new), input)

assert(irb.context.echo?, "echo? should be true by default")
assert(irb.context.echo_on_assignment?, "echo_on_assignment? should be true when IRB.conf[:ECHO_ON_ASSIGNMENT] is set to true")
refute(irb.context.echo_on_assignment?, "echo_on_assignment? should be false when IRB.conf[:ECHO_ON_ASSIGNMENT] is set to false")
refute(irb.context.omit_on_assignment?, "omit_on_assignment? should be false when IRB.conf[:OMIT_ON_ASSIGNMENT] is set to false")
end

def test_multiline_output_on_default_inspector
Expand Down