From c2d02a6ac234a1b0fe017196c047bda2034f0684 Mon Sep 17 00:00:00 2001 From: Mari Imaizumi Date: Sat, 6 Apr 2024 18:24:47 +0900 Subject: [PATCH] [ruby/reline] Continue processing even if terminfo database couldn't be found (https://github.com/ruby/reline/pull/673) Fix https://github.com/ruby/reline/issues/447 https://github.com/ruby/reline/issues/543 This problem occurs when Fiddle can be loaded, curses can be loaded, and TERM is not registered in Terminfo. It should also occur at hardcopy terminals and when Terminfo information is low, but no such reports have been received. Reline should not abort the process because of missing Terminfo. Reline proceeds with `Reline::Terminfo.enabled? == false` when fiddle or curses cannot be loaded. And does the same when Terminfo is present but TERM is not. https://github.com/ruby/reline/blob/ebab2875f1226f877376558d8758bc0e2a1776c7/lib/reline/terminfo.rb#L156-L160 You can check the operation with `TERM=foo bundle exec bin/console`. https://github.com/ruby/reline/commit/4ce247ce2b --- lib/reline/ansi.rb | 4 ++-- lib/reline/terminfo.rb | 21 +++++++-------------- test/reline/test_ansi_with_terminfo.rb | 2 +- test/reline/test_terminfo.rb | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/lib/reline/ansi.rb b/lib/reline/ansi.rb index 0d7226b36f41e0..a3719f502c957a 100644 --- a/lib/reline/ansi.rb +++ b/lib/reline/ansi.rb @@ -315,7 +315,7 @@ def self.move_cursor_down(x) end def self.hide_cursor - if Reline::Terminfo.enabled? + if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported? begin @@output.write Reline::Terminfo.tigetstr('civis') rescue Reline::Terminfo::TerminfoError @@ -327,7 +327,7 @@ def self.hide_cursor end def self.show_cursor - if Reline::Terminfo.enabled? + if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported? begin @@output.write Reline::Terminfo.tigetstr('cnorm') rescue Reline::Terminfo::TerminfoError diff --git a/lib/reline/terminfo.rb b/lib/reline/terminfo.rb index 2cfa32b9f7a9e0..6885a0c6be9242 100644 --- a/lib/reline/terminfo.rb +++ b/lib/reline/terminfo.rb @@ -80,23 +80,11 @@ module Reline::Terminfo def self.setupterm(term, fildes) errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT) ret = @setupterm.(term, fildes, errret_int) - errret = errret_int[0, Fiddle::SIZEOF_INT].unpack1('i') case ret when 0 # OK - 0 + @term_supported = true when -1 # ERR - case errret - when 1 - raise TerminfoError.new('The terminal is hardcopy, cannot be used for curses applications.') - when 0 - raise TerminfoError.new('The terminal could not be found, or that it is a generic type, having too little information for curses applications to run.') - when -1 - raise TerminfoError.new('The terminfo database could not be found.') - else # unknown - -1 - end - else # unknown - -2 + @term_supported = false end end @@ -148,9 +136,14 @@ def self.tigetnum(capname) num end + # NOTE: This means Fiddle and curses are enabled. def self.enabled? true end + + def self.term_supported? + @term_supported + end end if Reline::Terminfo.curses_dl module Reline::Terminfo diff --git a/test/reline/test_ansi_with_terminfo.rb b/test/reline/test_ansi_with_terminfo.rb index 13874606598246..e1c56b9ee12b23 100644 --- a/test/reline/test_ansi_with_terminfo.rb +++ b/test/reline/test_ansi_with_terminfo.rb @@ -109,4 +109,4 @@ 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? +end if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported? diff --git a/test/reline/test_terminfo.rb b/test/reline/test_terminfo.rb index dda9b324954715..4e59c5483864f9 100644 --- a/test/reline/test_terminfo.rb +++ b/test/reline/test_terminfo.rb @@ -58,4 +58,4 @@ def test_tigetnum_with_error assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum('unknown') } assert_raise(Reline::Terminfo::TerminfoError) { Reline::Terminfo.tigetnum(nil) } end -end if Reline::Terminfo.enabled? +end if Reline::Terminfo.enabled? && Reline::Terminfo.term_supported?