textbringer 1.1.1 → 1.1.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/.github/workflows/macos.yml +1 -0
- data/.github/workflows/ubuntu.yml +1 -0
- data/.github/workflows/windows.yml +1 -0
- data/CHANGES.md +4 -0
- data/exe/textbringer +4 -1
- data/lib/textbringer/buffer.rb +193 -78
- data/lib/textbringer/commands/files.rb +5 -1
- data/lib/textbringer/commands/isearch.rb +12 -1
- data/lib/textbringer/commands/misc.rb +6 -1
- data/lib/textbringer/config.rb +1 -0
- data/lib/textbringer/controller.rb +9 -8
- data/lib/textbringer/utils.rb +10 -3
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +2 -0
- data/textbringer.gemspec +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9641c360dd5bb038429536d85e666ff3518e37413eeece13898fa1a730665193
|
4
|
+
data.tar.gz: e2e9f71f90e060e30aac0bfa273fe65349eacc633f83c7c6dda034aa160436c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 285df14ab50ac3b27e5c61a3c24503c7ce724b84a918072ada9e920c323f94c46564b329a3217950bddeee5e1c4b5e83f426ad577bb8cb6596004c2b374fd12d
|
7
|
+
data.tar.gz: 6ed66854359cdd89310f77cb79c2b14cdafe4b5c7636aee662c7d1a4103563388e183bf11b5b7aab45fd691b70fa16c5d33f66231f109c6a733d05c98f1087e2
|
data/.github/workflows/macos.yml
CHANGED
data/CHANGES.md
CHANGED
data/exe/textbringer
CHANGED
data/lib/textbringer/buffer.rb
CHANGED
@@ -58,6 +58,8 @@ module Textbringer
|
|
58
58
|
end
|
59
59
|
}
|
60
60
|
|
61
|
+
STRING_HAS_BYTE_BASED_METHODS = String.instance_methods.include?(:bytesplice)
|
62
|
+
|
61
63
|
if !defined?(@@detect_encoding_proc)
|
62
64
|
@@detect_encoding_proc = DEFAULT_DETECT_ENCODING
|
63
65
|
|
@@ -268,7 +270,14 @@ module Textbringer
|
|
268
270
|
|
269
271
|
def file_encoding=(enc)
|
270
272
|
@file_encoding = Encoding.find(enc)
|
271
|
-
@binary =
|
273
|
+
@binary = @file_encoding == Encoding::ASCII_8BIT
|
274
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
275
|
+
if @binary
|
276
|
+
@contents.force_encoding(Encoding::ASCII_8BIT)
|
277
|
+
else
|
278
|
+
@contents.force_encoding(Encoding::UTF_8)
|
279
|
+
end
|
280
|
+
end
|
272
281
|
end
|
273
282
|
|
274
283
|
def binary?
|
@@ -437,20 +446,26 @@ module Textbringer
|
|
437
446
|
end
|
438
447
|
|
439
448
|
def to_s
|
440
|
-
result =
|
441
|
-
|
449
|
+
result = @contents.byteslice(0...@gap_start) +
|
450
|
+
@contents.byteslice(@gap_end..-1)
|
451
|
+
if !@binary && !STRING_HAS_BYTE_BASED_METHODS
|
452
|
+
result.force_encoding(Encoding::UTF_8)
|
453
|
+
end
|
442
454
|
result
|
443
455
|
end
|
444
456
|
|
445
457
|
def substring(s, e)
|
446
458
|
result =
|
447
459
|
if s > @gap_start || e <= @gap_start
|
448
|
-
@contents
|
460
|
+
@contents.byteslice(user_to_gap(s)...user_to_gap(e))
|
449
461
|
else
|
450
462
|
len = @gap_start - s
|
451
|
-
@contents
|
463
|
+
@contents.byteslice(user_to_gap(s), len) +
|
464
|
+
@contents.byteslice(@gap_end, e - s - len)
|
452
465
|
end
|
453
|
-
|
466
|
+
if !@binary && !STRING_HAS_BYTE_BASED_METHODS
|
467
|
+
result.force_encoding(Encoding::UTF_8)
|
468
|
+
end
|
454
469
|
result
|
455
470
|
end
|
456
471
|
|
@@ -459,7 +474,7 @@ module Textbringer
|
|
459
474
|
@contents.byteslice(location)
|
460
475
|
else
|
461
476
|
@contents.byteslice(location + gap_size)
|
462
|
-
end
|
477
|
+
end&.force_encoding(Encoding::ASCII_8BIT)
|
463
478
|
end
|
464
479
|
|
465
480
|
def byte_before(location = @point)
|
@@ -506,11 +521,19 @@ module Textbringer
|
|
506
521
|
end
|
507
522
|
|
508
523
|
def get_line_and_column(pos)
|
509
|
-
line = 1 + @contents
|
524
|
+
line = 1 + @contents.byteslice(0...user_to_gap(pos)).count("\n")
|
510
525
|
if pos == point_min
|
511
526
|
column = 1
|
512
527
|
else
|
513
|
-
|
528
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
529
|
+
begin
|
530
|
+
i = @contents.byterindex("\n", user_to_gap(get_pos(pos, -1)))
|
531
|
+
rescue RangeError
|
532
|
+
i = nil
|
533
|
+
end
|
534
|
+
else
|
535
|
+
i = @contents.rindex("\n", user_to_gap(pos - 1))
|
536
|
+
end
|
514
537
|
if i
|
515
538
|
i += 1
|
516
539
|
else
|
@@ -539,7 +562,11 @@ module Textbringer
|
|
539
562
|
pos = point_min
|
540
563
|
i = 1
|
541
564
|
while i < n && pos < @contents.bytesize
|
542
|
-
|
565
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
566
|
+
pos = @contents.byteindex("\n", pos)
|
567
|
+
else
|
568
|
+
pos = @contents.index("\n", pos)
|
569
|
+
end
|
543
570
|
break if pos.nil?
|
544
571
|
i += 1
|
545
572
|
pos += 1
|
@@ -552,11 +579,14 @@ module Textbringer
|
|
552
579
|
|
553
580
|
def insert(x, merge_undo = false)
|
554
581
|
s = x.to_s
|
582
|
+
if !binary? && !s.valid_encoding?
|
583
|
+
raise EditorError, "Invalid encoding: #{s.dump}"
|
584
|
+
end
|
555
585
|
check_read_only_flag
|
556
586
|
pos = @point
|
557
587
|
size = s.bytesize
|
558
588
|
adjust_gap(size)
|
559
|
-
@
|
589
|
+
splice_contents(@point, size, STRING_HAS_BYTE_BASED_METHODS ? s : s.b)
|
560
590
|
@marks.each do |m|
|
561
591
|
if m.location > @point
|
562
592
|
m.location += size
|
@@ -604,7 +634,7 @@ module Textbringer
|
|
604
634
|
if n > 0
|
605
635
|
str = substring(s, pos)
|
606
636
|
# fill the gap with NUL to avoid invalid byte sequence in UTF-8
|
607
|
-
@
|
637
|
+
splice_contents(@gap_end...user_to_gap(pos), "\0" * (pos - @point))
|
608
638
|
@gap_end += pos - @point
|
609
639
|
@marks.each do |m|
|
610
640
|
if m.location > pos
|
@@ -619,7 +649,7 @@ module Textbringer
|
|
619
649
|
str = substring(pos, s)
|
620
650
|
update_line_and_column(@point, pos)
|
621
651
|
# fill the gap with NUL to avoid invalid byte sequence in UTF-8
|
622
|
-
|
652
|
+
splice_contents(user_to_gap(pos)...@gap_start, "\0" * (@point - pos))
|
623
653
|
@marks.each do |m|
|
624
654
|
if m.location >= @point
|
625
655
|
m.location -= @point - pos
|
@@ -941,7 +971,7 @@ module Textbringer
|
|
941
971
|
adjust_gap
|
942
972
|
len = e - s
|
943
973
|
# fill the gap with NUL to avoid invalid byte sequence in UTF-8
|
944
|
-
@
|
974
|
+
splice_contents(@gap_end, len, "\0" * len)
|
945
975
|
@gap_end += len
|
946
976
|
@marks.each do |m|
|
947
977
|
if m.location > e
|
@@ -966,6 +996,9 @@ module Textbringer
|
|
966
996
|
def clear
|
967
997
|
check_read_only_flag
|
968
998
|
@contents = +""
|
999
|
+
if binary? || !STRING_HAS_BYTE_BASED_METHODS
|
1000
|
+
@contents.force_encoding(Encoding::ASCII_8BIT)
|
1001
|
+
end
|
969
1002
|
@point = @gap_start = @gap_end = 0
|
970
1003
|
@marks.each do |m|
|
971
1004
|
m.location = 0
|
@@ -1125,49 +1158,71 @@ module Textbringer
|
|
1125
1158
|
byteindex(true, r, @point) == @point
|
1126
1159
|
end
|
1127
1160
|
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
s.
|
1138
|
-
end
|
1139
|
-
begin
|
1140
|
-
i = s.send(method, re, offset)
|
1161
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
1162
|
+
def byteindex(forward, re, pos)
|
1163
|
+
@match_offsets = []
|
1164
|
+
method = forward ? :byteindex : :byterindex
|
1165
|
+
adjust_gap(0, 0)
|
1166
|
+
s = @contents.byteslice(@gap_end..-1)
|
1167
|
+
unless binary?
|
1168
|
+
s.force_encoding(Encoding::UTF_8)
|
1169
|
+
end
|
1170
|
+
i = s.send(method, re, pos)
|
1141
1171
|
if i
|
1142
1172
|
m = Regexp.last_match
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1173
|
+
(0 .. m.size - 1).each do |j|
|
1174
|
+
@match_offsets.push(m.byteoffset(j))
|
1175
|
+
end
|
1176
|
+
i
|
1177
|
+
else
|
1178
|
+
nil
|
1179
|
+
end
|
1180
|
+
end
|
1181
|
+
else
|
1182
|
+
def byteindex(forward, re, pos)
|
1183
|
+
@match_offsets = []
|
1184
|
+
method = forward ? :index : :rindex
|
1185
|
+
adjust_gap(0, 0)
|
1186
|
+
s = @contents[@gap_end..-1]
|
1187
|
+
if @binary
|
1188
|
+
offset = pos
|
1189
|
+
else
|
1190
|
+
offset = s.byteslice(0, pos).force_encoding(Encoding::UTF_8).size
|
1191
|
+
s.force_encoding(Encoding::UTF_8)
|
1192
|
+
end
|
1193
|
+
begin
|
1194
|
+
i = s.send(method, re, offset)
|
1195
|
+
if i
|
1196
|
+
m = Regexp.last_match
|
1197
|
+
if m.nil?
|
1198
|
+
# A bug of rindex
|
1199
|
+
@match_offsets.push([pos, pos])
|
1200
|
+
pos
|
1201
|
+
else
|
1202
|
+
b = m.pre_match.bytesize
|
1203
|
+
e = b + m.to_s.bytesize
|
1204
|
+
if e <= bytesize
|
1205
|
+
@match_offsets.push([b, e])
|
1206
|
+
match_beg = m.begin(0)
|
1207
|
+
match_str = m.to_s
|
1208
|
+
(1 .. m.size - 1).each do |j|
|
1209
|
+
cb, ce = m.offset(j)
|
1210
|
+
if cb.nil?
|
1211
|
+
@match_offsets.push([nil, nil])
|
1212
|
+
else
|
1213
|
+
bb = b + match_str[0, cb - match_beg].bytesize
|
1214
|
+
be = b + match_str[0, ce - match_beg].bytesize
|
1215
|
+
@match_offsets.push([bb, be])
|
1216
|
+
end
|
1162
1217
|
end
|
1218
|
+
b
|
1219
|
+
else
|
1220
|
+
nil
|
1163
1221
|
end
|
1164
|
-
b
|
1165
|
-
else
|
1166
|
-
nil
|
1167
1222
|
end
|
1223
|
+
else
|
1224
|
+
nil
|
1168
1225
|
end
|
1169
|
-
else
|
1170
|
-
nil
|
1171
1226
|
end
|
1172
1227
|
end
|
1173
1228
|
end
|
@@ -1248,7 +1303,7 @@ module Textbringer
|
|
1248
1303
|
end
|
1249
1304
|
|
1250
1305
|
def gap_filled_with_nul?
|
1251
|
-
@contents
|
1306
|
+
@contents.byteslice(@gap_start...@gap_end)&.match?(/\A\0*\z/)
|
1252
1307
|
end
|
1253
1308
|
|
1254
1309
|
def composite_edit
|
@@ -1425,40 +1480,79 @@ module Textbringer
|
|
1425
1480
|
else
|
1426
1481
|
@contents = s.encode(Encoding::UTF_8)
|
1427
1482
|
end
|
1428
|
-
|
1483
|
+
if !STRING_HAS_BYTE_BASED_METHODS
|
1484
|
+
@contents.force_encoding(Encoding::ASCII_8BIT)
|
1485
|
+
end
|
1429
1486
|
self.file_encoding = enc
|
1430
|
-
|
1431
|
-
|
1487
|
+
begin
|
1488
|
+
case @contents
|
1489
|
+
when /(?<!\r)\n/
|
1490
|
+
@file_format = :unix
|
1491
|
+
when /\r(?!\n)/
|
1492
|
+
@file_format = :mac
|
1493
|
+
@contents.gsub!(/\r/, "\n")
|
1494
|
+
when /\r\n/
|
1495
|
+
@file_format = :dos
|
1496
|
+
@contents.gsub!(/\r/, "")
|
1497
|
+
else
|
1498
|
+
@file_format = CONFIG[:default_file_format]
|
1499
|
+
end
|
1500
|
+
rescue ArgumentError
|
1432
1501
|
@file_format = :unix
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
@contents.
|
1439
|
-
|
1440
|
-
|
1502
|
+
end
|
1503
|
+
end
|
1504
|
+
|
1505
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
1506
|
+
def splice_contents(*args)
|
1507
|
+
@contents.bytesplice(*args)
|
1508
|
+
end
|
1509
|
+
else
|
1510
|
+
def splice_contents(*args)
|
1511
|
+
@contents.[]=(*args)
|
1441
1512
|
end
|
1442
1513
|
end
|
1443
1514
|
|
1444
1515
|
def adjust_gap(min_size = 0, pos = @point)
|
1445
1516
|
if @gap_start < pos
|
1446
1517
|
len = user_to_gap(pos) - @gap_end
|
1447
|
-
|
1448
|
-
@gap_start
|
1449
|
-
@gap_end
|
1518
|
+
s = @contents.byteslice(@gap_end, len)
|
1519
|
+
new_gap_start = @gap_start + len
|
1520
|
+
new_gap_end = @gap_end + len
|
1521
|
+
nul_filling_start = new_gap_start > @gap_end ? new_gap_start : @gap_end
|
1522
|
+
unless @binary
|
1523
|
+
# find the character boundary
|
1524
|
+
while nul_filling_start > @gap_end &&
|
1525
|
+
@contents.byteslice(nul_filling_start)&.b&.match?(/[\x80-\xbf]/n)
|
1526
|
+
nul_filling_start -= 1
|
1527
|
+
end
|
1528
|
+
end
|
1529
|
+
splice_contents(nul_filling_start...new_gap_end,
|
1530
|
+
"\0" * (new_gap_end - nul_filling_start))
|
1531
|
+
splice_contents(@gap_start...new_gap_start, s)
|
1532
|
+
@gap_start = new_gap_start
|
1533
|
+
@gap_end = new_gap_end
|
1450
1534
|
elsif @gap_start > pos
|
1451
1535
|
len = @gap_start - pos
|
1452
|
-
|
1453
|
-
@gap_start
|
1454
|
-
@gap_end
|
1536
|
+
s = @contents.byteslice(pos, len)
|
1537
|
+
new_gap_start = @gap_start - len
|
1538
|
+
new_gap_end = @gap_end - len
|
1539
|
+
nul_filling_end = new_gap_end < @gap_start ? new_gap_end : @gap_start
|
1540
|
+
unless @binary
|
1541
|
+
# find the character boundary
|
1542
|
+
while nul_filling_end < @gap_start &&
|
1543
|
+
@contents.byteslice(nul_filling_end)&.b&.match?(/[\x80-\xbf]/n)
|
1544
|
+
nul_filling_end += 1
|
1545
|
+
end
|
1546
|
+
end
|
1547
|
+
splice_contents(pos...nul_filling_end, "\0" * (nul_filling_end - pos))
|
1548
|
+
splice_contents(new_gap_end...@gap_end, s)
|
1549
|
+
@gap_start = new_gap_start
|
1550
|
+
@gap_end = new_gap_end
|
1455
1551
|
end
|
1456
|
-
# fill the gap with NUL to avoid invalid byte sequence in UTF-8
|
1457
|
-
@contents[@gap_start...@gap_end] = "\0" * (@gap_end - @gap_start)
|
1458
1552
|
if gap_size < min_size
|
1459
1553
|
new_gap_size = GAP_SIZE + min_size
|
1460
1554
|
extended_size = new_gap_size - gap_size
|
1461
|
-
@
|
1555
|
+
splice_contents(@gap_end, 0, "\0" * extended_size)
|
1462
1556
|
@gap_end += extended_size
|
1463
1557
|
end
|
1464
1558
|
end
|
@@ -1520,12 +1614,20 @@ module Textbringer
|
|
1520
1614
|
def update_line_and_column(pos, new_pos)
|
1521
1615
|
return if @save_point_level > 0
|
1522
1616
|
if pos < new_pos
|
1523
|
-
n = @contents
|
1617
|
+
n = @contents.byteslice(user_to_gap(pos)...user_to_gap(new_pos)).count("\n")
|
1524
1618
|
if n == 0
|
1525
1619
|
@current_column += substring(pos, new_pos).size
|
1526
1620
|
else
|
1527
1621
|
@current_line += n
|
1528
|
-
|
1622
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
1623
|
+
begin
|
1624
|
+
i = @contents.byterindex("\n", user_to_gap(get_pos(new_pos, -1)))
|
1625
|
+
rescue RangeError
|
1626
|
+
i = nil
|
1627
|
+
end
|
1628
|
+
else
|
1629
|
+
i = @contents.rindex("\n", user_to_gap(new_pos - 1))
|
1630
|
+
end
|
1529
1631
|
if i
|
1530
1632
|
i += 1
|
1531
1633
|
else
|
@@ -1534,12 +1636,20 @@ module Textbringer
|
|
1534
1636
|
@current_column = 1 + substring(gap_to_user(i), new_pos).size
|
1535
1637
|
end
|
1536
1638
|
elsif pos > new_pos
|
1537
|
-
n = @contents
|
1639
|
+
n = @contents.byteslice(user_to_gap(new_pos)...user_to_gap(pos)).count("\n")
|
1538
1640
|
if n == 0
|
1539
1641
|
@current_column -= substring(new_pos, pos).size
|
1540
1642
|
else
|
1541
1643
|
@current_line -= n
|
1542
|
-
|
1644
|
+
if STRING_HAS_BYTE_BASED_METHODS
|
1645
|
+
begin
|
1646
|
+
i = @contents.byterindex("\n", user_to_gap(get_pos(new_pos, - 1)))
|
1647
|
+
rescue RangeError
|
1648
|
+
i = nil
|
1649
|
+
end
|
1650
|
+
else
|
1651
|
+
i = @contents.rindex("\n", user_to_gap(new_pos - 1))
|
1652
|
+
end
|
1543
1653
|
if i
|
1544
1654
|
i += 1
|
1545
1655
|
else
|
@@ -1573,8 +1683,13 @@ module Textbringer
|
|
1573
1683
|
end
|
1574
1684
|
|
1575
1685
|
def write_to_file(f)
|
1576
|
-
[
|
1577
|
-
|
1686
|
+
[
|
1687
|
+
@contents.byteslice(0...@gap_start),
|
1688
|
+
@contents.byteslice(@gap_end..-1)
|
1689
|
+
].each do |s|
|
1690
|
+
if !STRING_HAS_BYTE_BASED_METHODS
|
1691
|
+
s.force_encoding(Encoding::UTF_8) unless @binary
|
1692
|
+
end
|
1578
1693
|
case @file_format
|
1579
1694
|
when :dos
|
1580
1695
|
s.gsub!(/\n/, "\r\n")
|
@@ -72,7 +72,11 @@ module Textbringer
|
|
72
72
|
|
73
73
|
define_command(:save_buffer, doc: "Save the current buffer to a file.") do
|
74
74
|
if Buffer.current.file_name.nil?
|
75
|
-
|
75
|
+
file_name = read_file_name("File to save in: ")
|
76
|
+
if File.directory?(file_name)
|
77
|
+
file_name = File.expand_path(Buffer.current.name, file_name)
|
78
|
+
end
|
79
|
+
Buffer.current.file_name = file_name
|
76
80
|
next if Buffer.current.file_name.nil?
|
77
81
|
end
|
78
82
|
if Buffer.current.file_modified?
|
@@ -138,7 +138,18 @@ module Textbringer
|
|
138
138
|
end
|
139
139
|
re = Regexp.new(Regexp.quote(ISEARCH_STATUS[:string]), options)
|
140
140
|
last_pos = ISEARCH_STATUS[:last_pos]
|
141
|
-
|
141
|
+
if forward
|
142
|
+
offset = last_pos
|
143
|
+
else
|
144
|
+
Buffer.current.save_excursion do
|
145
|
+
pos = last_pos - ISEARCH_STATUS[:string].bytesize
|
146
|
+
goto_char(last_pos)
|
147
|
+
while Buffer.current.point > pos
|
148
|
+
backward_char
|
149
|
+
end
|
150
|
+
offset = Buffer.current.point
|
151
|
+
end
|
152
|
+
end
|
142
153
|
if offset >= 0 && Buffer.current.byteindex(forward, re, offset)
|
143
154
|
if Buffer.current != Buffer.minibuffer
|
144
155
|
message(isearch_prompt + ISEARCH_STATUS[:string], log: false)
|
@@ -125,6 +125,7 @@ module Textbringer
|
|
125
125
|
define_command(:complete_minibuffer) do
|
126
126
|
minibuffer = Buffer.minibuffer
|
127
127
|
completion_proc = minibuffer[:completion_proc]
|
128
|
+
ignore_case = minibuffer[:completion_ignore_case]
|
128
129
|
if completion_proc
|
129
130
|
xs = completion_proc.call(minibuffer.to_s)
|
130
131
|
update_completions(xs)
|
@@ -136,7 +137,11 @@ module Textbringer
|
|
136
137
|
s = y.size.downto(1).lazy.map { |i|
|
137
138
|
y[0, i]
|
138
139
|
}.find { |i|
|
139
|
-
|
140
|
+
i = i.downcase if ignore_case
|
141
|
+
ys.all? { |j|
|
142
|
+
j = j.downcase if ignore_case
|
143
|
+
j.start_with?(i)
|
144
|
+
}
|
140
145
|
}
|
141
146
|
if s
|
142
147
|
complete_minibuffer_with_string(s)
|
data/lib/textbringer/config.rb
CHANGED
@@ -55,7 +55,15 @@ module Textbringer
|
|
55
55
|
@last_key = c
|
56
56
|
@key_sequence << @last_key
|
57
57
|
cmd = key_binding(@key_sequence)
|
58
|
-
if cmd.
|
58
|
+
if cmd.nil?
|
59
|
+
keys = Keymap.key_sequence_string(@key_sequence)
|
60
|
+
@key_sequence.clear
|
61
|
+
@prefix_arg = nil
|
62
|
+
message("#{keys} is undefined")
|
63
|
+
Window.beep
|
64
|
+
elsif cmd.is_a?(Keymap)
|
65
|
+
# multi-stroke key binding?
|
66
|
+
else
|
59
67
|
@this_command_keys = @key_sequence
|
60
68
|
@key_sequence = []
|
61
69
|
@this_command = cmd
|
@@ -73,13 +81,6 @@ module Textbringer
|
|
73
81
|
@last_command = @this_command
|
74
82
|
@this_command = nil
|
75
83
|
end
|
76
|
-
else
|
77
|
-
if cmd.nil?
|
78
|
-
keys = Keymap.key_sequence_string(@key_sequence)
|
79
|
-
@key_sequence.clear
|
80
|
-
@prefix_arg = nil
|
81
|
-
message("#{keys} is undefined")
|
82
|
-
end
|
83
84
|
end
|
84
85
|
Window.redisplay
|
85
86
|
rescue Exception => e
|
data/lib/textbringer/utils.rb
CHANGED
@@ -137,7 +137,7 @@ module Textbringer
|
|
137
137
|
}
|
138
138
|
|
139
139
|
def read_from_minibuffer(prompt, completion_proc: nil, default: nil,
|
140
|
-
initial_value: nil,
|
140
|
+
initial_value: nil, completion_ignore_case: false,
|
141
141
|
keymap: MINIBUFFER_LOCAL_MAP)
|
142
142
|
if Window.echo_area.active?
|
143
143
|
raise EditorError,
|
@@ -146,10 +146,12 @@ module Textbringer
|
|
146
146
|
old_buffer = Buffer.current
|
147
147
|
old_window = Window.current
|
148
148
|
old_completion_proc = Buffer.minibuffer[:completion_proc]
|
149
|
+
old_completion_ignore_case = Buffer.minibuffer[:completion_ignore_case]
|
149
150
|
old_current_prefix_arg = Controller.current.current_prefix_arg
|
150
151
|
old_minibuffer_map = Buffer.minibuffer.keymap
|
151
152
|
Buffer.minibuffer.keymap = keymap
|
152
153
|
Buffer.minibuffer[:completion_proc] = completion_proc
|
154
|
+
Buffer.minibuffer[:completion_ignore_case] = completion_ignore_case
|
153
155
|
Window.echo_area.active = true
|
154
156
|
begin
|
155
157
|
Window.current = Window.echo_area
|
@@ -177,6 +179,7 @@ module Textbringer
|
|
177
179
|
# Just in case old_window has been deleted by resize,
|
178
180
|
# in which case Window.current is set to the first window.
|
179
181
|
Window.current.buffer = Buffer.current = old_buffer
|
182
|
+
Buffer.minibuffer[:completion_ignore_case] = old_completion_ignore_case
|
180
183
|
Buffer.minibuffer[:completion_proc] = old_completion_proc
|
181
184
|
Buffer.minibuffer.keymap = old_minibuffer_map
|
182
185
|
Buffer.minibuffer.disable_input_method
|
@@ -201,8 +204,10 @@ module Textbringer
|
|
201
204
|
}
|
202
205
|
}
|
203
206
|
initial_value = default&.sub(%r"\A#{Regexp.quote(Dir.pwd)}/", "")
|
207
|
+
ignore_case = CONFIG[:read_file_name_completion_ignore_case]
|
204
208
|
file = read_from_minibuffer(prompt, completion_proc: f,
|
205
|
-
initial_value: initial_value
|
209
|
+
initial_value: initial_value,
|
210
|
+
completion_ignore_case: ignore_case)
|
206
211
|
File.expand_path(file)
|
207
212
|
end
|
208
213
|
|
@@ -223,8 +228,10 @@ module Textbringer
|
|
223
228
|
end
|
224
229
|
|
225
230
|
def read_encoding(prompt, **opts)
|
231
|
+
encoding_names = (Encoding.list.map(&:name) + Encoding.aliases.keys).
|
232
|
+
map(&:downcase).uniq
|
226
233
|
f = ->(s) {
|
227
|
-
complete_for_minibuffer(s.
|
234
|
+
complete_for_minibuffer(s.downcase, encoding_names)
|
228
235
|
}
|
229
236
|
read_from_minibuffer(prompt, completion_proc: f, **opts)
|
230
237
|
end
|
data/lib/textbringer/version.rb
CHANGED
data/lib/textbringer/window.rb
CHANGED
data/textbringer.gemspec
CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_runtime_dependency "clipboard", ">= 1.1"
|
27
27
|
spec.add_runtime_dependency "fiddley", ">= 0.0.5"
|
28
28
|
spec.add_runtime_dependency "editorconfig"
|
29
|
+
spec.add_runtime_dependency "warning"
|
29
30
|
|
30
31
|
spec.add_development_dependency "bundler"
|
31
32
|
spec.add_development_dependency "rake", ">= 12.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: textbringer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: warning
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: bundler
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|