textbringer 16 → 18

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: 0b838b91740f3985ebcdc6987e72ea7fe9daa28ad0b273a6f6e0f309818778a6
4
- data.tar.gz: 51a55425c1cdaefb69b74451c3c9091f85138549a27a60e8ebb23161b4530847
3
+ metadata.gz: 6880825c5cf726a2e49e28052cb09c0e8f0a15eadbf98b38e8806e6b486b9475
4
+ data.tar.gz: 79cef469e62da96630672057fda32b69ccdd349f76df36821f45a71be7e552d5
5
5
  SHA512:
6
- metadata.gz: 128afb2fe777b9847ace11badce3121391576a98b7caba7f5bdb93faf4383e00b15db4ae23e263e8f1a26fc79ef1b3fa5b12d02e6ae8b590533088c680ef3532
7
- data.tar.gz: 4e082735768a0d2647abf67ca9c7a5268ba6607fe59462de26dff2e59caca272c68224e061791cad58d6f81648bb17c9031b880361a56ce93912b3e27c487457
6
+ metadata.gz: 868b9d1cce93bf0dc1dabdb4e59c0dd775210c700b794b7093bfedb82d95d7d9e82191fc1d05daa9342e282d151567aa4d0d85a93f489ced5165e7d537d1e102
7
+ data.tar.gz: afad73fc5062774e6aa9b4d7cfa175be24f2dc25c9345218359ddce61f0049dcd7059709fe72c52c71d15d5625393a46987d0df04a36dbdc19d3855df02a8dab
@@ -10,7 +10,7 @@ module Textbringer
10
10
 
11
11
  attr_accessor :mode, :keymap
12
12
  attr_reader :name, :file_name, :file_encoding, :file_format, :point, :marks
13
- attr_reader :current_line, :current_column, :visible_mark, :mark_active
13
+ attr_reader :current_line, :current_column, :visible_mark, :isearch_mark, :mark_active
14
14
  attr_reader :last_match
15
15
  attr_reader :input_method
16
16
 
@@ -254,6 +254,7 @@ module Textbringer
254
254
  @save_point_level = 0
255
255
  @match_offsets = []
256
256
  @visible_mark = nil
257
+ @isearch_mark = nil
257
258
  @mark_active = false
258
259
  @read_only = read_only
259
260
  @callbacks = {}
@@ -948,6 +949,18 @@ module Textbringer
948
949
  end
949
950
  end
950
951
 
952
+ def set_isearch_mark(pos = @point)
953
+ @isearch_mark ||= new_mark
954
+ @isearch_mark.location = pos
955
+ end
956
+
957
+ def delete_isearch_mark
958
+ if @isearch_mark
959
+ @isearch_mark.delete
960
+ @isearch_mark = nil
961
+ end
962
+ end
963
+
951
964
  def activate_mark
952
965
  @mark_active = true
953
966
  set_visible_mark(@mark.location) if @mark
@@ -96,7 +96,8 @@ module Textbringer
96
96
  buffer = Buffer.current
97
97
  buffer.exchange_point_and_mark
98
98
  # Activate mark if transient mark mode is enabled
99
- if TransientMarkMode.enabled?
99
+ if TransientMarkMode.enabled? &&
100
+ Controller.current.this_command == :exchange_point_and_mark
100
101
  buffer.activate_mark
101
102
  end
102
103
  end
@@ -153,7 +154,8 @@ module Textbringer
153
154
  else
154
155
  buffer.push_mark
155
156
  # Activate mark if transient mark mode is enabled
156
- if TransientMarkMode.enabled?
157
+ if TransientMarkMode.enabled? &&
158
+ Controller.current.this_command == :set_mark_command
157
159
  buffer.activate_mark
158
160
  end
159
161
  message("Mark set")
@@ -77,10 +77,7 @@ module Textbringer
77
77
  end
78
78
 
79
79
  def isearch_done
80
- # Don't delete visible_mark if mark is active (transient mark mode)
81
- unless Buffer.current.mark_active?
82
- Buffer.current.delete_visible_mark
83
- end
80
+ Buffer.current.delete_isearch_mark
84
81
  Controller.current.overriding_map = nil
85
82
  remove_hook(:pre_command_hook, :isearch_pre_command_hook)
86
83
  ISEARCH_STATUS[:last_string] = ISEARCH_STATUS[:string]
@@ -94,7 +91,7 @@ module Textbringer
94
91
  end
95
92
 
96
93
  define_command(:isearch_abort, doc: "Abort incremental search.") do
97
- goto_char(Buffer.current[:isearch_start])
94
+ goto_char(ISEARCH_STATUS[:start])
98
95
  isearch_done
99
96
  raise Quit
100
97
  end
@@ -157,11 +154,8 @@ module Textbringer
157
154
  if Buffer.current != Buffer.minibuffer
158
155
  message(isearch_prompt + ISEARCH_STATUS[:string], log: false)
159
156
  end
160
- # Don't update visible_mark if mark is already active (transient mark mode)
161
- unless Buffer.current.mark_active?
162
- Buffer.current.set_visible_mark(forward ? match_beginning(0) :
163
- match_end(0))
164
- end
157
+ Buffer.current.set_isearch_mark(forward ? match_beginning(0) :
158
+ match_end(0))
165
159
  goto_char(forward ? match_end(0) : match_beginning(0))
166
160
  else
167
161
  if Buffer.current != Buffer.minibuffer
@@ -2,4 +2,6 @@ module Textbringer
2
2
  Face.define :mode_line, reverse: true
3
3
  Face.define :link, foreground: "blue", bold: true
4
4
  Face.define :control
5
+ Face.define :region, background: "blue", foreground: "white"
6
+ Face.define :isearch, background: "yellow", foreground: "black"
5
7
  end
@@ -28,6 +28,10 @@ module Textbringer
28
28
  :isearch_repeat_forward,
29
29
  :isearch_repeat_backward,
30
30
  :isearch_printing_char,
31
+ :isearch_delete_char,
32
+ :isearch_yank_word_or_char,
33
+ :isearch_quoted_insert,
34
+ :isearch_exit,
31
35
  # Undo/redo
32
36
  :undo,
33
37
  :redo_command,
@@ -1,3 +1,3 @@
1
1
  module Textbringer
2
- VERSION = "16"
2
+ VERSION = "18"
3
3
  end
@@ -236,6 +236,9 @@ module Textbringer
236
236
  @raw_key_buffer = []
237
237
  @key_buffer = []
238
238
  @cursor = Cursor.new(0, 0)
239
+ @in_region = false
240
+ @in_isearch = false
241
+ @current_highlight_attrs = 0
239
242
  end
240
243
 
241
244
  def echo_area?
@@ -405,23 +408,54 @@ module Textbringer
405
408
  @window.erase
406
409
  @window.setpos(0, 0)
407
410
  @window.attrset(0)
411
+ @in_region = false
412
+ @in_isearch = false
413
+ @current_highlight_attrs = 0
408
414
  if current? && @buffer.visible_mark &&
409
415
  @buffer.point_after_mark?(@buffer.visible_mark)
410
- @window.attron(Curses::A_REVERSE)
416
+ @window.attron(region_attr)
417
+ @in_region = true
418
+ end
419
+ if current? && @buffer.isearch_mark &&
420
+ @buffer.point_after_mark?(@buffer.isearch_mark)
421
+ # If already in region, switch to isearch (priority)
422
+ if @in_region
423
+ @window.attroff(region_attr)
424
+ end
425
+ @window.attron(isearch_attr)
426
+ @in_isearch = true
411
427
  end
412
428
  while !@buffer.end_of_buffer?
413
429
  cury = @window.cury
414
430
  curx = @window.curx
415
431
  update_cursor_and_attr(point, cury, curx)
416
432
  if attrs = @highlight_off[@buffer.point]
417
- @window.attroff(attrs)
433
+ if @in_region || @in_isearch
434
+ # In region: only turn off non-color attributes (bold, underline, etc.)
435
+ @window.attroff(attrs & ~Curses::A_COLOR)
436
+ else
437
+ @window.attroff(attrs)
438
+ end
439
+ @current_highlight_attrs = 0
418
440
  end
419
441
  if attrs = @highlight_on[@buffer.point]
420
- @window.attron(attrs)
442
+ if @in_region || @in_isearch
443
+ # In region: only turn on non-color attributes (preserve region background)
444
+ @window.attron(attrs & ~Curses::A_COLOR)
445
+ else
446
+ @window.attron(attrs)
447
+ end
448
+ @current_highlight_attrs = attrs
421
449
  end
422
450
  c = @buffer.char_after
423
451
  if c == "\n"
424
- @window.clrtoeol
452
+ # Fill to end of line with region background if in region
453
+ if @in_region
454
+ remaining = columns - curx
455
+ @window.addstr(" " * remaining) if remaining > 0
456
+ else
457
+ @window.clrtoeol
458
+ end
425
459
  break if cury == lines - 2 # lines include mode line
426
460
  @window.setpos(cury + 1, 0)
427
461
  @buffer.forward_char
@@ -441,7 +475,13 @@ module Textbringer
441
475
  if cury == lines - 2
442
476
  break
443
477
  else
444
- @window.clrtoeol
478
+ # Fill to end of line with region background if in region
479
+ if @in_region
480
+ remaining = columns - curx
481
+ @window.addstr(" " * remaining) if remaining > 0
482
+ else
483
+ @window.clrtoeol
484
+ end
445
485
  @window.setpos(cury + 1, 0)
446
486
  end
447
487
  end
@@ -450,8 +490,11 @@ module Textbringer
450
490
  break if newx == columns && cury == lines - 2
451
491
  @buffer.forward_char
452
492
  end
493
+ if current? && @buffer.isearch_mark
494
+ @window.attroff(isearch_attr)
495
+ end
453
496
  if current? && @buffer.visible_mark
454
- @window.attroff(Curses::A_REVERSE)
497
+ @window.attroff(region_attr)
455
498
  end
456
499
  @buffer.mark_to_point(@bottom_of_window)
457
500
  if @buffer.point_at_mark?(point)
@@ -679,20 +722,83 @@ module Textbringer
679
722
  if @buffer.point_at_mark?(point)
680
723
  @cursor.y = cury
681
724
  @cursor.x = curx
725
+ # Handle visible mark transitions
682
726
  if current? && @buffer.visible_mark
683
727
  if @buffer.point_after_mark?(@buffer.visible_mark)
684
- @window.attroff(Curses::A_REVERSE)
728
+ unless @in_isearch
729
+ @window.attroff(region_attr)
730
+ # Restore syntax highlighting colors after exiting region
731
+ if @current_highlight_attrs != 0
732
+ @window.attron(@current_highlight_attrs)
733
+ end
734
+ end
735
+ @in_region = false
685
736
  elsif @buffer.point_before_mark?(@buffer.visible_mark)
686
- @window.attron(Curses::A_REVERSE)
737
+ unless @in_isearch
738
+ @window.attron(region_attr)
739
+ end
740
+ @in_region = true
741
+ end
742
+ end
743
+ # Handle isearch mark transitions
744
+ if current? && @buffer.isearch_mark
745
+ if @buffer.point_after_mark?(@buffer.isearch_mark)
746
+ @window.attroff(isearch_attr)
747
+ @in_isearch = false
748
+ # If we were covering a region, restore it
749
+ if @in_region
750
+ @window.attron(region_attr)
751
+ elsif @current_highlight_attrs != 0
752
+ @window.attron(@current_highlight_attrs)
753
+ end
754
+ elsif @buffer.point_before_mark?(@buffer.isearch_mark)
755
+ # Entering isearch - turn off region if active
756
+ if @in_region
757
+ @window.attroff(region_attr)
758
+ end
759
+ @window.attron(isearch_attr)
760
+ @in_isearch = true
687
761
  end
688
762
  end
689
763
  end
764
+ # Handle transitions when point crosses isearch mark
765
+ if current? && @buffer.isearch_mark &&
766
+ @buffer.point_at_mark?(@buffer.isearch_mark)
767
+ if @buffer.point_after_mark?(point)
768
+ @window.attroff(isearch_attr)
769
+ @in_isearch = false
770
+ # If we have a region underneath, restore it
771
+ if @in_region
772
+ @window.attron(region_attr)
773
+ elsif @current_highlight_attrs != 0
774
+ @window.attron(@current_highlight_attrs)
775
+ end
776
+ elsif @buffer.point_before_mark?(point)
777
+ # Entering isearch - turn off region if active
778
+ if @in_region
779
+ @window.attroff(region_attr)
780
+ end
781
+ @window.attron(isearch_attr)
782
+ @in_isearch = true
783
+ end
784
+ end
785
+ # Handle transitions when point crosses visible mark
690
786
  if current? && @buffer.visible_mark &&
691
- @buffer.point_at_mark?(@buffer.visible_mark)
787
+ @buffer.point_at_mark?(@buffer.visible_mark)
692
788
  if @buffer.point_after_mark?(point)
693
- @window.attroff(Curses::A_REVERSE)
789
+ unless @in_isearch
790
+ @window.attroff(region_attr)
791
+ # Restore syntax highlighting colors after exiting region
792
+ if @current_highlight_attrs != 0
793
+ @window.attron(@current_highlight_attrs)
794
+ end
795
+ end
796
+ @in_region = false
694
797
  elsif @buffer.point_before_mark?(point)
695
- @window.attron(Curses::A_REVERSE)
798
+ unless @in_isearch
799
+ @window.attron(region_attr)
800
+ end
801
+ @in_region = true
696
802
  end
697
803
  end
698
804
  end
@@ -870,6 +976,14 @@ module Textbringer
870
976
  @key_buffer.shift
871
977
  end
872
978
  end
979
+
980
+ def region_attr
981
+ @@has_colors ? Face[:region].attributes : Curses::A_REVERSE
982
+ end
983
+
984
+ def isearch_attr
985
+ @@has_colors ? Face[:isearch].attributes : Curses::A_UNDERLINE
986
+ end
873
987
  end
874
988
 
875
989
  class EchoArea < Window
@@ -916,6 +1030,10 @@ module Textbringer
916
1030
  @window.addstr(@buffer.input_method_status)
917
1031
  end
918
1032
  @window.setpos(0, 0)
1033
+ @window.attrset(0)
1034
+ @in_region = false
1035
+ @in_isearch = false
1036
+ @current_highlight_attrs = 0
919
1037
  if @message
920
1038
  @window.addstr(escape(@message))
921
1039
  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: '16'
4
+ version: '18'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda