textbringer 21 → 22

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: 9fb85ae8a3790d1ae876ecac31730522e121047dde8cf759bfb58e137ac5fb59
4
- data.tar.gz: 70c9b7d737cda7b8fcc2bbfab347c2d22a47743ca9ec5d3c6863c4bee8b5005d
3
+ metadata.gz: 75bc23a6bf83f87be572ca81acfb29c2171d99d07d0fc48c5a50fac711b12ecb
4
+ data.tar.gz: 5811dd657e36666831c26b9212494138c815629fe24997bb939c375c6d4a7944
5
5
  SHA512:
6
- metadata.gz: 87cecff29b608feff2999cda9619b429d4158b74e6e2ef3d5560f2b742170553b5101996a6907ff1d9c8852086e76b429166108586f353ac73a1d0354276f4df
7
- data.tar.gz: 4208176e8fb0ce43237786129ddbcd5a77b8b052b7003ad414c7b018b35086c5f68dfa944c3ade415969f18484e9e298a980ef5e138668fbd60286cc697456a5
6
+ metadata.gz: a3b91ec8b00442665b7060840b1e7a43be4193f887b0d9bc6925e1eb528b8b7e6dd173e2ba2c453b11ab8d56a248a4ef875ba760427a06d27de5dea5c58b19e8
7
+ data.tar.gz: 0abd782f34b8ebc44391a86bc6074e8369773de886738681d025bfafe22f01d357889c54dd8fb8b20a1d321f4789dd590793d32c9d1ddb82d28228c29b8c4d33
@@ -2,7 +2,7 @@ require "curses"
2
2
 
3
3
  module Textbringer
4
4
  class Face
5
- attr_reader :name, :attributes
5
+ attr_reader :name, :attributes, :color_pair, :text_attrs
6
6
 
7
7
  @@face_table = {}
8
8
  @@next_color_pair = 1
@@ -39,11 +39,11 @@ module Textbringer
39
39
  @reverse = reverse
40
40
  Curses.init_pair(@color_pair,
41
41
  Color[foreground], Color[background])
42
- @attributes = 0
43
- @attributes |= Curses.color_pair(@color_pair)
44
- @attributes |= Curses::A_BOLD if bold
45
- @attributes |= Curses::A_UNDERLINE if underline
46
- @attributes |= Curses::A_REVERSE if reverse
42
+ @text_attrs = 0
43
+ @text_attrs |= Curses::A_BOLD if bold
44
+ @text_attrs |= Curses::A_UNDERLINE if underline
45
+ @text_attrs |= Curses::A_REVERSE if reverse
46
+ @attributes = Curses.color_pair(@color_pair) | @text_attrs
47
47
  self
48
48
  end
49
49
  end
@@ -142,24 +142,13 @@ module Textbringer
142
142
  @buffer.save_point do |point|
143
143
  @window.erase
144
144
 
145
- # Get face attributes if face is specified
146
- face_attrs = 0
147
- if @face && Window.has_colors?
148
- face = Face[@face]
149
- face_attrs = face.attributes if face
150
- end
145
+ # Get face if face is specified
146
+ face = @face && Window.has_colors? ? Face[@face] : nil
151
147
 
152
- # Get current line face attributes if specified
153
- current_line_attrs = 0
154
- if @current_line_face && Window.has_colors?
155
- current_line_face = Face[@current_line_face]
156
- current_line_attrs = current_line_face.attributes if current_line_face
157
- end
148
+ # Get current line face if specified
149
+ current_line_face = @current_line_face && Window.has_colors? ? Face[@current_line_face] : nil
158
150
 
159
- @window.attrset(face_attrs)
160
- @in_region = false
161
- @in_isearch = false
162
- @current_highlight_attrs = face_attrs
151
+ apply_face_attrs(@window, face)
163
152
 
164
153
  # First pass: find which line contains point
165
154
  point_line = nil
@@ -195,11 +184,10 @@ module Textbringer
195
184
  @window.setpos(line_num, 0)
196
185
 
197
186
  # Determine which face to use for this line
198
- line_attrs = if @current_line_face && line_num == point_line
199
- current_line_attrs
200
- else
201
- face_attrs
202
- end
187
+ line_face = @current_line_face && line_num == point_line ? current_line_face : face
188
+
189
+ # Set attributes for the entire line
190
+ apply_face_attrs(@window, line_face)
203
191
 
204
192
  # Render characters on this line
205
193
  col = 0
@@ -228,29 +216,17 @@ module Textbringer
228
216
  break
229
217
  end
230
218
 
