Skip to content

Commit 5543695

Browse files
aycabtanobu
authored andcommitted
[ruby/reline] Separate keystrokes each editing mode
ruby/reline@ee23e6f3f8
1 parent 16f31da commit 5543695

7 files changed

Lines changed: 128 additions & 69 deletions

File tree

lib/reline.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,7 @@ def readline(prompt = '', add_hist = false)
231231
unless config.test_mode
232232
config.read
233233
config.reset_default_key_bindings
234-
Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
235-
config.add_default_key_binding(key, func)
236-
end
234+
Reline::IOGate.set_default_key_bindings(config)
237235
end
238236

239237
line_editor.rerender

lib/reline/ansi.rb

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,52 +10,64 @@ def self.win?
1010
false
1111
end
1212

13-
RAW_KEYSTROKE_CONFIG = {
14-
# Console (80x25)
15-
[27, 91, 49, 126] => :ed_move_to_beg, # Home
16-
[27, 91, 52, 126] => :ed_move_to_end, # End
17-
[27, 91, 51, 126] => :key_delete, # Del
18-
[27, 91, 65] => :ed_prev_history, # ↑
19-
[27, 91, 66] => :ed_next_history, # ↓
20-
[27, 91, 67] => :ed_next_char, # →
21-
[27, 91, 68] => :ed_prev_char, # ←
13+
def self.set_default_key_bindings(config)
14+
{
15+
# Console (80x25)
16+
[27, 91, 49, 126] => :ed_move_to_beg, # Home
17+
[27, 91, 52, 126] => :ed_move_to_end, # End
18+
[27, 91, 51, 126] => :key_delete, # Del
19+
[27, 91, 65] => :ed_prev_history, # ↑
20+
[27, 91, 66] => :ed_next_history, # ↓
21+
[27, 91, 67] => :ed_next_char, # →
22+
[27, 91, 68] => :ed_prev_char, # ←
2223

23-
# KDE
24-
[27, 91, 72] => :ed_move_to_beg, # Home
25-
[27, 91, 70] => :ed_move_to_end, # End
26-
# Del is 0x08
27-
[27, 71, 65] => :ed_prev_history, # ↑
28-
[27, 71, 66] => :ed_next_history, # ↓
29-
[27, 71, 67] => :ed_next_char, # →
30-
[27, 71, 68] => :ed_prev_char, # ←
24+
# KDE
25+
[27, 91, 72] => :ed_move_to_beg, # Home
26+
[27, 91, 70] => :ed_move_to_end, # End
27+
# Del is 0x08
28+
[27, 71, 65] => :ed_prev_history, # ↑
29+
[27, 71, 66] => :ed_next_history, # ↓
30+
[27, 71, 67] => :ed_next_char, # →
31+
[27, 71, 68] => :ed_prev_char, # ←
3132

32-
# urxvt / exoterm
33-
[27, 91, 55, 126] => :ed_move_to_beg, # Home
34-
[27, 91, 56, 126] => :ed_move_to_end, # End
33+
# urxvt / exoterm
34+
[27, 91, 55, 126] => :ed_move_to_beg, # Home
35+
[27, 91, 56, 126] => :ed_move_to_end, # End
3536

36-
# GNOME
37-
[27, 79, 72] => :ed_move_to_beg, # Home
38-
[27, 79, 70] => :ed_move_to_end, # End
39-
# Del is 0x08
40-
# Arrow keys are the same of KDE
37+
# GNOME
38+
[27, 79, 72] => :ed_move_to_beg, # Home
39+
[27, 79, 70] => :ed_move_to_end, # End
40+
# Del is 0x08
41+
# Arrow keys are the same of KDE
4142

42-
# iTerm2
43-
[27, 27, 91, 67] => :em_next_word, # Option+→
44-
[27, 27, 91, 68] => :ed_prev_word, # Option+←
45-
[195, 166] => :em_next_word, # Option+f
46-
[195, 162] => :ed_prev_word, # Option+b
43+
# iTerm2
44+
[27, 27, 91, 67] => :em_next_word, # Option+→
45+
[27, 27, 91, 68] => :ed_prev_word, # Option+←
46+
[195, 166] => :em_next_word, # Option+f
47+
[195, 162] => :ed_prev_word, # Option+b
4748

48-
# others
49-
[27, 32] => :em_set_mark, # M-<space>
50-
[24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
51-
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
52-
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
49+
# others
50+
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
51+
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
5352

54-
[27, 79, 65] => :ed_prev_history, # ↑
55-
[27, 79, 66] => :ed_next_history, # ↓
56-
[27, 79, 67] => :ed_next_char, # →
57-
[27, 79, 68] => :ed_prev_char, # ←
58-
}
53+
[27, 79, 65] => :ed_prev_history, # ↑
54+
[27, 79, 66] => :ed_next_history, # ↓
55+
[27, 79, 67] => :ed_next_char, # →
56+
[27, 79, 68] => :ed_prev_char, # ←
57+
}.each_pair do |key, func|
58+
config.add_default_key_binding_by_keymap(:emacs, key, func)
59+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
60+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
61+
end
62+
63+
{
64+
# others
65+
[27, 32] => :em_set_mark, # M-<space>
66+
[24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
67+
}.each_pair do |key, func|
68+
config.add_default_key_binding_by_keymap(:emacs, key, func)
69+
end
70+
end
5971

6072
@@input = STDIN
6173
def self.input=(val)

lib/reline/config.rb

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ class InvalidInputrc < RuntimeError
4747

4848
def initialize
4949
@additional_key_bindings = {} # from inputrc
50-
@default_key_bindings = {} # environment-dependent
50+
@additional_key_bindings[:emacs] = {}
51+
@additional_key_bindings[:vi_insert] = {}
52+
@additional_key_bindings[:vi_command] = {}
5153
@skip_section = nil
5254
@if_stack = nil
5355
@editing_mode_label = :emacs
@@ -69,8 +71,9 @@ def reset
6971
if editing_mode_is?(:vi_command)
7072
@editing_mode_label = :vi_insert
7173
end
72-
@additional_key_bindings = {}
73-
@default_key_bindings = {}
74+
@additional_key_bindings.keys.each do |key|
75+
@additional_key_bindings[key].clear
76+
end
7477
end
7578

7679
def editing_mode
@@ -135,16 +138,22 @@ def read(file = nil)
135138
end
136139

137140
def key_bindings
138-
# override @default_key_bindings with @additional_key_bindings
139-
@default_key_bindings.merge(@additional_key_bindings)
141+
# override @key_actors[@editing_mode_label].default_key_bindings with @additional_key_bindings[@editing_mode_label]
142+
@key_actors[@editing_mode_label].default_key_bindings.merge(@additional_key_bindings[@editing_mode_label])
143+
end
144+
145+
def add_default_key_binding_by_keymap(keymap, keystroke, target)
146+
@key_actors[keymap].default_key_bindings[keystroke] = target
140147
end
141148

142149
def add_default_key_binding(keystroke, target)
143-
@default_key_bindings[keystroke] = target
150+
@key_actors[@keymap_label].default_key_bindings[keystroke] = target
144151
end
145152

146153
def reset_default_key_bindings
147-
@default_key_bindings = {}
154+
@key_actors.values.each do |ka|
155+
ka.reset_default_key_bindings
156+
end
148157
end
149158

150159
def read_lines(lines, file = nil)
@@ -174,7 +183,7 @@ def read_lines(lines, file = nil)
174183
key, func_name = $1, $2
175184
keystroke, func = bind_key(key, func_name)
176185
next unless keystroke
177-
@additional_key_bindings[keystroke] = func
186+
@additional_key_bindings[@keymap_label][keystroke] = func
178187
end
179188
end
180189
unless @if_stack.empty?

lib/reline/general_io.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ def self.win?
1313
false
1414
end
1515

16-
RAW_KEYSTROKE_CONFIG = {}
16+
def self.set_default_key_bindings(_)
17+
end
1718

1819
@@buf = []
1920

lib/reline/key_actor/base.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,16 @@ class Reline::KeyActor::Base
44
def get_method(key)
55
self.class::MAPPING[key]
66
end
7+
8+
def initialize
9+
@default_key_bindings = {}
10+
end
11+
12+
def default_key_bindings
13+
@default_key_bindings
14+
end
15+
16+
def reset_default_key_bindings
17+
@default_key_bindings.clear
18+
end
719
end

lib/reline/windows.rb

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,35 @@ def self.win_legacy_console?
1313
@@legacy_console
1414
end
1515

16-
RAW_KEYSTROKE_CONFIG = {
17-
[224, 72] => :ed_prev_history, # ↑
18-
[224, 80] => :ed_next_history, # ↓
19-
[224, 77] => :ed_next_char, # →
20-
[224, 75] => :ed_prev_char, # ←
21-
[224, 83] => :key_delete, # Del
22-
[224, 71] => :ed_move_to_beg, # Home
23-
[224, 79] => :ed_move_to_end, # End
24-
[ 0, 41] => :ed_unassigned, # input method on/off
25-
[ 0, 72] => :ed_prev_history, # ↑
26-
[ 0, 80] => :ed_next_history, # ↓
27-
[ 0, 77] => :ed_next_char, # →
28-
[ 0, 75] => :ed_prev_char, # ←
29-
[ 0, 83] => :key_delete, # Del
30-
[ 0, 71] => :ed_move_to_beg, # Home
31-
[ 0, 79] => :ed_move_to_end # End
32-
}
16+
def self.set_default_key_bindings(config)
17+
{
18+
[224, 72] => :ed_prev_history, # ↑
19+
[224, 80] => :ed_next_history, # ↓
20+
[224, 77] => :ed_next_char, # →
21+
[224, 75] => :ed_prev_char, # ←
22+
[224, 83] => :key_delete, # Del
23+
[224, 71] => :ed_move_to_beg, # Home
24+
[224, 79] => :ed_move_to_end, # End
25+
[ 0, 41] => :ed_unassigned, # input method on/off
26+
[ 0, 72] => :ed_prev_history, # ↑
27+
[ 0, 80] => :ed_next_history, # ↓
28+
[ 0, 77] => :ed_next_char, # →
29+
[ 0, 75] => :ed_prev_char, # ←
30+
[ 0, 83] => :key_delete, # Del
31+
[ 0, 71] => :ed_move_to_beg, # Home
32+
[ 0, 79] => :ed_move_to_end # End
33+
}.each_pair do |key, func|
34+
config.add_default_key_binding_by_keymap(:emacs, key, func)
35+
config.add_default_key_binding_by_keymap(:vi_insert, key, func)
36+
config.add_default_key_binding_by_keymap(:vi_command, key, func)
37+
end
38+
39+
{
40+
[27, 32] => :em_set_mark, # M-<space>
41+
}.each_pair do |key, func|
42+
config.add_default_key_binding_by_keymap(:emacs, key, func)
43+
end
44+
end
3345

3446
if defined? JRUBY_VERSION
3547
require 'win32api'

test/reline/test_config.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,21 @@ def test_additional_key_bindings_with_nesting_and_comment_out
241241
assert_equal expected, @config.key_bindings
242242
end
243243

244+
def test_additional_key_bindings_for_other_keymap
245+
@config.read_lines(<<~'LINES'.lines)
246+
set keymap vi-command
247+
"ab": "AB"
248+
set keymap vi-insert
249+
"cd": "CD"
250+
set keymap emacs
251+
"ef": "EF"
252+
set editing-mode vi # keymap changes to be vi-insert
253+
LINES
254+
255+
expected = { 'cd'.bytes => 'CD'.bytes }
256+
assert_equal expected, @config.key_bindings
257+
end
258+
244259
def test_history_size
245260
@config.read_lines(<<~LINES.lines)
246261
set history-size 5000

0 commit comments

Comments
 (0)