diff options
author | ima1zumi <mariimaizumi5@gmail.com> | 2021-11-09 23:22:12 +0900 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2021-12-02 23:41:43 +0900 |
commit | 697d7b8d629ae20c42611ac697bb7e763a7e7213 (patch) | |
tree | 7a0d604f9d0281313d22db0b664044c042d76e46 /lib/reline | |
parent | 3f1dcd7fffbe94538c233d4f916523b00dbc2889 (diff) |
[ruby/reline] Rescue if tigetstr(capname) cannot be obtained
fix https://github.com/ruby/reline/issues/384
If `$TERM` is `vt102`, there are no `kend`, `khome`, `civis`, or `cnorm` in capabilities.
`TerminfoError` is raised in `Reline::Terminfo.tigetstr(capname)`, so it is rescued if it does not exist.
https://github.com/ruby/reline/commit/c9f5112702
Diffstat (limited to 'lib/reline')
-rw-r--r-- | lib/reline/ansi.rb | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb index ae6961e29f..9e2dffa0f8 100644 --- a/lib/reline/ansi.rb +++ b/lib/reline/ansi.rb @@ -4,6 +4,19 @@ require 'timeout' require_relative 'terminfo' class Reline::ANSI + CAPNAME_KEY_BINDINGS = { + 'khome' => :ed_move_to_beg, + 'kend' => :ed_move_to_end, + 'kcuu1' => :ed_prev_history, + 'kcud1' => :ed_next_history, + 'kcuf1' => :ed_next_char, + 'kcub1' => :ed_prev_char, + 'cuu' => :ed_prev_history, + 'cud' => :ed_next_history, + 'cuf' => :ed_next_char, + 'cub' => :ed_prev_char, + } + if Reline::Terminfo.enabled? Reline::Terminfo.setupterm(0, 2) end @@ -44,20 +57,23 @@ class Reline::ANSI end def self.set_default_key_bindings_terminfo(config) - { - Reline::Terminfo.tigetstr('khome').bytes => :ed_move_to_beg, - Reline::Terminfo.tigetstr('kend').bytes => :ed_move_to_end, - Reline::Terminfo.tigetstr('kcuu1').bytes => :ed_prev_history, - Reline::Terminfo.tigetstr('kcud1').bytes => :ed_next_history, - Reline::Terminfo.tigetstr('kcuf1').bytes => :ed_next_char, - Reline::Terminfo.tigetstr('kcub1').bytes => :ed_prev_char, - # Escape sequences that omit the move distance and are set to defaults - # value 1 may be sometimes sent by pressing the arrow-key. - Reline::Terminfo.tigetstr('cuu').sub(/%p1%d/, '').bytes => :ed_prev_history, - Reline::Terminfo.tigetstr('cud').sub(/%p1%d/, '').bytes => :ed_next_history, - Reline::Terminfo.tigetstr('cuf').sub(/%p1%d/, '').bytes => :ed_next_char, - Reline::Terminfo.tigetstr('cub').sub(/%p1%d/, '').bytes => :ed_prev_char, - }.each_pair do |key, func| + key_bindings = CAPNAME_KEY_BINDINGS.map do |capname, key_binding| + begin + key_code = Reline::Terminfo.tigetstr(capname) + case capname + # Escape sequences that omit the move distance and are set to defaults + # value 1 may be sometimes sent by pressing the arrow-key. + when 'cuu', 'cud', 'cuf', 'cub' + [ key_code.sub(/%p1%d/, '').bytes, key_binding ] + else + [ key_code.bytes, key_binding ] + end + rescue TerminfoError + # capname is undefined + end + end.compact.to_h + + key_bindings.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) @@ -277,7 +293,11 @@ class Reline::ANSI def self.hide_cursor if Reline::Terminfo.enabled? - @@output.write Reline::Terminfo.tigetstr('civis') + begin + @@output.write Reline::Terminfo.tigetstr('civis') + rescue TerminfoError + # civis is undefined + end else # ignored end @@ -285,7 +305,11 @@ class Reline::ANSI def self.show_cursor if Reline::Terminfo.enabled? - @@output.write Reline::Terminfo.tigetstr('cnorm') + begin + @@output.write Reline::Terminfo.tigetstr('cnorm') + rescue TerminfoError + # cnorm is undefined + end else # ignored end |