231
- # Apply face attributes to all characters
232
- if line_attrs != 0
233
- @window.attron(line_attrs)
234
- end
235
219
  @window.addstr(s)
236
- if line_attrs != 0
237
- @window.attroff(line_attrs)
238
- end
239
220
 
240
221
  col += char_width
241
222
  @buffer.forward_char
242
223
  end
243
224
 
244
225
  # Fill remaining space on the line with the face background
245
- if line_attrs != 0 && col < @columns
246
- @window.attron(line_attrs)
247
- @window.addstr(" " * (@columns - col))
248
- @window.attroff(line_attrs)
249
- elsif line_attrs == 0 && face_attrs != 0 && col < @columns
250
- # Use default face for padding if no line-specific attrs
251
- @window.attron(face_attrs)
252
- @window.addstr(" " * (@columns - col))
253
- @window.attroff(face_attrs)
226
+ if col < @columns
227
+ fill_face = line_face || face
228
+ apply_face_attrs(@window, fill_face)
229
+ @window.addstr(" " * (@columns - col)) if fill_face
254
230
  end
255
231
 
256
232
  # Track cursor position
@@ -263,12 +239,11 @@ module Textbringer
263
239
  end
264
240
 
265
241
  # Fill remaining lines with the face background
266
- if face_attrs != 0
242
+ if face
267
243
  while line_num < @lines
268
244
  @window.setpos(line_num, 0)
269
- @window.attron(face_attrs)
245
+ apply_face_attrs(@window, face)
270
246
  @window.addstr(" " * @columns)
271
- @window.attroff(face_attrs)
272
247
  line_num += 1
273
248
  end
274
249
  end
@@ -18,8 +18,8 @@ module Textbringer
18
18
  :backward_char,
19
19
  :forward_word,
20
20
  :backward_word,
21
- :scroll_up_command,
22
- :scroll_down_command,
21
+ :scroll_up,
22
+ :scroll_down,
23
23
  :beginning_of_buffer,
24
24
  :end_of_buffer,
25
25
  # Search commands
@@ -1,3 +1,3 @@
1
1
  module Textbringer
2
- VERSION = "21"
2
+ VERSION = "22"
3
3
  end
@@ -1,6 +1,16 @@
1
1
  require "curses"
2
2
  require_relative "window/fallback_characters"
3
3
 
4
+ unless Curses::Window.method_defined?(:attr_set)
5
+ using Module.new {
6
+ refine Curses::Window do
7
+ def attr_set(attrs, pair)
8
+ attrset(attrs | Curses.color_pair(pair))
9
+ end
10
+ end
11
+ }
12
+ end
13
+
4
14
  module Textbringer
5
15
  class Window
6
16
  Cursor = Struct.new(:y, :x)
@@ -146,6 +156,10 @@ module Textbringer
146
156
  Curses.start_color
147
157
  Curses.use_default_colors
148
158
  load_faces
159
+ else
160
+ Face.define :mode_line, reverse: true
161
+ Face.define :region, reverse: true
162
+ Face.define :isearch, underline: true
149
163
  end
150
164
  begin
151
165
  window =
@@ -261,7 +275,7 @@ module Textbringer
261
275
  @cursor = Cursor.new(0, 0)
262
276
  @in_region = false
263
277
  @in_isearch = false
264
- @current_highlight_attrs = 0
278
+ @current_hl_face = nil
265
279
  end
266
280
 
267
281
  def echo_area?
@@ -410,10 +424,10 @@ module Textbringer
410
424
  b = @buffer.point
411
425
  end
412
426
  name = names.find { |n| $~[n] }
413
- attributes = Face[name]&.attributes
414
- if attributes
415
- @highlight_on[b] = attributes
416
- @highlight_off[e] = attributes
427
+ face = Face[name]
428
+ if face
429
+ @highlight_on[b] = face
430
+ @highlight_off[e] = true
417
431
  end
418
432
  end
419
433
  end
@@ -434,45 +448,30 @@ module Textbringer
434
448
  highlight
435
449
  @window.erase
436
450
  @window.setpos(0, 0)
437
- @window.attrset(0)
438
451
  @in_region = false
439
452
  @in_isearch = false
440
- @current_highlight_attrs = 0
453
+ @current_hl_face = nil
441
454
  if current_or_minibuffer_selected? && @buffer.visible_mark &&
442
455
  @buffer.point_after_mark?(@buffer.visible_mark)
443
- @window.attron(region_attr)
444
456
  @in_region = true
445
457
  end
446
458
  if current_or_minibuffer_selected? && @buffer.isearch_mark &&
447
459
  @buffer.point_after_mark?(@buffer.isearch_mark)
448
- # If already in region, switch to isearch (priority)
449
- if @in_region
450
- @window.attroff(region_attr)
451
- end
452
- @window.attron(isearch_attr)
460
+ @in_region = false
453
461
  @in_isearch = true
454
462
  end
463
+ apply_window_attrs(@window)
455
464
  while !@buffer.end_of_buffer?
456
465
  cury = @window.cury
457
466
  curx = @window.curx
458
467
  update_cursor_and_attr(point, cury, curx)
459
- if attrs = @highlight_off[@buffer.point]
460
- if @in_region || @in_isearch
461
- # In region: only turn off non-color attributes (bold, underline, etc.)
462
- @window.attroff(attrs & ~Curses::A_COLOR)
463
- else
464
- @window.attroff(attrs)
465
- end
466
- @current_highlight_attrs = 0
468
+ if @highlight_off[@buffer.point]
469
+ @current_hl_face = nil
470
+ apply_window_attrs(@window)
467
471
  end
468
- if attrs = @highlight_on[@buffer.point]
469
- if @in_region || @in_isearch
470
- # In region: only turn on non-color attributes (preserve region background)
471
- @window.attron(attrs & ~Curses::A_COLOR)
472
- else
473
- @window.attron(attrs)
474
- end
475
- @current_highlight_attrs = attrs
472
+ if face = @highlight_on[@buffer.point]
473
+ @current_hl_face = face
474
+ apply_window_attrs(@window)
476
475
  end
477
476
  c = @buffer.char_after
478
477
  if c == "\n"
@@ -517,12 +516,7 @@ module Textbringer
517
516
  break if newx == columns && cury == lines - 2
518
517
  @buffer.forward_char
519
518
  end
520
- if current_or_minibuffer_selected? && @buffer.isearch_mark
521
- @window.attroff(isearch_attr)
522
- end
523
- if current_or_minibuffer_selected? && @buffer.visible_mark
524
- @window.attroff(region_attr)
525
- end
519
+ apply_window_attrs(@window)
526
520
  @buffer.mark_to_point(@bottom_of_window)
527
521
  if @buffer.point_at_mark?(point)
528
522
  @cursor.y = @window.cury
@@ -712,8 +706,8 @@ module Textbringer
712
706
  def redisplay_mode_line
713
707
  @mode_line.erase
714
708
  @mode_line.setpos(0, 0)
715
- attrs = @@has_colors ? Face[:mode_line].attributes : Curses::A_REVERSE
716
- @mode_line.attrset(attrs)
709
+ face = Face[:mode_line]
710
+ @mode_line.attr_set(face.text_attrs, face.color_pair)
717
711
  @mode_line.addstr("#{@buffer.input_method_status} #{@buffer.name} ")
718
712
  @mode_line.addstr("[+]") if @buffer.modified?
719
713
  @mode_line.addstr("[RO]") if @buffer.read_only?
@@ -731,7 +725,7 @@ module Textbringer
731
725
  @mode_line.addstr(" #{line},#{column}")
732
726
  @mode_line.addstr(" (#{@buffer.mode_names.join(' ')})")
733
727
  @mode_line.addstr(" " * (columns - @mode_line.curx))
734
- @mode_line.attrset(0)
728
+ @mode_line.attr_set(0, 0)
735
729
  @mode_line.noutrefresh
736
730
  end
737
731
 
@@ -746,45 +740,28 @@ module Textbringer
746
740
  end
747
741
 
748
742
  def update_cursor_and_attr(point, cury, curx)
743
+ changed = false
749
744
  if @buffer.point_at_mark?(point)
750
745
  @cursor.y = cury
751
746
  @cursor.x = curx
752
747
  # Handle visible mark transitions
753
748
  if current_or_minibuffer_selected? && @buffer.visible_mark
754
749
  if @buffer.point_after_mark?(@buffer.visible_mark)
755
- unless @in_isearch
756
- @window.attroff(region_attr)
757
- # Restore syntax highlighting colors after exiting region
758
- if @current_highlight_attrs != 0
759
- @window.attron(@current_highlight_attrs)
760
- end
761
- end
762
750
  @in_region = false
751
+ changed = true
763
752
  elsif @buffer.point_before_mark?(@buffer.visible_mark)
764
- unless @in_isearch
765
- @window.attron(region_attr)
766
- end
767
753
  @in_region = true
754
+ changed = true
768
755
  end
769
756
  end
770
757
  # Handle isearch mark transitions
