From 145c1e0691d4a6ca8eda40a42e584a1f6899fae2 Mon Sep 17 00:00:00 2001 From: aycabta Date: Mon, 20 Dec 2021 14:36:37 +0900 Subject: [ruby/reline] Add support for overwriting dialog proc with the same name https://github.com/ruby/reline/commit/16aa20c380 --- lib/reline.rb | 14 ++++++-------- lib/reline/line_editor.rb | 8 ++++++-- test/reline/test_reline.rb | 9 ++++++--- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/lib/reline.rb b/lib/reline.rb index b92004c1ab..e5c722fe53 100644 --- a/lib/reline.rb +++ b/lib/reline.rb @@ -60,7 +60,7 @@ module Reline def initialize self.output = STDOUT - @dialog_proc_list = [] + @dialog_proc_list = {} yield self @completion_quote_character = nil @bracketed_paste_finished = false @@ -155,16 +155,15 @@ module Reline @dig_perfect_match_proc = p end + DialogProc = Struct.new(:dialog_proc, :context) def add_dialog_proc(name_sym, p, context = nil) raise ArgumentError unless p.respond_to?(:call) or p.nil? raise ArgumentError unless name_sym.instance_of?(Symbol) - @dialog_proc_list << [name_sym, p, context] + @dialog_proc_list[name_sym] = DialogProc.new(p, context) end def dialog_proc(name_sym) - dialog = @dialog_proc_list.find { |d| d[0] == name_sym } - dialog.nil? ? nil : dialog[1] - #@dialog_proc_list[name_sym] + @dialog_proc_list[name_sym] end def input=(val) @@ -307,9 +306,8 @@ module Reline line_editor.auto_indent_proc = auto_indent_proc line_editor.dig_perfect_match_proc = dig_perfect_match_proc line_editor.pre_input_hook = pre_input_hook - @dialog_proc_list.each do |d| - name_sym, dialog_proc, context = d - line_editor.add_dialog_proc(name_sym, dialog_proc, context) + @dialog_proc_list.each_pair do |name_sym, d| + line_editor.add_dialog_proc(name_sym, d.dialog_proc, d.context) end unless config.test_mode diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb index 4fbed471c3..657b3e7018 100644 --- a/lib/reline/line_editor.rb +++ b/lib/reline/line_editor.rb @@ -634,8 +634,12 @@ class Reline::LineEditor end def add_dialog_proc(name, p, context = nil) - return if @dialogs.any? { |d| d.name == name } - @dialogs << Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context)) + dialog = Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context)) + if index = @dialogs.find_index { |d| d.name == name } + @dialogs[index] = dialog + else + @dialogs << dialog + end end DIALOG_DEFAULT_HEIGHT = 20 diff --git a/test/reline/test_reline.rb b/test/reline/test_reline.rb index 4c909de4fb..1db99b5303 100644 --- a/test/reline/test_reline.rb +++ b/test/reline/test_reline.rb @@ -313,11 +313,13 @@ class Reline::Test < Reline::TestCase def test_add_dialog_proc p = proc {} Reline.add_dialog_proc(:test_proc, p) - assert_equal(p, Reline.dialog_proc(:test_proc)) + d = Reline.dialog_proc(:test_proc) + assert_equal(p, d.dialog_proc) l = lambda {} Reline.add_dialog_proc(:test_lambda, l) - assert_equal(l, Reline.dialog_proc(:test_lambda)) + d = Reline.dialog_proc(:test_lambda) + assert_equal(l, d.dialog_proc) assert_equal(nil, Reline.dialog_proc(:test_nothing)) @@ -327,7 +329,8 @@ class Reline::Test < Reline::TestCase dummy = DummyCallbackObject.new Reline.add_dialog_proc(:dummy, dummy) - assert_equal(dummy, Reline.dialog_proc(:dummy)) + d = Reline.dialog_proc(:dummy) + assert_equal(dummy, d.dialog_proc) end def test_readmultiline -- cgit v1.2.3