textbringer 17 → 19

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/exe/txtb +1 -1
  3. data/lib/textbringer/buffer.rb +37 -3
  4. data/lib/textbringer/commands/buffers.rb +4 -2
  5. data/lib/textbringer/commands/clipboard.rb +21 -6
  6. data/lib/textbringer/commands/completion.rb +133 -0
  7. data/lib/textbringer/commands/ctags.rb +1 -1
  8. data/lib/textbringer/commands/files.rb +11 -1
  9. data/lib/textbringer/commands/help.rb +1 -1
  10. data/lib/textbringer/commands/isearch.rb +4 -10
  11. data/lib/textbringer/commands/ispell.rb +0 -2
  12. data/lib/textbringer/commands/lsp.rb +389 -0
  13. data/lib/textbringer/commands/misc.rb +2 -1
  14. data/lib/textbringer/commands.rb +7 -3
  15. data/lib/textbringer/completion_popup.rb +188 -0
  16. data/lib/textbringer/faces/basic.rb +3 -1
  17. data/lib/textbringer/faces/completion.rb +4 -0
  18. data/lib/textbringer/floating_window.rb +327 -0
  19. data/lib/textbringer/input_methods/skk_input_method.rb +751 -0
  20. data/lib/textbringer/lsp/client.rb +568 -0
  21. data/lib/textbringer/lsp/server_registry.rb +138 -0
  22. data/lib/textbringer/mode.rb +3 -1
  23. data/lib/textbringer/modes/programming_mode.rb +17 -8
  24. data/lib/textbringer/modes/transient_mark_mode.rb +9 -2
  25. data/lib/textbringer/utils.rb +14 -10
  26. data/lib/textbringer/version.rb +1 -1
  27. data/lib/textbringer/window.rb +116 -19
  28. data/lib/textbringer.rb +7 -0
  29. data/sig/lib/textbringer/buffer.rbs +483 -0
  30. data/sig/lib/textbringer/color.rbs +9 -0
  31. data/sig/lib/textbringer/commands/buffers.rbs +93 -0
  32. data/sig/lib/textbringer/commands/clipboard.rbs +17 -0
  33. data/sig/lib/textbringer/commands/completion.rbs +20 -0
  34. data/sig/lib/textbringer/commands/ctags.rbs +11 -0
  35. data/sig/lib/textbringer/commands/dabbrev.rbs +4 -0
  36. data/sig/lib/textbringer/commands/files.rbs +29 -0
  37. data/sig/lib/textbringer/commands/fill.rbs +5 -0
  38. data/sig/lib/textbringer/commands/help.rbs +28 -0
  39. data/sig/lib/textbringer/commands/input_method.rbs +6 -0
  40. data/sig/lib/textbringer/commands/isearch.rbs +38 -0
  41. data/sig/lib/textbringer/commands/ispell.rbs +39 -0
  42. data/sig/lib/textbringer/commands/keyboard_macro.rbs +25 -0
  43. data/sig/lib/textbringer/commands/lsp.rbs +8 -0
  44. data/sig/lib/textbringer/commands/misc.rbs +74 -0
  45. data/sig/lib/textbringer/commands/rectangle.rbs +19 -0
  46. data/sig/lib/textbringer/commands/register.rbs +31 -0
  47. data/sig/lib/textbringer/commands/replace.rbs +17 -0
  48. data/sig/lib/textbringer/commands/server.rbs +31 -0
  49. data/sig/lib/textbringer/commands/ucs_normalize.rbs +9 -0
  50. data/sig/lib/textbringer/commands/windows.rbs +45 -0
  51. data/sig/lib/textbringer/commands.rbs +21 -0
  52. data/sig/lib/textbringer/completion_popup.rbs +40 -0
  53. data/sig/lib/textbringer/controller.rbs +58 -0
  54. data/sig/lib/textbringer/default_output.rbs +7 -0
  55. data/sig/lib/textbringer/errors.rbs +3 -0
  56. data/sig/lib/textbringer/face.rbs +19 -0
  57. data/sig/lib/textbringer/floating_window.rbs +42 -0
  58. data/sig/lib/textbringer/global_minor_mode.rbs +7 -0
  59. data/sig/lib/textbringer/input_method.rbs +28 -0
  60. data/sig/lib/textbringer/input_methods/hangul_input_method.rbs +12 -0
  61. data/sig/lib/textbringer/input_methods/hiragana_input_method.rbs +12 -0
  62. data/sig/lib/textbringer/input_methods/t_code_input_method.rbs +49 -0
  63. data/sig/lib/textbringer/keymap.rbs +33 -0
  64. data/sig/lib/textbringer/lsp/client.rbs +21 -0
  65. data/sig/lib/textbringer/lsp/server_registry.rbs +23 -0
  66. data/sig/lib/textbringer/minor_mode.rbs +12 -0
  67. data/sig/lib/textbringer/mode.rbs +70 -0
  68. data/sig/lib/textbringer/modes/backtrace_mode.rbs +8 -0
  69. data/sig/lib/textbringer/modes/buffer_list_mode.rbs +5 -0
  70. data/sig/lib/textbringer/modes/c_mode.rbs +21 -0
  71. data/sig/lib/textbringer/modes/completion_list_mode.rbs +5 -0
  72. data/sig/lib/textbringer/modes/fundamental_mode.rbs +3 -0
  73. data/sig/lib/textbringer/modes/help_mode.rbs +7 -0
  74. data/sig/lib/textbringer/modes/overwrite_mode.rbs +15 -0
  75. data/sig/lib/textbringer/modes/programming_mode.rbs +14 -0
  76. data/sig/lib/textbringer/modes/ruby_mode.rbs +57 -0
  77. data/sig/lib/textbringer/plugin.rbs +3 -0
  78. data/sig/lib/textbringer/ring.rbs +36 -0
  79. data/sig/lib/textbringer/utils.rbs +95 -0
  80. data/sig/lib/textbringer/window.rbs +183 -0
  81. data/textbringer.gemspec +1 -0
  82. metadata +76 -2
@@ -3,14 +3,23 @@ module Textbringer
3
3
  # abstract mode
4
4
  undefine_command(:programming_mode)
5
5
 
6
- define_generic_command :indent_line
7
- define_generic_command :reindent_then_newline_and_indent
8
- define_generic_command :indent_region
9
- define_generic_command :forward_definition
10
- define_generic_command :backward_definition
11
- define_generic_command :compile
12
- define_generic_command :toggle_test
13
- define_generic_command :indent_new_comment_line
6
+ define_generic_command :indent_line,
7
+ doc: "Indent the current line."
8
+ define_generic_command :reindent_then_newline_and_indent,
9
+ doc: "Reindent the current line, insert a new line, then indent the new line."
10
+ define_generic_command :indent_region,
11
+ doc: "Indent the region."
12
+ define_generic_command :forward_definition,
13
+ doc: "Go to the next definition of a class, method etc."
14
+ define_generic_command :backward_definition,
15
+ doc: "Go to the preivous definition of a class, method etc."
16
+ define_generic_command :compile,
17
+ doc: "Compile the program including the current buffer."
18
+ define_generic_command :toggle_test,
19
+ doc: "Open the test file corresponding to the current buffer. " \
20
+ "If the current buffer is a test file, open the file of the code under test."
21
+ define_generic_command :indent_new_comment_line,
22
+ doc: "Break line at point and indent, continuing comment if within one."
14
23
 
15
24
  define_keymap :PROGRAMMING_MODE_MAP
16
25
  PROGRAMMING_MODE_MAP.define_key("\t", :indent_line_command)
@@ -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,
@@ -36,8 +40,11 @@ module Textbringer
36
40
  :goto_char,
37
41
  :recenter,
38
42
  :move_to_beginning_of_line,
39
- :move_to_end_of_line
40
- ].to_set.freeze
43
+ :move_to_end_of_line,
44
+ # Other commands
45
+ :execute_command,
46
+ :eval_expression
47
+ ].to_set
41
48
 
42
49
  # Hook to deactivate mark before most commands
43
50
  PRE_COMMAND_HOOK = -> {
@@ -145,7 +145,8 @@ module Textbringer
145
145
  "Command attempted to use minibuffer while in minibuffer"
146
146
  end
147
147
  old_buffer = Buffer.current
148
- old_window = Window.current
148
+ old_minibuffer_selected = Window.minibuffer_selected
149
+ Window.minibuffer_selected = Window.current
149
150
  old_completion_proc = Buffer.minibuffer[:completion_proc]
150
151
  old_completion_ignore_case = Buffer.minibuffer[:completion_ignore_case]
151
152
  old_current_prefix_arg = Controller.current.current_prefix_arg
@@ -176,10 +177,11 @@ module Textbringer
176
177
  Window.echo_area.redisplay
177
178
  Window.update
178
179
  Window.echo_area.active = false
179
- Window.current = old_window
180
- # Just in case old_window has been deleted by resize,
180
+ Window.current = Window.minibuffer_selected
181
+ # Just in case Window.minibuffer_selected has been deleted by resize,
181
182
  # in which case Window.current is set to the first window.
182
183
  Window.current.buffer = Buffer.current = old_buffer
184
+ Window.minibuffer_selected = old_minibuffer_selected
183
185
  Buffer.minibuffer[:completion_ignore_case] = old_completion_ignore_case
184
186
  Buffer.minibuffer[:completion_proc] = old_completion_proc
185
187
  Buffer.minibuffer.keymap = old_minibuffer_map
@@ -373,20 +375,22 @@ module Textbringer
373
375
  end
374
376
  end
375
377
 
376
- def run_hooks(name, remove_on_error: false)
377
- hooks = Buffer.current[:hooks]
378
- run_hooks_in(hooks, name, remove_on_error:) if hooks
379
- run_hooks_in(HOOKS, name, remove_on_error:)
378
+ def run_hooks(name, *args, remove_on_error: false)
379
+ if Buffer.current
380
+ hooks = Buffer.current[:hooks]
381
+ run_hooks_in(hooks, name, *args, remove_on_error:) if hooks
382
+ end
383
+ run_hooks_in(HOOKS, name, *args, remove_on_error:)
380
384
  end
381
385
 
382
- def run_hooks_in(hooks, name, remove_on_error: false)
386
+ def run_hooks_in(hooks, name, *args, remove_on_error: false)
383
387
  hooks[name].delete_if do |func|
384
388
  begin
385
389
  case func
386
390
  when Symbol
387
- send(func)
391
+ send(func, *args)
388
392
  else
389
- func.call
393
+ func.call(*args)
390
394
  end
391
395
  false
392
396
  rescue Exception => e
@@ -1,3 +1,3 @@
1
1
  module Textbringer
2
- VERSION = "17"
2
+ VERSION = "19"
3
3
  end
@@ -20,6 +20,7 @@ module Textbringer
20
20
  @@started = false
21
21
  @@list = []
22
22
  @@current = nil
23
+ @@minibuffer_selected = nil
23
24
  @@echo_area = nil
24
25
  @@has_colors = false
25
26
 
@@ -45,6 +46,18 @@ module Textbringer
45
46
  Buffer.current = window.buffer
46
47
  end
47
48
 
49
+ class << self
50
+ alias selected current
51
+ end
52
+
53
+ def self.minibuffer_selected
54
+ @@minibuffer_selected
55
+ end
56
+
57
+ def self.minibuffer_selected=(window)
58
+ @@minibuffer_selected = window
59
+ end
60
+
48
61
  def self.delete_window(target = @@current)
49
62
  if target.echo_area?
50
63
  raise EditorError, "Can't delete the echo area"
@@ -117,6 +130,7 @@ module Textbringer
117
130
  def self.load_faces
118
131
  require_relative "faces/basic"
119
132
  require_relative "faces/programming"
133
+ require_relative "faces/completion"
120
134
  end
121
135
 
122
136
  def self.start
@@ -166,6 +180,15 @@ module Textbringer
166
180
  window.redisplay unless window.current?
167
181
  end
168
182
  current.redisplay
183
+ if defined?(FloatingWindow)
184
+ # Render floating windows on top
185
+ FloatingWindow.redisplay_all_floating
186
+ # Ensure cursor position is from the current window, not floating windows
187
+ # Refresh current window's cursor position after floating windows
188
+ if !FloatingWindow.floating_windows.empty?
189
+ current&.window&.noutrefresh
190
+ end
191
+ end
169
192
  update
170
193
  end
171
194
 
@@ -217,7 +240,7 @@ module Textbringer
217
240
  end
218
241
 
219
242
  attr_reader :buffer, :lines, :columns, :y, :x, :window, :mode_line
220
- attr_reader :top_of_window, :bottom_of_window
243
+ attr_reader :top_of_window, :bottom_of_window, :cursor
221
244
 
222
245
  def initialize(lines, columns, y, x)
223
246
  @lines = lines
@@ -237,6 +260,7 @@ module Textbringer
237
260
  @key_buffer = []
238
261
  @cursor = Cursor.new(0, 0)
239
262
  @in_region = false
263
+ @in_isearch = false
240
264
  @current_highlight_attrs = 0
241
265
  end
242
266
 
@@ -297,6 +321,10 @@ module Textbringer
297
321
  self == @@current
298
322
  end
299
323
 
324
+ def current_or_minibuffer_selected?
325
+ self == @@current || self == @@minibuffer_selected
326
+ end
327
+
300
328
  def read_event
301
329
  key = get_char
302
330
  if key.is_a?(Integer)
@@ -408,18 +436,28 @@ module Textbringer
408
436
  @window.setpos(0, 0)
409
437
  @window.attrset(0)
410
438
  @in_region = false
439
+ @in_isearch = false
411
440
  @current_highlight_attrs = 0
412
- if current? && @buffer.visible_mark &&
441
+ if current_or_minibuffer_selected? && @buffer.visible_mark &&
413
442
  @buffer.point_after_mark?(@buffer.visible_mark)
414
443
  @window.attron(region_attr)
415
444
  @in_region = true
416
445
  end
446
+ if current_or_minibuffer_selected? && @buffer.isearch_mark &&
447
+ @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)
453
+ @in_isearch = true
454
+ end
417
455
  while !@buffer.end_of_buffer?
418
456
  cury = @window.cury
419
457
  curx = @window.curx
420
458
  update_cursor_and_attr(point, cury, curx)
421
459
  if attrs = @highlight_off[@buffer.point]
422
- if @in_region
460
+ if @in_region || @in_isearch
423
461
  # In region: only turn off non-color attributes (bold, underline, etc.)
424
462
  @window.attroff(attrs & ~Curses::A_COLOR)
425
463
  else
@@ -428,7 +466,7 @@ module Textbringer
428
466
  @current_highlight_attrs = 0
429
467
  end
430
468
  if attrs = @highlight_on[@buffer.point]
431
- if @in_region
469
+ if @in_region || @in_isearch
432
470
  # In region: only turn on non-color attributes (preserve region background)
433
471
  @window.attron(attrs & ~Curses::A_COLOR)
434
472
  else
@@ -479,7 +517,10 @@ module Textbringer
479
517
  break if newx == columns && cury == lines - 2
480
518
  @buffer.forward_char
481
519
  end
482
- if current? && @buffer.visible_mark
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
483
524
  @window.attroff(region_attr)
484
525
  end
485
526
  @buffer.mark_to_point(@bottom_of_window)
@@ -708,31 +749,82 @@ module Textbringer
708
749
  if @buffer.point_at_mark?(point)
709
750
  @cursor.y = cury
710
751
  @cursor.x = curx
711
- if current? && @buffer.visible_mark
752
+ # Handle visible mark transitions
753
+ if current_or_minibuffer_selected? && @buffer.visible_mark
712
754
  if @buffer.point_after_mark?(@buffer.visible_mark)
713
- @window.attroff(region_attr)
714
- @in_region = false
715
- # Restore syntax highlighting colors after exiting region
716
- if @current_highlight_attrs != 0
717
- @window.attron(@current_highlight_attrs)
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
718
761
  end
762
+ @in_region = false
719
763
  elsif @buffer.point_before_mark?(@buffer.visible_mark)
720
- @window.attron(region_attr)
764
+ unless @in_isearch
765
+ @window.attron(region_attr)
766
+ end
721
767
  @in_region = true
722
768
  end
723
769
  end
