reline 0.3.0 → 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/reline/ansi.rb +1 -1
- data/lib/reline/config.rb +16 -10
- data/lib/reline/general_io.rb +6 -0
- data/lib/reline/key_actor/emacs.rb +1 -1
- data/lib/reline/line_editor.rb +23 -11
- data/lib/reline/terminfo.rb +44 -4
- data/lib/reline/version.rb +1 -1
- data/lib/reline/windows.rb +3 -3
- data/lib/reline.rb +41 -27
- metadata +4 -5
- data/lib/reline/sibori.rb +0 -170
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8198104fe3ad27c73acaaffc9c8b1c8b9a5c50069a26a71cd940dd2b5dc13afc
|
4
|
+
data.tar.gz: 171ff8cdf2ae4aebaf4cfb6cea131e2d90e5eb56a2c09dbe19acfa8765522ffc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3411f0086a0445d2d805fc46528a86b947c58b8e61a664dc08b437596702ef1f360cd7e85a1dab64bf159f6f39691b9d5110f951bd5376f4fce0439e9557532
|
7
|
+
data.tar.gz: 968ac4a376ba350590fd37d05525a5a2e5e26c44e159b5fd9b0c7400e260850e91088357c007651373d44b7b7d37c699852014d07258428be86081581baf0229
|
data/lib/reline/ansi.rb
CHANGED
@@ -150,7 +150,7 @@ class Reline::ANSI
|
|
150
150
|
until c = @@input.raw(intr: true) { @@input.wait_readable(0.1) && @@input.getbyte }
|
151
151
|
Reline.core.line_editor.resize
|
152
152
|
end
|
153
|
-
(c == 0x16 && @@input.raw(min: 0,
|
153
|
+
(c == 0x16 && @@input.raw(min: 0, time: 0, &:getbyte)) || c
|
154
154
|
rescue Errno::EIO
|
155
155
|
# Maybe the I/O has been closed.
|
156
156
|
nil
|
data/lib/reline/config.rb
CHANGED
@@ -45,6 +45,8 @@ class Reline::Config
|
|
45
45
|
attr_accessor v
|
46
46
|
end
|
47
47
|
|
48
|
+
attr_accessor :autocompletion
|
49
|
+
|
48
50
|
def initialize
|
49
51
|
@additional_key_bindings = {} # from inputrc
|
50
52
|
@additional_key_bindings[:emacs] = {}
|
@@ -55,6 +57,7 @@ class Reline::Config
|
|
55
57
|
@if_stack = nil
|
56
58
|
@editing_mode_label = :emacs
|
57
59
|
@keymap_label = :emacs
|
60
|
+
@keymap_prefix = []
|
58
61
|
@key_actors = {}
|
59
62
|
@key_actors[:emacs] = Reline::KeyActor::Emacs.new
|
60
63
|
@key_actors[:vi_insert] = Reline::KeyActor::ViInsert.new
|
@@ -93,14 +96,6 @@ class Reline::Config
|
|
93
96
|
(val.respond_to?(:any?) ? val : [val]).any?(@editing_mode_label)
|
94
97
|
end
|
95
98
|
|
96
|
-
def autocompletion=(val)
|
97
|
-
@autocompletion = val
|
98
|
-
end
|
99
|
-
|
100
|
-
def autocompletion
|
101
|
-
@autocompletion
|
102
|
-
end
|
103
|
-
|
104
99
|
def keymap
|
105
100
|
@key_actors[@keymap_label]
|
106
101
|
end
|
@@ -221,7 +216,7 @@ class Reline::Config
|
|
221
216
|
key, func_name = $1, $2
|
222
217
|
keystroke, func = bind_key(key, func_name)
|
223
218
|
next unless keystroke
|
224
|
-
@additional_key_bindings[@keymap_label][keystroke] = func
|
219
|
+
@additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
|
225
220
|
end
|
226
221
|
end
|
227
222
|
unless @if_stack.empty?
|
@@ -292,18 +287,29 @@ class Reline::Config
|
|
292
287
|
when 'emacs'
|
293
288
|
@editing_mode_label = :emacs
|
294
289
|
@keymap_label = :emacs
|
290
|
+
@keymap_prefix = []
|
295
291
|
when 'vi'
|
296
292
|
@editing_mode_label = :vi_insert
|
297
293
|
@keymap_label = :vi_insert
|
294
|
+
@keymap_prefix = []
|
298
295
|
end
|
299
296
|
when 'keymap'
|
300
297
|
case value
|
301
|
-
when 'emacs', 'emacs-standard'
|
298
|
+
when 'emacs', 'emacs-standard'
|
299
|
+
@keymap_label = :emacs
|
300
|
+
@keymap_prefix = []
|
301
|
+
when 'emacs-ctlx'
|
302
|
+
@keymap_label = :emacs
|
303
|
+
@keymap_prefix = [?\C-x.ord]
|
304
|
+
when 'emacs-meta'
|
302
305
|
@keymap_label = :emacs
|
306
|
+
@keymap_prefix = [?\e.ord]
|
303
307
|
when 'vi', 'vi-move', 'vi-command'
|
304
308
|
@keymap_label = :vi_command
|
309
|
+
@keymap_prefix = []
|
305
310
|
when 'vi-insert'
|
306
311
|
@keymap_label = :vi_insert
|
312
|
+
@keymap_prefix = []
|
307
313
|
end
|
308
314
|
when 'keyseq-timeout'
|
309
315
|
@keyseq_timeout = value.to_i
|
data/lib/reline/general_io.rb
CHANGED
data/lib/reline/line_editor.rb
CHANGED
@@ -466,15 +466,17 @@ class Reline::LineEditor
|
|
466
466
|
new_highest_in_this = calculate_height_by_width(prompt_width + calculate_width(@line.nil? ? '' : @line))
|
467
467
|
rendered = false
|
468
468
|
if @add_newline_to_end_of_buffer
|
469
|
+
clear_dialog_with_content
|
469
470
|
rerender_added_newline(prompt, prompt_width)
|
470
471
|
@add_newline_to_end_of_buffer = false
|
471
472
|
else
|
472
473
|
if @just_cursor_moving and not @rerender_all
|
474
|
+
clear_dialog_with_content
|
473
475
|
rendered = just_move_cursor
|
474
|
-
render_dialog((prompt_width + @cursor) % @screen_size.last)
|
475
476
|
@just_cursor_moving = false
|
476
477
|
return
|
477
478
|
elsif @previous_line_index or new_highest_in_this != @highest_in_this
|
479
|
+
clear_dialog_with_content
|
478
480
|
rerender_changed_current_line
|
479
481
|
@previous_line_index = nil
|
480
482
|
rendered = true
|
@@ -653,7 +655,10 @@ class Reline::LineEditor
|
|
653
655
|
end
|
654
656
|
|
655
657
|
private def padding_space_with_escape_sequences(str, width)
|
656
|
-
|
658
|
+
padding_width = width - calculate_width(str, true)
|
659
|
+
# padding_width should be only positive value. But macOS and Alacritty returns negative value.
|
660
|
+
padding_width = 0 if padding_width < 0
|
661
|
+
str + (' ' * padding_width)
|
657
662
|
end
|
658
663
|
|
659
664
|
private def render_each_dialog(dialog, cursor_column)
|
@@ -741,24 +746,21 @@ class Reline::LineEditor
|
|
741
746
|
Reline::IOGate.move_cursor_column(dialog.column)
|
742
747
|
dialog.contents.each_with_index do |item, i|
|
743
748
|
if i == pointer
|
744
|
-
|
749
|
+
fg_color = dialog_render_info.pointer_fg_color
|
750
|
+
bg_color = dialog_render_info.pointer_bg_color
|
745
751
|
else
|
746
|
-
|
747
|
-
|
748
|
-
else
|
749
|
-
bg_color = '46'
|
750
|
-
end
|
752
|
+
fg_color = dialog_render_info.fg_color
|
753
|
+
bg_color = dialog_render_info.bg_color
|
751
754
|
end
|
752
755
|
str_width = dialog.width - (dialog.scrollbar_pos.nil? ? 0 : @block_elem_width)
|
753
756
|
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
|
754
|
-
@output.write "\e[#{bg_color}m#{str}"
|
757
|
+
@output.write "\e[#{bg_color}m\e[#{fg_color}m#{str}"
|
755
758
|
if dialog.scrollbar_pos and (dialog.scrollbar_pos != old_dialog.scrollbar_pos or dialog.column != old_dialog.column)
|
756
759
|
@output.write "\e[37m"
|
757
760
|
if dialog.scrollbar_pos <= (i * 2) and (i * 2 + 1) < (dialog.scrollbar_pos + bar_height)
|
758
761
|
@output.write @full_block
|
759
762
|
elsif dialog.scrollbar_pos <= (i * 2) and (i * 2) < (dialog.scrollbar_pos + bar_height)
|
760
763
|
@output.write @upper_half_block
|
761
|
-
str += ''
|
762
764
|
elsif dialog.scrollbar_pos <= (i * 2 + 1) and (i * 2) < (dialog.scrollbar_pos + bar_height)
|
763
765
|
@output.write @lower_half_block
|
764
766
|
else
|
@@ -883,6 +885,14 @@ class Reline::LineEditor
|
|
883
885
|
end
|
884
886
|
end
|
885
887
|
|
888
|
+
private def clear_dialog_with_content
|
889
|
+
@dialogs.each do |dialog|
|
890
|
+
clear_each_dialog(dialog)
|
891
|
+
dialog.contents = nil
|
892
|
+
dialog.trap_key = nil
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
886
896
|
private def clear_each_dialog(dialog)
|
887
897
|
dialog.trap_key = nil
|
888
898
|
return unless dialog.contents
|
@@ -1420,7 +1430,7 @@ class Reline::LineEditor
|
|
1420
1430
|
if @waiting_operator_proc
|
1421
1431
|
if VI_MOTIONS.include?(method_symbol)
|
1422
1432
|
old_cursor, old_byte_pointer = @cursor, @byte_pointer
|
1423
|
-
@vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg
|
1433
|
+
@vi_arg = @waiting_operator_vi_arg if @waiting_operator_vi_arg&.> 1
|
1424
1434
|
block.(true)
|
1425
1435
|
unless @waiting_proc
|
1426
1436
|
cursor_diff, byte_pointer_diff = @cursor - old_cursor, @byte_pointer - old_byte_pointer
|
@@ -2223,6 +2233,8 @@ class Reline::LineEditor
|
|
2223
2233
|
@buffer_of_lines = [String.new(encoding: @encoding)] if @buffer_of_lines.empty?
|
2224
2234
|
@line_index = @buffer_of_lines.size - 1
|
2225
2235
|
@line = @buffer_of_lines.last
|
2236
|
+
@byte_pointer = @line.bytesize
|
2237
|
+
@cursor = @cursor_max = calculate_width(@line)
|
2226
2238
|
@rerender_all = true
|
2227
2239
|
@searching_prompt = "(%s)`%s'" % [prompt_name, search_word]
|
2228
2240
|
else
|
data/lib/reline/terminfo.rb
CHANGED
@@ -35,7 +35,7 @@ module Reline::Terminfo
|
|
35
35
|
# Gem module isn't defined in test-all of the Ruby repository, and
|
36
36
|
# Fiddle in Ruby 3.0.0 or later supports Fiddle::TYPE_VARIADIC.
|
37
37
|
fiddle_supports_variadic = true
|
38
|
-
elsif Fiddle.const_defined?(:VERSION) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
|
38
|
+
elsif Fiddle.const_defined?(:VERSION,false) and Gem::Version.create(Fiddle::VERSION) >= Gem::Version.create('1.0.1')
|
39
39
|
# Fiddle::TYPE_VARIADIC is supported from Fiddle 1.0.1.
|
40
40
|
fiddle_supports_variadic = true
|
41
41
|
else
|
@@ -74,12 +74,27 @@ module Reline::Terminfo
|
|
74
74
|
#extern 'char *tparm(const char *str, ...)'
|
75
75
|
@tiparm = Fiddle::Function.new(curses_dl['tparm'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VARIADIC], Fiddle::TYPE_VOIDP)
|
76
76
|
end
|
77
|
-
|
77
|
+
begin
|
78
|
+
#extern 'int tigetflag(char *str)'
|
79
|
+
@tigetflag = Fiddle::Function.new(curses_dl['tigetflag'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
80
|
+
rescue Fiddle::DLError
|
81
|
+
# OpenBSD lacks tigetflag
|
82
|
+
#extern 'int tgetflag(char *str)'
|
83
|
+
@tigetflag = Fiddle::Function.new(curses_dl['tgetflag'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
84
|
+
end
|
85
|
+
begin
|
86
|
+
#extern 'int tigetnum(char *str)'
|
87
|
+
@tigetnum = Fiddle::Function.new(curses_dl['tigetnum'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
88
|
+
rescue Fiddle::DLError
|
89
|
+
# OpenBSD lacks tigetnum
|
90
|
+
#extern 'int tgetnum(char *str)'
|
91
|
+
@tigetnum = Fiddle::Function.new(curses_dl['tgetnum'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT)
|
92
|
+
end
|
78
93
|
|
79
94
|
def self.setupterm(term, fildes)
|
80
|
-
errret_int =
|
95
|
+
errret_int = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INT)
|
81
96
|
ret = @setupterm.(term, fildes, errret_int)
|
82
|
-
errret = errret_int.unpack1('i')
|
97
|
+
errret = errret_int[0, Fiddle::SIZEOF_INT].unpack1('i')
|
83
98
|
case ret
|
84
99
|
when 0 # OK
|
85
100
|
0
|
@@ -106,6 +121,7 @@ module Reline::Terminfo
|
|
106
121
|
end
|
107
122
|
|
108
123
|
def self.tigetstr(capname)
|
124
|
+
raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String)
|
109
125
|
capability = @tigetstr.(capname)
|
110
126
|
case capability.to_i
|
111
127
|
when 0, -1
|
@@ -122,6 +138,30 @@ module Reline::Terminfo
|
|
122
138
|
@tiparm.(str, *new_args).to_s
|
123
139
|
end
|
124
140
|
|
141
|
+
def self.tigetflag(capname)
|
142
|
+
raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String)
|
143
|
+
flag = @tigetflag.(capname).to_i
|
144
|
+
case flag
|
145
|
+
when -1
|
146
|
+
raise TerminfoError, "not boolean capability: #{capname}"
|
147
|
+
when 0
|
148
|
+
raise TerminfoError, "can't find capability: #{capname}"
|
149
|
+
end
|
150
|
+
flag
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.tigetnum(capname)
|
154
|
+
raise TerminfoError, "capname is not String: #{capname.inspect}" unless capname.is_a?(String)
|
155
|
+
num = @tigetnum.(capname).to_i
|
156
|
+
case num
|
157
|
+
when -2
|
158
|
+
raise TerminfoError, "not numeric capability: #{capname}"
|
159
|
+
when -1
|
160
|
+
raise TerminfoError, "can't find capability: #{capname}"
|
161
|
+
end
|
162
|
+
num
|
163
|
+
end
|
164
|
+
|
125
165
|
def self.enabled?
|
126
166
|
true
|
127
167
|
end
|
data/lib/reline/version.rb
CHANGED
data/lib/reline/windows.rb
CHANGED
@@ -95,7 +95,7 @@ class Reline::Windows
|
|
95
95
|
end
|
96
96
|
|
97
97
|
VK_RETURN = 0x0D
|
98
|
-
VK_MENU = 0x12
|
98
|
+
VK_MENU = 0x12 # ALT key
|
99
99
|
VK_LMENU = 0xA4
|
100
100
|
VK_CONTROL = 0x11
|
101
101
|
VK_SHIFT = 0x10
|
@@ -249,7 +249,7 @@ class Reline::Windows
|
|
249
249
|
# no char, only control keys
|
250
250
|
return if key.char_code == 0 and key.control_keys.any?
|
251
251
|
|
252
|
-
@@output_buf.push("\e".ord) if key.control_keys.include?(:ALT)
|
252
|
+
@@output_buf.push("\e".ord) if key.control_keys.include?(:ALT) and !key.control_keys.include?(:CTRL)
|
253
253
|
|
254
254
|
@@output_buf.concat(key.char.bytes)
|
255
255
|
end
|
@@ -386,7 +386,7 @@ class Reline::Windows
|
|
386
386
|
def self.scroll_down(val)
|
387
387
|
return if val < 0
|
388
388
|
return unless csbi = get_console_screen_buffer_info
|
389
|
-
buffer_width, x, y,
|
389
|
+
buffer_width, buffer_lines, x, y, attributes, window_left, window_top, window_bottom = csbi.unpack('ssssSssx2s')
|
390
390
|
screen_height = window_bottom - window_top + 1
|
391
391
|
val = screen_height if val > screen_height
|
392
392
|
|
data/lib/reline.rb
CHANGED
@@ -33,7 +33,18 @@ module Reline
|
|
33
33
|
alias_method :==, :match?
|
34
34
|
end
|
35
35
|
CursorPos = Struct.new(:x, :y)
|
36
|
-
DialogRenderInfo = Struct.new(
|
36
|
+
DialogRenderInfo = Struct.new(
|
37
|
+
:pos,
|
38
|
+
:contents,
|
39
|
+
:bg_color,
|
40
|
+
:pointer_bg_color,
|
41
|
+
:fg_color,
|
42
|
+
:pointer_fg_color,
|
43
|
+
:width,
|
44
|
+
:height,
|
45
|
+
:scrollbar,
|
46
|
+
keyword_init: true
|
47
|
+
)
|
37
48
|
|
38
49
|
class Core
|
39
50
|
ATTR_READER_NAMES = %i(
|
@@ -58,6 +69,11 @@ module Reline
|
|
58
69
|
attr_accessor :last_incremental_search
|
59
70
|
attr_reader :output
|
60
71
|
|
72
|
+
extend Forwardable
|
73
|
+
def_delegators :config,
|
74
|
+
:autocompletion,
|
75
|
+
:autocompletion=
|
76
|
+
|
61
77
|
def initialize
|
62
78
|
self.output = STDOUT
|
63
79
|
@dialog_proc_list = {}
|
@@ -123,14 +139,6 @@ module Reline
|
|
123
139
|
@completion_proc = p
|
124
140
|
end
|
125
141
|
|
126
|
-
def autocompletion
|
127
|
-
@config.autocompletion
|
128
|
-
end
|
129
|
-
|
130
|
-
def autocompletion=(val)
|
131
|
-
@config.autocompletion = val
|
132
|
-
end
|
133
|
-
|
134
142
|
def output_modifier_proc=(p)
|
135
143
|
raise ArgumentError unless p.respond_to?(:call) or p.nil?
|
136
144
|
@output_modifier_proc = p
|
@@ -243,7 +251,16 @@ module Reline
|
|
243
251
|
context.push(cursor_pos_to_render, result, pointer, dialog)
|
244
252
|
end
|
245
253
|
dialog.pointer = pointer
|
246
|
-
DialogRenderInfo.new(
|
254
|
+
DialogRenderInfo.new(
|
255
|
+
pos: cursor_pos_to_render,
|
256
|
+
contents: result,
|
257
|
+
scrollbar: true,
|
258
|
+
height: 15,
|
259
|
+
bg_color: 46,
|
260
|
+
pointer_bg_color: 45,
|
261
|
+
fg_color: 37,
|
262
|
+
pointer_fg_color: 37
|
263
|
+
)
|
247
264
|
}
|
248
265
|
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
|
249
266
|
|
@@ -466,7 +483,7 @@ module Reline
|
|
466
483
|
end
|
467
484
|
|
468
485
|
private def may_req_ambiguous_char_width
|
469
|
-
@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or STDOUT.
|
486
|
+
@ambiguous_width = 2 if Reline::IOGate == Reline::GeneralIO or !STDOUT.tty?
|
470
487
|
return if defined? @ambiguous_width
|
471
488
|
Reline::IOGate.move_cursor_column(0)
|
472
489
|
begin
|
@@ -563,24 +580,21 @@ module Reline
|
|
563
580
|
end
|
564
581
|
|
565
582
|
require 'reline/general_io'
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
require 'reline/ansi'
|
573
|
-
Reline::ANSI
|
574
|
-
end
|
583
|
+
io = Reline::GeneralIO
|
584
|
+
unless ENV['TERM'] == 'dumb'
|
585
|
+
case RbConfig::CONFIG['host_os']
|
586
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
587
|
+
require 'reline/windows'
|
588
|
+
tty = (io = Reline::Windows).msys_tty?
|
575
589
|
else
|
576
|
-
|
590
|
+
tty = $stdout.tty?
|
577
591
|
end
|
592
|
+
end
|
593
|
+
Reline::IOGate = if tty
|
594
|
+
require 'reline/ansi'
|
595
|
+
Reline::ANSI
|
578
596
|
else
|
579
|
-
|
580
|
-
require 'reline/ansi'
|
581
|
-
Reline::ANSI
|
582
|
-
else
|
583
|
-
Reline::GeneralIO
|
584
|
-
end
|
597
|
+
io
|
585
598
|
end
|
599
|
+
|
586
600
|
Reline::HISTORY = Reline::History.new(Reline.core.config)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|
@@ -47,7 +47,6 @@ files:
|
|
47
47
|
- lib/reline/key_stroke.rb
|
48
48
|
- lib/reline/kill_ring.rb
|
49
49
|
- lib/reline/line_editor.rb
|
50
|
-
- lib/reline/sibori.rb
|
51
50
|
- lib/reline/terminfo.rb
|
52
51
|
- lib/reline/unicode.rb
|
53
52
|
- lib/reline/unicode/east_asian_width.rb
|
@@ -66,14 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
65
|
requirements:
|
67
66
|
- - ">="
|
68
67
|
- !ruby/object:Gem::Version
|
69
|
-
version: '2.
|
68
|
+
version: '2.6'
|
70
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
70
|
requirements:
|
72
71
|
- - ">="
|
73
72
|
- !ruby/object:Gem::Version
|
74
73
|
version: '0'
|
75
74
|
requirements: []
|
76
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.4.0.dev
|
77
76
|
signing_key:
|
78
77
|
specification_version: 4
|
79
78
|
summary: Alternative GNU Readline or Editline implementation by pure Ruby.
|
data/lib/reline/sibori.rb
DELETED
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'reline/unicode'
|
2
|
-
|
3
|
-
=begin
|
4
|
-
|
5
|
-
\ |
|
6
|
-
\ | <--- whipped cream
|
7
|
-
\ |
|
8
|
-
\ |
|
9
|
-
\-~~|
|
10
|
-
\ | <--- shibori kutigane (piping nozzle in Japanese)
|
11
|
-
\Ml
|
12
|
-
(\ __ __
|
13
|
-
( \--( ) )
|
14
|
-
(__(__)__) <--- compressed whipped cream
|
15
|
-
=end
|
16
|
-
|
17
|
-
class Sibori
|
18
|
-
attr_writer :output
|
19
|
-
|
20
|
-
def initialize(width, height, cursor_pos)
|
21
|
-
@width = width
|
22
|
-
@height = height
|
23
|
-
@cursor_pos = cursor_pos
|
24
|
-
@screen = [String.new]
|
25
|
-
@line_index = 0
|
26
|
-
@byte_pointer_in_line = 0
|
27
|
-
@cleared = false
|
28
|
-
clone_screen
|
29
|
-
end
|
30
|
-
|
31
|
-
def clone_screen
|
32
|
-
@prev_screen = @screen.map { |line|
|
33
|
-
line.dup
|
34
|
-
}
|
35
|
-
@prev_cursor_pos = @cursor_pos.dup
|
36
|
-
@prev_line_index = @line_index
|
37
|
-
end
|
38
|
-
|
39
|
-
def print(str)
|
40
|
-
#$stderr.puts "print #{str.inspect}"
|
41
|
-
line = @screen[@line_index]
|
42
|
-
before = line.byteslice(0, @byte_pointer_in_line)
|
43
|
-
str_width = Reline::Unicode.calculate_width(str, true)
|
44
|
-
after_cursor = line.byteslice(@byte_pointer_in_line..-1)
|
45
|
-
after_cursor_width = Reline::Unicode.calculate_width(after_cursor, true)
|
46
|
-
rest = ''
|
47
|
-
if after_cursor_width > str_width
|
48
|
-
rest_byte_pointer = @byte_pointer_in_line + width_to_bytesize(after_cursor, str_width)
|
49
|
-
rest = line.byteslice(rest_byte_pointer..-1)
|
50
|
-
end
|
51
|
-
@screen[@line_index] = before + str + rest
|
52
|
-
@byte_pointer_in_line += str.bytesize
|
53
|
-
@cursor_pos.x += Reline::Unicode.calculate_width(str, true)
|
54
|
-
end
|
55
|
-
|
56
|
-
def move_cursor_column(col)
|
57
|
-
#$stderr.puts "move_cursor_column(#{col})"
|
58
|
-
@byte_pointer_in_line = width_to_bytesize(@screen[@line_index], col)
|
59
|
-
@cursor_pos.x = col
|
60
|
-
end
|
61
|
-
|
62
|
-
def move_cursor_up(val)
|
63
|
-
#$stderr.puts "move_cursor_up(#{val})"
|
64
|
-
if @line_index.positive?
|
65
|
-
@line_index -= val
|
66
|
-
@byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
|
67
|
-
@cursor_pos.y -= val
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def move_cursor_down(val)
|
72
|
-
#$stderr.puts "move_cursor_down(#{val})"
|
73
|
-
if @line_index < @height - 1
|
74
|
-
#$stderr.puts "@line_index #{@line_index} @screen.size #{@screen.size} @height #{@height}"
|
75
|
-
#$stderr.puts @screen.inspect
|
76
|
-
@line_index += val
|
77
|
-
@screen[@line_index] = String.new if @line_index == @screen.size
|
78
|
-
@byte_pointer_in_line = width_to_bytesize(@screen[@line_index], @cursor_pos.x)
|
79
|
-
@cursor_pos.y += val
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def scroll_down(val)
|
84
|
-
#$stderr.puts "scroll_down(#{val})"
|
85
|
-
if val >= @height
|
86
|
-
clear_screen
|
87
|
-
@line_index = @screen.size - 1
|
88
|
-
return
|
89
|
-
end
|
90
|
-
@screen.size.times do |n|
|
91
|
-
if n < @screen.size - val
|
92
|
-
#$stderr.puts "A @screen[#{val} + #{n}] (#{@screen[val + n].inspect}) to @screen[#{n}]"
|
93
|
-
@screen[n] = @screen[val + n]
|
94
|
-
else
|
95
|
-
#$stderr.puts "B String.new to @screen[#{n}]"
|
96
|
-
@screen[n] = String.new
|
97
|
-
end
|
98
|
-
end
|
99
|
-
@line_index += val
|
100
|
-
end
|
101
|
-
|
102
|
-
def erase_after_cursor
|
103
|
-
#$stderr.puts "erase_after_cursor"
|
104
|
-
@screen[@line_index] = @screen[@line_index].byteslice(0, @byte_pointer_in_line)
|
105
|
-
end
|
106
|
-
|
107
|
-
def clear_screen
|
108
|
-
#$stderr.puts "clear_screen"
|
109
|
-
@screen = [String.new]
|
110
|
-
@line_index = 0
|
111
|
-
@byte_pointer_in_line = 0
|
112
|
-
@cursor_pos.x = @cursor_pos.y = 0
|
113
|
-
@cleared = true
|
114
|
-
Reline::IOGate.clear_screen
|
115
|
-
end
|
116
|
-
|
117
|
-
private def width_to_bytesize(str, width)
|
118
|
-
lines, _ = Reline::Unicode.split_by_width(str, width)
|
119
|
-
lines.first.bytesize
|
120
|
-
end
|
121
|
-
|
122
|
-
def render
|
123
|
-
#$stderr.puts ?* * 100
|
124
|
-
Reline::IOGate.move_cursor_up(@prev_line_index) if @prev_line_index.positive?
|
125
|
-
#$stderr.puts "! move_cursor_up(#{@prev_line_index})" if @prev_line_index.positive?
|
126
|
-
#$stderr.puts "@prev_line_index #{@prev_line_index} @line_index #{@line_index}"
|
127
|
-
if @screen.size > @prev_screen.size
|
128
|
-
#$stderr.puts ?a * 100
|
129
|
-
down = @screen.size - @prev_screen.size
|
130
|
-
#$stderr.puts "#{@prev_cursor_pos.y} #{down} #{@height}"
|
131
|
-
if @prev_cursor_pos.y + down > (@height - 1)
|
132
|
-
#$stderr.puts ?b * 100
|
133
|
-
scroll = (@prev_cursor_pos.y + down) - (@height - 1)
|
134
|
-
Reline::IOGate.scroll_down(scroll)
|
135
|
-
#$stderr.puts "! scroll_down(#{scroll})"
|
136
|
-
#$stderr.puts "down #{down}"
|
137
|
-
Reline::IOGate.move_cursor_up(@screen.size - 1 - scroll)
|
138
|
-
#$stderr.puts "! move_cursor_up(#{@screen.size - 1})"
|
139
|
-
else
|
140
|
-
#$stderr.puts ?c * 100
|
141
|
-
end
|
142
|
-
end
|
143
|
-
@screen.size.times do |n|
|
144
|
-
Reline::IOGate.move_cursor_column(0)
|
145
|
-
#$stderr.puts "! move_cursor_column(0)"
|
146
|
-
@output.write @screen[n]
|
147
|
-
#$stderr.puts "! print #{@screen[n].inspect}"
|
148
|
-
Reline::IOGate.erase_after_cursor
|
149
|
-
#$stderr.puts "! erase_after_cursor"
|
150
|
-
Reline::IOGate.move_cursor_down(1) if n != (@screen.size - 1)
|
151
|
-
#$stderr.puts "! move_cursor_down(1)" if n != (@screen.size - 1)
|
152
|
-
end
|
153
|
-
up = @screen.size - 1 - @line_index
|
154
|
-
Reline::IOGate.move_cursor_up(up) if up.positive?
|
155
|
-
#$stderr.puts "! move_cursor_up(#{up})" if up.positive?
|
156
|
-
column = Reline::Unicode.calculate_width(@screen[@line_index].byteslice(0, @byte_pointer_in_line), true)
|
157
|
-
Reline::IOGate.move_cursor_column(column)
|
158
|
-
#$stderr.puts "! move_cursor_column(#{column}) #{@byte_pointer_in_line}"
|
159
|
-
clone_screen
|
160
|
-
#$stderr.puts ?- * 10
|
161
|
-
end
|
162
|
-
|
163
|
-
def prep
|
164
|
-
Reline::IOGate.prep
|
165
|
-
end
|
166
|
-
|
167
|
-
def deprep
|
168
|
-
Reline::IOGate.deprep
|
169
|
-
end
|
170
|
-
end
|