rcurses 3.1 → 3.3
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/lib/rcurses/pane.rb +78 -29
- data/lib/rcurses.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c115cb970dc679cf90286b3881c0543de420c76930fe25ae63adf224433f6c62
|
4
|
+
data.tar.gz: d837ebda76384152815d687fd614ad41b48e8a7af4c131f125e1b4ad293b02bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9733a2dc05ac13ec49cd8bbd21681da9b0436f845d0a66256e30dc23c5038fb11f25b225174a0b9b008ebb1f0ea5f01a4a8e6571496e4119553ed8f895d2966
|
7
|
+
data.tar.gz: 0fde756777022b0606a041ddecaf3f1e44ef00b2e7f099f09ef25ca1c3fb3b18eaf8f067cccc2debf6c216efcee2c01d875cc2f865a59d36f19845deaec134c6
|
data/lib/rcurses/pane.rb
CHANGED
@@ -1,4 +1,33 @@
|
|
1
1
|
module Rcurses
|
2
|
+
# A simple display_width function that approximates how many columns a string occupies.
|
3
|
+
# This is a simplified version that may need adjustments for full Unicode support.
|
4
|
+
def self.display_width(str)
|
5
|
+
width = 0
|
6
|
+
str.each_char do |char|
|
7
|
+
cp = char.ord
|
8
|
+
if cp == 0
|
9
|
+
# NUL – no width
|
10
|
+
elsif cp < 32 || (cp >= 0x7F && cp < 0xA0)
|
11
|
+
# Control characters: no width
|
12
|
+
width += 0
|
13
|
+
# Approximate common wide ranges:
|
14
|
+
elsif (cp >= 0x1100 && cp <= 0x115F) ||
|
15
|
+
cp == 0x2329 || cp == 0x232A ||
|
16
|
+
(cp >= 0x2E80 && cp <= 0xA4CF) ||
|
17
|
+
(cp >= 0xAC00 && cp <= 0xD7A3) ||
|
18
|
+
(cp >= 0xF900 && cp <= 0xFAFF) ||
|
19
|
+
(cp >= 0xFE10 && cp <= 0xFE19) ||
|
20
|
+
(cp >= 0xFE30 && cp <= 0xFE6F) ||
|
21
|
+
(cp >= 0xFF00 && cp <= 0xFF60) ||
|
22
|
+
(cp >= 0xFFE0 && cp <= 0xFFE6)
|
23
|
+
width += 2
|
24
|
+
else
|
25
|
+
width += 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
width
|
29
|
+
end
|
30
|
+
|
2
31
|
class Pane
|
3
32
|
require 'clipboard' # Ensure the 'clipboard' gem is installed
|
4
33
|
include Cursor
|
@@ -78,12 +107,10 @@ module Rcurses
|
|
78
107
|
end
|
79
108
|
|
80
109
|
# Diff-based refresh that minimizes flicker.
|
81
|
-
#
|
82
|
-
# Content lines are wrapped in vertical border characters when @border is true.
|
110
|
+
# In this updated version we lazily process only the raw lines required to fill the pane.
|
83
111
|
def refresh(cont = @text)
|
84
112
|
@max_h, @max_w = IO.console.winsize
|
85
113
|
|
86
|
-
# Adjust pane dimensions and positions.
|
87
114
|
if @border
|
88
115
|
@w = @max_w - 2 if @w > @max_w - 2
|
89
116
|
@h = @max_h - 2 if @h > @max_h - 2
|
@@ -96,27 +123,45 @@ module Rcurses
|
|
96
123
|
@y = 1 if @y < 1; @y = @max_h - @h + 1 if @y + @h > @max_h + 1
|
97
124
|
end
|
98
125
|
|
99
|
-
# Save current cursor position.
|
100
126
|
o_row, o_col = pos
|
101
|
-
|
102
127
|
STDOUT.print "\e[?25l" # Hide cursor
|
103
128
|
|
104
129
|
fmt = [@fg, @bg].compact.join(',')
|
105
|
-
|
106
|
-
|
130
|
+
|
131
|
+
# Lazy evaluation: If the content or pane width has changed, reinitialize the lazy cache.
|
132
|
+
if !defined?(@cached_text) || @cached_text != cont || @cached_w != @w
|
133
|
+
@raw_txt = cont.split("\n")
|
134
|
+
@lazy_txt = [] # This will hold the processed (wrapped) lines as needed.
|
135
|
+
@lazy_index = 0 # Pointer to the next raw line to process.
|
136
|
+
@cached_text = cont
|
137
|
+
@cached_w = @w
|
138
|
+
end
|
139
|
+
|
140
|
+
content_rows = @h
|
141
|
+
# Ensure we have processed enough lines for the current scroll position + visible area.
|
142
|
+
required_lines = @ix + content_rows
|
143
|
+
while @lazy_txt.size < required_lines && @lazy_index < @raw_txt.size
|
144
|
+
raw_line = @raw_txt[@lazy_index]
|
145
|
+
# If the raw line is short, no wrapping is needed.
|
146
|
+
if raw_line.respond_to?(:pure) && raw_line.pure.length < @w
|
147
|
+
processed = [raw_line]
|
148
|
+
else
|
149
|
+
processed = split_line_with_ansi(raw_line, @w)
|
150
|
+
end
|
151
|
+
@lazy_txt.concat(processed)
|
152
|
+
@lazy_index += 1
|
153
|
+
end
|
154
|
+
@txt = @lazy_txt
|
155
|
+
|
107
156
|
@ix = @txt.length - 1 if @ix > @txt.length - 1
|
108
157
|
@ix = 0 if @ix < 0
|
109
158
|
|
110
|
-
# Build the new frame as an array of strings.
|
111
159
|
new_frame = []
|
112
160
|
if @border
|
113
|
-
# Top border spans (@w + 2) characters.
|
114
161
|
top_border = ("┌" + "─" * @w + "┐").c(fmt)
|
115
162
|
new_frame << top_border
|
116
163
|
end
|
117
164
|
|
118
|
-
# Build content lines.
|
119
|
-
content_rows = @h
|
120
165
|
content_rows.times do |i|
|
121
166
|
line_str = ""
|
122
167
|
l = @ix + i
|
@@ -136,37 +181,21 @@ module Rcurses
|
|
136
181
|
line_str = " ".c(fmt) * @w
|
137
182
|
end
|
138
183
|
|
139
|
-
# If border is enabled, add vertical border characters.
|
140
184
|
if @border
|
141
185
|
line_str = "│" + line_str + "│"
|
142
186
|
end
|
143
187
|
|
144
|
-
# Add scroll markers (overwrite the last character) if needed.
|
145
|
-
if i == 0 and @ix > 0 and @scroll
|
146
|
-
line_str[-1] = "∆".c(fmt)
|
147
|
-
@moreup = true
|
148
|
-
elsif i == content_rows - 1 and @txt.length - @ix > @h and @scroll
|
149
|
-
line_str[-1] = "∇".c(fmt)
|
150
|
-
@moredown = true
|
151
|
-
else
|
152
|
-
@moreup = false
|
153
|
-
@moredown = false
|
154
|
-
end
|
155
188
|
new_frame << line_str
|
156
189
|
end
|
157
190
|
|
158
191
|
if @border
|
159
|
-
# Bottom border.
|
160
192
|
bottom_border = ("└" + "─" * @w + "┘").c(fmt)
|
161
193
|
new_frame << bottom_border
|
162
194
|
end
|
163
195
|
|
164
|
-
# Diff-based update: update only lines that changed.
|
165
196
|
diff_buf = ""
|
166
197
|
new_frame.each_with_index do |line, i|
|
167
|
-
# Determine row number:
|
168
198
|
row_num = @border ? (@y - 1 + i) : (@y + i)
|
169
|
-
# When border is enabled, all lines (including content) start at column (@x - 1)
|
170
199
|
col_num = @border ? (@x - 1) : @x
|
171
200
|
if @prev_frame.nil? || @prev_frame[i] != line ||
|
172
201
|
(@border && (i == 0 || i == new_frame.size - 1))
|
@@ -176,13 +205,33 @@ module Rcurses
|
|
176
205
|
|
177
206
|
diff_buf << "\e[#{o_row};#{o_col}H"
|
178
207
|
print diff_buf
|
179
|
-
#STDOUT.print "\e[?25h" # Show cursor - but use Cursor.show instead if needed
|
180
|
-
|
181
208
|
@prev_frame = new_frame
|
209
|
+
|
210
|
+
# Draw scroll markers after printing the frame.
|
211
|
+
if @scroll
|
212
|
+
marker_col = @border ? (@x + @w - 1) : (@x + @w - 1)
|
213
|
+
if @ix > 0
|
214
|
+
print "\e[#{@y};#{marker_col}H" + "∆".c(fmt)
|
215
|
+
end
|
216
|
+
# If there are more processed lines than fit in the pane
|
217
|
+
# OR there remain raw lines to process, show the down marker.
|
218
|
+
if (@txt.length - @ix) > @h || (@lazy_index < @raw_txt.size)
|
219
|
+
print "\e[#{@y + @h - 1};#{marker_col}H" + "∇".c(fmt)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
if @border
|
224
|
+
(0...@h).each do |i|
|
225
|
+
print "\e[#{@y + i};#{@x + @w}H" + "│".c(fmt)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
182
229
|
new_frame.join("\n")
|
183
230
|
end
|
184
231
|
|
185
232
|
def textformat(cont)
|
233
|
+
# This method is no longer used in refresh since we process lazily,
|
234
|
+
# but is kept here if needed elsewhere.
|
186
235
|
lines = cont.split("\n")
|
187
236
|
result = []
|
188
237
|
lines.each do |line|
|
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.
|
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
|
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.
|
4
|
+
version: '3.3'
|
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-
|
11
|
+
date: 2025-04-04 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.
|
33
|
-
|
32
|
+
in panes. Cursor movement around the terminal. New in 3.3: Faster rendering of pane
|
33
|
+
content.'
|
34
34
|
email: g@isene.com
|
35
35
|
executables: []
|
36
36
|
extensions: []
|