textbringer 0.2.1 → 0.2.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/.travis.yml +2 -2
- data/CHANGES.md +10 -0
- data/exe/textbringer +34 -30
- data/lib/textbringer/commands.rb +1 -0
- data/lib/textbringer/commands/buffers.rb +1 -1
- data/lib/textbringer/commands/windows.rb +8 -2
- data/lib/textbringer/controller.rb +52 -10
- data/lib/textbringer/keymap.rb +1 -0
- data/lib/textbringer/modes/c_mode.rb +3 -5
- data/lib/textbringer/plugin.rb +9 -4
- data/lib/textbringer/utils.rb +25 -1
- data/lib/textbringer/version.rb +1 -1
- data/lib/textbringer/window.rb +7 -6
- data/textbringer.gemspec +1 -3
- metadata +5 -34
- data/Guardfile +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df46cdf2ec8419a33fbfd4e23f41272bd4204ba2
|
4
|
+
data.tar.gz: 47179c38f72119aa5c4b96f01c80d28f10660531
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b39cb72604f03c738a02b37fcc7c8d74bef47590ddde2293e6207f7be1147572395b760a02bcc74537872de3152967f447bcfb03b1fb83f447c274eff0322371
|
7
|
+
data.tar.gz: 864a8f20870885c9fb7c2252779cbe269f08ed34b1650b06233172fb69eac9fcdf76da5b6292150db4940ba7ce14b3f308b89c78084be811fd0f255553e8c720
|
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.2.2
|
2
|
+
|
3
|
+
* Rename read_char to read_event and add read_char as a new method.
|
4
|
+
* Add next_tick and background for background threads.
|
5
|
+
* Add the force: option to kill_buffer.
|
6
|
+
* bind C-? ([delete] on Mac) to backward_delete_char.
|
7
|
+
Pull request #23 by moguno.
|
8
|
+
* Make commands module_functions.
|
9
|
+
* Use fiddley instead of ffi.
|
10
|
+
|
1
11
|
## 0.2.1
|
2
12
|
|
3
13
|
* Add revert_buffer and revert_buffer_with_encoding.
|
data/exe/textbringer
CHANGED
@@ -16,40 +16,44 @@ end
|
|
16
16
|
$VERBOSE = nil
|
17
17
|
|
18
18
|
Controller.current = Controller.new
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
ARGV.
|
26
|
-
|
19
|
+
begin
|
20
|
+
Window.start do
|
21
|
+
begin
|
22
|
+
Plugin.load_plugins
|
23
|
+
load_user_config
|
24
|
+
ruby_mode
|
25
|
+
if ARGV.size > 0
|
26
|
+
ARGV.each do |arg|
|
27
|
+
find_file(arg)
|
28
|
+
end
|
27
29
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
if Buffer.dumped_buffers_exist?(CONFIG[:buffer_dump_dir])
|
31
|
+
Window.redisplay
|
32
|
+
if yes_or_no?("Dumped buffers found; restore them?")
|
33
|
+
buffers = Buffer.load_dumped_buffers(CONFIG[:buffer_dump_dir])
|
34
|
+
switch_to_buffer(buffers.last)
|
35
|
+
end
|
34
36
|
end
|
37
|
+
rescue Exception => e
|
38
|
+
show_exception(e)
|
35
39
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
begin
|
41
|
-
trap(:CONT) { Window.redraw }
|
42
|
-
rescue ArgumentError
|
43
|
-
end
|
44
|
-
begin
|
45
|
-
loop do
|
46
|
-
Controller.current.command_loop(TOP_LEVEL_TAG)
|
47
|
-
Window.redisplay
|
40
|
+
Window.redisplay
|
41
|
+
begin
|
42
|
+
trap(:CONT) { Window.redraw }
|
43
|
+
rescue ArgumentError
|
48
44
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
begin
|
46
|
+
loop do
|
47
|
+
Controller.current.command_loop(TOP_LEVEL_TAG)
|
48
|
+
Window.redisplay
|
49
|
+
end
|
50
|
+
rescue Exception => e
|
51
|
+
if !e.is_a?(SystemExit)
|
52
|
+
Buffer.dump_unsaved_buffers(CONFIG[:buffer_dump_dir])
|
53
|
+
end
|
54
|
+
raise
|
52
55
|
end
|
53
|
-
raise
|
54
56
|
end
|
57
|
+
ensure
|
58
|
+
Controller.current.close
|
55
59
|
end
|
data/lib/textbringer/commands.rb
CHANGED
@@ -26,6 +26,7 @@ module Textbringer
|
|
26
26
|
def define_command(name, doc: "No documentation", &block)
|
27
27
|
name = name.intern
|
28
28
|
Commands.send(:define_method, name, &block)
|
29
|
+
Commands.send(:module_function, name)
|
29
30
|
Commands.command_table[name] = Command.new(name, block, doc)
|
30
31
|
name
|
31
32
|
end
|
@@ -171,7 +171,7 @@ module Textbringer
|
|
171
171
|
define_command(:quoted_insert,
|
172
172
|
doc: "Read a character, and insert it.") do
|
173
173
|
|n = number_prefix_arg|
|
174
|
-
c = Controller.current.
|
174
|
+
c = Controller.current.read_event
|
175
175
|
if !c.is_a?(String)
|
176
176
|
raise EditorError, "Invalid key"
|
177
177
|
end
|
@@ -100,11 +100,12 @@ module Textbringer
|
|
100
100
|
end
|
101
101
|
|
102
102
|
define_command(:kill_buffer, doc: "Kill buffer.") do
|
103
|
-
|buffer = read_buffer("Kill buffer: ", default: Buffer.current.name)
|
103
|
+
|buffer = read_buffer("Kill buffer: ", default: Buffer.current.name),
|
104
|
+
force: false|
|
104
105
|
if buffer.is_a?(String)
|
105
106
|
buffer = Buffer[buffer]
|
106
107
|
end
|
107
|
-
if buffer.modified?
|
108
|
+
if !force && buffer.modified?
|
108
109
|
next unless yes_or_no?("The last change is not saved; kill anyway?")
|
109
110
|
message("Arioch! Arioch! Blood and souls for my Lord Arioch!")
|
110
111
|
end
|
@@ -112,6 +113,11 @@ module Textbringer
|
|
112
113
|
if Buffer.current.nil?
|
113
114
|
switch_to_buffer(Buffer.other)
|
114
115
|
end
|
116
|
+
Window.list(include_echo_area: true).each do |window|
|
117
|
+
if window.buffer == buffer
|
118
|
+
window.buffer = Buffer.current
|
119
|
+
end
|
120
|
+
end
|
115
121
|
end
|
116
122
|
end
|
117
123
|
end
|
@@ -36,6 +36,14 @@ module Textbringer
|
|
36
36
|
@recording_keyboard_macro = nil
|
37
37
|
@last_keyboard_macro = nil
|
38
38
|
@executing_keyboard_macro = nil
|
39
|
+
@next_tick_queue = []
|
40
|
+
@next_tick_queue_mutex = Mutex.new
|
41
|
+
@next_tick_input, @next_tick_output = IO.pipe
|
42
|
+
end
|
43
|
+
|
44
|
+
def close
|
45
|
+
@next_tick_input.close
|
46
|
+
@next_tick_output.close
|
39
47
|
end
|
40
48
|
|
41
49
|
def command_loop(tag)
|
@@ -43,7 +51,7 @@ module Textbringer
|
|
43
51
|
loop do
|
44
52
|
begin
|
45
53
|
echo_input
|
46
|
-
c =
|
54
|
+
c = read_event
|
47
55
|
break if c.nil?
|
48
56
|
Window.echo_area.clear_message
|
49
57
|
@last_key = c
|
@@ -92,22 +100,56 @@ module Textbringer
|
|
92
100
|
end
|
93
101
|
|
94
102
|
def wait_input(msecs)
|
103
|
+
# TODO: Check @next_tick_queue
|
95
104
|
if executing_keyboard_macro?
|
96
105
|
return @executing_keyboard_macro.first
|
97
106
|
end
|
98
107
|
Window.current.wait_input(msecs)
|
99
108
|
end
|
100
109
|
|
101
|
-
def
|
102
|
-
|
110
|
+
def next_tick(&block)
|
111
|
+
@next_tick_queue_mutex.synchronize do
|
112
|
+
@next_tick_queue.push(block)
|
113
|
+
end
|
114
|
+
@next_tick_output.write("\n")
|
115
|
+
end
|
116
|
+
|
117
|
+
def read_event
|
118
|
+
event = read_event_nonblock
|
119
|
+
if event
|
120
|
+
return event
|
121
|
+
end
|
122
|
+
loop do
|
123
|
+
if Window.echo_area.active?
|
124
|
+
wait_files = [STDIN]
|
125
|
+
else
|
126
|
+
wait_files = [STDIN, @next_tick_input]
|
127
|
+
end
|
128
|
+
files, = IO.select(wait_files, [], [], 1)
|
129
|
+
# KEY_RESIZE may be returned even if STDIN is not included in files.
|
130
|
+
event = read_event_nonblock
|
131
|
+
if event
|
132
|
+
return event
|
133
|
+
end
|
134
|
+
if !Window.echo_area.active? && files&.include?(@next_tick_input)
|
135
|
+
c = @next_tick_input.read_nonblock(1, exception: false)
|
136
|
+
if !c.nil? && c != :wait_readable
|
137
|
+
block = @next_tick_queue_mutex.synchronize {
|
138
|
+
@next_tick_queue.shift
|
139
|
+
}
|
140
|
+
block.call
|
141
|
+
Window.redisplay
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
103
145
|
end
|
104
146
|
|
105
|
-
def
|
106
|
-
|
147
|
+
def read_event_nonblock
|
148
|
+
read_event_with_keyboard_macro(:read_event_nonblock)
|
107
149
|
end
|
108
150
|
|
109
151
|
def received_keyboard_quit?
|
110
|
-
while key =
|
152
|
+
while key = read_event_nonblock
|
111
153
|
if GLOBAL_MAP.lookup([key]) == :keyboard_quit
|
112
154
|
return true
|
113
155
|
end
|
@@ -208,9 +250,9 @@ module Textbringer
|
|
208
250
|
|
209
251
|
private
|
210
252
|
|
211
|
-
def
|
253
|
+
def read_event_with_keyboard_macro(read_event_method)
|
212
254
|
if !executing_keyboard_macro?
|
213
|
-
c =
|
255
|
+
c = call_read_event_method(read_event_method)
|
214
256
|
if @recording_keyboard_macro
|
215
257
|
@recording_keyboard_macro.push(c)
|
216
258
|
end
|
@@ -220,8 +262,8 @@ module Textbringer
|
|
220
262
|
end
|
221
263
|
end
|
222
264
|
|
223
|
-
def
|
224
|
-
Window.current.send(
|
265
|
+
def call_read_event_method(read_event_method)
|
266
|
+
Window.current.send(read_event_method)
|
225
267
|
end
|
226
268
|
end
|
227
269
|
end
|
data/lib/textbringer/keymap.rb
CHANGED
@@ -109,6 +109,7 @@ module Textbringer
|
|
109
109
|
GLOBAL_MAP.define_key(?\C-d, :delete_char)
|
110
110
|
GLOBAL_MAP.define_key(:backspace, :backward_delete_char)
|
111
111
|
GLOBAL_MAP.define_key(?\C-h, :backward_delete_char)
|
112
|
+
GLOBAL_MAP.define_key(?\C-?, :backward_delete_char)
|
112
113
|
GLOBAL_MAP.define_key(?\C-a, :beginning_of_line)
|
113
114
|
GLOBAL_MAP.define_key(:home, :beginning_of_line)
|
114
115
|
GLOBAL_MAP.define_key(?\C-e, :end_of_line)
|
@@ -78,8 +78,8 @@ module Textbringer
|
|
78
78
|
(?<singleline_comment> \/\/ .*(?:\\\n.*)*(?<!\\)\n )
|
79
79
|
) |
|
80
80
|
(?<partial_comment>
|
81
|
-
(?<
|
82
|
-
(?<
|
81
|
+
(?<partial_multiline_comment> \/\* (?:.|\n)* ) |
|
82
|
+
(?<partial_singleline_comment> \/\/ .*? \\\n (?:.|\n)* )
|
83
83
|
) |
|
84
84
|
(?<keyword>
|
85
85
|
(?: #{KEYWORDS.join("|")} ) \b
|
@@ -177,10 +177,9 @@ module Textbringer
|
|
177
177
|
|
178
178
|
def lex(s)
|
179
179
|
tokens = []
|
180
|
-
pos = 0
|
181
180
|
line = 1
|
182
181
|
column = 0
|
183
|
-
|
182
|
+
s.scan(TOKEN_REGEXP) do
|
184
183
|
text = $&
|
185
184
|
token_name = TOKEN_NAMES.find { |name| $~[name] }
|
186
185
|
if text.empty?
|
@@ -194,7 +193,6 @@ module Textbringer
|
|
194
193
|
else
|
195
194
|
column += text.size
|
196
195
|
end
|
197
|
-
pos += text.size
|
198
196
|
end
|
199
197
|
tokens
|
200
198
|
end
|
data/lib/textbringer/plugin.rb
CHANGED
@@ -2,9 +2,14 @@
|
|
2
2
|
|
3
3
|
module Textbringer
|
4
4
|
module Plugin
|
5
|
+
class << self
|
6
|
+
attr_accessor :directory
|
7
|
+
end
|
8
|
+
|
9
|
+
@directory = File.expand_path("~/.textbringer/plugins")
|
10
|
+
|
5
11
|
def self.load_plugins
|
6
|
-
files = Gem.find_files("textbringer_plugin.rb")
|
7
|
-
files.group_by { |file|
|
12
|
+
files = Gem.find_files("textbringer_plugin.rb").group_by { |file|
|
8
13
|
file.slice(/([^\/]+)-[\w.]+\/lib\/textbringer_plugin\.rb\z/, 1)
|
9
14
|
}.map { |gem, versions|
|
10
15
|
versions.sort_by { |version|
|
@@ -12,10 +17,10 @@ module Textbringer
|
|
12
17
|
1)
|
13
18
|
Gem::Version.create(v)
|
14
19
|
}.last
|
15
|
-
}.
|
20
|
+
} + Dir.glob(File.join(directory, "*/**/textbringer_plugin.rb"))
|
21
|
+
files.each do |file|
|
16
22
|
load(file)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
21
|
-
|
data/lib/textbringer/utils.rb
CHANGED
@@ -49,8 +49,32 @@ module Textbringer
|
|
49
49
|
sleep(secs)
|
50
50
|
end
|
51
51
|
|
52
|
+
def background
|
53
|
+
Thread.start do
|
54
|
+
begin
|
55
|
+
yield
|
56
|
+
rescue Exception => e
|
57
|
+
next_tick do
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def next_tick(*args, &block)
|
65
|
+
Controller.current.next_tick(*args, &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def read_event
|
69
|
+
Controller.current.read_event
|
70
|
+
end
|
71
|
+
|
52
72
|
def read_char
|
53
|
-
Controller.current.
|
73
|
+
event = Controller.current.read_event
|
74
|
+
if !event.is_a?(String)
|
75
|
+
raise EditorError, "Non character event: #{event.inspect}"
|
76
|
+
end
|
77
|
+
event
|
54
78
|
end
|
55
79
|
|
56
80
|
def received_keyboard_quit?
|
data/lib/textbringer/version.rb
CHANGED
data/lib/textbringer/window.rb
CHANGED
@@ -322,7 +322,7 @@ module Textbringer
|
|
322
322
|
self == @@current
|
323
323
|
end
|
324
324
|
|
325
|
-
def
|
325
|
+
def read_event
|
326
326
|
key = get_char
|
327
327
|
if key.is_a?(Integer)
|
328
328
|
if PDCurses.dll_loaded?
|
@@ -340,10 +340,10 @@ module Textbringer
|
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
343
|
-
def
|
343
|
+
def read_event_nonblock
|
344
344
|
@window.nodelay = true
|
345
345
|
begin
|
346
|
-
|
346
|
+
read_event
|
347
347
|
ensure
|
348
348
|
@window.nodelay = false
|
349
349
|
end
|
@@ -553,7 +553,7 @@ module Textbringer
|
|
553
553
|
|
554
554
|
def scroll_up
|
555
555
|
if @bottom_of_window.location == @buffer.point_max
|
556
|
-
raise
|
556
|
+
raise RangeError, "End of buffer"
|
557
557
|
end
|
558
558
|
@buffer.point_to_mark(@bottom_of_window)
|
559
559
|
@buffer.previous_line
|
@@ -563,7 +563,7 @@ module Textbringer
|
|
563
563
|
|
564
564
|
def scroll_down
|
565
565
|
if @top_of_window.location == @buffer.point_min
|
566
|
-
raise
|
566
|
+
raise RangeError, "Beginning of buffer"
|
567
567
|
end
|
568
568
|
@buffer.point_to_mark(@top_of_window)
|
569
569
|
@buffer.next_line
|
@@ -928,7 +928,8 @@ module Textbringer
|
|
928
928
|
if width > max_width
|
929
929
|
@buffer.forward_char
|
930
930
|
break
|
931
|
-
elsif width == max_width || @buffer.beginning_of_line?
|
931
|
+
elsif width == max_width || @buffer.beginning_of_line? ||
|
932
|
+
@buffer.point_at_mark?(@top_of_window)
|
932
933
|
break
|
933
934
|
end
|
934
935
|
@buffer.backward_char
|
data/textbringer.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency "curses", "~> 1.2"
|
25
25
|
spec.add_runtime_dependency "unicode-display_width", "~> 1.1"
|
26
26
|
spec.add_runtime_dependency "clipboard", "~> 1.1"
|
27
|
-
spec.add_runtime_dependency "
|
27
|
+
spec.add_runtime_dependency "fiddley", ">= 0.0.5"
|
28
28
|
spec.add_runtime_dependency "editorconfig"
|
29
29
|
|
30
30
|
spec.add_development_dependency "bundler", "~> 1.14"
|
@@ -33,7 +33,5 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency "simplecov"
|
34
34
|
spec.add_development_dependency "codecov"
|
35
35
|
spec.add_development_dependency "bundler-audit"
|
36
|
-
spec.add_development_dependency "guard"
|
37
|
-
spec.add_development_dependency "guard-shell"
|
38
36
|
spec.add_development_dependency "ripper-tags"
|
39
37
|
end
|
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.2.
|
4
|
+
version: 0.2.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: 2017-
|
11
|
+
date: 2017-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: fiddley
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.0.5
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.0.5
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: editorconfig
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,34 +164,6 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: guard
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - ">="
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
type: :development
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: guard-shell
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
195
167
|
- !ruby/object:Gem::Dependency
|
196
168
|
name: ripper-tags
|
197
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,7 +193,6 @@ files:
|
|
221
193
|
- ".travis.yml"
|
222
194
|
- CHANGES.md
|
223
195
|
- Gemfile
|
224
|
-
- Guardfile
|
225
196
|
- LICENSE.txt
|
226
197
|
- README.md
|
227
198
|
- Rakefile
|
data/Guardfile
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# A sample Guardfile
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
## Uncomment and set this to only include directories you want to watch
|
5
|
-
# directories %w(app lib config test spec features) \
|
6
|
-
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
-
|
8
|
-
## Note: if you are using the `directories` clause above and you are not
|
9
|
-
## watching the project directory ('.'), then you will want to move
|
10
|
-
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
-
#
|
12
|
-
# $ mkdir config
|
13
|
-
# $ mv Guardfile config/
|
14
|
-
# $ ln -s config/Guardfile .
|
15
|
-
#
|
16
|
-
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
-
|
18
|
-
guard :shell do
|
19
|
-
watch(%r'^(lib|test)/.+\.rb$') do
|
20
|
-
`bundle exec tbtags -R`
|
21
|
-
end
|
22
|
-
end
|