Skip to content

Commit

Permalink
Merge pull request #278 from aycabta/separate-keystrokes-each-editing…
Browse files Browse the repository at this point in the history
…-mode

Separate keystrokes each editing mode
  • Loading branch information
aycabta authored Apr 6, 2021
2 parents b3d7f2a + ee23e6f commit 990b56f
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 69 deletions.
4 changes: 1 addition & 3 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,7 @@ def readline(prompt = '', add_hist = false)
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
Expand Down
92 changes: 52 additions & 40 deletions lib/reline/ansi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,64 @@ def self.win?
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)
Expand Down
25 changes: 17 additions & 8 deletions lib/reline/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ class InvalidInputrc < RuntimeError

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
Expand All @@ -69,8 +71,9 @@ def reset
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
Expand Down Expand Up @@ -135,16 +138,22 @@ def read(file = nil)
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)
Expand Down Expand Up @@ -174,7 +183,7 @@ def read_lines(lines, file = nil)
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?
Expand Down
3 changes: 2 additions & 1 deletion lib/reline/general_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def self.win?
false
end

RAW_KEYSTROKE_CONFIG = {}
def self.set_default_key_bindings(_)
end

@@buf = []

Expand Down
12 changes: 12 additions & 0 deletions lib/reline/key_actor/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
46 changes: 29 additions & 17 deletions lib/reline/windows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,35 @@ def self.win_legacy_console?
@@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'
Expand Down
15 changes: 15 additions & 0 deletions test/reline/test_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,21 @@ def test_additional_key_bindings_with_nesting_and_comment_out
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
Expand Down

0 comments on commit 990b56f

Please sign in to comment.