summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraycabta <aycabta@gmail.com>2021-04-05 16:03:53 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-04-08 21:41:00 +0900
commit5543695a19faccea325f91c9791d06dc4d29e132 (patch)
tree15d58fc8f8a9e0daac8d7d2c75cfd47d3a4aae65
parent16f31da92e0c8722cb1f708d1a6938c386d477cf (diff)
[ruby/reline] Separate keystrokes each editing mode
https://github.com/ruby/reline/commit/ee23e6f3f8
-rw-r--r--lib/reline.rb4
-rw-r--r--lib/reline/ansi.rb92
-rw-r--r--lib/reline/config.rb25
-rw-r--r--lib/reline/general_io.rb3
-rw-r--r--lib/reline/key_actor/base.rb12
-rw-r--r--lib/reline/windows.rb46
-rw-r--r--test/reline/test_config.rb15
7 files changed, 128 insertions, 69 deletions
diff --git a/lib/reline.rb b/lib/reline.rb
index a7bd4d9280..6fc27caecd 100644
--- a/lib/reline.rb
+++ b/lib/reline.rb
@@ -231,9 +231,7 @@ module Reline
unless config.test_mode
config.read
config.reset_default_key_bindings
- Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
- config.add_default_key_binding(key, func)
- end
+ Reline::IOGate.set_default_key_bindings(config)
end
line_editor.rerender
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
index b2d7e7d910..f8e82c199d 100644
--- a/lib/reline/ansi.rb
+++ b/lib/reline/ansi.rb
@@ -10,52 +10,64 @@ class Reline::ANSI
false
end
- RAW_KEYSTROKE_CONFIG = {
- # Console (80x25)
- [27, 91, 49, 126] => :ed_move_to_beg, # Home
- [27, 91, 52, 126] => :ed_move_to_end, # End
- [27, 91, 51, 126] => :key_delete, # Del
- [27, 91, 65] => :ed_prev_history, # ↑
- [27, 91, 66] => :ed_next_history, # ↓
- [27, 91, 67] => :ed_next_char, # →
- [27, 91, 68] => :ed_prev_char, # ←
+ def self.set_default_key_bindings(config)
+ {
+ # Console (80x25)
+ [27, 91, 49, 126] => :ed_move_to_beg, # Home
+ [27, 91, 52, 126] => :ed_move_to_end, # End
+ [27, 91, 51, 126] => :key_delete, # Del
+ [27, 91, 65] => :ed_prev_history, # ↑
+ [27, 91, 66] => :ed_next_history, # ↓
+ [27, 91, 67] => :ed_next_char, # →
+ [27, 91, 68] => :ed_prev_char, # ←
- # KDE
- [27, 91, 72] => :ed_move_to_beg, # Home
- [27, 91, 70] => :ed_move_to_end, # End
- # Del is 0x08
- [27, 71, 65] => :ed_prev_history, # ↑
- [27, 71, 66] => :ed_next_history, # ↓
- [27, 71, 67] => :ed_next_char, # →
- [27, 71, 68] => :ed_prev_char, # ←
+ # KDE
+ [27, 91, 72] => :ed_move_to_beg, # Home
+ [27, 91, 70] => :ed_move_to_end, # End
+ # Del is 0x08
+ [27, 71, 65] => :ed_prev_history, # ↑
+ [27, 71, 66] => :ed_next_history, # ↓
+ [27, 71, 67] => :ed_next_char, # →
+ [27, 71, 68] => :ed_prev_char, # ←
- # urxvt / exoterm
- [27, 91, 55, 126] => :ed_move_to_beg, # Home
- [27, 91, 56, 126] => :ed_move_to_end, # End
+ # urxvt / exoterm
+ [27, 91, 55, 126] => :ed_move_to_beg, # Home
+ [27, 91, 56, 126] => :ed_move_to_end, # End
- # GNOME
- [27, 79, 72] => :ed_move_to_beg, # Home
- [27, 79, 70] => :ed_move_to_end, # End
- # Del is 0x08
- # Arrow keys are the same of KDE
+ # GNOME
+ [27, 79, 72] => :ed_move_to_beg, # Home
+ [27, 79, 70] => :ed_move_to_end, # End
+ # Del is 0x08
+ # Arrow keys are the same of KDE
- # iTerm2
- [27, 27, 91, 67] => :em_next_word, # Option+→
- [27, 27, 91, 68] => :ed_prev_word, # Option+←
- [195, 166] => :em_next_word, # Option+f
- [195, 162] => :ed_prev_word, # Option+b
+ # iTerm2
+ [27, 27, 91, 67] => :em_next_word, # Option+→
+ [27, 27, 91, 68] => :ed_prev_word, # Option+←
+ [195, 166] => :em_next_word, # Option+f
+ [195, 162] => :ed_prev_word, # Option+b
- # others
- [27, 32] => :em_set_mark, # M-<space>
- [24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
- [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
- [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
+ # others
+ [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
+ [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
- [27, 79, 65] => :ed_prev_history, # ↑
- [27, 79, 66] => :ed_next_history, # ↓
- [27, 79, 67] => :ed_next_char, # →
- [27, 79, 68] => :ed_prev_char, # ←
- }
+ [27, 79, 65] => :ed_prev_history, # ↑
+ [27, 79, 66] => :ed_next_history, # ↓
+ [27, 79, 67] => :ed_next_char, # →
+ [27, 79, 68] => :ed_prev_char, # ←
+ }.each_pair do |key, func|
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
+ config.add_default_key_binding_by_keymap(:vi_command, key, func)
+ end
+
+ {
+ # others
+ [27, 32] => :em_set_mark, # M-<space>
+ [24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
+ }.each_pair do |key, func|
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
+ end
+ end
@@input = STDIN
def self.input=(val)
diff --git a/lib/reline/config.rb b/lib/reline/config.rb
index 63ab7b7402..f916fc63ff 100644
--- a/lib/reline/config.rb
+++ b/lib/reline/config.rb
@@ -47,7 +47,9 @@ class Reline::Config
def initialize
@additional_key_bindings = {} # from inputrc
- @default_key_bindings = {} # environment-dependent
+ @additional_key_bindings[:emacs] = {}
+ @additional_key_bindings[:vi_insert] = {}
+ @additional_key_bindings[:vi_command] = {}
@skip_section = nil
@if_stack = nil
@editing_mode_label = :emacs
@@ -69,8 +71,9 @@ class Reline::Config
if editing_mode_is?(:vi_command)
@editing_mode_label = :vi_insert
end
- @additional_key_bindings = {}
- @default_key_bindings = {}
+ @additional_key_bindings.keys.each do |key|
+ @additional_key_bindings[key].clear
+ end
end
def editing_mode
@@ -135,16 +138,22 @@ class Reline::Config
end
def key_bindings
- # override @default_key_bindings with @additional_key_bindings
- @default_key_bindings.merge(@additional_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])
+ end
+
+ def add_default_key_binding_by_keymap(keymap, keystroke, target)
+ @key_actors[keymap].default_key_bindings[keystroke] = target
end
def add_default_key_binding(keystroke, target)
- @default_key_bindings[keystroke] = target
+ @key_actors[@keymap_label].default_key_bindings[keystroke] = target
end
def reset_default_key_bindings
- @default_key_bindings = {}
+ @key_actors.values.each do |ka|
+ ka.reset_default_key_bindings
+ end
end
def read_lines(lines, file = nil)
@@ -174,7 +183,7 @@ class Reline::Config
key, func_name = $1, $2
keystroke, func = bind_key(key, func_name)
next unless keystroke
- @additional_key_bindings[keystroke] = func
+ @additional_key_bindings[@keymap_label][keystroke] = func
end
end
unless @if_stack.empty?
diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb
index 01a592e038..8c8e22d2e6 100644
--- a/lib/reline/general_io.rb
+++ b/lib/reline/general_io.rb
@@ -13,7 +13,8 @@ class Reline::GeneralIO
false
end
- RAW_KEYSTROKE_CONFIG = {}
+ def self.set_default_key_bindings(_)
+ end
@@buf = []
diff --git a/lib/reline/key_actor/base.rb b/lib/reline/key_actor/base.rb
index f4abac55d4..a1cd7fb2a1 100644
--- a/lib/reline/key_actor/base.rb
+++ b/lib/reline/key_actor/base.rb
@@ -4,4 +4,16 @@ class Reline::KeyActor::Base
def get_method(key)
self.class::MAPPING[key]
end
+
+ def initialize
+ @default_key_bindings = {}
+ end
+
+ def default_key_bindings
+ @default_key_bindings
+ end
+
+ def reset_default_key_bindings
+ @default_key_bindings.clear
+ end
end
diff --git a/lib/reline/windows.rb b/lib/reline/windows.rb
index 6edc68e780..c645458cfc 100644
--- a/lib/reline/windows.rb
+++ b/lib/reline/windows.rb
@@ -13,23 +13,35 @@ class Reline::Windows
@@legacy_console
end
- RAW_KEYSTROKE_CONFIG = {
- [224, 72] => :ed_prev_history, # ↑
- [224, 80] => :ed_next_history, # ↓
- [224, 77] => :ed_next_char, # →
- [224, 75] => :ed_prev_char, # ←
- [224, 83] => :key_delete, # Del
- [224, 71] => :ed_move_to_beg, # Home
- [224, 79] => :ed_move_to_end, # End
- [ 0, 41] => :ed_unassigned, # input method on/off
- [ 0, 72] => :ed_prev_history, # ↑
- [ 0, 80] => :ed_next_history, # ↓
- [ 0, 77] => :ed_next_char, # →
- [ 0, 75] => :ed_prev_char, # ←
- [ 0, 83] => :key_delete, # Del
- [ 0, 71] => :ed_move_to_beg, # Home
- [ 0, 79] => :ed_move_to_end # End
- }
+ def self.set_default_key_bindings(config)
+ {
+ [224, 72] => :ed_prev_history, # ↑
+ [224, 80] => :ed_next_history, # ↓
+ [224, 77] => :ed_next_char, # →
+ [224, 75] => :ed_prev_char, # ←
+ [224, 83] => :key_delete, # Del
+ [224, 71] => :ed_move_to_beg, # Home
+ [224, 79] => :ed_move_to_end, # End
+ [ 0, 41] => :ed_unassigned, # input method on/off
+ [ 0, 72] => :ed_prev_history, # ↑
+ [ 0, 80] => :ed_next_history, # ↓
+ [ 0, 77] => :ed_next_char, # →
+ [ 0, 75] => :ed_prev_char, # ←
+ [ 0, 83] => :key_delete, # Del
+ [ 0, 71] => :ed_move_to_beg, # Home
+ [ 0, 79] => :ed_move_to_end # End
+ }.each_pair do |key, func|
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
+ config.add_default_key_binding_by_keymap(:vi_insert, key, func)
+ config.add_default_key_binding_by_keymap(:vi_command, key, func)
+ end
+
+ {
+ [27, 32] => :em_set_mark, # M-<space>
+ }.each_pair do |key, func|
+ config.add_default_key_binding_by_keymap(:emacs, key, func)
+ end
+ end
if defined? JRUBY_VERSION
require 'win32api'
diff --git a/test/reline/test_config.rb b/test/reline/test_config.rb
index c1455cd136..2cca0e71f7 100644
--- a/test/reline/test_config.rb
+++ b/test/reline/test_config.rb
@@ -241,6 +241,21 @@ class Reline::Config::Test < Reline::TestCase
assert_equal expected, @config.key_bindings
end
+ def test_additional_key_bindings_for_other_keymap
+ @config.read_lines(<<~'LINES'.lines)
+ set keymap vi-command
+ "ab": "AB"
+ set keymap vi-insert
+ "cd": "CD"
+ set keymap emacs
+ "ef": "EF"
+ set editing-mode vi # keymap changes to be vi-insert
+ LINES
+
+ expected = { 'cd'.bytes => 'CD'.bytes }
+ assert_equal expected, @config.key_bindings
+ end
+
def test_history_size
@config.read_lines(<<~LINES.lines)
set history-size 5000