rcurses 3.2 → 3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79ceb9c8cca6e61988655c520a5b43f5f2a37b95f9c3064b59cefa962795b751
4
- data.tar.gz: 67ad97d3a492318eff06f393eb4366d575b1cf2de2bc471b02b15a12d3505aaf
3
+ metadata.gz: '089c7b974ce66ffc1afdc8c70d6b5d354f11926894329367c4ac304fc56e7af4'
4
+ data.tar.gz: 23e9d5853f8977ecc914a4cdbfce0a26570d9e3076415709a150c59b5ddc61df
5
5
  SHA512:
6
- metadata.gz: b0a668847e6b6f276ed5ee059d3e194184f4313556316ab3c80604d63cc8b99e5a733559b8e6e97da90c6fa2191ecdfc5b15e6639c41caa577f8810b0da87b77
7
- data.tar.gz: 95a8a6b48bc7399121b50b3cbeae29631feab2b76a537a93c585bf9e654492e8bebbb30bb881b6b8522ec17866209c657a133511d500cdcdb589d17b2a3585c4
6
+ metadata.gz: 31a9cf284d90a1ead46acfc3f3f77c0777e6e879481e01203e2bb7219579b6d694d50c08d9af7beedcd7a355244bee5975b4f3d9b037827081430abf08363721
7
+ data.tar.gz: d0f9ed3cdf1a29c10e1a732f61e62c2054ad549edb04398ea5a273c49730c7bdb567e16e59ee67ebdcc9d420499e1823f2c11b087b558bb7e3bfb71b1293b6b0
data/README.md CHANGED
@@ -79,6 +79,7 @@ Method | Description
79
79
  new/init | Initializes a Pane with optional arguments `x, y, w, h, fg and bg`
80
80
  move(x,y) | Move the pane by `x`and `y` (`mypane.move(-4,5)` will move the pane left four characters and five characters down)
81
81
  refresh | Refreshes/redraws the Pane with content
