зеркало из https://github.com/github/ruby.git
[ruby/reline] Fix inputrc nested $if $else $endif bug
(https://github.com/ruby/reline/pull/689) https://github.com/ruby/reline/commit/0d8aea26ec
This commit is contained in:
Родитель
3a5d9553a7
Коммит
4ff249363d
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче