rcurses 3.1 → 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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rcurses/pane.rb +55 -27
  3. data/lib/rcurses.rb +1 -1
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07bf042dcaa49e65d87441e77e32cb04f6d8738abe081979bc8589966b2ec65f
4
- data.tar.gz: 234ad19f3e79216d0dd0561e2cfbb43318d7f308c596ab2a847eeda6fefe9563
3
+ metadata.gz: 79ceb9c8cca6e61988655c520a5b43f5f2a37b95f9c3064b59cefa962795b751
4
+ data.tar.gz: 67ad97d3a492318eff06f393eb4366d575b1cf2de2bc471b02b15a12d3505aaf
5
5
  SHA512:
6
- metadata.gz: d8d764879351431d6057dd1fa573ca2bba3134c207c8c4f1ad4f511d1d12ca93c392e163401a9592c18b6af48f590d7509e510592f4191bf156c89c1c89d644a
7
- data.tar.gz: 8ffe0551b49238aa84ef6811d140c398a96736c92f77afd10afd0116431d6856d6472f619345b96827391a9b83d152965704f586119bcd56410b626100da71e1
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
@@ -78,12 +107,12 @@ module Rcurses
78
107
  end
79
108
 
80
109
  # Diff-based refresh that minimizes flicker.
81
- # Building a frame (an array of lines) that includes borders (if enabled).
82
- # Content lines are wrapped in vertical border characters when @border is true.
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.
83
113
  def refresh(cont = @text)
84
114
  @max_h, @max_w = IO.console.winsize
85
115
 
86
- # Adjust pane dimensions and positions.
87
116
  if @border
88
117
  @w = @max_w - 2 if @w > @max_w - 2
89
118
  @h = @max_h - 2 if @h > @max_h - 2
@@ -96,9 +125,7 @@ module Rcurses
96
125
  @y = 1 if @y < 1; @y = @max_h - @h + 1 if @y + @h > @max_h + 1
97
126
  end
98
127
 
99
- # Save current cursor position.
100
128
  o_row, o_col = pos
101
-
102
129
  STDOUT.print "\e[?25l" # Hide cursor
103
130
 
104
131
  fmt = [@fg, @bg].compact.join(',')
@@ -107,15 +134,12 @@ module Rcurses
107
134
  @ix = @txt.length - 1 if @ix > @txt.length - 1
108
135
  @ix = 0 if @ix < 0
109
136
 
110
- # Build the new frame as an array of strings.
111
137
  new_frame = []
112
138
  if @border
113
- # Top border spans (@w + 2) characters.
114
139
  top_border = ("┌" + "─" * @w + "┐").c(fmt)
115
140
  new_frame << top_border
116
141
  end
117
142
 
118
- # Build content lines.
119
143
  content_rows = @h
120
144
  content_rows.times do |i|
121
145
  line_str = ""
@@ -136,37 +160,21 @@ module Rcurses
136
160
  line_str = " ".c(fmt) * @w
137
161
  end
138
162
 
139
- # If border is enabled, add vertical border characters.
140
163
  if @border
141
164
  line_str = "│" + line_str + "│"
142
165
  end
143
166
 
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
167
  new_frame << line_str
156
168
  end
157
169
 
158
170
  if @border
159
- # Bottom border.
160
171
  bottom_border = ("└" + "─" * @w + "┘").c(fmt)
161
172
  new_frame << bottom_border
162
173
  end
163
174
 
164
- # Diff-based update: update only lines that changed.
165
175
  diff_buf = ""
166
176
  new_frame.each_with_index do |line, i|
167
- # Determine row number:
168
177
  row_num = @border ? (@y - 1 + i) : (@y + i)
169
- # When border is enabled, all lines (including content) start at column (@x - 1)
170
178
  col_num = @border ? (@x - 1) : @x
171
179
  if @prev_frame.nil? || @prev_frame[i] != line ||
172
180
  (@border && (i == 0 || i == new_frame.size - 1))
@@ -176,9 +184,30 @@ module Rcurses
176
184
 
177
185
  diff_buf << "\e[#{o_row};#{o_col}H"
178
186
  print diff_buf
179
- #STDOUT.print "\e[?25h" # Show cursor - but use Cursor.show instead if needed
180
-
187
+ #STDOUT.print "\e[?25h" # We leave the cursor hidden unless explicitly shown
181
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
203
+
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
210
+
182
211
  new_frame.join("\n")
183
212
  end
184
213
 
@@ -533,4 +562,3 @@ module Rcurses
533
562
  end
534
563
  end
535
564
  end
536
-
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.1: Flicker reduction by diff rendering
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.1'
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-01 00:00:00.000000000 Z
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.1: Flicker reduction by
33
- diff rendering.'
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: []