textbringer 1.4.1 → 3
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/push_gem.yml +4 -4
- data/lib/textbringer/buffer.rb +43 -5
- data/lib/textbringer/commands/buffers.rb +33 -0
- data/lib/textbringer/commands/files.rb +1 -1
- data/lib/textbringer/commands/help.rb +44 -2
- data/lib/textbringer/commands/misc.rb +25 -0
- data/lib/textbringer/commands/register.rb +4 -1
- data/lib/textbringer/commands/ucs_normalize.rb +39 -0
- data/lib/textbringer/default_output.rb +12 -4
- data/lib/textbringer/input_method.rb +22 -0
- data/lib/textbringer/input_methods/hangul_input_method.rb +73 -0
- data/lib/textbringer/input_methods/hiragana_input_method.rb +0 -2
- data/lib/textbringer/input_methods/t_code_input_method.rb +0 -19
- data/lib/textbringer/keymap.rb +5 -0
- data/lib/textbringer/mode.rb +1 -1
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window/fallback_characters.rb +118 -0
- data/lib/textbringer/window.rb +133 -47
- data/lib/textbringer.rb +2 -0
- data/textbringer.gemspec +9 -0
- metadata +132 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66be90097685aaa387bc495b1ec0480eeaa4f7015480c5358fd07268d3e14fdb
|
4
|
+
data.tar.gz: f848eefb51793d46065411ef40b5c8c96f04ebb490a1919c3497e44ed7f0c574
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33afdb5cdc3c255a5910e0757393a650dce8ab09b705a58725f391a70e8c46bf7a1b1c31959bf4ed0e96b435c0ba745d3f13c353f5c869f64afa764b23551f9a
|
7
|
+
data.tar.gz: 9b9cc0408ab6d79038d080ebfce6fe3c6c11fe600b88a267c0d2b75c35d12eec02e9a8d95aa82169919fdb49da13c973274b7a9a05edba1a570641167e09c094
|
@@ -24,21 +24,21 @@ jobs:
|
|
24
24
|
steps:
|
25
25
|
# Set up
|
26
26
|
- name: Harden Runner
|
27
|
-
uses: step-security/harden-runner@
|
27
|
+
uses: step-security/harden-runner@v2
|
28
28
|
with:
|
29
29
|
egress-policy: audit
|
30
30
|
|
31
|
-
- uses: actions/checkout@
|
31
|
+
- uses: actions/checkout@v4
|
32
32
|
|
33
33
|
- name: Set up Ruby
|
34
|
-
uses: ruby/setup-ruby@
|
34
|
+
uses: ruby/setup-ruby@v1
|
35
35
|
with:
|
36
36
|
bundler-cache: true
|
37
37
|
ruby-version: ruby
|
38
38
|
|
39
39
|
# Release
|
40
40
|
- name: Publish to RubyGems
|
41
|
-
uses: rubygems/release-gem@
|
41
|
+
uses: rubygems/release-gem@v1
|
42
42
|
|
43
43
|
- name: Create GitHub release
|
44
44
|
run: |
|
data/lib/textbringer/buffer.rb
CHANGED
@@ -71,6 +71,8 @@ module Textbringer
|
|
71
71
|
false
|
72
72
|
end
|
73
73
|
|
74
|
+
WORD_COMPONENT_REGEXP = /\p{Letter}|\p{Number}|\p{M}/
|
75
|
+
|
74
76
|
if !defined?(@@detect_encoding_proc)
|
75
77
|
@@detect_encoding_proc = DEFAULT_DETECT_ENCODING
|
76
78
|
|
@@ -683,7 +685,8 @@ module Textbringer
|
|
683
685
|
forward_char(-n)
|
684
686
|
end
|
685
687
|
|
686
|
-
def forward_word(n = 1, regexp:
|
688
|
+
def forward_word(n = 1, regexp: WORD_COMPONENT_REGEXP)
|
689
|
+
return backward_word(-n) if n < 0
|
687
690
|
n.times do
|
688
691
|
while !end_of_buffer? && regexp !~ char_after
|
689
692
|
forward_char
|
@@ -694,7 +697,8 @@ module Textbringer
|
|
694
697
|
end
|
695
698
|
end
|
696
699
|
|
697
|
-
def backward_word(n = 1, regexp:
|
700
|
+
def backward_word(n = 1, regexp: WORD_COMPONENT_REGEXP)
|
701
|
+
return forward_word(-n) if n < 0
|
698
702
|
n.times do
|
699
703
|
break if beginning_of_buffer?
|
700
704
|
backward_char
|
@@ -820,6 +824,10 @@ module Textbringer
|
|
820
824
|
@point > mark.location
|
821
825
|
end
|
822
826
|
|
827
|
+
def point_compare_mark(mark)
|
828
|
+
@point - mark.location
|
829
|
+
end
|
830
|
+
|
823
831
|
def exchange_point_and_mark(mark = @mark)
|
824
832
|
if mark.nil?
|
825
833
|
raise EditorError, "The mark is not set"
|
@@ -989,14 +997,23 @@ module Textbringer
|
|
989
997
|
end
|
990
998
|
end
|
991
999
|
|
992
|
-
def replace(str, start: point_min, end: point_max)
|
1000
|
+
def replace(str = nil, start: point_min, end: point_max, &block)
|
1001
|
+
end_pos = binding.local_variable_get(:end)
|
1002
|
+
if str.nil?
|
1003
|
+
str = block.call(substring(start, end_pos))
|
1004
|
+
end
|
993
1005
|
composite_edit do
|
994
|
-
delete_region(start,
|
1006
|
+
delete_region(start, end_pos)
|
995
1007
|
goto_char(start)
|
996
1008
|
insert(str)
|
997
1009
|
end
|
998
1010
|
end
|
999
1011
|
|
1012
|
+
def replace_region(str = nil, &block)
|
1013
|
+
s, e = Buffer.region_boundaries(@point, mark)
|
1014
|
+
replace(str, start: s, end: e, &block)
|
1015
|
+
end
|
1016
|
+
|
1000
1017
|
def clear
|
1001
1018
|
check_read_only_flag
|
1002
1019
|
@contents = String.new
|
@@ -1040,6 +1057,27 @@ module Textbringer
|
|
1040
1057
|
end
|
1041
1058
|
end
|
1042
1059
|
|
1060
|
+
def convert_word(n = 1, &block)
|
1061
|
+
s = point
|
1062
|
+
forward_word(n)
|
1063
|
+
e = point
|
1064
|
+
s, e = Buffer.region_boundaries(s, e)
|
1065
|
+
str = substring(s, e).gsub(/[\p{Letter}\p{Number}]+/, &block)
|
1066
|
+
replace(str, start: s, end: e)
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
def downcase_word(n = 1)
|
1070
|
+
convert_word(n, &:downcase)
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def upcase_word(n = 1)
|
1074
|
+
convert_word(n, &:upcase)
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
def capitalize_word(n = 1)
|
1078
|
+
convert_word(n, &:capitalize)
|
1079
|
+
end
|
1080
|
+
|
1043
1081
|
def insert_for_yank(s)
|
1044
1082
|
if @mark.nil? || !point_at_mark?(@mark)
|
1045
1083
|
push_mark
|
@@ -1441,7 +1479,7 @@ module Textbringer
|
|
1441
1479
|
def set_contents(s, enc)
|
1442
1480
|
case s.encoding
|
1443
1481
|
when Encoding::UTF_8, Encoding::ASCII_8BIT
|
1444
|
-
@contents = s
|
1482
|
+
@contents = +s
|
1445
1483
|
else
|
1446
1484
|
@contents = s.encode(Encoding::UTF_8)
|
1447
1485
|
end
|
@@ -264,5 +264,38 @@ module Textbringer
|
|
264
264
|
e = buffer.re_search_forward(Regexp.quote(char), count: count)
|
265
265
|
buffer.kill_region(s, e)
|
266
266
|
end
|
267
|
+
|
268
|
+
define_command(:downcase_word,
|
269
|
+
doc: <<~EOD) do
|
270
|
+
Convert to lower case from point to end of word, moving over.
|
271
|
+
EOD
|
272
|
+
|n = number_prefix_arg|
|
273
|
+
Buffer.current.downcase_word(n)
|
274
|
+
end
|
275
|
+
|
276
|
+
define_command(:upcase_word,
|
277
|
+
doc: <<~EOD) do
|
278
|
+
Convert to upper case from point to end of word, moving over.
|
279
|
+
EOD
|
280
|
+
|n = number_prefix_arg|
|
281
|
+
Buffer.current.upcase_word(n)
|
282
|
+
end
|
283
|
+
|
284
|
+
define_command(:capitalize_word,
|
285
|
+
doc: <<~EOD) do
|
286
|
+
Capitalize from point to the end of word, moving over.
|
287
|
+
EOD
|
288
|
+
|n = number_prefix_arg|
|
289
|
+
Buffer.current.capitalize_word(n)
|
290
|
+
end
|
291
|
+
|
292
|
+
define_command(:insert_char,
|
293
|
+
doc: <<~EOD) do
|
294
|
+
Insert character.
|
295
|
+
EOD
|
296
|
+
|c = read_from_minibuffer("Insert character (hex): "),
|
297
|
+
n = number_prefix_arg|
|
298
|
+
Buffer.current.insert(c.hex.chr(Encoding::UTF_8) * n)
|
299
|
+
end
|
267
300
|
end
|
268
301
|
end
|
@@ -128,7 +128,7 @@ module Textbringer
|
|
128
128
|
|dir_name = read_file_name("Change directory: ",
|
129
129
|
default: Buffer.current.file_name &&
|
130
130
|
File.dirname(Buffer.current.file_name))|
|
131
|
-
Dir.chdir(dir_name)
|
131
|
+
Dir.chdir(File.expand_path(dir_name))
|
132
132
|
end
|
133
133
|
|
134
134
|
define_command(:find_alternate_file, doc: "Find an alternate file.") do
|
@@ -18,9 +18,14 @@ module Textbringer
|
|
18
18
|
help.clear
|
19
19
|
yield(help)
|
20
20
|
help.beginning_of_buffer
|
21
|
-
|
22
|
-
help_mode
|
21
|
+
help.apply_mode(HelpMode)
|
23
22
|
end
|
23
|
+
if Window.list.size == 1
|
24
|
+
split_window
|
25
|
+
end
|
26
|
+
windows = Window.list
|
27
|
+
i = (windows.index(Window.current) + 1) % windows.size
|
28
|
+
windows[i].buffer = help
|
24
29
|
end
|
25
30
|
private :show_help
|
26
31
|
|
@@ -143,6 +148,43 @@ module Textbringer
|
|
143
148
|
push_help_command([:describe_method, name])
|
144
149
|
end
|
145
150
|
|
151
|
+
define_command(:describe_char,
|
152
|
+
doc: "Describe the char after point") do
|
153
|
+
require "unicode/name"
|
154
|
+
require "unicode/blocks"
|
155
|
+
require "unicode/scripts"
|
156
|
+
require "unicode/categories"
|
157
|
+
require "unicode/types"
|
158
|
+
|
159
|
+
show_help do |help|
|
160
|
+
buffer = Buffer.current
|
161
|
+
c = buffer.char_after
|
162
|
+
if c.nil?
|
163
|
+
raise "No character follows specified position"
|
164
|
+
end
|
165
|
+
percent = (100.0 * buffer.point / buffer.bytesize).to_i
|
166
|
+
char = /[\0-\x20\x7f]/.match?(c) ? Keymap.key_name(c) : c
|
167
|
+
codepoint = "U+%04X" % c.ord
|
168
|
+
name = Unicode::Name.readable(c)
|
169
|
+
script = Unicode::Scripts.script(c)
|
170
|
+
category = Unicode::Categories.category(c)
|
171
|
+
category_long = Unicode::Categories.category(c, format: :long)
|
172
|
+
block = Unicode::Blocks.block(c)
|
173
|
+
type = Unicode::Types.type(c)
|
174
|
+
help.insert(<<EOF)
|
175
|
+
position: #{buffer.point} of #{buffer.bytesize} (#{percent}%), column: #{buffer.current_column}
|
176
|
+
character: #{char}
|
177
|
+
codepoint: #{codepoint}
|
178
|
+
name: #{name}
|
179
|
+
block: #{block}
|
180
|
+
script: #{script}
|
181
|
+
category: #{category} (#{category_long})
|
182
|
+
type: #{type}
|
183
|
+
EOF
|
184
|
+
end
|
185
|
+
push_help_command([:describe_char])
|
186
|
+
end
|
187
|
+
|
146
188
|
define_command(:help_go_back, doc: "Go back to the previous help.") do
|
147
189
|
if !HELP_RING.empty?
|
148
190
|
HELP_RING.rotate(1)
|
@@ -353,5 +353,30 @@ module Textbringer
|
|
353
353
|
define_command(:jit_resume) do
|
354
354
|
RubyVM::MJIT.resume
|
355
355
|
end
|
356
|
+
|
357
|
+
define_command(:what_cursor_position,
|
358
|
+
doc: "Print info on cursor position.") do
|
359
|
+
|arg = current_prefix_arg|
|
360
|
+
|
361
|
+
buffer = Buffer.current
|
362
|
+
c = buffer.char_after
|
363
|
+
if c
|
364
|
+
char = format("Char: %s (U+%04X) ",
|
365
|
+
/[\0-\x20\x7f]/.match?(c) ? Keymap.key_name(c) : c,
|
366
|
+
c.ord)
|
367
|
+
else
|
368
|
+
char = ""
|
369
|
+
end
|
370
|
+
if buffer.bytesize == 0
|
371
|
+
percent = "EOB"
|
372
|
+
else
|
373
|
+
percent = (100.0 * buffer.point / buffer.bytesize).to_i
|
374
|
+
end
|
375
|
+
column = buffer.current_column
|
376
|
+
message("#{char}point=#{buffer.point} of #{buffer.bytesize} (#{percent}%) column=#{column}")
|
377
|
+
if arg && c
|
378
|
+
describe_char
|
379
|
+
end
|
380
|
+
end
|
356
381
|
end
|
357
382
|
end
|
@@ -88,7 +88,10 @@ module Textbringer
|
|
88
88
|
|
89
89
|
define_command(:insert_register) do
|
90
90
|
|register = read_register("Insert register:"),
|
91
|
-
arg =
|
91
|
+
arg = nil|
|
92
|
+
if arg.nil? && Controller.current.this_command == :insert_register
|
93
|
+
arg = !current_prefix_arg
|
94
|
+
end
|
92
95
|
buffer = Buffer.current
|
93
96
|
str = REGISTERS[register]
|
94
97
|
if arg
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Textbringer
|
2
|
+
module Commands
|
3
|
+
define_command(:ucs_normalize_nfc_region,
|
4
|
+
doc: <<~EOD) do
|
5
|
+
Compose the region according to the Unicode NFC.
|
6
|
+
EOD
|
7
|
+
Buffer.current.replace_region do |s|
|
8
|
+
s.unicode_normalize(:nfc)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
define_command(:ucs_normalize_nfd_region,
|
13
|
+
doc: <<~EOD) do
|
14
|
+
Decompose the region according to the Unicode NFD.
|
15
|
+
EOD
|
16
|
+
Buffer.current.replace_region do |s|
|
17
|
+
s.unicode_normalize(:nfd)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
define_command(:ucs_normalize_nfkc_region,
|
22
|
+
doc: <<~EOD) do
|
23
|
+
Compose the region according to the Unicode NFKC.
|
24
|
+
EOD
|
25
|
+
Buffer.current.replace_region do |s|
|
26
|
+
s.unicode_normalize(:nfkc)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
define_command(:ucs_normalize_nfkd_region,
|
31
|
+
doc: <<~EOD) do
|
32
|
+
Decompose the region according to the Unicode NFKD.
|
33
|
+
EOD
|
34
|
+
Buffer.current.replace_region do |s|
|
35
|
+
s.unicode_normalize(:nfkd)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -9,10 +9,18 @@ module Textbringer
|
|
9
9
|
def flush
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
[
|
13
|
+
:print,
|
14
|
+
:printf,
|
15
|
+
:putc,
|
16
|
+
:puts,
|
17
|
+
:"<<"
|
18
|
+
].each do |mid|
|
19
|
+
define_method(mid) do |*args|
|
20
|
+
buffer = StringIO.new
|
21
|
+
buffer.send(mid, *args)
|
22
|
+
write(buffer.string)
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|
@@ -59,5 +59,27 @@ module Textbringer
|
|
59
59
|
def handle_event(event)
|
60
60
|
raise EditorError, "subclass must override InputMethod#handle_event"
|
61
61
|
end
|
62
|
+
|
63
|
+
def with_target_buffer(&block)
|
64
|
+
if isearch_mode?
|
65
|
+
@isearch_buffer ||= Buffer.new
|
66
|
+
if @isearch_buffer.to_s != ISEARCH_STATUS[:string]
|
67
|
+
@isearch_buffer.replace(ISEARCH_STATUS[:string])
|
68
|
+
end
|
69
|
+
@isearch_buffer.modified = false
|
70
|
+
begin
|
71
|
+
block.call(@isearch_buffer)
|
72
|
+
ensure
|
73
|
+
ISEARCH_STATUS[:string] = @isearch_buffer.to_s
|
74
|
+
isearch_search if @isearch_buffer.modified?
|
75
|
+
if Buffer.current != Buffer.minibuffer
|
76
|
+
message(isearch_prompt + ISEARCH_STATUS[:string], log: false)
|
77
|
+
end
|
78
|
+
Window.redisplay
|
79
|
+
end
|
80
|
+
else
|
81
|
+
block.call(Buffer.current)
|
82
|
+
end
|
83
|
+
end
|
62
84
|
end
|
63
85
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Textbringer
|
2
|
+
class HangulInputMethod < InputMethod
|
3
|
+
KEY_TO_COMPATIBILITY_JAMO = {
|
4
|
+
"q" => "ㅂ", "w" => "ㅈ", "e" => "ㄷ", "r" => "ㄱ", "t" => "ㅅ",
|
5
|
+
"y" => "ㅛ", "u" => "ㅕ", "i" => "ㅑ", "o" => "ㅐ", "p" => "ㅔ",
|
6
|
+
"a" => "ㅁ", "s" => "ㄴ", "d" => "ㅇ", "f" => "ㄹ", "g" => "ㅎ",
|
7
|
+
"h" => "ㅗ", "j" => "ㅓ", "k" => "ㅏ", "l" => "ㅣ",
|
8
|
+
"z" => "ㅋ", "x" => "ㅌ", "c" => "ㅊ", "v" => "ㅍ", "b" => "ㅠ",
|
9
|
+
"n" => "ㅜ", "m" => "ㅡ",
|
10
|
+
"Q" => "ㅃ", "W" => "ㅉ", "E" => "ㄸ", "R" => "ㄲ", "T" => "ㅆ",
|
11
|
+
"O" => "ㅒ", "P" => "ㅖ"
|
12
|
+
}
|
13
|
+
|
14
|
+
COMPATIBILITY_JAMO_TO_FINAL = {
|
15
|
+
"ㄱ" => "ᆨ", "ㄲ" => "ᆩ", "ㄳ" => "ᆪ", "ㄴ" => "ᆫ",
|
16
|
+
"ㄵ" => "ᆬ", "ㄶ" => "ᆭ", "ㄷ" => "ᆮ", "ㄹ" => "ᆯ",
|
17
|
+
"ㄺ" => "ᆰ", "ㄻ" => "ᆱ", "ㄼ" => "ᆲ", "ㄽ" => "ᆳ",
|
18
|
+
"ㄾ" => "ᆴ", "ㄿ" => "ᆵ", "ㅀ" => "ᆶ", "ㅁ" => "ᆷ",
|
19
|
+
"ㅂ" => "ᆸ", "ㅄ" => "ᆹ", "ㅅ" => "ᆺ", "ㅆ" => "ᆻ",
|
20
|
+
"ㅇ" => "ᆼ", "ㅈ" => "ᆽ", "ㅊ" => "ᆾ", "ㅋ" => "ᆿ",
|
21
|
+
"ㅌ" => "ᇀ", "ㅍ" => "ᇁ", "ㅎ" => "ᇂ"
|
22
|
+
}
|
23
|
+
|
24
|
+
FINAL_TO_INITIAL = {
|
25
|
+
"ᆨ" => "ᄀ", "ᆩ" => "ᄁ", "ᆫ" => "ᄂ", "ᆮ" => "ᄃ",
|
26
|
+
"ᆯ" => "ᄅ", "ᆷ" => "ᄆ", "ᆸ" => "ᄇ", "ᆺ" => "ᄉ",
|
27
|
+
"ᆻ" => "ᄊ", "ᆼ" => "ᄋ", "ᆽ" => "ᄌ", "ᆾ" => "ᄎ",
|
28
|
+
"ᆿ" => "ᄏ", "ᇀ" => "ᄐ", "ᇁ" => "ᄑ", "ᇂ" => "ᄒ"
|
29
|
+
}
|
30
|
+
|
31
|
+
def status
|
32
|
+
"한"
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_event(event)
|
36
|
+
return event if !event.is_a?(String)
|
37
|
+
jamo = KEY_TO_COMPATIBILITY_JAMO[event]
|
38
|
+
return event if jamo.nil?
|
39
|
+
with_target_buffer do |buffer|
|
40
|
+
prev = buffer.char_before
|
41
|
+
if /[\u{3131}-\u{3183}\u{ac00}-\u{d7a3}]/.match?(prev) # jamo or syllables
|
42
|
+
decomposed_prev, prev = decompose_prev(prev, jamo)
|
43
|
+
if c = compose_hangul(prev, jamo)
|
44
|
+
buffer.backward_delete_char
|
45
|
+
c = decomposed_prev + c if decomposed_prev
|
46
|
+
buffer.insert(c)
|
47
|
+
Window.redisplay
|
48
|
+
return nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
jamo
|
53
|
+
end
|
54
|
+
|
55
|
+
def decompose_prev(prev, jamo)
|
56
|
+
if /[\u{ac00}-\u{d7a3}]/.match?(prev) && # syllables
|
57
|
+
/[\u{314f}-\u{3163}]/.match?(jamo) # vowels
|
58
|
+
s = prev.unicode_normalize(:nfd)
|
59
|
+
if s.size == 3 && (initial = FINAL_TO_INITIAL[s[2]])
|
60
|
+
return s[0, 2].unicode_normalize(:nfc), initial
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return nil, prev
|
64
|
+
end
|
65
|
+
|
66
|
+
def compose_hangul(prev, jamo)
|
67
|
+
# Use NFKC for compatibility jamo
|
68
|
+
c = (prev + (COMPATIBILITY_JAMO_TO_FINAL[jamo] || jamo)).
|
69
|
+
unicode_normalize(:nfkc)
|
70
|
+
c.size == 1 ? c : nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -86,23 +86,6 @@ module Textbringer
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
def with_target_buffer(&block)
|
90
|
-
if isearch_mode?
|
91
|
-
@isearch_buffer ||= Buffer.new
|
92
|
-
if @isearch_buffer.to_s != ISEARCH_STATUS[:string]
|
93
|
-
@isearch_buffer.replace(ISEARCH_STATUS[:string])
|
94
|
-
end
|
95
|
-
block.call(@isearch_buffer)
|
96
|
-
ISEARCH_STATUS[:string] = @isearch_buffer.to_s
|
97
|
-
if Buffer.current != Buffer.minibuffer
|
98
|
-
message(isearch_prompt + ISEARCH_STATUS[:string], log: false)
|
99
|
-
Window.redisplay
|
100
|
-
end
|
101
|
-
else
|
102
|
-
block.call(Buffer.current)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
89
|
def bushu_compose
|
107
90
|
with_target_buffer do |buffer|
|
108
91
|
pos = buffer.point
|
@@ -117,7 +100,6 @@ module Textbringer
|
|
117
100
|
buffer.goto_char(pos)
|
118
101
|
end
|
119
102
|
end
|
120
|
-
isearch_search if isearch_mode?
|
121
103
|
Window.redisplay
|
122
104
|
nil
|
123
105
|
end
|
@@ -276,7 +258,6 @@ module Textbringer
|
|
276
258
|
buffer.insert(s + @mazegaki_suffix)
|
277
259
|
end
|
278
260
|
end
|
279
|
-
isearch_search if isearch_mode?
|
280
261
|
end
|
281
262
|
|
282
263
|
def hide_help_window
|
data/lib/textbringer/keymap.rb
CHANGED
@@ -215,6 +215,11 @@ module Textbringer
|
|
215
215
|
GLOBAL_MAP.define_key([:f1, "m"], :describe_method)
|
216
216
|
GLOBAL_MAP.define_key("\C-x#", :server_edit_done)
|
217
217
|
GLOBAL_MAP.define_key("\C-\\", :toggle_input_method)
|
218
|
+
GLOBAL_MAP.define_key("\M-l", :downcase_word)
|
219
|
+
GLOBAL_MAP.define_key("\M-u", :upcase_word)
|
220
|
+
GLOBAL_MAP.define_key("\M-c", :capitalize_word)
|
221
|
+
GLOBAL_MAP.define_key("\C-x8\C-m", :insert_char)
|
222
|
+
GLOBAL_MAP.define_key("\C-x=", :what_cursor_position)
|
218
223
|
GLOBAL_MAP.handle_undefined_key do |key|
|
219
224
|
if key.is_a?(String) && /[\0-\x7f]/ !~ key
|
220
225
|
:self_insert
|
data/lib/textbringer/mode.rb
CHANGED
data/lib/textbringer/version.rb
CHANGED
@@ -0,0 +1,118 @@
|
|
1
|
+
module Textbringer
|
2
|
+
class Window
|
3
|
+
FALLBACK_CHARACTERS = {
|
4
|
+
# Diacritical marks
|
5
|
+
## https://www.unicode.org/charts/PDF/U0300.pdf
|
6
|
+
## characters combinable with alphabet:
|
7
|
+
## ("\u{0300}".."\u{036f}").filter { |c|
|
8
|
+
## ("a".."z").any? { |c2|
|
9
|
+
## "#{c2}#{c}".unicode_normalize(:nfc).size == 1
|
10
|
+
## }
|
11
|
+
## }
|
12
|
+
"̀" => "`",
|
13
|
+
"́" => "´",
|
14
|
+
"̂" => "ˆ",
|
15
|
+
"̃" => "˜",
|
16
|
+
"̄" => "¯",
|
17
|
+
"̆" => "˘",
|
18
|
+
"̇" => "˙",
|
19
|
+
"̈" => "¨",
|
20
|
+
"̉" => "ˀ",
|
21
|
+
"̊" => "˚",
|
22
|
+
"̋" => "˝",
|
23
|
+
"̌" => "ˇ",
|
24
|
+
"̏" => '"',
|
25
|
+
"̑" => nil, # combining character only
|
26
|
+
"̛" => nil, # combining character only
|
27
|
+
"̣" => nil, # combining character only
|
28
|
+
"̤" => nil, # combining character only
|
29
|
+
"̥" => "˳",
|
30
|
+
"̦" => ",",
|
31
|
+
"̧" => "¸",
|
32
|
+
"̨" => "˛",
|
33
|
+
"̭" => nil, # combining character only
|
34
|
+
"̮" => nil, # combining character only
|
35
|
+
"̰" => nil, # combining character only
|
36
|
+
"̱" => "ˍ",
|
37
|
+
"̀" => nil, # combining character only
|
38
|
+
"́" => nil, # combining character only
|
39
|
+
"̈́" => nil, # combining character only
|
40
|
+
|
41
|
+
# Hiragana
|
42
|
+
"゙" => "゛",
|
43
|
+
"゚" => "゜",
|
44
|
+
|
45
|
+
# Hangul jamo
|
46
|
+
## initial
|
47
|
+
"ᄀ" => "ㄱ",
|
48
|
+
"ᄁ" => "ㄲ",
|
49
|
+
"ᄂ" => "ㄴ",
|
50
|
+
"ᄃ" => "ㄷ",
|
51
|
+
"ᄄ" => "ㄸ",
|
52
|
+
"ᄅ" => "ㄹ",
|
53
|
+
"ᄆ" => "ㅁ",
|
54
|
+
"ᄇ" => "ㅂ",
|
55
|
+
"ᄈ" => "ㅃ",
|
56
|
+
"ᄉ" => "ㅅ",
|
57
|
+
"ᄊ" => "ㅆ",
|
58
|
+
"ᄋ" => "ㅇ",
|
59
|
+
"ᄌ" => "ㅈ",
|
60
|
+
"ᄍ" => "ㅉ",
|
61
|
+
"ᄎ" => "ㅊ",
|
62
|
+
"ᄏ" => "ㅋ",
|
63
|
+
"ᄐ" => "ㅌ",
|
64
|
+
"ᄑ" => "ㅍ",
|
65
|
+
"ᄒ" => "ㅎ",
|
66
|
+
## medial
|
67
|
+
"ᅡ" => "ㅏ",
|
68
|
+
"ᅢ" => "ㅐ",
|
69
|
+
"ᅣ" => "ㅑ",
|
70
|
+
"ᅤ" => "ㅒ",
|
71
|
+
"ᅥ" => "ㅓ",
|
72
|
+
"ᅦ" => "ㅔ",
|
73
|
+
"ᅧ" => "ㅕ",
|
74
|
+
"ᅨ" => "ㅖ",
|
75
|
+
"ᅩ" => "ㅗ",
|
76
|
+
"ᅪ" => "ㅘ",
|
77
|
+
"ᅫ" => "ㅙ",
|
78
|
+
"ᅬ" => "ㅚ",
|
79
|
+
"ᅭ" => "ㅛ",
|
80
|
+
"ᅮ" => "ㅜ",
|
81
|
+
"ᅯ" => "ㅝ",
|
82
|
+
"ᅰ" => "ㅞ",
|
83
|
+
"ᅱ" => "ㅟ",
|
84
|
+
"ᅲ" => "ㅠ",
|
85
|
+
"ᅳ" => "ㅡ",
|
86
|
+
"ᅴ" => "ㅢ",
|
87
|
+
"ᅵ" => "ㅣ",
|
88
|
+
## final
|
89
|
+
"ᆨ" => "ㄱ",
|
90
|
+
"ᆩ" => "ㄲ",
|
91
|
+
"ᆪ" => "ㄳ",
|
92
|
+
"ᆫ" => "ㄴ",
|
93
|
+
"ᆬ" => "ㄵ",
|
94
|
+
"ᆭ" => "ㄶ",
|
95
|
+
"ᆮ" => "ㄷ",
|
96
|
+
"ᆯ" => "ㄹ",
|
97
|
+
"ᆰ" => "ㄺ",
|
98
|
+
"ᆱ" => "ㄻ",
|
99
|
+
"ᆲ" => "ㄼ",
|
100
|
+
"ᆳ" => "ㄽ",
|
101
|
+
"ᆴ" => "ㄾ",
|
102
|
+
"ᆵ" => "ㄿ",
|
103
|
+
"ᆶ" => "ㅀ",
|
104
|
+
"ᆷ" => "ㅁ",
|
105
|
+
"ᆸ" => "ㅂ",
|
106
|
+
"ᆹ" => "ㅄ",
|
107
|
+
"ᆺ" => "ㅅ",
|
108
|
+
"ᆻ" => "ㅆ",
|
109
|
+
"ᆼ" => "ㅇ",
|
110
|
+
"ᆽ" => "ㅈ",
|
111
|
+
"ᆾ" => "ㅊ",
|
112
|
+
"ᆿ" => "ㅋ",
|
113
|
+
"ᇀ" => "ㅌ",
|
114
|
+
"ᇁ" => "ㅍ",
|
115
|
+
"ᇂ" => "ㅎ"
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
data/lib/textbringer/window.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require "curses"
|
2
|
+
require_relative "window/fallback_characters"
|
2
3
|
|
3
4
|
module Textbringer
|
4
5
|
class Window
|
6
|
+
Cursor = Struct.new(:y, :x)
|
7
|
+
|
5
8
|
KEY_NAMES = {}
|
6
9
|
Curses.constants.grep(/\AKEY_/).each do |name|
|
7
10
|
KEY_NAMES[Curses.const_get(name)] =
|
@@ -232,6 +235,7 @@ module Textbringer
|
|
232
235
|
@deleted = false
|
233
236
|
@raw_key_buffer = []
|
234
237
|
@key_buffer = []
|
238
|
+
@cursor = Cursor.new(0, 0)
|
235
239
|
end
|
236
240
|
|
237
241
|
def echo_area?
|
@@ -395,7 +399,7 @@ module Textbringer
|
|
395
399
|
@buffer.point_to_mark(@point_mark)
|
396
400
|
end
|
397
401
|
framer
|
398
|
-
y = x = 0
|
402
|
+
@cursor.y = @cursor.x = 0
|
399
403
|
@buffer.point_to_mark(@top_of_window)
|
400
404
|
highlight
|
401
405
|
@window.erase
|
@@ -406,25 +410,9 @@ module Textbringer
|
|
406
410
|
@window.attron(Curses::A_REVERSE)
|
407
411
|
end
|
408
412
|
while !@buffer.end_of_buffer?
|
409
|
-
cury
|
410
|
-
|
411
|
-
|
412
|
-
if current? && @buffer.visible_mark
|
413
|
-
if @buffer.point_after_mark?(@buffer.visible_mark)
|
414
|
-
@window.attroff(Curses::A_REVERSE)
|
415
|
-
elsif @buffer.point_before_mark?(@buffer.visible_mark)
|
416
|
-
@window.attron(Curses::A_REVERSE)
|
417
|
-
end
|
418
|
-
end
|
419
|
-
end
|
420
|
-
if current? && @buffer.visible_mark &&
|
421
|
-
@buffer.point_at_mark?(@buffer.visible_mark)
|
422
|
-
if @buffer.point_after_mark?(point)
|
423
|
-
@window.attroff(Curses::A_REVERSE)
|
424
|
-
elsif @buffer.point_before_mark?(point)
|
425
|
-
@window.attron(Curses::A_REVERSE)
|
426
|
-
end
|
427
|
-
end
|
413
|
+
cury = @window.cury
|
414
|
+
curx = @window.curx
|
415
|
+
update_cursor_and_attr(point, cury, curx)
|
428
416
|
if attrs = @highlight_off[@buffer.point]
|
429
417
|
@window.attroff(attrs)
|
430
418
|
end
|
@@ -442,12 +430,13 @@ module Textbringer
|
|
442
430
|
n = calc_tab_width(curx)
|
443
431
|
c = " " * n
|
444
432
|
else
|
445
|
-
c =
|
433
|
+
c = compose_character(point, cury, curx, c)
|
446
434
|
end
|
435
|
+
s = escape(c)
|
447
436
|
if curx < columns - 4
|
448
437
|
newx = nil
|
449
438
|
else
|
450
|
-
newx = curx + Buffer.display_width(
|
439
|
+
newx = curx + Buffer.display_width(s)
|
451
440
|
if newx > columns
|
452
441
|
if cury == lines - 2
|
453
442
|
break
|
@@ -457,12 +446,7 @@ module Textbringer
|
|
457
446
|
end
|
458
447
|
end
|
459
448
|
end
|
460
|
-
|
461
|
-
# ncurses on macOS prints U+FEFF, U+FE0F etc. as space,
|
462
|
-
# so ignore it
|
463
|
-
else
|
464
|
-
@window.addstr(c)
|
465
|
-
end
|
449
|
+
@window.addstr(s)
|
466
450
|
break if newx == columns && cury == lines - 2
|
467
451
|
@buffer.forward_char
|
468
452
|
end
|
@@ -471,16 +455,17 @@ module Textbringer
|
|
471
455
|
end
|
472
456
|
@buffer.mark_to_point(@bottom_of_window)
|
473
457
|
if @buffer.point_at_mark?(point)
|
474
|
-
y
|
458
|
+
@cursor.y = @window.cury
|
459
|
+
@cursor.x = @window.curx
|
475
460
|
end
|
476
|
-
if x == columns - 1
|
461
|
+
if @cursor.x == columns - 1
|
477
462
|
c = @buffer.char_after(point.location)
|
478
463
|
if c && Buffer.display_width(c) > 1
|
479
|
-
y += 1
|
480
|
-
x = 0
|
464
|
+
@cursor.y += 1
|
465
|
+
@cursor.x = 0
|
481
466
|
end
|
482
467
|
end
|
483
|
-
@window.setpos(y, x)
|
468
|
+
@window.setpos(@cursor.y, @cursor.x)
|
484
469
|
@window.noutrefresh
|
485
470
|
end
|
486
471
|
end
|
@@ -690,6 +675,84 @@ module Textbringer
|
|
690
675
|
"0x" + c.unpack("H*")[0]
|
691
676
|
end
|
692
677
|
|
678
|
+
def update_cursor_and_attr(point, cury, curx)
|
679
|
+
if @buffer.point_at_mark?(point)
|
680
|
+
@cursor.y = cury
|
681
|
+
@cursor.x = curx
|
682
|
+
if current? && @buffer.visible_mark
|
683
|
+
if @buffer.point_after_mark?(@buffer.visible_mark)
|
684
|
+
@window.attroff(Curses::A_REVERSE)
|
685
|
+
elsif @buffer.point_before_mark?(@buffer.visible_mark)
|
686
|
+
@window.attron(Curses::A_REVERSE)
|
687
|
+
end
|
688
|
+
end
|
689
|
+
end
|
690
|
+
if current? && @buffer.visible_mark &&
|
691
|
+
@buffer.point_at_mark?(@buffer.visible_mark)
|
692
|
+
if @buffer.point_after_mark?(point)
|
693
|
+
@window.attroff(Curses::A_REVERSE)
|
694
|
+
elsif @buffer.point_before_mark?(point)
|
695
|
+
@window.attron(Curses::A_REVERSE)
|
696
|
+
end
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
def compose_character(point, cury, curx, c)
|
701
|
+
return c if @buffer.binary? || c.nil? || c.match?(/\p{M}/)
|
702
|
+
if c.match?(/[\u{1100}-\u{115f}]/) # hangul initial consonants
|
703
|
+
return compose_hangul_character(point, cury, curx, c)
|
704
|
+
end
|
705
|
+
pos = @buffer.point + c.bytesize
|
706
|
+
while nextc = @buffer.char_after(pos)
|
707
|
+
case nextc
|
708
|
+
when /\p{Variation_Selector}/
|
709
|
+
c += nextc
|
710
|
+
when /[\p{Mn}\p{Me}]/ # nonspacing & enclosing marks
|
711
|
+
# Normalize パ (U+30CF + U+309A) to パ (U+30D1) so that curses can
|
712
|
+
# caluculate display width correctly.
|
713
|
+
newc = (c + nextc).unicode_normalize(:nfc)
|
714
|
+
return c if newc.size != c.size
|
715
|
+
c = newc
|
716
|
+
else
|
717
|
+
return c
|
718
|
+
end
|
719
|
+
@buffer.forward_char
|
720
|
+
update_cursor_and_attr(point, cury, curx)
|
721
|
+
pos += nextc.bytesize
|
722
|
+
end
|
723
|
+
c
|
724
|
+
end
|
725
|
+
|
726
|
+
def compose_hangul_character(point, cury, curx, initial)
|
727
|
+
pos = @buffer.point + initial.bytesize
|
728
|
+
medial = @buffer.char_after(pos)
|
729
|
+
if !medial&.match?(/[\u{1160}-\u{11a7}]/)
|
730
|
+
return initial
|
731
|
+
end
|
732
|
+
final = @buffer.char_after(pos + medial.bytesize)
|
733
|
+
if final&.match?(/[\u{11a8}-\u{11ff}]/)
|
734
|
+
newc = (initial + medial + final).unicode_normalize(:nfc)
|
735
|
+
if newc.size == 1
|
736
|
+
2.times do
|
737
|
+
@buffer.forward_char
|
738
|
+
update_cursor_and_attr(point, cury, curx)
|
739
|
+
end
|
740
|
+
newc
|
741
|
+
else
|
742
|
+
c
|
743
|
+
end
|
744
|
+
else
|
745
|
+
newc = (initial + medial).unicode_normalize(:nfc)
|
746
|
+
if newc.size == 1
|
747
|
+
@buffer.forward_char
|
748
|
+
update_cursor_and_attr(point, cury, curx)
|
749
|
+
newc
|
750
|
+
else
|
751
|
+
c
|
752
|
+
end
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
693
756
|
def escape(s)
|
694
757
|
if !s.valid_encoding?
|
695
758
|
s = s.b
|
@@ -701,8 +764,18 @@ module Textbringer
|
|
701
764
|
"<%02X>" % c.ord
|
702
765
|
}
|
703
766
|
else
|
704
|
-
s.gsub(/
|
705
|
-
|
767
|
+
s.gsub(/
|
768
|
+
(?<ascii_control>[\0-\b\v-\x1f\x7f])
|
769
|
+
| (?<nonascii_control>\p{C})
|
770
|
+
| (?<other_special_char>[\p{M}\p{In_Hangul_Jamo}])
|
771
|
+
/x) { |c|
|
772
|
+
if $~[:ascii_control]
|
773
|
+
"^" + (c.ord ^ 0x40).chr
|
774
|
+
elsif $~[:nonascii_control]
|
775
|
+
"<%04x>" % c.ord
|
776
|
+
elsif $~[:other_special_char]
|
777
|
+
FALLBACK_CHARACTERS[c] || c
|
778
|
+
end
|
706
779
|
}
|
707
780
|
end
|
708
781
|
end
|
@@ -836,8 +909,12 @@ module Textbringer
|
|
836
909
|
|
837
910
|
def redisplay
|
838
911
|
return if @buffer.nil?
|
839
|
-
@buffer.save_point do |
|
912
|
+
@buffer.save_point do |point|
|
840
913
|
@window.erase
|
914
|
+
if @buffer.input_method_status != "--"
|
915
|
+
@window.setpos(@window.cury, editable_columns + 1)
|
916
|
+
@window.addstr(@buffer.input_method_status)
|
917
|
+
end
|
841
918
|
@window.setpos(0, 0)
|
842
919
|
if @message
|
843
920
|
@window.addstr(escape(@message))
|
@@ -846,29 +923,30 @@ module Textbringer
|
|
846
923
|
@window.addstr(prompt)
|
847
924
|
framer
|
848
925
|
@buffer.point_to_mark(@top_of_window)
|
849
|
-
y = x = 0
|
926
|
+
@cursor.y = @cursor.x = 0
|
850
927
|
while !@buffer.end_of_buffer?
|
851
|
-
cury
|
852
|
-
|
853
|
-
|
854
|
-
end
|
928
|
+
cury = @window.cury
|
929
|
+
curx = @window.curx
|
930
|
+
update_cursor_and_attr(point, cury, curx)
|
855
931
|
c = @buffer.char_after
|
856
932
|
if c == "\n"
|
857
933
|
break
|
858
934
|
end
|
935
|
+
c = compose_character(point, cury, curx, c)
|
859
936
|
s = escape(c)
|
860
937
|
newx = curx + Buffer.display_width(s)
|
861
|
-
if newx >
|
938
|
+
if newx > editable_columns
|
862
939
|
break
|
863
940
|
end
|
864
941
|
@window.addstr(s)
|
865
|
-
break if newx >= @columns
|
866
942
|
@buffer.forward_char
|
943
|
+
break if newx >= editable_columns
|
867
944
|
end
|
868
|
-
if @buffer.point_at_mark?(
|
869
|
-
y
|
945
|
+
if @buffer.point_at_mark?(point)
|
946
|
+
@cursor.y = @window.cury
|
947
|
+
@cursor.x = @window.curx
|
870
948
|
end
|
871
|
-
@window.setpos(y, x)
|
949
|
+
@window.setpos(@cursor.y, @cursor.x)
|
872
950
|
end
|
873
951
|
@window.noutrefresh
|
874
952
|
end
|
@@ -890,6 +968,14 @@ module Textbringer
|
|
890
968
|
@window.resize(lines, columns)
|
891
969
|
end
|
892
970
|
|
971
|
+
def editable_columns
|
972
|
+
if @buffer.input_method_status == "--"
|
973
|
+
@columns
|
974
|
+
else
|
975
|
+
@columns - Buffer.display_width(@buffer.input_method_status) - 1
|
976
|
+
end
|
977
|
+
end
|
978
|
+
|
893
979
|
private
|
894
980
|
|
895
981
|
def initialize_window(num_lines, num_columns, y, x)
|
@@ -902,7 +988,7 @@ module Textbringer
|
|
902
988
|
|
903
989
|
def framer
|
904
990
|
@buffer.save_point do |saved|
|
905
|
-
max_width =
|
991
|
+
max_width = editable_columns - @window.curx
|
906
992
|
width = 0
|
907
993
|
loop do
|
908
994
|
c = @buffer.char_after
|
data/lib/textbringer.rb
CHANGED
@@ -23,6 +23,7 @@ require_relative "textbringer/commands/keyboard_macro"
|
|
23
23
|
require_relative "textbringer/commands/fill"
|
24
24
|
require_relative "textbringer/commands/server"
|
25
25
|
require_relative "textbringer/commands/input_method"
|
26
|
+
require_relative "textbringer/commands/ucs_normalize"
|
26
27
|
require_relative "textbringer/commands/help"
|
27
28
|
require_relative "textbringer/mode"
|
28
29
|
require_relative "textbringer/modes/fundamental_mode"
|
@@ -36,6 +37,7 @@ require_relative "textbringer/modes/help_mode"
|
|
36
37
|
require_relative "textbringer/input_method"
|
37
38
|
require_relative "textbringer/input_methods/t_code_input_method"
|
38
39
|
require_relative "textbringer/input_methods/hiragana_input_method"
|
40
|
+
require_relative "textbringer/input_methods/hangul_input_method"
|
39
41
|
require_relative "textbringer/plugin"
|
40
42
|
require_relative "textbringer/controller"
|
41
43
|
require_relative "textbringer/default_output"
|
data/textbringer.gemspec
CHANGED
@@ -21,14 +21,23 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.required_ruby_version = '>= 3.1'
|
23
23
|
|
24
|
+
spec.add_runtime_dependency "rdoc"
|
25
|
+
spec.add_runtime_dependency "ostruct"
|
26
|
+
spec.add_runtime_dependency "irb"
|
24
27
|
spec.add_runtime_dependency "nkf"
|
25
28
|
spec.add_runtime_dependency "drb"
|
26
29
|
spec.add_runtime_dependency "curses", ">= 1.2.7"
|
27
30
|
spec.add_runtime_dependency "unicode-display_width", ">= 1.1"
|
28
31
|
spec.add_runtime_dependency "clipboard", ">= 1.1"
|
32
|
+
spec.add_runtime_dependency "fiddle"
|
29
33
|
spec.add_runtime_dependency "fiddley", ">= 0.0.5"
|
30
34
|
spec.add_runtime_dependency "editorconfig"
|
31
35
|
spec.add_runtime_dependency "warning"
|
36
|
+
spec.add_runtime_dependency "unicode-name"
|
37
|
+
spec.add_runtime_dependency "unicode-categories"
|
38
|
+
spec.add_runtime_dependency "unicode-blocks"
|
39
|
+
spec.add_runtime_dependency "unicode-scripts"
|
40
|
+
spec.add_runtime_dependency "unicode-types"
|
32
41
|
|
33
42
|
spec.add_development_dependency "bundler"
|
34
43
|
spec.add_development_dependency "rake", ">= 12.0"
|
metadata
CHANGED
@@ -1,15 +1,56 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: textbringer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: '3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-04-10 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rdoc
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: ostruct
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: irb
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
13
54
|
- !ruby/object:Gem::Dependency
|
14
55
|
name: nkf
|
15
56
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +121,20 @@ dependencies:
|
|
80
121
|
- - ">="
|
81
122
|
- !ruby/object:Gem::Version
|
82
123
|
version: '1.1'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: fiddle
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
type: :runtime
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
83
138
|
- !ruby/object:Gem::Dependency
|
84
139
|
name: fiddley
|
85
140
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +177,76 @@ dependencies:
|
|
122
177
|
- - ">="
|
123
178
|
- !ruby/object:Gem::Version
|
124
179
|
version: '0'
|
180
|
+
- !ruby/object:Gem::Dependency
|
181
|
+
name: unicode-name
|
182
|
+
requirement: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
type: :runtime
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - ">="
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
- !ruby/object:Gem::Dependency
|
195
|
+
name: unicode-categories
|
196
|
+
requirement: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
type: :runtime
|
202
|
+
prerelease: false
|
203
|
+
version_requirements: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
- !ruby/object:Gem::Dependency
|
209
|
+
name: unicode-blocks
|
210
|
+
requirement: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
type: :runtime
|
216
|
+
prerelease: false
|
217
|
+
version_requirements: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: unicode-scripts
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - ">="
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
type: :runtime
|
230
|
+
prerelease: false
|
231
|
+
version_requirements: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
- !ruby/object:Gem::Dependency
|
237
|
+
name: unicode-types
|
238
|
+
requirement: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - ">="
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '0'
|
243
|
+
type: :runtime
|
244
|
+
prerelease: false
|
245
|
+
version_requirements: !ruby/object:Gem::Requirement
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
125
250
|
- !ruby/object:Gem::Dependency
|
126
251
|
name: bundler
|
127
252
|
requirement: !ruby/object:Gem::Requirement
|
@@ -239,6 +364,7 @@ files:
|
|
239
364
|
- lib/textbringer/commands/register.rb
|
240
365
|
- lib/textbringer/commands/replace.rb
|
241
366
|
- lib/textbringer/commands/server.rb
|
367
|
+
- lib/textbringer/commands/ucs_normalize.rb
|
242
368
|
- lib/textbringer/commands/windows.rb
|
243
369
|
- lib/textbringer/config.rb
|
244
370
|
- lib/textbringer/controller.rb
|
@@ -248,6 +374,7 @@ files:
|
|
248
374
|
- lib/textbringer/faces/basic.rb
|
249
375
|
- lib/textbringer/faces/programming.rb
|
250
376
|
- lib/textbringer/input_method.rb
|
377
|
+
- lib/textbringer/input_methods/hangul_input_method.rb
|
251
378
|
- lib/textbringer/input_methods/hiragana_input_method.rb
|
252
379
|
- lib/textbringer/input_methods/t_code_input_method.rb
|
253
380
|
- lib/textbringer/input_methods/t_code_input_method/tables.rb
|
@@ -266,6 +393,7 @@ files:
|
|
266
393
|
- lib/textbringer/utils.rb
|
267
394
|
- lib/textbringer/version.rb
|
268
395
|
- lib/textbringer/window.rb
|
396
|
+
- lib/textbringer/window/fallback_characters.rb
|
269
397
|
- logo/logo.jpg
|
270
398
|
- logo/logo.png
|
271
399
|
- screenshot.png
|
@@ -274,7 +402,6 @@ homepage: https://github.com/shugo/textbringer
|
|
274
402
|
licenses:
|
275
403
|
- MIT
|
276
404
|
metadata: {}
|
277
|
-
post_install_message:
|
278
405
|
rdoc_options: []
|
279
406
|
require_paths:
|
280
407
|
- lib
|
@@ -289,8 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
289
416
|
- !ruby/object:Gem::Version
|
290
417
|
version: '0'
|
291
418
|
requirements: []
|
292
|
-
rubygems_version: 3.
|
293
|
-
signing_key:
|
419
|
+
rubygems_version: 3.6.2
|
294
420
|
specification_version: 4
|
295
421
|
summary: An Emacs-like text editor
|
296
422
|
test_files: []
|