summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2021-09-05 23:33:59 +0900
committergit <svn-admin@ruby-lang.org>2021-09-06 05:23:06 +0900
commit544cd3fb910ff41cdc87c70edf1d00e4f6d5b435 (patch)
tree50f17d93fc0f23aa71728dcfdfc28be30c34cf98
parentbb6d45cfeecc8e16ec22e89ab40fb6b56177da7f (diff)
downloadruby-544cd3fb910ff41cdc87c70edf1d00e4f6d5b435.tar.gz
[ruby/reline] Support oneshot key bindings config for key_trap of dialog callbacks
https://github.com/ruby/reline/commit/5f1141b693
-rw-r--r--lib/reline/config.rb12
-rw-r--r--lib/reline/line_editor.rb19
2 files changed, 25 insertions, 6 deletions
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index d859aeb079..ee73143e0f 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -50,6 +50,7 @@ class Reline::Config
@additional_key_bindings[:emacs] = {}
@additional_key_bindings[:vi_insert] = {}
@additional_key_bindings[:vi_command] = {}
+ @oneshot_key_bindings = {}
@skip_section = nil
@if_stack = nil
@editing_mode_label = :emacs
@@ -75,6 +76,7 @@ class Reline::Config
@additional_key_bindings.keys.each do |key|
@additional_key_bindings[key].clear
end
+ @oneshot_key_bindings.clear
reset_default_key_bindings
end
@@ -149,7 +151,15 @@ class Reline::Config
def key_bindings
# override @key_actors[@editing_mode_label].default_key_bindings with @additional_key_bindings[@editing_mode_label]
- @key_actors[@editing_mode_label].default_key_bindings.merge(@additional_key_bindings[@editing_mode_label])
+ @key_actors[@editing_mode_label].default_key_bindings.merge(@additional_key_bindings[@editing_mode_label]).merge(@oneshot_key_bindings)
+ end
+
+ def add_oneshot_key_binding(keystroke, target)
+ @oneshot_key_bindings[keystroke] = target
+ end
+
+ def reset_oneshot_key_bindings
+ @oneshot_key_bindings.clear
end
def add_default_key_binding_by_keymap(keymap, keystroke, target)
diff --git a/lib/reline/line_editor.rb b/lib/reline/line_editor.rb
index 21db97fce6..c2ef1970c1 100644
--- a/lib/reline/line_editor.rb
+++ b/lib/reline/line_editor.rb
@@ -550,8 +550,9 @@ class Reline::LineEditor
attr_reader :name, :contents, :width
attr_accessor :scroll_top, :column, :vertical_offset, :lines_backup, :trap_key
- def initialize(name, proc_scope)
+ def initialize(name, config, proc_scope)
@name = name
+ @config = config
@proc_scope = proc_scope
@width = nil
@scroll_top = 0
@@ -575,13 +576,21 @@ class Reline::LineEditor
def call(key)
@proc_scope.set_dialog(self)
@proc_scope.set_key(key)
- @proc_scope.call
+ dialog_render_info = @proc_scope.call
+ if @trap_key
+ if @trap_key.is_a?(Array)
+ @config.add_oneshot_key_binding(@trap_key, @name)
+ elsif @trap_key.is_a?(Integer) or @trap_key.is_a?(Reline::Key)
+ @config.add_oneshot_key_binding([@trap_key], @name)
+ end
+ end
+ dialog_render_info
end
end
def add_dialog_proc(name, p, context = nil)
return if @dialogs.any? { |d| d.name == name }
- @dialogs << Dialog.new(name, DialogProcScope.new(self, @config, p, context))
+ @dialogs << Dialog.new(name, @config, DialogProcScope.new(self, @config, p, context))
end
DIALOG_HEIGHT = 20
@@ -1497,9 +1506,9 @@ class Reline::LineEditor
def input_key(key)
@last_key = key
+ @config.reset_oneshot_key_bindings
@dialogs.each do |dialog|
- # The dialog will intercept the key if trap_key is set.
- if dialog.trap_key and dialog.trap_key.match?(key)
+ if key.char.instance_of?(Symbol) and key.char == dialog.name
return
end
end