hyperlist 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/diagnose_ruby34_detailed.rb +156 -0
- data/hyperlist +5 -32
- data/hyperlist.gemspec +2 -2
- data/rcurses_ruby34_patch.rb +149 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7963687b87c7d271d9e45e5574e7af4edb900e49cc60a567774e4be54a386f51
|
4
|
+
data.tar.gz: '055148f7bc87ab9af632b5ad52eae9a367bdc8b4c84c8bbff28ed5686502e30a'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17a562ee3ccdbcd2434c7a6fc5b08f3bccb696fb0a0100e735ea7e5f5e267021de31c0b9c8007dd4990818e236d9d0f7a87cebeed4384b69161202e0f1f6f8c9
|
7
|
+
data.tar.gz: 27a237a412326e4f45fa17cd7b622bfa5073f39a4b2f87ce1bc6af264eb0506d2f663b39338cd66738b54f95e7ccd48d85838c58eb6bad7c15ec84e007bd68dc
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
All notable changes to the HyperList Ruby TUI will be documented in this file.
|
4
4
|
|
5
|
+
## [1.1.7] - 2025-08-15
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
- **Updated rcurses dependency to 5.1.6**
|
9
|
+
- Fixes Ruby 3.4.5 hanging issue during terminal initialization
|
10
|
+
- rcurses now handles stdin.raw! blocking with timeout and stty fallback
|
11
|
+
- Fully backward compatible
|
12
|
+
|
5
13
|
## [1.1.6] - 2025-08-14
|
6
14
|
|
7
15
|
### Fixed
|
@@ -0,0 +1,156 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Detailed diagnostic script for Ruby 3.4.5 compatibility issues
|
3
|
+
|
4
|
+
puts "Ruby Compatibility Diagnostic for HyperList (Detailed)"
|
5
|
+
puts "=" * 50
|
6
|
+
puts "Ruby version: #{RUBY_VERSION}"
|
7
|
+
puts "Ruby platform: #{RUBY_PLATFORM}"
|
8
|
+
puts
|
9
|
+
|
10
|
+
# Test 0: Environment check
|
11
|
+
puts "Test 0: Environment check..."
|
12
|
+
puts " TERM: #{ENV['TERM']}"
|
13
|
+
puts " SHELL: #{ENV['SHELL']}"
|
14
|
+
puts " HOME: #{ENV['HOME']}"
|
15
|
+
puts " PATH includes gem bin: #{ENV['PATH'].include?('.gem')}"
|
16
|
+
puts
|
17
|
+
|
18
|
+
# Test 1: Basic rcurses load
|
19
|
+
puts "Test 1: Loading rcurses gem..."
|
20
|
+
STDOUT.flush
|
21
|
+
begin
|
22
|
+
require 'rcurses'
|
23
|
+
puts " ✓ rcurses loaded"
|
24
|
+
puts " Rcurses constants defined: #{Rcurses.constants.sort.join(', ')}" if defined?(Rcurses)
|
25
|
+
STDOUT.flush
|
26
|
+
rescue LoadError => e
|
27
|
+
puts " ✗ Failed to load rcurses: #{e.message}"
|
28
|
+
exit 1
|
29
|
+
end
|
30
|
+
|
31
|
+
# Test 2: Check rcurses version and methods
|
32
|
+
puts "\nTest 2: Checking rcurses methods..."
|
33
|
+
STDOUT.flush
|
34
|
+
if defined?(Rcurses)
|
35
|
+
puts " Methods available: #{Rcurses.methods(false).sort.join(', ')}"
|
36
|
+
puts " Responds to init!: #{Rcurses.respond_to?(:init!)}"
|
37
|
+
puts " Responds to done!: #{Rcurses.respond_to?(:done!)}"
|
38
|
+
STDOUT.flush
|
39
|
+
end
|
40
|
+
|
41
|
+
# Test 3: Try initialization with timeout
|
42
|
+
puts "\nTest 3: Attempting rcurses initialization (with 2 second timeout)..."
|
43
|
+
STDOUT.flush
|
44
|
+
|
45
|
+
require 'timeout'
|
46
|
+
begin
|
47
|
+
Timeout::timeout(2) do
|
48
|
+
puts " Calling Rcurses.init!..."
|
49
|
+
STDOUT.flush
|
50
|
+
|
51
|
+
# Try to capture any initialization issues
|
52
|
+
old_stdout = $stdout
|
53
|
+
old_stderr = $stderr
|
54
|
+
|
55
|
+
begin
|
56
|
+
Rcurses.init!
|
57
|
+
puts " ✓ Rcurses.init! returned successfully"
|
58
|
+
rescue => e
|
59
|
+
puts " ✗ Rcurses.init! raised: #{e.class} - #{e.message}"
|
60
|
+
puts " Backtrace: #{e.backtrace.first(3).join("\n ")}"
|
61
|
+
ensure
|
62
|
+
$stdout = old_stdout
|
63
|
+
$stderr = old_stderr
|
64
|
+
end
|
65
|
+
|
66
|
+
STDOUT.flush
|
67
|
+
end
|
68
|
+
rescue Timeout::Error
|
69
|
+
puts " ✗ Rcurses.init! timed out after 2 seconds"
|
70
|
+
puts " This suggests init! is hanging"
|
71
|
+
STDOUT.flush
|
72
|
+
end
|
73
|
+
|
74
|
+
# Test 4: Check terminal control without rcurses
|
75
|
+
puts "\nTest 4: Direct terminal control test..."
|
76
|
+
STDOUT.flush
|
77
|
+
begin
|
78
|
+
# Save terminal state
|
79
|
+
system("stty -g > /tmp/terminal_state.txt 2>/dev/null")
|
80
|
+
|
81
|
+
# Try basic terminal operations
|
82
|
+
print "\e[?25l" # Hide cursor
|
83
|
+
print "\e[2J" # Clear screen
|
84
|
+
print "\e[H" # Home
|
85
|
+
print "Terminal control test"
|
86
|
+
sleep 0.5
|
87
|
+
print "\e[2J\e[H" # Clear again
|
88
|
+
print "\e[?25h" # Show cursor
|
89
|
+
|
90
|
+
puts " ✓ Direct terminal control works"
|
91
|
+
STDOUT.flush
|
92
|
+
rescue => e
|
93
|
+
puts " ✗ Terminal control failed: #{e.message}"
|
94
|
+
STDOUT.flush
|
95
|
+
ensure
|
96
|
+
# Restore terminal
|
97
|
+
system("stty $(cat /tmp/terminal_state.txt) 2>/dev/null")
|
98
|
+
print "\e[?25h" # Ensure cursor is visible
|
99
|
+
end
|
100
|
+
|
101
|
+
# Test 5: Check IO/console
|
102
|
+
puts "\nTest 5: IO/console functionality..."
|
103
|
+
STDOUT.flush
|
104
|
+
begin
|
105
|
+
require 'io/console'
|
106
|
+
|
107
|
+
# Check if stdin is a tty
|
108
|
+
puts " STDIN.tty?: #{STDIN.tty?}"
|
109
|
+
puts " STDOUT.tty?: #{STDOUT.tty?}"
|
110
|
+
|
111
|
+
# Test raw mode
|
112
|
+
begin
|
113
|
+
STDIN.raw { }
|
114
|
+
puts " ✓ STDIN.raw works"
|
115
|
+
rescue => e
|
116
|
+
puts " ✗ STDIN.raw failed: #{e.message}"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Test noecho
|
120
|
+
begin
|
121
|
+
STDIN.noecho { }
|
122
|
+
puts " ✓ STDIN.noecho works"
|
123
|
+
rescue => e
|
124
|
+
puts " ✗ STDIN.noecho failed: #{e.message}"
|
125
|
+
end
|
126
|
+
|
127
|
+
STDOUT.flush
|
128
|
+
rescue => e
|
129
|
+
puts " ✗ Failed: #{e.message}"
|
130
|
+
STDOUT.flush
|
131
|
+
end
|
132
|
+
|
133
|
+
# Test 6: Check if rcurses is trying to use methods that don't exist
|
134
|
+
puts "\nTest 6: Checking potential Ruby 3.4 incompatibilities..."
|
135
|
+
STDOUT.flush
|
136
|
+
|
137
|
+
# Check Thread methods
|
138
|
+
puts " Thread.respond_to?(:handle_interrupt): #{Thread.respond_to?(:handle_interrupt)}"
|
139
|
+
puts " Signal.list includes WINCH: #{Signal.list.include?('WINCH')}"
|
140
|
+
|
141
|
+
# Check IO methods that might be different
|
142
|
+
if defined?(IO.console)
|
143
|
+
console = IO.console
|
144
|
+
puts " IO.console class: #{console.class}"
|
145
|
+
puts " IO.console methods include raw: #{console.respond_to?(:raw)}"
|
146
|
+
puts " IO.console methods include getch: #{console.respond_to?(:getch)}"
|
147
|
+
end
|
148
|
+
|
149
|
+
puts "\n" + "=" * 50
|
150
|
+
puts "Diagnostic complete!"
|
151
|
+
puts "\nIf the script hangs at 'Calling Rcurses.init!', it means rcurses"
|
152
|
+
puts "is incompatible with Ruby 3.4.5 and needs to be updated."
|
153
|
+
STDOUT.flush
|
154
|
+
|
155
|
+
# Clean exit
|
156
|
+
exit 0
|
data/hyperlist
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
# Check for help/version BEFORE loading any libraries
|
8
8
|
if ARGV[0] == '-h' || ARGV[0] == '--help'
|
9
9
|
puts <<~HELP
|
10
|
-
HyperList v1.1.
|
10
|
+
HyperList v1.1.7 - Terminal User Interface for HyperList files
|
11
11
|
|
12
12
|
USAGE
|
13
13
|
hyperlist [OPTIONS] [FILE]
|
@@ -52,7 +52,7 @@ if ARGV[0] == '-h' || ARGV[0] == '--help'
|
|
52
52
|
HELP
|
53
53
|
exit 0
|
54
54
|
elsif ARGV[0] == '-v' || ARGV[0] == '--version'
|
55
|
-
puts "HyperList v1.1.
|
55
|
+
puts "HyperList v1.1.7"
|
56
56
|
exit 0
|
57
57
|
end
|
58
58
|
|
@@ -70,7 +70,7 @@ class HyperListApp
|
|
70
70
|
include Rcurses::Input
|
71
71
|
include Rcurses::Cursor
|
72
72
|
|
73
|
-
VERSION = "1.1.
|
73
|
+
VERSION = "1.1.7"
|
74
74
|
|
75
75
|
def initialize(filename = nil)
|
76
76
|
@filename = filename ? File.expand_path(filename) : nil
|
@@ -4555,35 +4555,8 @@ class HyperListApp
|
|
4555
4555
|
end
|
4556
4556
|
|
4557
4557
|
# Main
|
4558
|
-
if __FILE__ == $0
|
4558
|
+
if __FILE__ == $0
|
4559
4559
|
# Normal operation - help/version already handled at top of file
|
4560
|
-
|
4561
|
-
# For Ruby 3.4+, explicitly initialize rcurses if needed
|
4562
|
-
if RUBY_VERSION >= "3.4.0"
|
4563
|
-
begin
|
4564
|
-
Rcurses.init! unless Rcurses.respond_to?(:initialized?) && Rcurses.initialized?
|
4565
|
-
rescue => e
|
4566
|
-
# If initialization fails, try to provide helpful error
|
4567
|
-
puts "Failed to initialize terminal interface: #{e.message}"
|
4568
|
-
puts "Try running with: ruby #{__FILE__} #{ARGV.join(' ')}"
|
4569
|
-
exit 1
|
4570
|
-
end
|
4571
|
-
end
|
4572
|
-
|
4573
4560
|
app = HyperListApp.new(ARGV[0])
|
4574
|
-
|
4575
|
-
begin
|
4576
|
-
app.run
|
4577
|
-
ensure
|
4578
|
-
# Ensure proper cleanup for Ruby 3.4+
|
4579
|
-
if RUBY_VERSION >= "3.4.0"
|
4580
|
-
begin
|
4581
|
-
Rcurses.done! if defined?(Rcurses.done!)
|
4582
|
-
rescue
|
4583
|
-
# Fallback cleanup
|
4584
|
-
print "\e[?25h" # Show cursor
|
4585
|
-
system("stty sane 2>/dev/null")
|
4586
|
-
end
|
4587
|
-
end
|
4588
|
-
end
|
4561
|
+
app.run
|
4589
4562
|
end
|
data/hyperlist.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "hyperlist"
|
3
|
-
spec.version = "1.1.
|
3
|
+
spec.version = "1.1.7"
|
4
4
|
spec.authors = ["Geir Isene"]
|
5
5
|
spec.email = ["g@isene.com"]
|
6
6
|
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.require_paths = ["."]
|
29
29
|
|
30
30
|
# Runtime dependencies
|
31
|
-
spec.add_runtime_dependency "rcurses", "~> 5.1", ">= 5.1.
|
31
|
+
spec.add_runtime_dependency "rcurses", "~> 5.1", ">= 5.1.6"
|
32
32
|
|
33
33
|
# Development dependencies
|
34
34
|
spec.add_development_dependency "minitest", "~> 5.0"
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Patch for rcurses to work with Ruby 3.4.5
|
3
|
+
# This shows the minimal changes needed to fix the initialization hang
|
4
|
+
|
5
|
+
module Rcurses
|
6
|
+
class << self
|
7
|
+
# Override init! with Ruby 3.4+ compatibility
|
8
|
+
def init_with_ruby34_fix!
|
9
|
+
return if @initialized
|
10
|
+
return unless $stdin.tty?
|
11
|
+
|
12
|
+
# Ruby 3.4.5 compatibility: Use Timeout to prevent hangs
|
13
|
+
# and try different approaches
|
14
|
+
begin
|
15
|
+
if RUBY_VERSION >= "3.4.0"
|
16
|
+
# For Ruby 3.4+, try using the block form first
|
17
|
+
# which properly handles terminal state
|
18
|
+
begin
|
19
|
+
require 'timeout'
|
20
|
+
|
21
|
+
# Try to set raw mode with timeout
|
22
|
+
Timeout::timeout(0.5) do
|
23
|
+
# In Ruby 3.4+, raw! might need explicit flush
|
24
|
+
$stdout.flush
|
25
|
+
$stderr.flush
|
26
|
+
|
27
|
+
# Try setting raw mode
|
28
|
+
$stdin.raw!
|
29
|
+
end
|
30
|
+
|
31
|
+
# Set echo separately with timeout
|
32
|
+
Timeout::timeout(0.5) do
|
33
|
+
$stdin.echo = false
|
34
|
+
end
|
35
|
+
rescue Timeout::Error
|
36
|
+
# If raw! hangs, try alternative approach
|
37
|
+
# Use stty command as fallback
|
38
|
+
system("stty raw -echo 2>/dev/null")
|
39
|
+
@using_stty = true
|
40
|
+
end
|
41
|
+
else
|
42
|
+
# Original code for older Ruby versions
|
43
|
+
$stdin.raw!
|
44
|
+
$stdin.echo = false
|
45
|
+
end
|
46
|
+
rescue Errno::ENOTTY, Errno::ENODEV
|
47
|
+
# Not a terminal, can't initialize
|
48
|
+
return
|
49
|
+
rescue => e
|
50
|
+
# Log error but don't fail
|
51
|
+
$stderr.puts "rcurses init warning: #{e.message}" if ENV['DEBUG']
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
55
|
+
# ensure cleanup on normal exit
|
56
|
+
at_exit do
|
57
|
+
if $! && !$!.is_a?(SystemExit) && !$!.is_a?(Interrupt)
|
58
|
+
@error_to_display = $!
|
59
|
+
end
|
60
|
+
cleanup_with_ruby34_fix!
|
61
|
+
end
|
62
|
+
|
63
|
+
# ensure cleanup on signals
|
64
|
+
%w[INT TERM].each do |sig|
|
65
|
+
trap(sig) { cleanup_with_ruby34_fix!; exit }
|
66
|
+
end
|
67
|
+
|
68
|
+
@initialized = true
|
69
|
+
end
|
70
|
+
|
71
|
+
def cleanup_with_ruby34_fix!
|
72
|
+
return if @cleaned_up
|
73
|
+
|
74
|
+
begin
|
75
|
+
if @using_stty
|
76
|
+
# If we used stty for initialization, use it for cleanup too
|
77
|
+
system("stty sane 2>/dev/null")
|
78
|
+
elsif RUBY_VERSION >= "3.4.0"
|
79
|
+
# Ruby 3.4+ cleanup with timeout
|
80
|
+
begin
|
81
|
+
Timeout::timeout(0.5) do
|
82
|
+
$stdin.cooked!
|
83
|
+
$stdin.echo = true
|
84
|
+
end
|
85
|
+
rescue Timeout::Error
|
86
|
+
# Fallback to stty
|
87
|
+
system("stty sane 2>/dev/null")
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# Original cleanup
|
91
|
+
$stdin.cooked!
|
92
|
+
$stdin.echo = true
|
93
|
+
end
|
94
|
+
rescue => e
|
95
|
+
# Last resort cleanup
|
96
|
+
system("stty sane 2>/dev/null")
|
97
|
+
end
|
98
|
+
|
99
|
+
# Rest of cleanup remains the same
|
100
|
+
if @error_to_display.nil?
|
101
|
+
Rcurses.clear_screen
|
102
|
+
else
|
103
|
+
print "\e[999;1H"
|
104
|
+
print "\e[K"
|
105
|
+
end
|
106
|
+
|
107
|
+
Cursor.show
|
108
|
+
@cleaned_up = true
|
109
|
+
|
110
|
+
if @error_to_display
|
111
|
+
display_error(@error_to_display)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Test the patch
|
118
|
+
if __FILE__ == $0
|
119
|
+
puts "Testing rcurses Ruby 3.4.5 patch..."
|
120
|
+
puts "Ruby version: #{RUBY_VERSION}"
|
121
|
+
|
122
|
+
# Load rcurses
|
123
|
+
require 'rcurses'
|
124
|
+
|
125
|
+
# Apply the patch
|
126
|
+
class << Rcurses
|
127
|
+
alias_method :init_original!, :init!
|
128
|
+
alias_method :init!, :init_with_ruby34_fix!
|
129
|
+
alias_method :cleanup!, :cleanup_with_ruby34_fix!
|
130
|
+
end
|
131
|
+
|
132
|
+
# Test initialization
|
133
|
+
begin
|
134
|
+
puts "Calling Rcurses.init! with patch..."
|
135
|
+
Rcurses.init!
|
136
|
+
puts "✓ Initialization successful!"
|
137
|
+
|
138
|
+
# Do a simple test
|
139
|
+
print "\e[2J\e[H"
|
140
|
+
print "Patch works! Press any key..."
|
141
|
+
$stdin.getch if $stdin.respond_to?(:getch)
|
142
|
+
|
143
|
+
rescue => e
|
144
|
+
puts "✗ Error: #{e.message}"
|
145
|
+
ensure
|
146
|
+
Rcurses.cleanup!
|
147
|
+
puts "✓ Cleanup successful!"
|
148
|
+
end
|
149
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hyperlist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '5.1'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 5.1.
|
22
|
+
version: 5.1.6
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '5.1'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 5.1.
|
32
|
+
version: 5.1.6
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: minitest
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -76,12 +76,14 @@ files:
|
|
76
76
|
- debug_instructions.md
|
77
77
|
- diagnose.rb
|
78
78
|
- diagnose_ruby34.rb
|
79
|
+
- diagnose_ruby34_detailed.rb
|
79
80
|
- diagnose_safe.rb
|
80
81
|
- fix_terminal.sh
|
81
82
|
- hyperlist
|
82
83
|
- hyperlist.gemspec
|
83
84
|
- hyperlist_logo.svg
|
84
85
|
- hyperlist_ruby34_wrapper.rb
|
86
|
+
- rcurses_ruby34_patch.rb
|
85
87
|
- sample.hl
|
86
88
|
- screenshot_help.png
|
87
89
|
- screenshot_sample.png
|