summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhillip Hellewell <phillip.hellewell@mx.com>2022-03-06 00:22:57 -0700
committergit <svn-admin@ruby-lang.org>2023-01-10 12:18:14 +0000
commit97f8f2c4703361624823ef76d6cfe804ba1e651b (patch)
tree93d7fedd49eb82c0075b3517e9b260f70270b8be
parent47ca75d38a0a16332bd1b40806b27763a433f630 (diff)
[ruby/reline] Add key binding for Delete
https://github.com/ruby/reline/commit/603eacee22
-rw-r--r--lib/reline/ansi.rb5
-rw-r--r--test/reline/helper.rb13
-rw-r--r--test/reline/test_ansi_with_terminfo.rb82
-rw-r--r--test/reline/test_ansi_without_terminfo.rb75
4 files changed, 170 insertions, 5 deletions
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb
index c40085e50d..3c6997e0f8 100644
--- a/lib/reline/ansi.rb
+++ b/lib/reline/ansi.rb
@@ -7,6 +7,7 @@ class Reline::ANSI
CAPNAME_KEY_BINDINGS = {
'khome' => :ed_move_to_beg,
'kend' => :ed_move_to_end,
+ 'kdch1' => :key_delete,
'kcuu1' => :ed_prev_history,
'kcud1' => :ed_next_history,
'kcuf1' => :ed_next_char,
@@ -29,8 +30,8 @@ class Reline::ANSI
false
end
- def self.set_default_key_bindings(config)
- if Reline::Terminfo.enabled?
+ def self.set_default_key_bindings(config, allow_terminfo: true)
+ if allow_terminfo && Reline::Terminfo.enabled?
set_default_key_bindings_terminfo(config)
else
set_default_key_bindings_comprehensive_list(config)
diff --git a/test/reline/helper.rb b/test/reline/helper.rb
index e8b8e3a6e1..be155124a4 100644
--- a/test/reline/helper.rb
+++ b/test/reline/helper.rb
@@ -7,15 +7,15 @@ require 'test/unit'
module Reline
class <<self
- def test_mode
+ def test_mode(ansi: false)
remove_const('IOGate') if const_defined?('IOGate')
- const_set('IOGate', Reline::GeneralIO)
+ const_set('IOGate', ansi ? Reline::ANSI : Reline::GeneralIO)
if ENV['RELINE_TEST_ENCODING']
encoding = Encoding.find(ENV['RELINE_TEST_ENCODING'])
else
encoding = Encoding::UTF_8
end
- Reline::GeneralIO.reset(encoding: encoding)
+ Reline::GeneralIO.reset(encoding: encoding) unless ansi
send(:core).config.instance_variable_set(:@test_mode, true)
send(:core).config.reset
end
@@ -122,4 +122,11 @@ class Reline::TestCase < Test::Unit::TestCase
end
assert_equal(expected, lines)
end
+
+ def assert_key_binding(input, method_symbol, editing_modes = [:emacs, :vi_insert, :vi_command])
+ editing_modes.each do |editing_mode|
+ @config.editing_mode = editing_mode
+ assert_equal(method_symbol, @config.editing_mode.default_key_bindings[input.bytes])
+ end
+ end
end
diff --git a/test/reline/test_ansi_with_terminfo.rb b/test/reline/test_ansi_with_terminfo.rb
new file mode 100644
index 0000000000..a6c3a5e500
--- /dev/null
+++ b/test/reline/test_ansi_with_terminfo.rb
@@ -0,0 +1,82 @@
+require_relative 'helper'
+require 'reline/ansi'
+
+class Reline::ANSI::TestWithTerminfo < Reline::TestCase
+ def setup
+ Reline.send(:test_mode, ansi: true)
+ @config = Reline::Config.new
+ Reline::IOGate.set_default_key_bindings(@config, allow_terminfo: true)
+ end
+
+ def teardown
+ Reline.test_reset
+ end
+
+ # Home key
+ def test_khome
+ assert_key_binding(Reline::Terminfo.tigetstr('khome'), :ed_move_to_beg)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # End key
+ def test_kend
+ assert_key_binding(Reline::Terminfo.tigetstr('kend'), :ed_move_to_end)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Delete key
+ def test_kdch1
+ assert_key_binding(Reline::Terminfo.tigetstr('kdch1'), :key_delete)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Up arrow key
+ def test_kcuu1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcuu1'), :ed_prev_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Down arrow key
+ def test_kcud1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcud1'), :ed_next_history)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Right arrow key
+ def test_kcuf1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcuf1'), :ed_next_char)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Left arrow key
+ def test_kcub1
+ assert_key_binding(Reline::Terminfo.tigetstr('kcub1'), :ed_prev_char)
+ rescue Reline::Terminfo::TerminfoError => e
+ omit e.message
+ end
+
+ # Ctrl+arrow and Meta+arrow; always mapped regardless of terminfo enabled or not
+ def test_extended
+ assert_key_binding("\e[1;5C", :em_next_word) # Ctrl+→
+ assert_key_binding("\e[1;5D", :ed_prev_word) # Ctrl+←
+ assert_key_binding("\e[1;3C", :em_next_word) # Meta+→
+ assert_key_binding("\e[1;3D", :ed_prev_word) # Meta+←
+ end
+
+ # Shift-Tab; always mapped regardless of terminfo enabled or not
+ def test_shift_tab
+ assert_key_binding("\e[Z", :completion_journey_up, [:emacs, :vi_insert])
+ end
+
+ # A few emacs bindings that are always mapped regardless of terminfo enabled or not
+ def test_more_emacs
+ assert_key_binding("\e ", :em_set_mark, [:emacs])
+ assert_key_binding("\C-x\C-x", :em_exchange_mark, [:emacs])
+ end
+end if Reline::Terminfo.enabled?
diff --git a/test/reline/test_ansi_without_terminfo.rb b/test/reline/test_ansi_without_terminfo.rb
new file mode 100644
index 0000000000..28b929849b
--- /dev/null
+++ b/test/reline/test_ansi_without_terminfo.rb
@@ -0,0 +1,75 @@
+require_relative 'helper'
+require 'reline/ansi'
+
+class Reline::ANSI::TestWithoutTerminfo < Reline::TestCase
+ def setup
+ Reline.send(:test_mode, ansi: true)
+ @config = Reline::Config.new
+ Reline::IOGate.set_default_key_bindings(@config, allow_terminfo: false)
+ end
+
+ def teardown
+ Reline.test_reset
+ end
+
+ def test_home
+ assert_key_binding("\e[1~", :ed_move_to_beg) # Console (80x25)
+ assert_key_binding("\e[H", :ed_move_to_beg) # KDE
+ assert_key_binding("\e[7~", :ed_move_to_beg) # urxvt / exoterm
+ assert_key_binding("\eOH", :ed_move_to_beg) # GNOME
+ end
+
+ def test_end
+ assert_key_binding("\e[4~", :ed_move_to_end) # Console (80x25)
+ assert_key_binding("\e[F", :ed_move_to_end) # KDE
+ assert_key_binding("\e[8~", :ed_move_to_end) # urxvt / exoterm
+ assert_key_binding("\eOF", :ed_move_to_end) # GNOME
+ end
+
+ def test_delete
+ assert_key_binding("\e[3~", :key_delete)
+ end
+
+ def test_up_arrow
+ assert_key_binding("\e[A", :ed_prev_history) # Console (80x25)
+ assert_key_binding("\eGA", :ed_prev_history) # KDE
+ assert_key_binding("\eOA", :ed_prev_history)
+ end
+
+ def test_down_arrow
+ assert_key_binding("\e[B", :ed_next_history) # Console (80x25)
+ assert_key_binding("\eGB", :ed_next_history) # KDE
+ assert_key_binding("\eOB", :ed_next_history)
+ end
+
+ def test_right_arrow
+ assert_key_binding("\e[C", :ed_next_char) # Console (80x25)
+ assert_key_binding("\eGC", :ed_next_char) # KDE
+ assert_key_binding("\eOC", :ed_next_char)
+ end
+
+ def test_left_arrow
+ assert_key_binding("\e[D", :ed_prev_char) # Console (80x25)
+ assert_key_binding("\eGD", :ed_prev_char) # KDE
+ assert_key_binding("\eOD", :ed_prev_char)
+ end
+
+ # Ctrl+arrow and Meta+arrow; always mapped regardless of terminfo enabled or not
+ def test_extended
+ assert_key_binding("\e[1;5C", :em_next_word) # Ctrl+→
+ assert_key_binding("\e[1;5D", :ed_prev_word) # Ctrl+←
+ assert_key_binding("\e[1;3C", :em_next_word) # Meta+→
+ assert_key_binding("\e[1;3D", :ed_prev_word) # Meta+←
+ end
+
+ # Shift-Tab; always mapped regardless of terminfo enabled or not
+ def test_shift_tab
+ assert_key_binding("\e[Z", :completion_journey_up, [:emacs, :vi_insert])
+ end
+
+ # A few emacs bindings that are always mapped regardless of terminfo enabled or not
+ def test_more_emacs
+ assert_key_binding("\e ", :em_set_mark, [:emacs])
+ assert_key_binding("\C-x\C-x", :em_exchange_mark, [:emacs])
+ end
+end