82
+ full_refresh | Refreshes/redraws the Pane with content completely (without diff rendering)
82
83
  edit | An editor for the Pane. When this is invoked, all existing font dressing is stripped and the user gets to edit the raw text. The user can add font effects similar to Markdown; Use an asterisk before and after text to be drawn in bold, text between forward-slashes become italic, and underline before and after text means the text will be underlined, a hash-sign before and after text makes the text reverse colored. You can also combine a whole set of dressings in this format: `<23,245,biurl|Hello World!>` - this will make "Hello World!" print in the color 23 with the background color 245 (regardless of the Pane's fg/bg setting) in bold, italic, underlined, reversed colored and blinking. Hitting `ESC` while in edit mode will disregard the edits, while `Ctrl-S` will save the edits
83
84
  editline | Used for one-line Panes. It will print the content of the property `prompt` and then the property `text` that can then be edited by the user. Hitting `ESC` will disregard the edits, while `ENTER` will save the edited text
84
85
  puts(text) | Short form for setting panel.text, then doing a refresh of that panel
@@ -105,6 +106,7 @@ l | Set text to be printed blinking (example: `"TEST".l`)
105
106
  r | Set text to be printed in reverse colors (example: `"TEST".r`)
106
107
  c(code) | Use coded format like "TEST".c("204,45,bui") to print "TEST" in bold, underline italic, fg=204 and bg=45 (the format is `.c("fg,bg,biulr"))
107
108
  pure | Strip text of any "dressing" (example: with `text = "TEST".b`, you will have bold text in the variable `text`, then with `text.pure` it will show "uncoded" or pure text)
109
+ ansi_clean | Strip seemingly uncolored strings of ansi code (those that are enclosed in "\e[0m"
108
110
  shorten(n) | Shorten the pure version of the string to 'n' characters, preserving any ANSI coding
109
111
  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
110
112
 
data/lib/rcurses/pane.rb CHANGED
@@ -106,10 +106,14 @@ module Rcurses
106
106
  refresh
107
107
  end
108
108
 
109
+ # full_refresh forces a complete repaint.
110
+ def full_refresh(cont = @text)
111
+ @prev_frame = nil
112
+ refresh(cont)
113
+ end
114
+
109
115
  # Diff-based refresh that minimizes flicker.
110
- # (This is your previously best-working code.)
111
- # We have removed scroll marker insertion from within the double-buffered frame.
112
- # Instead, after printing the frame we reprint the right border column.
116
+ # In this updated version we lazily process only the raw lines required to fill the pane.
113
117
  def refresh(cont = @text)
114
118
  @max_h, @max_w = IO.console.winsize
115
119
 
@@ -129,8 +133,32 @@ module Rcurses
129
133
  STDOUT.print "\e[?25l" # Hide cursor
130
134
 
131
135
  fmt = [@fg, @bg].compact.join(',')
132
- @txt = cont.split("\n")
133
- @txt = textformat(cont) if @txt.any? { |line| line.pure.length >= @w }
136
+
137
+ # Lazy evaluation: If the content or pane width has changed, reinitialize the lazy cache.
138
+ if !defined?(@cached_text) || @cached_text != cont || @cached_w != @w
139
+ @raw_txt = cont.split("\n")
140
+ @lazy_txt = [] # This will hold the processed (wrapped) lines as needed.
141
+ @lazy_index = 0 # Pointer to the next raw line to process.
142
+ @cached_text = cont
143
+ @cached_w = @w
144
+ end
145
+
146
+ content_rows = @h
147
+ # Ensure we have processed enough lines for the current scroll position + visible area.
148
+ required_lines = @ix + content_rows
149
+ while @lazy_txt.size < required_lines && @lazy_index < @raw_txt.size
150
+ raw_line = @raw_txt[@lazy_index]
151
+ # If the raw line is short, no wrapping is needed.
152
+ if raw_line.respond_to?(:pure) && raw_line.pure.length < @w
153
+ processed = [raw_line]
154
+ else
155
+ processed = split_line_with_ansi(raw_line, @w)
156
+ end
157
+ @lazy_txt.concat(processed)
158
+ @lazy_index += 1
159
+ end
160
+ @txt = @lazy_txt
161
+
134
162
  @ix = @txt.length - 1 if @ix > @txt.length - 1
135
163
  @ix = 0 if @ix < 0
136
164
 
@@ -140,7 +168,6 @@ module Rcurses
140
168
  new_frame << top_border
141
169
  end
142
170
 
143
- content_rows = @h
144
171
  content_rows.times do |i|
145
172
  line_str = ""
146
173
  l = @ix + i
@@ -184,24 +211,21 @@ module Rcurses
184
211
 
185
212
  diff_buf << "\e[#{o_row};#{o_col}H"
186
213
  print diff_buf
187
- #STDOUT.print "\e[?25h" # We leave the cursor hidden unless explicitly shown
188
214
  @prev_frame = new_frame
189
215
 
190
- # Now, after printing the frame, draw the scroll markers separately.
216
+ # Draw scroll markers after printing the frame.
191
217
  if @scroll
192
- # Use the same marker column as before.
193
218
  marker_col = @border ? (@x + @w - 1) : (@x + @w - 1)
194
- # Draw top marker at row = @y + 1 (inside the frame)
195
219
  if @ix > 0
196
220
  print "\e[#{@y};#{marker_col}H" + "∆".c(fmt)
197
221
  end
198
- # Draw bottom marker at row = @y + @h - 1 (inside the frame)
199
- if (@txt.length - @ix) > @h
222
+ # If there are more processed lines than fit in the pane
223
+ # OR there remain raw lines to process, show the down marker.
224
+ if (@txt.length - @ix) > @h || (@lazy_index < @raw_txt.size)
200
225
  print "\e[#{@y + @h - 1};#{marker_col}H" + "∇".c(fmt)
201
226
  end
202
227
  end
203
228
 
204
- # Now, reprint the right border column for each content line to fill any holes.
205
229
  if @border
206
230
  (0...@h).each do |i|
207
231
  print "\e[#{@y + i};#{@x + @w}H" + "│".c(fmt)
@@ -212,6 +236,8 @@ module Rcurses
212
236
  end
213
237
 
214
238
  def textformat(cont)
239
+ # This method is no longer used in refresh since we process lazily,
240
+ # but is kept here if needed elsewhere.
215
241
  lines = cont.split("\n")
216
242
  result = []
217
243
  lines.each do |line|
@@ -562,3 +588,4 @@ module Rcurses
562
588
  end
563
589
  end
564
590
  end
591
+
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: 3.2: Fixed scroll markers and UTF-8 double-wide characters breaking borders
8
+ # Version: 3.3: Faster rendering of pane content
9
9
 
10
10
  require 'io/console' # Basic gem for rcurses
11
11
  require 'io/wait' # stdin handling
@@ -34,6 +34,16 @@ class String
34
34
  prop
35
35
  end
36
36
 
37
+ def clean_ansi
38
+ # Remove surrounding \e[0m if the string is otherwise unstyled
39
+ stripped = self.gsub(/\A\e\[0m/, '').gsub(/\e\[0m\z/, '')
40
+ if stripped.pure == stripped
41
+ stripped
42
+ else
43
+ self
44
+ end
45
+ end
46
+
37
47
  def pure
38
48
  self.gsub(/\e\[\d+(?:;\d+)*m/, '')
39
49
  end
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: '3.2'
4
+ version: '3.4'
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-04-02 00:00:00.000000000 Z
11
+ date: 2025-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -29,8 +29,8 @@ description: 'Create curses applications for the terminal easier than ever. Crea
29
29
  up text (in panes or anywhere in the terminal) in bold, italic, underline, reverse
30
30
  color, blink and in any 256 terminal colors for foreground and background. Use a
31
31
  simple editor to let users edit text in panes. Left, right or center align text
32
- in panes. Cursor movement around the terminal. New in 3.2: Fixed scroll markers
33
- and UTF-8 double-wide characters breaking borders.'
32
+ in panes. Cursor movement around the terminal. New in 3.4: Added ansi_clean and
33
+ full_refresh methods.'
34
34
  email: g@isene.com
35
35
  executables: []
36
36
  extensions: []