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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -6
  3. data/lib/rcurses.rb +50 -4
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5132248f03d0f62fed76d2f525b0a84bf512ba0454054623e4d8528b435d9f64
4
- data.tar.gz: 11ab84d968557065955885eb27d188677889d78e5ee46acc1a62064bc9b27116
3
+ metadata.gz: ce484ba636e927e6344a8bb0552c49aec18df5cf3d2ebcb1c80c1d3927da3005
4
+ data.tar.gz: 9565880d7a799a27f364e3ec543f69c5061db9e9951684b3747cad5380b5ce85
5
5
  SHA512:
6
- metadata.gz: 12c461a57d353bc5a7273de1a664676a95c2d9ef445096e08222b447b45a1b0b847e9cc1570e475046e24f49264cabb1ae9b9c1e2944e09639bd9b2c881e20b6
7
- data.tar.gz: 8602247bbf7c6e6377349f68dc7c2f8ff422f28890886ad5772a5aa1f5b6aed7acd1dcee8d1a66afeb7cf563dc4da832dc3caf4225922e1ffa7d6591f9204d28
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 5.0.0 brings major improvements!
14
- - **Memory leak fixes** - Better memory management and history limits
15
- - **Terminal state protection** - Proper terminal restoration on crashes
16
- - **Enhanced Unicode support** - Better handling of CJK characters and emojis
17
- - **Error handling improvements** - More robust operation in edge cases
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.0: Added safe_gsub methods to prevent ANSI code corruption
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.0
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-01 00:00:00.000000000 Z
11
+ date: 2025-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard