rcurses 6.1.0 → 6.1.1
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/README.md +37 -6
- data/lib/rcurses.rb +50 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce484ba636e927e6344a8bb0552c49aec18df5cf3d2ebcb1c80c1d3927da3005
|
4
|
+
data.tar.gz: 9565880d7a799a27f364e3ec543f69c5061db9e9951684b3747cad5380b5ce85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6406ba055a63fcd8b187920f4280931b046d651919b08e3792db6a09de8ef5d5383de853847cd44cebf579ccb71c8a7a19b2d147cf825579dca6c96113130b1
|
7
|
+
data.tar.gz: 5522b3932739d6b726bed53a9b349006f0c7ab44bd79038008ed1f4db2cde530d0fe95e6f38d25bbf627b03a2dea4e8dd10f89991761ea048c65eec79f5dd92c
|
data/README.md
CHANGED
@@ -10,14 +10,23 @@ Here's a somewhat simple example of a TUI program using rcurses: The [T-REX](htt
|
|
10
10
|
|
11
11
|
And here's a much more involved example: The [RTFM](https://github.com/isene/RTFM) terminal file manager.
|
12
12
|
|
13
|
-
# NOTE: Version
|
14
|
-
- **
|
15
|
-
- **
|
16
|
-
- **
|
17
|
-
- **
|
18
|
-
- **Performance optimizations** - Maintains the speed of version 4.8.3
|
13
|
+
# NOTE: Version 6.1.1 adds optional error logging!
|
14
|
+
- **Error logging** - Set `RCURSES_ERROR_LOG=1` to log crashes to `/tmp/rcurses_errors_PID.log`
|
15
|
+
- **Race-condition free** - Uses process-specific filenames to avoid conflicts
|
16
|
+
- **Stack trace preservation** - Full backtraces logged even when screen is cleared
|
17
|
+
- **Completely opt-in** - Zero impact unless explicitly enabled
|
19
18
|
- **Full backward compatibility** - All existing applications work unchanged
|
20
19
|
|
20
|
+
Previous improvements in 6.1.0:
|
21
|
+
- **Safe regex substitution** - New `safe_gsub` methods prevent ANSI code corruption
|
22
|
+
- **ANSI detection** - Check if strings contain ANSI codes with `has_ansi?`
|
23
|
+
- **Visible length calculation** - Get true text length with `visible_length`
|
24
|
+
- **Conditional coloring** - Apply colors only when needed with `safe_fg`/`safe_bg`
|
25
|
+
|
26
|
+
Previous major improvements in 5.0.0:
|
27
|
+
- Memory leak fixes, terminal state protection, enhanced Unicode support
|
28
|
+
- Error handling improvements and performance optimizations
|
29
|
+
|
21
30
|
Version 4.5 gave full RGB support in addition to 256-colors. Just write a color as a string - e.g. `"d533e0"` for a hexadecimal RGB color (or use the terminal 256 colors by supplying an integer in the range 0-255)
|
22
31
|
|
23
32
|
# Why?
|
@@ -129,12 +138,34 @@ pure | Strip text of any "dressing" (example: with `text = "TEST".b`,
|
|
129
138
|
clean_ansi | Strip seemingly uncolored strings of ansi code (those that are enclosed in "\e[0m"
|
130
139
|
shorten(n) | Shorten the pure version of the string to 'n' characters, preserving any ANSI coding
|
131
140
|
inject("chars",pos) | Inject "chars" at position 'pos' in the pure version of the string (if 'pos' is '-1', then append at end). Preserves any ANSI code
|
141
|
+
safe_gsub(pattern, replacement) | Apply regex substitution without corrupting existing ANSI codes (example: `colored_text.safe_gsub(/\[([^\]]*)\]/) { |m| m.fg(46) }`)
|
142
|
+
safe_gsub!(pattern, replacement) | In-place version of safe_gsub
|
143
|
+
has_ansi? | Check if string contains ANSI escape sequences (returns true/false)
|
144
|
+
visible_length | Get the visible length of text (excluding ANSI codes)
|
145
|
+
safe_fg(fg) | Apply foreground color only if string doesn't already have ANSI codes
|
146
|
+
safe_bg(bg) | Apply background color only if string doesn't already have ANSI codes
|
132
147
|
|
133
148
|
PS: Blink does not work in conjunction with setting a background color in urxvt. It does work in gnome-terminal. But the overall performance in urxvt as orders of magnitude better than gnome-terminal.
|
134
149
|
|
135
150
|
# Cleaning up upon exit
|
136
151
|
End a program with `Rcurses.clear_screen` to clear the screen for any rcurses residues.
|
137
152
|
|
153
|
+
# Error Logging (New in 6.1.1)
|
154
|
+
When applications using rcurses crash, stack traces are typically lost because rcurses clears the screen on exit. To debug crashes, you can now enable error logging:
|
155
|
+
|
156
|
+
```bash
|
157
|
+
RCURSES_ERROR_LOG=1 my_rcurses_app
|
158
|
+
```
|
159
|
+
|
160
|
+
This will create a detailed error log at `/tmp/rcurses_errors_PID.log` containing:
|
161
|
+
- Full stack trace with line numbers
|
162
|
+
- Error class and message
|
163
|
+
- Process information (PID, program name, working directory)
|
164
|
+
- Ruby and rcurses version information
|
165
|
+
- Relevant environment variables
|
166
|
+
|
167
|
+
Each process gets its own log file (using PID) to prevent race conditions when multiple rcurses applications are running simultaneously. The feature is completely opt-in and has zero performance impact when disabled.
|
168
|
+
|
138
169
|
# module Cursor
|
139
170
|
To use this module, first do `include Rcurses::Cursor`. Create a new cursor object with `mycursor = Rcurses::Cursor`. Then you can apply the following methods to `mycursor`:
|
140
171
|
|
data/lib/rcurses.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Web_site: http://isene.com/
|
6
6
|
# Github: https://github.com/isene/rcurses
|
7
7
|
# License: Public domain
|
8
|
-
# Version: 6.1.
|
8
|
+
# Version: 6.1.1: Added optional error logging with RCURSES_ERROR_LOG=1
|
9
9
|
|
10
10
|
require 'io/console' # Basic gem for rcurses
|
11
11
|
require 'io/wait' # stdin handling
|
@@ -124,15 +124,18 @@ module Rcurses
|
|
124
124
|
|
125
125
|
# Private: Display error information after terminal cleanup
|
126
126
|
def display_error(error)
|
127
|
+
# Log error to file if RCURSES_ERROR_LOG is set
|
128
|
+
log_error_to_file(error) if ENV['RCURSES_ERROR_LOG'] == '1'
|
129
|
+
|
127
130
|
# Only display if we're in a TTY and not in a test environment
|
128
131
|
return unless $stdout.tty?
|
129
|
-
|
132
|
+
|
130
133
|
# Add some spacing and make the error very visible
|
131
134
|
puts "\n\n\e[41;37m APPLICATION CRASHED \e[0m"
|
132
135
|
puts "\e[31m═══════════════════════════════════════════════════════════\e[0m"
|
133
136
|
puts "\e[33mError Type:\e[0m #{error.class}"
|
134
137
|
puts "\e[33mMessage:\e[0m #{error.message}"
|
135
|
-
|
138
|
+
|
136
139
|
# Show backtrace if debug mode is enabled
|
137
140
|
if ENV['DEBUG'] || ENV['RCURSES_DEBUG']
|
138
141
|
puts "\n\e[33mBacktrace:\e[0m"
|
@@ -142,11 +145,54 @@ module Rcurses
|
|
142
145
|
else
|
143
146
|
puts "\n\e[90mTip: Set DEBUG=1 or RCURSES_DEBUG=1 to see the full backtrace\e[0m"
|
144
147
|
end
|
145
|
-
|
148
|
+
|
146
149
|
puts "\e[31m═══════════════════════════════════════════════════════════\e[0m"
|
147
150
|
puts "\e[33mNote:\e[0m The application state above shows where the error occurred."
|
151
|
+
|
152
|
+
# Show log file location if logging is enabled
|
153
|
+
if ENV['RCURSES_ERROR_LOG'] == '1'
|
154
|
+
puts "\e[33mError logged to:\e[0m /tmp/rcurses_errors_#{Process.pid}.log"
|
155
|
+
end
|
148
156
|
puts ""
|
149
157
|
end
|
158
|
+
|
159
|
+
# Private: Log error details to a PID-specific file
|
160
|
+
def log_error_to_file(error)
|
161
|
+
return unless ENV['RCURSES_ERROR_LOG'] == '1'
|
162
|
+
|
163
|
+
log_file = "/tmp/rcurses_errors_#{Process.pid}.log"
|
164
|
+
timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
165
|
+
|
166
|
+
begin
|
167
|
+
File.open(log_file, "a") do |f|
|
168
|
+
f.puts "=" * 60
|
169
|
+
f.puts "RCURSES ERROR LOG - #{timestamp}"
|
170
|
+
f.puts "PID: #{Process.pid}"
|
171
|
+
f.puts "Program: #{$0}"
|
172
|
+
f.puts "Working Directory: #{Dir.pwd}"
|
173
|
+
f.puts "Ruby Version: #{RUBY_VERSION}"
|
174
|
+
f.puts "Rcurses Version: 6.1.1"
|
175
|
+
f.puts "=" * 60
|
176
|
+
f.puts "Error Class: #{error.class}"
|
177
|
+
f.puts "Error Message: #{error.message}"
|
178
|
+
f.puts
|
179
|
+
f.puts "Full Backtrace:"
|
180
|
+
error.backtrace.each_with_index do |line, i|
|
181
|
+
f.puts " #{i}: #{line}"
|
182
|
+
end
|
183
|
+
f.puts
|
184
|
+
f.puts "Environment Variables:"
|
185
|
+
ENV.select { |k, v| k.start_with?('RCURSES') || k == 'DEBUG' }.each do |k, v|
|
186
|
+
f.puts " #{k}=#{v}"
|
187
|
+
end
|
188
|
+
f.puts "=" * 60
|
189
|
+
f.puts
|
190
|
+
end
|
191
|
+
rescue => file_error
|
192
|
+
# Silently fail if we can't write to log file - don't interfere with main error display
|
193
|
+
# This prevents cascading errors that could hide the original problem
|
194
|
+
end
|
195
|
+
end
|
150
196
|
|
151
197
|
# Public: Run a block with proper error handling and terminal cleanup
|
152
198
|
# This ensures errors are displayed after terminal is restored
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rcurses
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1.
|
4
|
+
version: 6.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|