770
+ # Handle isearch mark transitions
771
+ if current_or_minibuffer_selected? && @buffer.isearch_mark
772
+ if @buffer.point_after_mark?(@buffer.isearch_mark)
773
+ @window.attroff(isearch_attr)
774
+ @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
781
+ 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
+ @in_isearch = true
788
+ end
789
+ end
724
790
  end
725
- if current? && @buffer.visible_mark &&
726
- @buffer.point_at_mark?(@buffer.visible_mark)
791
+ # Handle transitions when point crosses isearch mark
792
+ if current_or_minibuffer_selected? && @buffer.isearch_mark &&
793
+ @buffer.point_at_mark?(@buffer.isearch_mark)
727
794
  if @buffer.point_after_mark?(point)
728
- @window.attroff(region_attr)
729
- @in_region = false
730
- # Restore syntax highlighting colors after exiting region
731
- if @current_highlight_attrs != 0
795
+ @window.attroff(isearch_attr)
796
+ @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
732
801
  @window.attron(@current_highlight_attrs)
733
802
  end
734
803
  elsif @buffer.point_before_mark?(point)
735
- @window.attron(region_attr)
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
+ @in_isearch = true
810
+ end
811
+ end
812
+ # Handle transitions when point crosses visible mark
813
+ if current_or_minibuffer_selected? && @buffer.visible_mark &&
814
+ @buffer.point_at_mark?(@buffer.visible_mark)
815
+ 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
+ @in_region = false
824
+ elsif @buffer.point_before_mark?(point)
825
+ unless @in_isearch
826
+ @window.attron(region_attr)
827
+ end
736
828
  @in_region = true
737
829
  end
738
830
  end
@@ -915,6 +1007,10 @@ module Textbringer
915
1007
  def region_attr
916
1008
  @@has_colors ? Face[:region].attributes : Curses::A_REVERSE
917
1009
  end
1010
+
1011
+ def isearch_attr
1012
+ @@has_colors ? Face[:isearch].attributes : Curses::A_UNDERLINE
1013
+ end
918
1014
  end
919
1015
 
920
1016
  class EchoArea < Window
@@ -963,6 +1059,7 @@ module Textbringer
963
1059
  @window.setpos(0, 0)
964
1060
  @window.attrset(0)
965
1061
  @in_region = false
1062
+ @in_isearch = false
966
1063
  @current_highlight_attrs = 0
967
1064
  if @message
968
1065
  @window.addstr(escape(@message))
data/lib/textbringer.rb CHANGED
@@ -4,10 +4,14 @@ require_relative "textbringer/errors"
4
4
  require_relative "textbringer/ring"
5
5
  require_relative "textbringer/buffer"
6
6
  require_relative "textbringer/window"
7
+ require_relative "textbringer/floating_window"
7
8
  require_relative "textbringer/keymap"
8
9
  require_relative "textbringer/utils"
9
10
  require_relative "textbringer/color"
10
11
  require_relative "textbringer/face"
12
+ require_relative "textbringer/completion_popup"
13
+ require_relative "textbringer/lsp/client"
14
+ require_relative "textbringer/lsp/server_registry"
11
15
  require_relative "textbringer/commands"
12
16
  require_relative "textbringer/commands/buffers"
13
17
  require_relative "textbringer/commands/windows"
@@ -27,6 +31,8 @@ require_relative "textbringer/commands/server"
27
31
  require_relative "textbringer/commands/input_method"
28
32
  require_relative "textbringer/commands/ucs_normalize"
29
33
  require_relative "textbringer/commands/help"
34
+ require_relative "textbringer/commands/completion"
35
+ require_relative "textbringer/commands/lsp"
30
36
  require_relative "textbringer/mode"
31
37
  require_relative "textbringer/modes/fundamental_mode"
32
38
  require_relative "textbringer/modes/programming_mode"
@@ -44,6 +50,7 @@ require_relative "textbringer/input_method"
44
50
  require_relative "textbringer/input_methods/t_code_input_method"
45
51
  require_relative "textbringer/input_methods/hiragana_input_method"
46
52
  require_relative "textbringer/input_methods/hangul_input_method"
53
+ require_relative "textbringer/input_methods/skk_input_method"
47
54
  require_relative "textbringer/plugin"
48
55
  require_relative "textbringer/controller"
49
56
  require_relative "textbringer/default_output"