rcurses 3.0 → 3.2
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 +100 -55
- 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: 79ceb9c8cca6e61988655c520a5b43f5f2a37b95f9c3064b59cefa962795b751
|
4
|
+
data.tar.gz: 67ad97d3a492318eff06f393eb4366d575b1cf2de2bc471b02b15a12d3505aaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0a668847e6b6f276ed5ee059d3e194184f4313556316ab3c80604d63cc8b99e5a733559b8e6e97da90c6fa2191ecdfc5b15e6639c41caa577f8810b0da87b77
|
7
|
+
data.tar.gz: 95a8a6b48bc7399121b50b3cbeae29631feab2b76a537a93c585bf9e654492e8bebbb30bb881b6b8522ec17866209c657a133511d500cdcdb589d17b2a3585c4
|
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
|
@@ -8,22 +37,25 @@ module Rcurses
|
|
8
37
|
attr_accessor :moreup, :moredown
|
9
38
|
|
10
39
|
def initialize(x = 1, y = 1, w = 1, h = 1, fg = nil, bg = nil)
|
40
|
+
@max_h, @max_w = IO.console.winsize
|
11
41
|
@x = x
|
12
42
|
@y = y
|
13
43
|
@w = w
|
14
44
|
@h = h
|
15
45
|
@fg, @bg = fg, bg
|
16
|
-
@text = ""
|
17
|
-
@align = "l"
|
18
|
-
@scroll = true
|
19
|
-
@prompt = ""
|
20
|
-
@ix = 0
|
21
|
-
@
|
46
|
+
@text = "" # Initialize text variable
|
47
|
+
@align = "l" # Default alignment
|
48
|
+
@scroll = true # Enable scroll indicators
|
49
|
+
@prompt = "" # Prompt for editline
|
50
|
+
@ix = 0 # Starting text line index
|
51
|
+
@prev_frame = nil # Holds the previously rendered frame (array of lines)
|
52
|
+
@line = 0 # For cursor tracking during editing:
|
53
|
+
@pos = 0 # For cursor tracking during editing:
|
22
54
|
end
|
23
55
|
|
24
|
-
def move(
|
25
|
-
@x +=
|
26
|
-
@y +=
|
56
|
+
def move(dx, dy)
|
57
|
+
@x += dx
|
58
|
+
@y += dy
|
27
59
|
refresh
|
28
60
|
end
|
29
61
|
|
@@ -74,11 +106,13 @@ module Rcurses
|
|
74
106
|
refresh
|
75
107
|
end
|
76
108
|
|
77
|
-
#
|
109
|
+
# 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.
|
78
113
|
def refresh(cont = @text)
|
79
114
|
@max_h, @max_w = IO.console.winsize
|
80
115
|
|
81
|
-
# Adjust pane dimensions (unchanged logic)
|
82
116
|
if @border
|
83
117
|
@w = @max_w - 2 if @w > @max_w - 2
|
84
118
|
@h = @max_h - 2 if @h > @max_h - 2
|
@@ -91,24 +125,24 @@ module Rcurses
|
|
91
125
|
@y = 1 if @y < 1; @y = @max_h - @h + 1 if @y + @h > @max_h + 1
|
92
126
|
end
|
93
127
|
|
94
|
-
# Save current cursor position.
|
95
128
|
o_row, o_col = pos
|
129
|
+
STDOUT.print "\e[?25l" # Hide cursor
|
96
130
|
|
97
|
-
# Hide cursor and switch to alternate screen buffer (if desired). Hide it any case and use Curses.show to bring it back.
|
98
|
-
# Note: The alternate screen buffer means your program’s output won’t mix with the normal terminal content.
|
99
|
-
STDOUT.print "\e[?25l" # hide cursor
|
100
|
-
# Uncomment the next line to use the alternate screen buffer.
|
101
|
-
#STDOUT.print "\e[?1049h"
|
102
|
-
|
103
|
-
buf = ""
|
104
|
-
buf << "\e[#{@y};#{@x}H" # Move cursor to start of pane.
|
105
131
|
fmt = [@fg, @bg].compact.join(',')
|
106
132
|
@txt = cont.split("\n")
|
107
133
|
@txt = textformat(cont) if @txt.any? { |line| line.pure.length >= @w }
|
108
134
|
@ix = @txt.length - 1 if @ix > @txt.length - 1
|
109
135
|
@ix = 0 if @ix < 0
|
110
136
|
|
111
|
-
|
137
|
+
new_frame = []
|
138
|
+
if @border
|
139
|
+
top_border = ("┌" + "─" * @w + "┐").c(fmt)
|
140
|
+
new_frame << top_border
|
141
|
+
end
|
142
|
+
|
143
|
+
content_rows = @h
|
144
|
+
content_rows.times do |i|
|
145
|
+
line_str = ""
|
112
146
|
l = @ix + i
|
113
147
|
if @txt[l].to_s != ""
|
114
148
|
pl = @w - @txt[l].pure.length
|
@@ -116,53 +150,65 @@ module Rcurses
|
|
116
150
|
hl = pl / 2
|
117
151
|
case @align
|
118
152
|
when "l"
|
119
|
-
|
153
|
+
line_str = @txt[l].c(fmt) + " ".c(fmt) * pl
|
120
154
|
when "r"
|
121
|
-
|
155
|
+
line_str = " ".c(fmt) * pl + @txt[l].c(fmt)
|
122
156
|
when "c"
|
123
|
-
|
157
|
+
line_str = " ".c(fmt) * hl + @txt[l].c(fmt) + " ".c(fmt) * (pl - hl)
|
124
158
|
end
|
125
159
|
else
|
126
|
-
|
160
|
+
line_str = " ".c(fmt) * @w
|
127
161
|
end
|
128
|
-
buf << "\e[#{@y + i + 1};#{@x}H" # Next line.
|
129
|
-
end
|
130
162
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
@moreup = true
|
135
|
-
else
|
136
|
-
@moreup = false
|
137
|
-
end
|
163
|
+
if @border
|
164
|
+
line_str = "│" + line_str + "│"
|
165
|
+
end
|
138
166
|
|
139
|
-
|
140
|
-
buf << "\e[#{@y + @h - 1};#{@x + @w - 1}H" << "∇".c(fmt)
|
141
|
-
@moredown = true
|
142
|
-
else
|
143
|
-
@moredown = false
|
167
|
+
new_frame << line_str
|
144
168
|
end
|
145
169
|
|
146
|
-
# Draw border if enabled.
|
147
170
|
if @border
|
148
|
-
|
149
|
-
|
150
|
-
buf << "\e[#{@y + i};#{@x - 1}H" << "│".c(fmt)
|
151
|
-
buf << "\e[#{@y + i};#{@x + @w}H" << "│".c(fmt)
|
152
|
-
end
|
153
|
-
buf << "\e[#{@y + @h};#{@x - 1}H" << ("└" + "─" * @w + "┘").c(fmt)
|
171
|
+
bottom_border = ("└" + "─" * @w + "┘").c(fmt)
|
172
|
+
new_frame << bottom_border
|
154
173
|
end
|
155
174
|
|
156
|
-
|
157
|
-
|
175
|
+
diff_buf = ""
|
176
|
+
new_frame.each_with_index do |line, i|
|
177
|
+
row_num = @border ? (@y - 1 + i) : (@y + i)
|
178
|
+
col_num = @border ? (@x - 1) : @x
|
179
|
+
if @prev_frame.nil? || @prev_frame[i] != line ||
|
180
|
+
(@border && (i == 0 || i == new_frame.size - 1))
|
181
|
+
diff_buf << "\e[#{row_num};#{col_num}H" << line
|
182
|
+
end
|
183
|
+
end
|
158
184
|
|
159
|
-
|
160
|
-
print
|
185
|
+
diff_buf << "\e[#{o_row};#{o_col}H"
|
186
|
+
print diff_buf
|
187
|
+
#STDOUT.print "\e[?25h" # We leave the cursor hidden unless explicitly shown
|
188
|
+
@prev_frame = new_frame
|
189
|
+
|
190
|
+
# Now, after printing the frame, draw the scroll markers separately.
|
191
|
+
if @scroll
|
192
|
+
# Use the same marker column as before.
|
193
|
+
marker_col = @border ? (@x + @w - 1) : (@x + @w - 1)
|
194
|
+
# Draw top marker at row = @y + 1 (inside the frame)
|
195
|
+
if @ix > 0
|
196
|
+
print "\e[#{@y};#{marker_col}H" + "∆".c(fmt)
|
197
|
+
end
|
198
|
+
# Draw bottom marker at row = @y + @h - 1 (inside the frame)
|
199
|
+
if (@txt.length - @ix) > @h
|
200
|
+
print "\e[#{@y + @h - 1};#{marker_col}H" + "∇".c(fmt)
|
201
|
+
end
|
202
|
+
end
|
161
203
|
|
162
|
-
#
|
163
|
-
|
204
|
+
# Now, reprint the right border column for each content line to fill any holes.
|
205
|
+
if @border
|
206
|
+
(0...@h).each do |i|
|
207
|
+
print "\e[#{@y + i};#{@x + @w}H" + "│".c(fmt)
|
208
|
+
end
|
209
|
+
end
|
164
210
|
|
165
|
-
|
211
|
+
new_frame.join("\n")
|
166
212
|
end
|
167
213
|
|
168
214
|
def textformat(cont)
|
@@ -439,7 +485,7 @@ module Rcurses
|
|
439
485
|
def calculate_posx
|
440
486
|
total_length = 0
|
441
487
|
(@ix + @line).times do |i|
|
442
|
-
total_length += @txt[i].pure.length + 1 # +1 for
|
488
|
+
total_length += @txt[i].pure.length + 1 # +1 for newline
|
443
489
|
end
|
444
490
|
total_length += @pos
|
445
491
|
total_length
|
@@ -516,4 +562,3 @@ module Rcurses
|
|
516
562
|
end
|
517
563
|
end
|
518
564
|
end
|
519
|
-
|
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.2: Fixed scroll markers and UTF-8 double-wide characters breaking borders
|
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.2'
|
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-02 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
|
-
double
|
32
|
+
in panes. Cursor movement around the terminal. New in 3.2: Fixed scroll markers
|
33
|
+
and UTF-8 double-wide characters breaking borders.'
|
34
34
|
email: g@isene.com
|
35
35
|
executables: []
|
36
36
|
extensions: []
|