textbringer 0.3.0 → 0.3.1
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/.editorconfig +3 -0
- data/.travis.yml +6 -6
- data/CHANGES.md +4 -0
- data/exe/tbclient +34 -0
- data/lib/textbringer.rb +1 -0
- data/lib/textbringer/buffer.rb +53 -6
- data/lib/textbringer/commands/buffers.rb +4 -5
- data/lib/textbringer/commands/files.rb +1 -1
- data/lib/textbringer/commands/fill.rb +1 -1
- data/lib/textbringer/commands/isearch.rb +2 -2
- data/lib/textbringer/commands/register.rb +2 -2
- data/lib/textbringer/commands/server.rb +63 -0
- data/lib/textbringer/keymap.rb +2 -1
- data/lib/textbringer/mode.rb +2 -2
- data/lib/textbringer/modes/c_mode.rb +2 -2
- data/lib/textbringer/modes/ruby_mode.rb +2 -2
- data/lib/textbringer/utils.rb +9 -5
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +1 -1
- data/textbringer.gemspec +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 501a7f57f239b45890a30564482e20d2f80d20b5b21719268f97d0f787600c77
|
4
|
+
data.tar.gz: 56ec3be0a84a84663542072d76d0bfd868e42144cab77d51439d3ba317fe6302
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc8752782f2b63601fc382a88689b79d874d3deef1a829ef2efaa969ccfc43175b7d6f8ca2757dd345a88bb997cbc0e3b0aafaf4bcabafad478234e6e4ecd3af
|
7
|
+
data.tar.gz: 3d7ec2385be73f6d739e5fd0b547c28dc24001e58827d2d4ae15753d03d8d71e257a8f0efd50a9630ea169d3d2c58ade94104be772d9e0d91dfce08ea0b5f957
|
data/.editorconfig
CHANGED
data/.travis.yml
CHANGED
@@ -4,28 +4,28 @@ matrix:
|
|
4
4
|
- os: linux
|
5
5
|
dist: trusty
|
6
6
|
sudo: false
|
7
|
-
rvm: 2.
|
7
|
+
rvm: 2.4.5
|
8
8
|
- os: linux
|
9
9
|
dist: trusty
|
10
10
|
sudo: false
|
11
|
-
rvm: 2.
|
11
|
+
rvm: 2.5.2
|
12
12
|
- os: linux
|
13
13
|
dist: trusty
|
14
14
|
sudo: false
|
15
|
-
rvm: 2.
|
15
|
+
rvm: 2.6.0
|
16
16
|
- os: linux
|
17
17
|
dist: trusty
|
18
18
|
sudo: false
|
19
19
|
rvm: ruby-head
|
20
20
|
- os: osx
|
21
21
|
osx_image: xcode8.2
|
22
|
-
rvm: 2.
|
22
|
+
rvm: 2.4.5
|
23
23
|
- os: osx
|
24
24
|
osx_image: xcode8.2
|
25
|
-
rvm: 2.
|
25
|
+
rvm: 2.5.2
|
26
26
|
- os: osx
|
27
27
|
osx_image: xcode8.2
|
28
|
-
rvm: 2.
|
28
|
+
rvm: 2.6.0
|
29
29
|
- os: osx
|
30
30
|
osx_image: xcode8.2
|
31
31
|
rvm: ruby-head
|
data/CHANGES.md
CHANGED
data/exe/tbclient
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "drb"
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
eval = false
|
7
|
+
wait = true
|
8
|
+
uri = "drbunix:" + File.expand_path("server.sock", "~/.textbringer")
|
9
|
+
|
10
|
+
opt = OptionParser.new
|
11
|
+
opt.banner = "Usage: tbclient [OPTIONS] FILE"
|
12
|
+
opt.on("--uri URI", "Specify the URI of the server") do |val|
|
13
|
+
uri = val
|
14
|
+
end
|
15
|
+
opt.on("-e", "--eval", "Evaluate FILE as a Ruby expression") do
|
16
|
+
eval = true
|
17
|
+
end
|
18
|
+
opt.on("-n", "--no-wait", "Don't wait for the server") do
|
19
|
+
wait = false
|
20
|
+
end
|
21
|
+
args = ARGV.dup
|
22
|
+
opt.parse!(args)
|
23
|
+
if args.empty?
|
24
|
+
STDERR.puts(opt.help)
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
arg = args.first
|
28
|
+
tb = DRbObject.new_with_uri(uri)
|
29
|
+
if eval
|
30
|
+
puts tb.eval(arg)
|
31
|
+
else
|
32
|
+
tb.visit_file(File.expand_path(arg), wait: wait)
|
33
|
+
end
|
34
|
+
|
data/lib/textbringer.rb
CHANGED
@@ -23,6 +23,7 @@ require_relative "textbringer/commands/clipboard"
|
|
23
23
|
require_relative "textbringer/commands/register"
|
24
24
|
require_relative "textbringer/commands/keyboard_macro"
|
25
25
|
require_relative "textbringer/commands/fill"
|
26
|
+
require_relative "textbringer/commands/server"
|
26
27
|
require_relative "textbringer/commands/help"
|
27
28
|
require_relative "textbringer/mode"
|
28
29
|
require_relative "textbringer/modes/fundamental_mode"
|
data/lib/textbringer/buffer.rb
CHANGED
@@ -4,6 +4,7 @@ require "nkf"
|
|
4
4
|
require "unicode/display_width"
|
5
5
|
require "json"
|
6
6
|
require "fileutils"
|
7
|
+
require "editorconfig"
|
7
8
|
|
8
9
|
module Textbringer
|
9
10
|
class Buffer
|
@@ -398,6 +399,13 @@ module Textbringer
|
|
398
399
|
raise EditorError, "File name is not set"
|
399
400
|
end
|
400
401
|
file_name = File.expand_path(file_name)
|
402
|
+
config = EditorConfig.load_file(file_name)
|
403
|
+
if config["trim_trailing_whitespace"]
|
404
|
+
trim_trailing_whitespace
|
405
|
+
end
|
406
|
+
if config["insert_final_newline"]
|
407
|
+
insert_final_newline
|
408
|
+
end
|
401
409
|
begin
|
402
410
|
File.open(file_name, "w",
|
403
411
|
external_encoding: @file_encoding, binmode: true) do |f|
|
@@ -666,7 +674,7 @@ module Textbringer
|
|
666
674
|
end
|
667
675
|
end
|
668
676
|
end
|
669
|
-
|
677
|
+
|
670
678
|
def forward_line(n = 1)
|
671
679
|
if n > 0
|
672
680
|
n.times do
|
@@ -683,7 +691,7 @@ module Textbringer
|
|
683
691
|
end
|
684
692
|
end
|
685
693
|
end
|
686
|
-
|
694
|
+
|
687
695
|
def backward_line(n = 1)
|
688
696
|
forward_line(-n)
|
689
697
|
end
|
@@ -941,7 +949,7 @@ module Textbringer
|
|
941
949
|
m.location = s
|
942
950
|
end
|
943
951
|
end
|
944
|
-
push_undo(DeleteAction.new(self, old_pos, s, str))
|
952
|
+
push_undo(DeleteAction.new(self, old_pos, s, str))
|
945
953
|
self.modified = true
|
946
954
|
end
|
947
955
|
end
|
@@ -1328,7 +1336,15 @@ module Textbringer
|
|
1328
1336
|
end
|
1329
1337
|
|
1330
1338
|
def gsub(*args, &block)
|
1331
|
-
|
1339
|
+
if block
|
1340
|
+
s = to_s.gsub(*args) { |*params|
|
1341
|
+
set_block_backref(block, $~)
|
1342
|
+
block.call(*params)
|
1343
|
+
}
|
1344
|
+
else
|
1345
|
+
s = to_s.gsub(*args)
|
1346
|
+
end
|
1347
|
+
|
1332
1348
|
composite_edit do
|
1333
1349
|
delete_region(point_min, point_max)
|
1334
1350
|
insert(s)
|
@@ -1336,6 +1352,26 @@ module Textbringer
|
|
1336
1352
|
self
|
1337
1353
|
end
|
1338
1354
|
|
1355
|
+
def trim_trailing_whitespace
|
1356
|
+
save_excursion do
|
1357
|
+
beginning_of_buffer
|
1358
|
+
composite_edit do
|
1359
|
+
while re_search_forward(/[ \t]+$/, raise_error: false)
|
1360
|
+
replace_match("")
|
1361
|
+
end
|
1362
|
+
end
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
def insert_final_newline
|
1367
|
+
save_excursion do
|
1368
|
+
end_of_buffer
|
1369
|
+
if char_before != "\n"
|
1370
|
+
insert("\n")
|
1371
|
+
end
|
1372
|
+
end
|
1373
|
+
end
|
1374
|
+
|
1339
1375
|
private
|
1340
1376
|
|
1341
1377
|
def set_contents(s, enc)
|
@@ -1348,7 +1384,7 @@ module Textbringer
|
|
1348
1384
|
@contents.force_encoding(Encoding::ASCII_8BIT)
|
1349
1385
|
self.file_encoding = enc
|
1350
1386
|
case @contents
|
1351
|
-
when /(?<!\r)\n/
|
1387
|
+
when /(?<!\r)\n/
|
1352
1388
|
@file_format = :unix
|
1353
1389
|
when /\r(?!\n)/
|
1354
1390
|
@file_format = :mac
|
@@ -1391,7 +1427,7 @@ module Textbringer
|
|
1391
1427
|
if pos <= @gap_start
|
1392
1428
|
pos
|
1393
1429
|
else
|
1394
|
-
gap_size + pos
|
1430
|
+
gap_size + pos
|
1395
1431
|
end
|
1396
1432
|
end
|
1397
1433
|
|
@@ -1540,6 +1576,17 @@ module Textbringer
|
|
1540
1576
|
callback.call(self)
|
1541
1577
|
end
|
1542
1578
|
end
|
1579
|
+
|
1580
|
+
def set_block_backref(block, backref)
|
1581
|
+
Thread.current[:__textbringer_backref] = backref
|
1582
|
+
begin
|
1583
|
+
block.binding.eval(<<-EOC)
|
1584
|
+
$~ = Thread.current[:__textbringer_backref]
|
1585
|
+
EOC
|
1586
|
+
ensure
|
1587
|
+
Thread.current[:__textbringer_backref] = nil
|
1588
|
+
end
|
1589
|
+
end
|
1543
1590
|
end
|
1544
1591
|
|
1545
1592
|
class Mark
|
@@ -7,7 +7,7 @@ module Textbringer
|
|
7
7
|
|n = number_prefix_arg|
|
8
8
|
Buffer.current.forward_char(n)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
define_command(:backward_char,
|
12
12
|
doc: "Move point n characters backward.") do
|
13
13
|
|n = number_prefix_arg|
|
@@ -25,26 +25,25 @@ module Textbringer
|
|
25
25
|
|n = number_prefix_arg|
|
26
26
|
Buffer.current.backward_word(n)
|
27
27
|
end
|
28
|
-
|
29
28
|
|
30
29
|
define_command(:next_line,
|
31
30
|
doc: "Move point n lines forward.") do
|
32
31
|
|n = number_prefix_arg|
|
33
32
|
Buffer.current.next_line(n)
|
34
33
|
end
|
35
|
-
|
34
|
+
|
36
35
|
define_command(:previous_line,
|
37
36
|
doc: "Move point n lines backward.") do
|
38
37
|
|n = number_prefix_arg|
|
39
38
|
Buffer.current.previous_line(n)
|
40
39
|
end
|
41
|
-
|
40
|
+
|
42
41
|
define_command(:delete_char,
|
43
42
|
doc: "Delete n characters forward.") do
|
44
43
|
|n = number_prefix_arg|
|
45
44
|
Buffer.current.delete_char(n)
|
46
45
|
end
|
47
|
-
|
46
|
+
|
48
47
|
define_command(:backward_delete_char,
|
49
48
|
doc: "Delete n characters backward.") do
|
50
49
|
|n = number_prefix_arg|
|
@@ -122,7 +122,7 @@ module Textbringer
|
|
122
122
|
|
123
123
|
define_command(:chdir, doc: "Change the current working directory.") do
|
124
124
|
|dir_name = read_file_name("Change directory: ",
|
125
|
-
default: Buffer.current.file_name &&
|
125
|
+
default: Buffer.current.file_name &&
|
126
126
|
File.dirname(Buffer.current.file_name))|
|
127
127
|
Dir.chdir(dir_name)
|
128
128
|
end
|
@@ -8,7 +8,7 @@ module Textbringer
|
|
8
8
|
end
|
9
9
|
ISEARCH_MODE_MAP.define_key(?\t, :isearch_printing_char)
|
10
10
|
ISEARCH_MODE_MAP.handle_undefined_key do |key|
|
11
|
-
if key.is_a?(String) && /[\0-\x7f]/ !~ key
|
11
|
+
if key.is_a?(String) && /[\0-\x7f]/ !~ key
|
12
12
|
:isearch_printing_char
|
13
13
|
else
|
14
14
|
nil
|
@@ -21,7 +21,7 @@ module Textbringer
|
|
21
21
|
ISEARCH_MODE_MAP.define_key(?\C-w, :isearch_yank_word_or_char)
|
22
22
|
ISEARCH_MODE_MAP.define_key(?\C-m, :isearch_exit)
|
23
23
|
ISEARCH_MODE_MAP.define_key(?\C-g, :isearch_abort)
|
24
|
-
|
24
|
+
|
25
25
|
ISEARCH_STATUS = {
|
26
26
|
forward: true,
|
27
27
|
string: "",
|
@@ -4,7 +4,7 @@ module Textbringer
|
|
4
4
|
module Commands
|
5
5
|
class BufferPosition
|
6
6
|
attr_reader :buffer, :mark
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(buffer, mark)
|
9
9
|
@buffer = buffer
|
10
10
|
@mark = mark
|
@@ -118,7 +118,7 @@ module Textbringer
|
|
118
118
|
when Integer
|
119
119
|
REGISTERS[register] = i + prefix_numeric_value(n)
|
120
120
|
when String
|
121
|
-
append_to_register(register,
|
121
|
+
append_to_register(register,
|
122
122
|
Buffer.current.mark, Buffer.current.point, n)
|
123
123
|
else
|
124
124
|
raise ArgumentError, "Register doesn't contain a number or text"
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "drb"
|
4
|
+
|
5
|
+
module Textbringer
|
6
|
+
module Commands
|
7
|
+
define_command(:server_start,
|
8
|
+
doc: "Start Textbringer server.") do
|
9
|
+
uri = CONFIG[:server_uri] ||
|
10
|
+
"drbunix:" + File.expand_path("server.sock", "~/.textbringer")
|
11
|
+
options = CONFIG[:server_options] || { UNIXFileMode: 0600 }
|
12
|
+
DRb.start_service(uri, Server.new, options)
|
13
|
+
end
|
14
|
+
|
15
|
+
define_command(:server_kill,
|
16
|
+
doc: "Kill Textbringer server.") do
|
17
|
+
DRb.stop_service
|
18
|
+
end
|
19
|
+
|
20
|
+
define_command(:server_edit_done,
|
21
|
+
doc: "Finish server edit.") do
|
22
|
+
queue = Buffer.current[:client_wait_queue]
|
23
|
+
if queue.nil?
|
24
|
+
raise EditorError, "No waiting clients"
|
25
|
+
end
|
26
|
+
if Buffer.current.modified? &&
|
27
|
+
y_or_n?("Save file #{Buffer.current.file_name}?")
|
28
|
+
save_buffer
|
29
|
+
end
|
30
|
+
kill_buffer(Buffer.current, force: true)
|
31
|
+
queue.push(:done)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Server
|
36
|
+
def eval(s)
|
37
|
+
redisplay do
|
38
|
+
Controller.current.instance_eval(s).inspect
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def visit_file(filename, wait: true)
|
43
|
+
queue = Queue.new if wait
|
44
|
+
redisplay do
|
45
|
+
find_file(filename)
|
46
|
+
Buffer.current[:client_wait_queue] = queue if wait
|
47
|
+
end
|
48
|
+
queue.deq if wait
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def redisplay
|
54
|
+
foreground! do
|
55
|
+
begin
|
56
|
+
yield
|
57
|
+
ensure
|
58
|
+
Window.redisplay
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/textbringer/keymap.rb
CHANGED
@@ -191,8 +191,9 @@ module Textbringer
|
|
191
191
|
GLOBAL_MAP.define_key([:f1, "b"], :describe_bindings)
|
192
192
|
GLOBAL_MAP.define_key([:f1, "f"], :describe_command)
|
193
193
|
GLOBAL_MAP.define_key([:f1, "k"], :describe_key)
|
194
|
+
GLOBAL_MAP.define_key("\C-x#", :server_edit_done)
|
194
195
|
GLOBAL_MAP.handle_undefined_key do |key|
|
195
|
-
if key.is_a?(String) && /[\0-\x7f]/ !~ key
|
196
|
+
if key.is_a?(String) && /[\0-\x7f]/ !~ key
|
196
197
|
:self_insert
|
197
198
|
else
|
198
199
|
nil
|
data/lib/textbringer/mode.rb
CHANGED
@@ -35,7 +35,7 @@ module Textbringer
|
|
35
35
|
(?: " (?: [^\\"] | \\ (?:.|\n) )* " ) |
|
36
36
|
(?: ' (?: [^\\'] | \\ (?:.|\n) )* ' )
|
37
37
|
/x
|
38
|
-
|
38
|
+
|
39
39
|
def initialize(buffer)
|
40
40
|
super(buffer)
|
41
41
|
@buffer[:indent_level] = CONFIG[:c_indent_level]
|
@@ -68,7 +68,7 @@ module Textbringer
|
|
68
68
|
:partial_comment,
|
69
69
|
:unknown
|
70
70
|
]
|
71
|
-
|
71
|
+
|
72
72
|
TOKEN_REGEXP = /\G(?:
|
73
73
|
(?<preprocessing_directive>
|
74
74
|
^[ \t\f\v]*(?:\#|%:).*(?:\\\n.*)*[^\\]\n
|
@@ -259,7 +259,7 @@ module Textbringer
|
|
259
259
|
indentation
|
260
260
|
end
|
261
261
|
end
|
262
|
-
|
262
|
+
|
263
263
|
BLOCK_END = {
|
264
264
|
"{" => "}",
|
265
265
|
"(" => ")",
|
@@ -334,7 +334,7 @@ module Textbringer
|
|
334
334
|
end
|
335
335
|
nil
|
336
336
|
end
|
337
|
-
|
337
|
+
|
338
338
|
class PartialLiteralAnalyzer < Ripper
|
339
339
|
def self.in_literal?(src)
|
340
340
|
new(src).in_literal?
|
data/lib/textbringer/utils.rb
CHANGED
@@ -54,20 +54,22 @@ module Textbringer
|
|
54
54
|
begin
|
55
55
|
yield
|
56
56
|
rescue Exception => e
|
57
|
-
|
57
|
+
foreground do
|
58
58
|
raise e
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
64
|
+
def foreground(&block)
|
65
65
|
Controller.current.next_tick(&block)
|
66
66
|
end
|
67
67
|
|
68
|
-
|
68
|
+
alias next_tick foreground
|
69
|
+
|
70
|
+
def foreground!
|
69
71
|
q = Queue.new
|
70
|
-
|
72
|
+
foreground do
|
71
73
|
begin
|
72
74
|
result = yield
|
73
75
|
q.push([:ok, result])
|
@@ -77,12 +79,14 @@ module Textbringer
|
|
77
79
|
end
|
78
80
|
status, value = q.pop
|
79
81
|
if status == :error
|
80
|
-
raise value
|
82
|
+
raise value
|
81
83
|
else
|
82
84
|
value
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
88
|
+
alias next_tick! foreground!
|
89
|
+
|
86
90
|
def read_event
|
87
91
|
Controller.current.read_event
|
88
92
|
end
|
data/lib/textbringer/version.rb
CHANGED
data/lib/textbringer/window.rb
CHANGED
data/textbringer.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.required_ruby_version = '>= 2.3'
|
23
23
|
|
24
|
-
spec.add_runtime_dependency "curses", ">= 1.2.
|
24
|
+
spec.add_runtime_dependency "curses", ">= 1.2.6"
|
25
25
|
spec.add_runtime_dependency "unicode-display_width", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "clipboard", "~> 1.1"
|
27
27
|
spec.add_runtime_dependency "fiddley", ">= 0.0.5"
|
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: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.2.
|
19
|
+
version: 1.2.6
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.2.
|
26
|
+
version: 1.2.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: unicode-display_width
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -183,6 +183,7 @@ description: Textbringer is a member of a demon race that takes on the form of a
|
|
183
183
|
email:
|
184
184
|
- shugo@ruby-lang.org
|
185
185
|
executables:
|
186
|
+
- tbclient
|
186
187
|
- tbtags
|
187
188
|
- textbringer
|
188
189
|
extensions: []
|
@@ -198,6 +199,7 @@ files:
|
|
198
199
|
- Rakefile
|
199
200
|
- appveyor.yml
|
200
201
|
- bin/console
|
202
|
+
- exe/tbclient
|
201
203
|
- exe/tbtags
|
202
204
|
- exe/textbringer
|
203
205
|
- lib/textbringer.rb
|
@@ -216,6 +218,7 @@ files:
|
|
216
218
|
- lib/textbringer/commands/misc.rb
|
217
219
|
- lib/textbringer/commands/register.rb
|
218
220
|
- lib/textbringer/commands/replace.rb
|
221
|
+
- lib/textbringer/commands/server.rb
|
219
222
|
- lib/textbringer/commands/windows.rb
|
220
223
|
- lib/textbringer/config.rb
|
221
224
|
- lib/textbringer/controller.rb
|