771
758
  if current_or_minibuffer_selected? && @buffer.isearch_mark
772
759
  if @buffer.point_after_mark?(@buffer.isearch_mark)
773
- @window.attroff(isearch_attr)
774
760
  @in_isearch = false
775
- # If we were covering a region, restore it
776
- if @in_region
777
- @window.attron(region_attr)
778
- elsif @current_highlight_attrs != 0
779
- @window.attron(@current_highlight_attrs)
780
- end
761
+ changed = true
781
762
  elsif @buffer.point_before_mark?(@buffer.isearch_mark)
782
- # Entering isearch - turn off region if active
783
- if @in_region
784
- @window.attroff(region_attr)
785
- end
786
- @window.attron(isearch_attr)
787
763
  @in_isearch = true
764
+ changed = true
788
765
  end
789
766
  end
790
767
  end
@@ -792,42 +769,25 @@ module Textbringer
792
769
  if current_or_minibuffer_selected? && @buffer.isearch_mark &&
793
770
  @buffer.point_at_mark?(@buffer.isearch_mark)
794
771
  if @buffer.point_after_mark?(point)
795
- @window.attroff(isearch_attr)
796
772
  @in_isearch = false
797
- # If we have a region underneath, restore it
798
- if @in_region
799
- @window.attron(region_attr)
800
- elsif @current_highlight_attrs != 0
801
- @window.attron(@current_highlight_attrs)
802
- end
773
+ changed = true
803
774
  elsif @buffer.point_before_mark?(point)
804
- # Entering isearch - turn off region if active
805
- if @in_region
806
- @window.attroff(region_attr)
807
- end
808
- @window.attron(isearch_attr)
809
775
  @in_isearch = true
776
+ changed = true
810
777
  end
811
778
  end
812
779
  # Handle transitions when point crosses visible mark
813
780
  if current_or_minibuffer_selected? && @buffer.visible_mark &&
814
781
  @buffer.point_at_mark?(@buffer.visible_mark)
815
782
  if @buffer.point_after_mark?(point)
816
- unless @in_isearch
817
- @window.attroff(region_attr)
818
- # Restore syntax highlighting colors after exiting region
819
- if @current_highlight_attrs != 0
820
- @window.attron(@current_highlight_attrs)
821
- end
822
- end
823
783
  @in_region = false
784
+ changed = true
824
785
  elsif @buffer.point_before_mark?(point)
825
- unless @in_isearch
826
- @window.attron(region_attr)
827
- end
828
786
  @in_region = true
787
+ changed = true
829
788
  end
830
789
  end
790
+ apply_window_attrs(@window) if changed
831
791
  end
832
792
 
833
793
  def compose_character(point, cury, curx, c)
@@ -1004,12 +964,28 @@ module Textbringer
1004
964
  end
1005
965
  end
1006
966
 
1007
- def region_attr
1008
- @@has_colors ? Face[:region].attributes : Curses::A_REVERSE
967
+ def apply_face_attrs(win, face)
968
+ win.attr_set(face&.text_attrs || 0, face&.color_pair || 0)
1009
969
  end
1010
970
 
1011
- def isearch_attr
1012
- @@has_colors ? Face[:isearch].attributes : Curses::A_UNDERLINE
971
+ def apply_window_attrs(win)
972
+ if @in_isearch
973
+ face = Face[:isearch]
974
+ elsif @in_region
975
+ face = Face[:region]
976
+ else
977
+ face = @current_hl_face
978
+ end
979
+
980
+ if face
981
+ text_attrs = face.text_attrs
982
+ if (@in_isearch || @in_region) && @current_hl_face
983
+ text_attrs |= @current_hl_face.text_attrs
984
+ end
985
+ win.attr_set(text_attrs, face.color_pair)
986
+ else
987
+ win.attr_set(0, 0)
988
+ end
1013
989
  end
1014
990
  end
1015
991
 
@@ -1057,10 +1033,10 @@ module Textbringer
1057
1033
  @window.addstr(@buffer.input_method_status)
1058
1034
  end
1059
1035
  @window.setpos(0, 0)
1060
- @window.attrset(0)
1036
+ @window.attr_set(0, 0)
1061
1037
  @in_region = false
1062
1038
  @in_isearch = false
1063
- @current_highlight_attrs = 0
1039
+ @current_hl_face = nil
1064
1040
  if @message
1065
1041
  @window.addstr(escape(@message))
1066
1042
  else
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: textbringer
3
3
  version: !ruby/object:Gem::Version
4
- version: '21'
4
+ version: '22'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda