summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomoya ishida <tomoyapenguin@gmail.com>2024-04-26 01:12:46 +0900
committergit <svn-admin@ruby-lang.org>2024-04-25 16:12:50 +0000
commit4ff249363de16b4e5bf3166ba3df04e0f9e352a0 (patch)
tree195b50e0d7e76a2efe43400b04b53c41fdc53f09
parent3a5d9553a7b2c21d121160b1646e43884825ede0 (diff)
[ruby/reline] Fix inputrc nested $if $else $endif bug
(https://github.com/ruby/reline/pull/689) https://github.com/ruby/reline/commit/0d8aea26ec
-rw-r--r--lib/reline/config.rb29
-rw-r--r--test/reline/test_config.rb32
2 files changed, 43 insertions, 18 deletions
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index 4c07a73701..d7564ba4b7 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -53,8 +53,6 @@ class Reline::Config
@additional_key_bindings[:vi_insert] = {}
@additional_key_bindings[:vi_command] = {}
@oneshot_key_bindings = {}
- @skip_section = nil
- @if_stack = nil
@editing_mode_label = :emacs
@keymap_label = :emacs
@keymap_prefix = []
@@ -190,9 +188,7 @@ class Reline::Config
end
end
end
- conditions = [@skip_section, @if_stack]
- @skip_section = nil
- @if_stack = []
+ if_stack = []
lines.each_with_index do |line, no|
next if line.match(/\A\s*#/)
@@ -201,11 +197,11 @@ class Reline::Config
line = line.chomp.lstrip
if line.start_with?('$')
- handle_directive(line[1..-1], file, no)
+ handle_directive(line[1..-1], file, no, if_stack)
next
end
- next if @skip_section
+ next if if_stack.any? { |_no, skip| skip }
case line
when /^set +([^ ]+) +([^ ]+)/i
@@ -219,14 +215,12 @@ class Reline::Config
@additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
end
end
- unless @if_stack.empty?
- raise InvalidInputrc, "#{file}:#{@if_stack.last[1]}: unclosed if"
+ unless if_stack.empty?
+ raise InvalidInputrc, "#{file}:#{if_stack.last[0]}: unclosed if"
end
- ensure
- @skip_section, @if_stack = conditions
end
- def handle_directive(directive, file, no)
+ def handle_directive(directive, file, no, if_stack)
directive, args = directive.split(' ')
case directive
when 'if'
@@ -239,18 +233,17 @@ class Reline::Config
condition = true if args == 'Ruby'
condition = true if args == 'Reline'
end
- @if_stack << [file, no, @skip_section]
- @skip_section = !condition
+ if_stack << [no, !condition]
when 'else'
- if @if_stack.empty?
+ if if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched else"
end
- @skip_section = !@skip_section
+ if_stack.last[1] = !if_stack.last[1]
when 'endif'
- if @if_stack.empty?
+ if if_stack.empty?
raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
end
- @skip_section = @if_stack.pop
+ if_stack.pop
when 'include'
read(File.expand_path(args))
end
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index 9ead047ce4..e9f0a9449d 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -216,6 +216,38 @@ class Reline::Config::Test < Reline::TestCase
end
end
+ def test_nested_if_else
+ @config.read_lines(<<~LINES.lines)
+ $if Ruby
+ "\x1": "O"
+ $if NotRuby
+ "\x2": "X"
+ $else
+ "\x3": "O"
+ $if Ruby
+ "\x4": "O"
+ $else
+ "\x5": "X"
+ $endif
+ "\x6": "O"
+ $endif
+ "\x7": "O"
+ $else
+ "\x8": "X"
+ $if NotRuby
+ "\x9": "X"
+ $else
+ "\xA": "X"
+ $endif
+ "\xB": "X"
+ $endif
+ "\xC": "O"
+ LINES
+ keys = [0x1, 0x3, 0x4, 0x6, 0x7, 0xC]
+ key_bindings = keys.to_h { |k| [[k.ord], ['O'.ord]] }
+ assert_equal(key_bindings, @config.instance_variable_get(:@additional_key_bindings)[:emacs])
+ end
+
def test_unclosed_if
e = assert_raise(Reline::Config::InvalidInputrc) do
@config.read_lines(<<~LINES.lines, "INPUTRC")