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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b83487edc5f542afe9444b4393375aedd1ea82b4893997b17c6c4a33a3a4d76
4
- data.tar.gz: 60b6f47109aad0c55ed9832b97a8a54a65ad7cf7cac95341a20b2f01ba23234d
3
+ metadata.gz: 9641c360dd5bb038429536d85e666ff3518e37413eeece13898fa1a730665193
4
+ data.tar.gz: e2e9f71f90e060e30aac0bfa273fe65349eacc633f83c7c6dda034aa160436c6
5
5
  SHA512:
6
- metadata.gz: 17399f8a6297f0b77cd03cdac6c24c64b6e6da82dc596b6e5bdfa7ba807cdcb8c9e32d12e376b219941ee14a2ef4a60e63bab9e2a07723a107b5e01b259eb034
7
- data.tar.gz: 27b5e0e6011257b5beafc563b439944a72c7018cd058060bde55618369a55ec2c6596840f0de661a075f361485f5f27e76d908c6b04360f1342986a48b78797d
6
+ metadata.gz: 285df14ab50ac3b27e5c61a3c24503c7ce724b84a918072ada9e920c323f94c46564b329a3217950bddeee5e1c4b5e83f426ad577bb8cb6596004c2b374fd12d
7
+ data.tar.gz: 6ed66854359cdd89310f77cb79c2b14cdafe4b5c7636aee662c7d1a4103563388e183bf11b5b7aab45fd691b70fa16c5d33f66231f109c6a733d05c98f1087e2
@@ -5,6 +5,7 @@ on: [push]
5
5
  jobs:
6
6
  build:
7
7
  runs-on: macos-latest
8
+ timeout-minutes: 10
8
9
  steps:
9
10
  - uses: actions/checkout@master
10
11
  - name: Install dependencies
@@ -8,6 +8,7 @@ jobs:
8
8
  matrix:
9
9
  ruby: [ head, 3.1, 3.0, 2.7, 2.6 ]
10
10
  runs-on: ubuntu-latest
11
+ timeout-minutes: 10
11
12
  steps:
12
13
  - uses: actions/checkout@v2
13
14
  - uses: ruby/setup-ruby@v1
@@ -8,6 +8,7 @@ jobs:
8
8
  strategy:
9
9
  matrix:
10
10
  ruby: [ 'mingw', 'mswin', '3.0', '2.7', '2.6' ]
11
+ timeout-minutes: 10
11
12
  steps:
12
13
  - uses: actions/checkout@v2
13
14
  - name: Set up Ruby
data/CHANGES.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1.2
2
+
3
+ * Buf fixes.
4
+
1
5
  ## 1.1.1
2
6
 
3
7
  * Bug fixes.
data/exe/textbringer CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $VERBOSE = nil
3
+ require "warning"
4
+
5
+ Warning.ignore(/already initialized constant /)
6
+ Warning.ignore(/previous definition of /)
4
7
 
5
8
  require "textbringer"
6
9
 
@@ -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 = enc == Encoding::ASCII_8BIT
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 = (@contents[0...@gap_start] + @contents[@gap_end..-1])
441
- result.force_encoding(Encoding::UTF_8) unless @binary
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[user_to_gap(s)...user_to_gap(e)]
460
+ @contents.byteslice(user_to_gap(s)...user_to_gap(e))
449
461
  else
450
462
  len = @gap_start - s
451
- @contents[user_to_gap(s), len] + @contents[@gap_end, e - s - len]
463
+ @contents.byteslice(user_to_gap(s), len) +
464
+ @contents.byteslice(@gap_end, e - s - len)
452
465
  end
