reline 0.5.3 → 0.5.4
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 +19 -19
- data/lib/reline/line_editor.rb +10 -15
- data/lib/reline/unicode.rb +58 -6
- data/lib/reline/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 45922535b3972631020c6b33bc6b88fd400062fb2c0820ab95ab991704c1fc42
|
4
|
+
data.tar.gz: 53f36ad5e7e196ba34a22990c32b38556653b7384bd99108a791d1b4c7cd3b36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb1b50add8dc60baeefd1fecce83abbaf0e134c16c30ca7fd268efe46d364638280bd2a16100e54be6dbf691bc8a9d4220c53210233a06a0278361c07bd5a56f
|
7
|
+
data.tar.gz: 5ed4f57373cd6e9329de58b9361037e4f8e510020c0ba59970de5733a8c8f4b5c004b871d8e21f013ee065daed9b55f433142529b5e4039276a0f0adbc00c4d9
|
data/lib/reline/ansi.rb
CHANGED
@@ -284,7 +284,7 @@ class Reline::ANSI
|
|
284
284
|
buf = @@output.pread(@@output.pos, 0)
|
285
285
|
row = buf.count("\n")
|
286
286
|
column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0
|
287
|
-
rescue Errno::ESPIPE
|
287
|
+
rescue Errno::ESPIPE, IOError
|
288
288
|
# Just returns column 1 for ambiguous width because this I/O is not
|
289
289
|
# tty and can't seek.
|
290
290
|
row = 0
|
data/lib/reline/config.rb
CHANGED
@@ -53,8 +53,6 @@ class Reline::Config
|
|
53
53
|
@additional_key_bindings[:vi_insert] = {}
|
54
54
|
@additional_key_bindings[:vi_command] = {}
|
55
55
|
@oneshot_key_bindings = {}
|
56
|
-
@skip_section = nil
|
57
|
-
@if_stack = nil
|
58
56
|
@editing_mode_label = :emacs
|
59
57
|
@keymap_label = :emacs
|
60
58
|
@keymap_prefix = []
|
@@ -190,9 +188,7 @@ class Reline::Config
|
|
190
188
|
end
|
191
189
|
end
|
192
190
|
end
|
193
|
-
|
194
|
-
@skip_section = nil
|
195
|
-
@if_stack = []
|
191
|
+
if_stack = []
|
196
192
|
|
197
193
|
lines.each_with_index do |line, no|
|
198
194
|
next if line.match(/\A\s*#/)
|
@@ -201,11 +197,11 @@ class Reline::Config
|
|
201
197
|
|
202
198
|
line = line.chomp.lstrip
|
203
199
|
if line.start_with?('$')
|
204
|
-
handle_directive(line[1..-1], file, no)
|
200
|
+
handle_directive(line[1..-1], file, no, if_stack)
|
205
201
|
next
|
206
202
|
end
|
207
203
|
|
208
|
-
next if
|
204
|
+
next if if_stack.any? { |_no, skip| skip }
|
209
205
|
|
210
206
|
case line
|
211
207
|
when /^set +([^ ]+) +([^ ]+)/i
|
@@ -214,43 +210,47 @@ class Reline::Config
|
|
214
210
|
next
|
215
211
|
when /\s*("#{KEYSEQ_PATTERN}+")\s*:\s*(.*)\s*$/o
|
216
212
|
key, func_name = $1, $2
|
213
|
+
func_name = func_name.split.first
|
217
214
|
keystroke, func = bind_key(key, func_name)
|
218
215
|
next unless keystroke
|
219
216
|
@additional_key_bindings[@keymap_label][@keymap_prefix + keystroke] = func
|
220
217
|
end
|
221
218
|
end
|
222
|
-
unless
|
223
|
-
raise InvalidInputrc, "#{file}:#{
|
219
|
+
unless if_stack.empty?
|
220
|
+
raise InvalidInputrc, "#{file}:#{if_stack.last[0]}: unclosed if"
|
224
221
|
end
|
225
|
-
ensure
|
226
|
-
@skip_section, @if_stack = conditions
|
227
222
|
end
|
228
223
|
|
229
|
-
def handle_directive(directive, file, no)
|
224
|
+
def handle_directive(directive, file, no, if_stack)
|
230
225
|
directive, args = directive.split(' ')
|
231
226
|
case directive
|
232
227
|
when 'if'
|
233
228
|
condition = false
|
234
229
|
case args
|
235
|
-
when
|
230
|
+
when /^mode=(vi|emacs)$/i
|
231
|
+
mode = $1.downcase
|
232
|
+
# NOTE: mode=vi means vi-insert mode
|
233
|
+
mode = 'vi_insert' if mode == 'vi'
|
234
|
+
if @editing_mode_label == mode.to_sym
|
235
|
+
condition = true
|
236
|
+
end
|
236
237
|
when 'term'
|
237
238
|
when 'version'
|
238
239
|
else # application name
|
239
240
|
condition = true if args == 'Ruby'
|
240
241
|
condition = true if args == 'Reline'
|
241
242
|
end
|
242
|
-
|
243
|
-
@skip_section = !condition
|
243
|
+
if_stack << [no, !condition]
|
244
244
|
when 'else'
|
245
|
-
if
|
245
|
+
if if_stack.empty?
|
246
246
|
raise InvalidInputrc, "#{file}:#{no}: unmatched else"
|
247
247
|
end
|
248
|
-
|
248
|
+
if_stack.last[1] = !if_stack.last[1]
|
249
249
|
when 'endif'
|
250
|
-
if
|
250
|
+
if if_stack.empty?
|
251
251
|
raise InvalidInputrc, "#{file}:#{no}: unmatched endif"
|
252
252
|
end
|
253
|
-
|
253
|
+
if_stack.pop
|
254
254
|
when 'include'
|
255
255
|
read(File.expand_path(args))
|
256
256
|
end
|
data/lib/reline/line_editor.rb
CHANGED
@@ -414,8 +414,13 @@ class Reline::LineEditor
|
|
414
414
|
@output.write "#{Reline::IOGate::RESET_COLOR}#{' ' * width}"
|
415
415
|
else
|
416
416
|
x, w, content = new_items[level]
|
417
|
-
|
418
|
-
|
417
|
+
cover_begin = base_x != 0 && new_levels[base_x - 1] == level
|
418
|
+
cover_end = new_levels[base_x + width] == level
|
419
|
+
pos = 0
|
420
|
+
unless x == base_x && w == width
|
421
|
+
content, pos = Reline::Unicode.take_mbchar_range(content, base_x - x, width, cover_begin: cover_begin, cover_end: cover_end, padding: true)
|
422
|
+
end
|
423
|
+
Reline::IOGate.move_cursor_column x + pos
|
419
424
|
@output.write "#{Reline::IOGate::RESET_COLOR}#{content}#{Reline::IOGate::RESET_COLOR}"
|
420
425
|
end
|
421
426
|
base_x += width
|
@@ -699,13 +704,6 @@ class Reline::LineEditor
|
|
699
704
|
|
700
705
|
DIALOG_DEFAULT_HEIGHT = 20
|
701
706
|
|
702
|
-
private def padding_space_with_escape_sequences(str, width)
|
703
|
-
padding_width = width - calculate_width(str, true)
|
704
|
-
# padding_width should be only positive value. But macOS and Alacritty returns negative value.
|
705
|
-
padding_width = 0 if padding_width < 0
|
706
|
-
str + (' ' * padding_width)
|
707
|
-
end
|
708
|
-
|
709
707
|
private def dialog_range(dialog, dialog_y)
|
710
708
|
x_range = dialog.column...dialog.column + dialog.width
|
711
709
|
y_range = dialog_y + dialog.vertical_offset...dialog_y + dialog.vertical_offset + dialog.contents.size
|
@@ -778,7 +776,7 @@ class Reline::LineEditor
|
|
778
776
|
dialog.contents = contents.map.with_index do |item, i|
|
779
777
|
line_sgr = i == pointer ? enhanced_sgr : default_sgr
|
780
778
|
str_width = dialog.width - (scrollbar_pos.nil? ? 0 : @block_elem_width)
|
781
|
-
str =
|
779
|
+
str, = Reline::Unicode.take_mbchar_range(item, 0, str_width, padding: true)
|
782
780
|
colored_content = "#{line_sgr}#{str}"
|
783
781
|
if scrollbar_pos
|
784
782
|
if scrollbar_pos <= (i * 2) and (i * 2 + 1) < (scrollbar_pos + bar_height)
|
@@ -1120,6 +1118,7 @@ class Reline::LineEditor
|
|
1120
1118
|
end
|
1121
1119
|
end
|
1122
1120
|
if key.char.nil?
|
1121
|
+
process_insert(force: true)
|
1123
1122
|
if @first_char
|
1124
1123
|
@eof = true
|
1125
1124
|
end
|
@@ -1542,11 +1541,7 @@ class Reline::LineEditor
|
|
1542
1541
|
alias_method :vi_zero, :ed_move_to_beg
|
1543
1542
|
|
1544
1543
|
private def ed_move_to_end(key)
|
1545
|
-
@byte_pointer =
|
1546
|
-
while @byte_pointer < current_line.bytesize
|
1547
|
-
byte_size = Reline::Unicode.get_next_mbchar_size(current_line, @byte_pointer)
|
1548
|
-
@byte_pointer += byte_size
|
1549
|
-
end
|
1544
|
+
@byte_pointer = current_line.bytesize
|
1550
1545
|
end
|
1551
1546
|
alias_method :end_of_line, :ed_move_to_end
|
1552
1547
|
|
data/lib/reline/unicode.rb
CHANGED
@@ -145,7 +145,13 @@ class Reline::Unicode
|
|
145
145
|
lines.last << NON_PRINTING_END
|
146
146
|
when csi
|
147
147
|
lines.last << csi
|
148
|
-
|
148
|
+
unless in_zero_width
|
149
|
+
if csi == -"\e[m" || csi == -"\e[0m"
|
150
|
+
seq.clear
|
151
|
+
else
|
152
|
+
seq << csi
|
153
|
+
end
|
154
|
+
end
|
149
155
|
when osc
|
150
156
|
lines.last << osc
|
151
157
|
seq << osc
|
@@ -173,32 +179,78 @@ class Reline::Unicode
|
|
173
179
|
|
174
180
|
# Take a chunk of a String cut by width with escape sequences.
|
175
181
|
def self.take_range(str, start_col, max_width)
|
182
|
+
take_mbchar_range(str, start_col, max_width).first
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.take_mbchar_range(str, start_col, width, cover_begin: false, cover_end: false, padding: false)
|
176
186
|
chunk = String.new(encoding: str.encoding)
|
187
|
+
|
188
|
+
end_col = start_col + width
|
177
189
|
total_width = 0
|
178
190
|
rest = str.encode(Encoding::UTF_8)
|
179
191
|
in_zero_width = false
|
192
|
+
chunk_start_col = nil
|
193
|
+
chunk_end_col = nil
|
194
|
+
has_csi = false
|
180
195
|
rest.scan(WIDTH_SCANNER) do |non_printing_start, non_printing_end, csi, osc, gc|
|
181
196
|
case
|
182
197
|
when non_printing_start
|
183
198
|
in_zero_width = true
|
199
|
+
chunk << NON_PRINTING_START
|
184
200
|
when non_printing_end
|
185
201
|
in_zero_width = false
|
202
|
+
chunk << NON_PRINTING_END
|
186
203
|
when csi
|
204
|
+
has_csi = true
|
187
205
|
chunk << csi
|
188
206
|
when osc
|
189
207
|
chunk << osc
|
190
208
|
when gc
|
191
209
|
if in_zero_width
|
192
210
|
chunk << gc
|
211
|
+
next
|
212
|
+
end
|
213
|
+
|
214
|
+
mbchar_width = get_mbchar_width(gc)
|
215
|
+
prev_width = total_width
|
216
|
+
total_width += mbchar_width
|
217
|
+
|
218
|
+
if (cover_begin || padding ? total_width <= start_col : prev_width < start_col)
|
219
|
+
# Current character haven't reached start_col yet
|
220
|
+
next
|
221
|
+
elsif padding && !cover_begin && prev_width < start_col && start_col < total_width
|
222
|
+
# Add preceding padding. This padding might have background color.
|
223
|
+
chunk << ' '
|
224
|
+
chunk_start_col ||= start_col
|
225
|
+
chunk_end_col = total_width
|
226
|
+
next
|
227
|
+
elsif (cover_end ? prev_width < end_col : total_width <= end_col)
|
228
|
+
# Current character is in the range
|
229
|
+
chunk << gc
|
230
|
+
chunk_start_col ||= prev_width
|
231
|
+
chunk_end_col = total_width
|
232
|
+
break if total_width >= end_col
|
193
233
|
else
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
234
|
+
# Current character exceeds end_col
|
235
|
+
if padding && end_col < total_width
|
236
|
+
# Add succeeding padding. This padding might have background color.
|
237
|
+
chunk << ' '
|
238
|
+
chunk_start_col ||= prev_width
|
239
|
+
chunk_end_col = end_col
|
240
|
+
end
|
241
|
+
break
|
198
242
|
end
|
199
243
|
end
|
200
244
|
end
|
201
|
-
|
245
|
+
chunk_start_col ||= start_col
|
246
|
+
chunk_end_col ||= start_col
|
247
|
+
if padding && chunk_end_col < end_col
|
248
|
+
# Append padding. This padding should not include background color.
|
249
|
+
chunk << "\e[0m" if has_csi
|
250
|
+
chunk << ' ' * (end_col - chunk_end_col)
|
251
|
+
chunk_end_col = end_col
|
252
|
+
end
|
253
|
+
[chunk, chunk_start_col, chunk_end_col - chunk_start_col]
|
202
254
|
end
|
203
255
|
|
204
256
|
def self.get_next_mbchar_size(line, byte_pointer)
|
data/lib/reline/version.rb
CHANGED
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.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: io-console
|