mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/reline] Separate keystrokes each editing mode
https://github.com/ruby/reline/commit/ee23e6f3f8
This commit is contained in:
parent
16f31da92e
commit
5543695a19
7 changed files with 128 additions and 69 deletions
|
@ -231,9 +231,7 @@ module Reline
|
||||||
unless config.test_mode
|
unless config.test_mode
|
||||||
config.read
|
config.read
|
||||||
config.reset_default_key_bindings
|
config.reset_default_key_bindings
|
||||||
Reline::IOGate::RAW_KEYSTROKE_CONFIG.each_pair do |key, func|
|
Reline::IOGate.set_default_key_bindings(config)
|
||||||
config.add_default_key_binding(key, func)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
line_editor.rerender
|
line_editor.rerender
|
||||||
|
|
|
@ -10,52 +10,64 @@ class Reline::ANSI
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
RAW_KEYSTROKE_CONFIG = {
|
def self.set_default_key_bindings(config)
|
||||||
# Console (80x25)
|
{
|
||||||
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
# Console (80x25)
|
||||||
[27, 91, 52, 126] => :ed_move_to_end, # End
|
[27, 91, 49, 126] => :ed_move_to_beg, # Home
|
||||||
[27, 91, 51, 126] => :key_delete, # Del
|
[27, 91, 52, 126] => :ed_move_to_end, # End
|
||||||
[27, 91, 65] => :ed_prev_history, # ↑
|
[27, 91, 51, 126] => :key_delete, # Del
|
||||||
[27, 91, 66] => :ed_next_history, # ↓
|
[27, 91, 65] => :ed_prev_history, # ↑
|
||||||
[27, 91, 67] => :ed_next_char, # →
|
[27, 91, 66] => :ed_next_history, # ↓
|
||||||
[27, 91, 68] => :ed_prev_char, # ←
|
[27, 91, 67] => :ed_next_char, # →
|
||||||
|
[27, 91, 68] => :ed_prev_char, # ←
|
||||||
|
|
||||||
# KDE
|
# KDE
|
||||||
[27, 91, 72] => :ed_move_to_beg, # Home
|
[27, 91, 72] => :ed_move_to_beg, # Home
|
||||||
[27, 91, 70] => :ed_move_to_end, # End
|
[27, 91, 70] => :ed_move_to_end, # End
|
||||||
# Del is 0x08
|
# Del is 0x08
|
||||||
[27, 71, 65] => :ed_prev_history, # ↑
|
[27, 71, 65] => :ed_prev_history, # ↑
|
||||||
[27, 71, 66] => :ed_next_history, # ↓
|
[27, 71, 66] => :ed_next_history, # ↓
|
||||||
[27, 71, 67] => :ed_next_char, # →
|
[27, 71, 67] => :ed_next_char, # →
|
||||||
[27, 71, 68] => :ed_prev_char, # ←
|
[27, 71, 68] => :ed_prev_char, # ←
|
||||||
|
|
||||||
# urxvt / exoterm
|
# urxvt / exoterm
|
||||||
[27, 91, 55, 126] => :ed_move_to_beg, # Home
|
[27, 91, 55, 126] => :ed_move_to_beg, # Home
|
||||||
[27, 91, 56, 126] => :ed_move_to_end, # End
|
[27, 91, 56, 126] => :ed_move_to_end, # End
|
||||||
|
|
||||||
# GNOME
|
# GNOME
|
||||||
[27, 79, 72] => :ed_move_to_beg, # Home
|
[27, 79, 72] => :ed_move_to_beg, # Home
|
||||||
[27, 79, 70] => :ed_move_to_end, # End
|
[27, 79, 70] => :ed_move_to_end, # End
|
||||||
# Del is 0x08
|
# Del is 0x08
|
||||||
# Arrow keys are the same of KDE
|
# Arrow keys are the same of KDE
|
||||||
|
|
||||||
# iTerm2
|
# iTerm2
|
||||||
[27, 27, 91, 67] => :em_next_word, # Option+→
|
[27, 27, 91, 67] => :em_next_word, # Option+→
|
||||||
[27, 27, 91, 68] => :ed_prev_word, # Option+←
|
[27, 27, 91, 68] => :ed_prev_word, # Option+←
|
||||||
[195, 166] => :em_next_word, # Option+f
|
[195, 166] => :em_next_word, # Option+f
|
||||||
[195, 162] => :ed_prev_word, # Option+b
|
[195, 162] => :ed_prev_word, # Option+b
|
||||||
|
|
||||||
# others
|
# others
|
||||||
[27, 32] => :em_set_mark, # M-<space>
|
[27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→
|
||||||
[24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows
|
[27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+←
|
||||||
[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, 65] => :ed_prev_history, # ↑
|
||||||
[27, 79, 66] => :ed_next_history, # ↓
|
[27, 79, 66] => :ed_next_history, # ↓
|
||||||
[27, 79, 67] => :ed_next_char, # →
|
[27, 79, 67] => :ed_next_char, # →
|
||||||
[27, 79, 68] => :ed_prev_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
|
@@input = STDIN
|
||||||
def self.input=(val)
|
def self.input=(val)
|
||||||
|
|
|
@ -47,7 +47,9 @@ class Reline::Config
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@additional_key_bindings = {} # from inputrc
|
@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
|
@skip_section = nil
|
||||||
@if_stack = nil
|
@if_stack = nil
|
||||||
@editing_mode_label = :emacs
|
@editing_mode_label = :emacs
|
||||||
|
@ -69,8 +71,9 @@ class Reline::Config
|
||||||
if editing_mode_is?(:vi_command)
|
if editing_mode_is?(:vi_command)
|
||||||
@editing_mode_label = :vi_insert
|
@editing_mode_label = :vi_insert
|
||||||
end
|
end
|
||||||
@additional_key_bindings = {}
|
@additional_key_bindings.keys.each do |key|
|
||||||
@default_key_bindings = {}
|
@additional_key_bindings[key].clear
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def editing_mode
|
def editing_mode
|
||||||
|
@ -135,16 +138,22 @@ class Reline::Config
|
||||||
end
|
end
|
||||||
|
|
||||||
def key_bindings
|
def key_bindings
|
||||||
# override @default_key_bindings with @additional_key_bindings
|
# override @key_actors[@editing_mode_label].default_key_bindings with @additional_key_bindings[@editing_mode_label]
|
||||||
@default_key_bindings.merge(@additional_key_bindings)
|
@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
|
end
|
||||||
|
|
||||||
def add_default_key_binding(keystroke, target)
|
def add_default_key_binding(keystroke, target)
|
||||||
@default_key_bindings[keystroke] = target
|
@key_actors[@keymap_label].default_key_bindings[keystroke] = target
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_default_key_bindings
|
def reset_default_key_bindings
|
||||||
@default_key_bindings = {}
|
@key_actors.values.each do |ka|
|
||||||
|
ka.reset_default_key_bindings
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_lines(lines, file = nil)
|
def read_lines(lines, file = nil)
|
||||||
|
@ -174,7 +183,7 @@ class Reline::Config
|
||||||
key, func_name = $1, $2
|
key, func_name = $1, $2
|
||||||
keystroke, func = bind_key(key, func_name)
|
keystroke, func = bind_key(key, func_name)
|
||||||
next unless keystroke
|
next unless keystroke
|
||||||
@additional_key_bindings[keystroke] = func
|
@additional_key_bindings[@keymap_label][keystroke] = func
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
unless @if_stack.empty?
|
unless @if_stack.empty?
|
||||||
|
|
|
@ -13,7 +13,8 @@ class Reline::GeneralIO
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
RAW_KEYSTROKE_CONFIG = {}
|
def self.set_default_key_bindings(_)
|
||||||
|
end
|
||||||
|
|
||||||
@@buf = []
|
@@buf = []
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,16 @@ class Reline::KeyActor::Base
|
||||||
def get_method(key)
|
def get_method(key)
|
||||||
self.class::MAPPING[key]
|
self.class::MAPPING[key]
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -13,23 +13,35 @@ class Reline::Windows
|
||||||
@@legacy_console
|
@@legacy_console
|
||||||
end
|
end
|
||||||
|
|
||||||
RAW_KEYSTROKE_CONFIG = {
|
def self.set_default_key_bindings(config)
|
||||||
[224, 72] => :ed_prev_history, # ↑
|
{
|
||||||
[224, 80] => :ed_next_history, # ↓
|
[224, 72] => :ed_prev_history, # ↑
|
||||||
[224, 77] => :ed_next_char, # →
|
[224, 80] => :ed_next_history, # ↓
|
||||||
[224, 75] => :ed_prev_char, # ←
|
[224, 77] => :ed_next_char, # →
|
||||||
[224, 83] => :key_delete, # Del
|
[224, 75] => :ed_prev_char, # ←
|
||||||
[224, 71] => :ed_move_to_beg, # Home
|
[224, 83] => :key_delete, # Del
|
||||||
[224, 79] => :ed_move_to_end, # End
|
[224, 71] => :ed_move_to_beg, # Home
|
||||||
[ 0, 41] => :ed_unassigned, # input method on/off
|
[224, 79] => :ed_move_to_end, # End
|
||||||
[ 0, 72] => :ed_prev_history, # ↑
|
[ 0, 41] => :ed_unassigned, # input method on/off
|
||||||
[ 0, 80] => :ed_next_history, # ↓
|
[ 0, 72] => :ed_prev_history, # ↑
|
||||||
[ 0, 77] => :ed_next_char, # →
|
[ 0, 80] => :ed_next_history, # ↓
|
||||||
[ 0, 75] => :ed_prev_char, # ←
|
[ 0, 77] => :ed_next_char, # →
|
||||||
[ 0, 83] => :key_delete, # Del
|
[ 0, 75] => :ed_prev_char, # ←
|
||||||
[ 0, 71] => :ed_move_to_beg, # Home
|
[ 0, 83] => :key_delete, # Del
|
||||||
[ 0, 79] => :ed_move_to_end # End
|
[ 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
|
if defined? JRUBY_VERSION
|
||||||
require 'win32api'
|
require 'win32api'
|
||||||
|
|
|
@ -241,6 +241,21 @@ class Reline::Config::Test < Reline::TestCase
|
||||||
assert_equal expected, @config.key_bindings
|
assert_equal expected, @config.key_bindings
|
||||||
end
|
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
|
def test_history_size
|
||||||
@config.read_lines(<<~LINES.lines)
|
@config.read_lines(<<~LINES.lines)
|
||||||
set history-size 5000
|
set history-size 5000
|
||||||
|
|
Loading…
Reference in a new issue