453
- result.force_encoding(Encoding::UTF_8) unless @binary
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[0...user_to_gap(pos)].count("\n")
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
- i = @contents.rindex("\n", user_to_gap(pos - 1))
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
- pos = @contents.index("\n", pos)
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
- @contents[@point, size] = s.b
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
- @contents[@gap_end...user_to_gap(pos)] = "\0" * (pos - @point)
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
- @contents[user_to_gap(pos)...@gap_start] = "\0" * (@point - pos)
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
- @contents[@gap_end, len] = "\0" * len
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
- def byteindex(forward, re, pos)
1129
- @match_offsets = []
1130
- method = forward ? :index : :rindex
1131
- adjust_gap(0, point_max)
1132
- s = @contents[0...@gap_start]
1133
- if @binary
1134
- offset = pos
1135
- else
1136
- offset = s.byteslice(0, pos).force_encoding(Encoding::UTF_8).size
1137
- s.force_encoding(Encoding::UTF_8)
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
- if m.nil?
1144
- # A bug of rindex
1145
- @match_offsets.push([pos, pos])
1146
- pos
1147
- else
1148
- b = m.pre_match.bytesize
1149
- e = b + m.to_s.bytesize
1150
- if e <= bytesize
1151
- @match_offsets.push([b, e])
1152
- match_beg = m.begin(0)
1153
- match_str = m.to_s
1154
- (1 .. m.size - 1).each do |j|
1155
- cb, ce = m.offset(j)
1156
- if cb.nil?
1157
- @match_offsets.push([nil, nil])
1158
- else
1159
- bb = b + match_str[0, cb - match_beg].bytesize
1160
- be = b + match_str[0, ce - match_beg].bytesize
1161
- @match_offsets.push([bb, be])
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[@gap_start...@gap_end]&.match?(/\A\0*\z/)
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
- @contents.force_encoding(Encoding::ASCII_8BIT)
1483
+ if !STRING_HAS_BYTE_BASED_METHODS
1484
+ @contents.force_encoding(Encoding::ASCII_8BIT)
1485
+ end
1429
1486
  self.file_encoding = enc
1430
- case @contents
1431
- when /(?<!\r)\n/
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
- when /\r(?!\n)/
1434
- @file_format = :mac
1435
- @contents.gsub!(/\r/, "\n")
1436
- when /\r\n/
1437
- @file_format = :dos
1438
- @contents.gsub!(/\r/, "")
1439
- else
1440
- @file_format = CONFIG[:default_file_format]
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
- @contents[@gap_start, len] = @contents[@gap_end, len]
1448
- @gap_start += len
1449
- @gap_end += len
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
- @contents[@gap_end - len, len] = @contents[pos, len]
1453
- @gap_start -= len
1454
- @gap_end -= len
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
- @contents[@gap_end, 0] = "\0" * extended_size
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[user_to_gap(pos)...user_to_gap(new_pos)].count("\n")
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
- i = @contents.rindex("\n", user_to_gap(new_pos - 1))
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[user_to_gap(new_pos)...user_to_gap(pos)].count("\n")
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
- i = @contents.rindex("\n", user_to_gap(new_pos - 1))
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
- [@contents[0...@gap_start], @contents[@gap_end..-1]].each do |s|
1577
- s.force_encoding(Encoding::UTF_8) unless @binary
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
- Buffer.current.file_name = read_file_name("File to save in: ")
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
- offset = forward ? last_pos : last_pos - ISEARCH_STATUS[:string].bytesize
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
- ys.all? { |j| j.start_with?(i) }
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)
@@ -16,6 +16,7 @@ module Textbringer
16
16
  shell_command_switch: "-c",
17
17
  grep_command: "grep -nH -e",
18
18
  fill_column: 70,
19
+ read_file_name_completion_ignore_case: RUBY_PLATFORM.match?(/darwin/),
19
20
  default_input_method: "t_code"
20
21
  }
21
22
  end
@@ -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.is_a?(Symbol) || cmd.respond_to?(:call)
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
@@ -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.upcase, Encoding.list.map(&:name))
234
+ complete_for_minibuffer(s.downcase, encoding_names)
228
235
  }
229
236
  read_from_minibuffer(prompt, completion_proc: f, **opts)
230
237
  end
@@ -1,3 +1,3 @@
1
1
  module Textbringer
2
- VERSION = "1.1.1"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -687,6 +687,8 @@ module Textbringer
687
687
  else
688
688
  "U+%04X" % c.ord
689
689
  end
690
+ rescue ArgumentError
691
+ "0x" + c.unpack("H*")[0]
690
692
  end
691
693
 
692
694
  def escape(s)
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.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-01-06 00:00:00.000000000 Z
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