guard 2.6.1 → 2.7.0
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/README.md +73 -58
- data/bin/guard +2 -2
- data/lib/guard.rb +64 -59
- data/lib/guard/cli.rb +66 -60
- data/lib/guard/cli.rb.orig +215 -0
- data/lib/guard/commander.rb +45 -69
- data/lib/guard/commands/all.rb +21 -19
- data/lib/guard/commands/change.rb +17 -22
- data/lib/guard/commands/notification.rb +15 -16
- data/lib/guard/commands/pause.rb +14 -15
- data/lib/guard/commands/reload.rb +19 -20
- data/lib/guard/commands/scope.rb +23 -19
- data/lib/guard/commands/show.rb +13 -16
- data/lib/guard/deprecated_methods.rb +6 -10
- data/lib/guard/deprecator.rb +52 -37
- data/lib/guard/dsl.rb +55 -33
- data/lib/guard/dsl_describer.rb +83 -31
- data/lib/guard/dsl_describer.rb.orig +184 -0
- data/lib/guard/group.rb +7 -6
- data/lib/guard/guard.rb +4 -4
- data/lib/guard/guard.rb.orig +42 -0
- data/lib/guard/guardfile.rb +12 -13
- data/lib/guard/guardfile/evaluator.rb +77 -55
- data/lib/guard/guardfile/evaluator.rb.orig +275 -0
- data/lib/guard/guardfile/generator.rb +25 -20
- data/lib/guard/interactor.rb +52 -293
- data/lib/guard/interactor.rb.orig +85 -0
- data/lib/guard/jobs/base.rb +21 -0
- data/lib/guard/jobs/pry_wrapper.rb +290 -0
- data/lib/guard/jobs/pry_wrapper.rb.orig +293 -0
- data/lib/guard/jobs/sleep.rb +25 -0
- data/lib/guard/notifier.rb +42 -39
- data/lib/guard/notifiers/base.rb +25 -24
- data/lib/guard/notifiers/emacs.rb +30 -24
- data/lib/guard/notifiers/file_notifier.rb +3 -7
- data/lib/guard/notifiers/gntp.rb +22 -22
- data/lib/guard/notifiers/growl.rb +16 -15
- data/lib/guard/notifiers/libnotify.rb +7 -10
- data/lib/guard/notifiers/notifysend.rb +15 -14
- data/lib/guard/notifiers/rb_notifu.rb +8 -10
- data/lib/guard/notifiers/terminal_notifier.rb +15 -11
- data/lib/guard/notifiers/terminal_title.rb +4 -8
- data/lib/guard/notifiers/tmux.rb +104 -71
- data/lib/guard/options.rb +1 -5
- data/lib/guard/plugin.rb +1 -3
- data/lib/guard/plugin/base.rb +12 -9
- data/lib/guard/plugin/hooker.rb +1 -5
- data/lib/guard/plugin_util.rb +46 -25
- data/lib/guard/plugin_util.rb.orig +178 -0
- data/lib/guard/rake_task.rb +4 -7
- data/lib/guard/reevaluator.rb +13 -0
- data/lib/guard/runner.rb +50 -78
- data/lib/guard/runner.rb.orig +200 -0
- data/lib/guard/setuper.rb +199 -130
- data/lib/guard/setuper.rb.orig +348 -0
- data/lib/guard/sheller.rb +107 -0
- data/lib/guard/tags +367 -0
- data/lib/guard/ui.rb +50 -38
- data/lib/guard/ui.rb.orig +254 -0
- data/lib/guard/ui/colors.rb +17 -21
- data/lib/guard/version.rb +1 -1
- data/lib/guard/version.rb.orig +3 -0
- data/lib/guard/watcher.rb +49 -62
- metadata +21 -4
- data/lib/guard/notifiers/growl_notify.rb +0 -93
@@ -0,0 +1,85 @@
|
|
1
|
+
require "guard/ui"
|
2
|
+
|
3
|
+
require "guard/jobs/sleep"
|
4
|
+
require "guard/jobs/pry_wrapper"
|
5
|
+
|
6
|
+
module Guard
|
7
|
+
class Interactor
|
8
|
+
# Initializes the interactor. This configures
|
9
|
+
# Pry and creates some custom commands and aliases
|
10
|
+
# for Guard.
|
11
|
+
#
|
12
|
+
def initialize(no_interaction = false)
|
13
|
+
@interactive = !no_interaction && self.class.enabled?
|
14
|
+
|
15
|
+
job_klass = interactive? ? Jobs::PryWrapper : Jobs::Sleep
|
16
|
+
@idle_job = job_klass.new(self.class.options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def interactive?
|
20
|
+
@interactive
|
21
|
+
end
|
22
|
+
|
23
|
+
# Run in foreground and wait until interrupted or closed
|
24
|
+
def foreground
|
25
|
+
idle_job.foreground
|
26
|
+
end
|
27
|
+
|
28
|
+
# Remove interactor so other tasks can run in foreground
|
29
|
+
def background
|
30
|
+
idle_job.background
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle_interrupt
|
34
|
+
idle_job.handle_interrupt
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
def options
|
39
|
+
@options ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Pass options to interactor's job when it's created
|
43
|
+
attr_writer :options
|
44
|
+
|
45
|
+
# TODO: allow custom user idle jobs, e.g. [:pry, :sleep, :exit, ...]
|
46
|
+
def enabled?
|
47
|
+
@enabled || @enabled.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :enabled, :enabled?
|
51
|
+
|
52
|
+
# TODO: handle switching interactors during runtime?
|
53
|
+
attr_writer :enabled
|
54
|
+
|
55
|
+
# Converts and validates a plain text scope
|
56
|
+
# to a valid plugin or group scope.
|
57
|
+
#
|
58
|
+
# @param [Array<String>] entries the text scope
|
59
|
+
# @return [Hash, Array<String>] the plugin or group scope, the unknown
|
60
|
+
# entries
|
61
|
+
#
|
62
|
+
# TODO: call this from within action, not within interactor command
|
63
|
+
def convert_scope(entries)
|
64
|
+
scopes = { plugins: [], groups: [] }
|
65
|
+
unknown = []
|
66
|
+
|
67
|
+
entries.each do |entry|
|
68
|
+
if plugin = ::Guard.plugin(entry)
|
69
|
+
scopes[:plugins] << plugin
|
70
|
+
elsif group = ::Guard.group(entry)
|
71
|
+
scopes[:groups] << group
|
72
|
+
else
|
73
|
+
unknown << entry
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
[scopes, unknown]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
attr_reader :idle_job
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Guard
|
2
|
+
module Jobs
|
3
|
+
class Base
|
4
|
+
def initialize(_options)
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Symbol] :stopped once job is finished
|
8
|
+
# @return [Symbol] :exit to tell Guard to terminate
|
9
|
+
def foreground
|
10
|
+
end
|
11
|
+
|
12
|
+
def background
|
13
|
+
end
|
14
|
+
|
15
|
+
# Signal handler calls this, so avoid actually doing
|
16
|
+
# anything other than signaling threads
|
17
|
+
def handle_interrupt
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require "guard/commands/all"
|
2
|
+
require "guard/commands/change"
|
3
|
+
require "guard/commands/notification"
|
4
|
+
require "guard/commands/pause"
|
5
|
+
require "guard/commands/reload"
|
6
|
+
require "guard/commands/scope"
|
7
|
+
require "guard/commands/show"
|
8
|
+
|
9
|
+
require "guard/jobs/base"
|
10
|
+
|
11
|
+
module Guard
|
12
|
+
module Jobs
|
13
|
+
class TerminalSettings
|
14
|
+
def initialize
|
15
|
+
@settings = nil
|
16
|
+
@works = ::Guard::Sheller.run("hash", "stty") || false
|
17
|
+
end
|
18
|
+
|
19
|
+
def restore
|
20
|
+
return unless configurable? && @settings
|
21
|
+
::Guard::Sheller.run("stty #{ @setting } 2>#{ DEV_NULL }")
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
return unless configurable?
|
26
|
+
@settings = ::Guard::Sheller.stdout("stty -g 2>#{ DEV_NULL }").chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
def echo
|
30
|
+
return unless configurable?
|
31
|
+
::Guard::Sheller.run("stty echo 2>#{ DEV_NULL }")
|
32
|
+
end
|
33
|
+
|
34
|
+
def configurable?
|
35
|
+
@works
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class PryWrapper < Base
|
40
|
+
# The default Ruby script to configure Guard Pry if the option `:guard_rc`
|
41
|
+
# is not defined.
|
42
|
+
GUARD_RC = "~/.guardrc"
|
43
|
+
|
44
|
+
# The default Guard Pry history file if the option `:history_file` is not
|
45
|
+
# defined.
|
46
|
+
HISTORY_FILE = "~/.guard_history"
|
47
|
+
|
48
|
+
# List of shortcuts for each interactor command
|
49
|
+
SHORTCUTS = {
|
50
|
+
help: "h",
|
51
|
+
all: "a",
|
52
|
+
reload: "r",
|
53
|
+
change: "c",
|
54
|
+
show: "s",
|
55
|
+
scope: "o",
|
56
|
+
notification: "n",
|
57
|
+
pause: "p",
|
58
|
+
exit: "e",
|
59
|
+
quit: "q"
|
60
|
+
}
|
61
|
+
|
62
|
+
def initialize(options)
|
63
|
+
@mutex = Mutex.new
|
64
|
+
@thread = nil
|
65
|
+
@terminal_settings = TerminalSettings.new
|
66
|
+
|
67
|
+
_setup(options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def foreground
|
71
|
+
::Guard::UI.debug "Start interactor"
|
72
|
+
@terminal_settings.save
|
73
|
+
|
74
|
+
_start_pry
|
75
|
+
@thread.join
|
76
|
+
thread = @thread
|
77
|
+
thread.nil? ? :stopped : :exit
|
78
|
+
ensure
|
79
|
+
::Guard::UI.reset_line
|
80
|
+
::Guard::UI.debug "Interactor was stopped or killed"
|
81
|
+
@terminal_settings.restore
|
82
|
+
end
|
83
|
+
|
84
|
+
def background
|
85
|
+
_kill_pry
|
86
|
+
end
|
87
|
+
|
88
|
+
def handle_interrupt
|
89
|
+
thread = @thread
|
90
|
+
fail Interrupt unless thread
|
91
|
+
thread.raise Interrupt
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
attr_reader :thread
|
97
|
+
|
98
|
+
def _start_pry
|
99
|
+
@mutex.synchronize do
|
100
|
+
unless @thread
|
101
|
+
@thread = Thread.new { Pry.start }
|
102
|
+
@thread.join(0.5) # give pry a chance to start
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def _kill_pry
|
108
|
+
@mutex.synchronize do
|
109
|
+
unless @thread.nil?
|
110
|
+
@thread.kill
|
111
|
+
@thread = nil # set to nil so we know we were killed
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def _setup(options)
|
117
|
+
Pry.config.should_load_rc = false
|
118
|
+
Pry.config.should_load_local_rc = false
|
119
|
+
history_file_path = options[:history_file] || HISTORY_FILE
|
120
|
+
Pry.config.history.file = File.expand_path(history_file_path)
|
121
|
+
|
122
|
+
_add_hooks(options)
|
123
|
+
|
124
|
+
::Guard::Commands::All.import
|
125
|
+
::Guard::Commands::Change.import
|
126
|
+
::Guard::Commands::Notification.import
|
127
|
+
::Guard::Commands::Pause.import
|
128
|
+
::Guard::Commands::Reload.import
|
129
|
+
::Guard::Commands::Show.import
|
130
|
+
::Guard::Commands::Scope.import
|
131
|
+
|
132
|
+
_setup_commands
|
133
|
+
_configure_prompt
|
134
|
+
end
|
135
|
+
|
136
|
+
# Add Pry hooks:
|
137
|
+
#
|
138
|
+
# * Load `~/.guardrc` within each new Pry session.
|
139
|
+
# * Load project's `.guardrc` within each new Pry session.
|
140
|
+
# * Restore prompt after each evaluation.
|
141
|
+
#
|
142
|
+
def _add_hooks(options)
|
143
|
+
_add_load_guard_rc_hook(Pathname(options[:guard_rc] || GUARD_RC))
|
144
|
+
_add_load_project_guard_rc_hook(Pathname.pwd + ".guardrc")
|
145
|
+
_add_restore_visibility_hook if @terminal_settings.configurable?
|
146
|
+
end
|
147
|
+
|
148
|
+
# Add a `when_started` hook that loads a global .guardrc if it exists.
|
149
|
+
#
|
150
|
+
def _add_load_guard_rc_hook(guard_rc)
|
151
|
+
Pry.config.hooks.add_hook :when_started, :load_guard_rc do
|
152
|
+
guard_rc.expand_path.tap { |p| load p if p.exist? }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Add a `when_started` hook that loads a project .guardrc if it exists.
|
157
|
+
#
|
158
|
+
def _add_load_project_guard_rc_hook(guard_rc)
|
159
|
+
Pry.config.hooks.add_hook :when_started, :load_project_guard_rc do
|
160
|
+
load guard_rc if guard_rc.exist?
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Add a `after_eval` hook that restores visibility after a command is
|
165
|
+
# eval.
|
166
|
+
def _add_restore_visibility_hook
|
167
|
+
Pry.config.hooks.add_hook :after_eval, :restore_visibility do
|
168
|
+
@terminal_settings.echo
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def _setup_commands
|
173
|
+
_replace_reset_command
|
174
|
+
_create_run_all_command
|
175
|
+
_create_command_aliases
|
176
|
+
_create_guard_commands
|
177
|
+
_create_group_commands
|
178
|
+
end
|
179
|
+
|
180
|
+
# Replaces reset defined inside of Pry with a reset that
|
181
|
+
# instead restarts guard.
|
182
|
+
#
|
183
|
+
def _replace_reset_command
|
184
|
+
Pry.commands.command "reset", "Reset the Guard to a clean state." do
|
185
|
+
output.puts "Guard reset."
|
186
|
+
exec "guard"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Creates a command that triggers the `:run_all` action
|
191
|
+
# when the command is empty (just pressing enter on the
|
192
|
+
# beginning of a line).
|
193
|
+
#
|
194
|
+
def _create_run_all_command
|
195
|
+
Pry.commands.block_command(/^$/, "Hit enter to run all") do
|
196
|
+
Pry.run_command "all"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Creates command aliases for the commands: `help`, `reload`, `change`,
|
201
|
+
# `scope`, `notification`, `pause`, `exit` and `quit`, which will be the
|
202
|
+
# first letter of the command.
|
203
|
+
#
|
204
|
+
def _create_command_aliases
|
205
|
+
SHORTCUTS.each do |command, shortcut|
|
206
|
+
Pry.commands.alias_command shortcut, command.to_s
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Create a shorthand command to run the `:run_all`
|
211
|
+
# action on a specific Guard plugin. For example,
|
212
|
+
# when guard-rspec is available, then a command
|
213
|
+
# `rspec` is created that runs `all rspec`.
|
214
|
+
#
|
215
|
+
def _create_guard_commands
|
216
|
+
::Guard.plugins.each do |guard_plugin|
|
217
|
+
cmd = "Run all #{ guard_plugin.title }"
|
218
|
+
Pry.commands.create_command guard_plugin.name, cmd do
|
219
|
+
group "Guard"
|
220
|
+
|
221
|
+
def process
|
222
|
+
Pry.run_command "all #{ match }"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Create a shorthand command to run the `:run_all`
|
229
|
+
# action on a specific Guard group. For example,
|
230
|
+
# when you have a group `frontend`, then a command
|
231
|
+
# `frontend` is created that runs `all frontend`.
|
232
|
+
#
|
233
|
+
def _create_group_commands
|
234
|
+
::Guard.groups.each do |group|
|
235
|
+
next if group.name == :default
|
236
|
+
|
237
|
+
cmd = "Run all #{ group.title }"
|
238
|
+
Pry.commands.create_command group.name.to_s, cmd do
|
239
|
+
group "Guard"
|
240
|
+
|
241
|
+
def process
|
242
|
+
Pry.run_command "all #{ match }"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Configures the pry prompt to see `guard` instead of
|
249
|
+
# `pry`.
|
250
|
+
#
|
251
|
+
def _configure_prompt
|
252
|
+
Pry.config.prompt = [_prompt(">"), _prompt("*")]
|
253
|
+
end
|
254
|
+
|
255
|
+
# Returns the plugins scope, or the groups scope ready for display in the
|
256
|
+
# prompt.
|
257
|
+
#
|
258
|
+
def _scope_for_prompt
|
259
|
+
scope_name = [:plugins, :groups].detect do |name|
|
260
|
+
! ::Guard.scope[name].empty?
|
261
|
+
end
|
262
|
+
scope_name ? "#{_join_scope_for_prompt(scope_name)} " : ""
|
263
|
+
end
|
264
|
+
|
265
|
+
# Joins the scope corresponding to the given scope name with commas.
|
266
|
+
#
|
267
|
+
def _join_scope_for_prompt(scope_name)
|
268
|
+
::Guard.scope[scope_name].map(&:title).join(",")
|
269
|
+
end
|
270
|
+
|
271
|
+
# Returns a proc that will return itself a string ending with the given
|
272
|
+
# `ending_char` when called.
|
273
|
+
#
|
274
|
+
def _prompt(ending_char)
|
275
|
+
proc do |target_self, nest_level, pry|
|
276
|
+
history = pry.input_array.size
|
277
|
+
process = ::Guard.listener.paused? ? "pause" : "guard"
|
278
|
+
level = ":#{ nest_level }" unless nest_level.zero?
|
279
|
+
|
280
|
+
"[#{ history }] #{ _scope_for_prompt }#{ process }"\
|
281
|
+
"(#{ _clip_name(target_self) })#{ level }#{ ending_char } "
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def _clip_name(target)
|
286
|
+
Pry.view_clip(target)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
require "guard/commands/all"
|
2
|
+
require "guard/commands/change"
|
3
|
+
require "guard/commands/notification"
|
4
|
+
require "guard/commands/pause"
|
5
|
+
require "guard/commands/reload"
|
6
|
+
require "guard/commands/scope"
|
7
|
+
require "guard/commands/show"
|
8
|
+
|
9
|
+
require "guard/jobs/base"
|
10
|
+
|
11
|
+
module Guard
|
12
|
+
module Jobs
|
13
|
+
class TerminalSettings
|
14
|
+
def initialize
|
15
|
+
@settings = nil
|
16
|
+
@works = ::Guard::Sheller.run("hash", "stty") || false
|
17
|
+
end
|
18
|
+
|
19
|
+
def restore
|
20
|
+
return unless configurable? && @settings
|
21
|
+
::Guard::Sheller.run("stty #{ @setting } 2>#{ DEV_NULL }")
|
22
|
+
end
|
23
|
+
|
24
|
+
def save
|
25
|
+
return unless configurable?
|
26
|
+
@settings = ::Guard::Sheller.stdout("stty -g 2>#{ DEV_NULL }").chomp
|
27
|
+
end
|
28
|
+
|
29
|
+
def echo
|
30
|
+
return unless configurable?
|
31
|
+
::Guard::Sheller.run("stty echo 2>#{ DEV_NULL }")
|
32
|
+
end
|
33
|
+
|
34
|
+
def configurable?
|
35
|
+
@works
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class PryWrapper < Base
|
40
|
+
# The default Ruby script to configure Guard Pry if the option `:guard_rc`
|
41
|
+
# is not defined.
|
42
|
+
GUARD_RC = "~/.guardrc"
|
43
|
+
|
44
|
+
# The default Guard Pry history file if the option `:history_file` is not
|
45
|
+
# defined.
|
46
|
+
HISTORY_FILE = "~/.guard_history"
|
47
|
+
|
48
|
+
# List of shortcuts for each interactor command
|
49
|
+
SHORTCUTS = {
|
50
|
+
help: "h",
|
51
|
+
all: "a",
|
52
|
+
reload: "r",
|
53
|
+
change: "c",
|
54
|
+
show: "s",
|
55
|
+
scope: "o",
|
56
|
+
notification: "n",
|
57
|
+
pause: "p",
|
58
|
+
exit: "e",
|
59
|
+
quit: "q"
|
60
|
+
}
|
61
|
+
|
62
|
+
def initialize(options)
|
63
|
+
@mutex = Mutex.new
|
64
|
+
@thread = nil
|
65
|
+
@terminal_settings = TerminalSettings.new
|
66
|
+
|
67
|
+
_setup(options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def foreground
|
71
|
+
::Guard::UI.debug "Start interactor"
|
72
|
+
@terminal_settings.save
|
73
|
+
|
74
|
+
_start_pry
|
75
|
+
@thread.join
|
76
|
+
thread = @thread
|
77
|
+
thread.nil? ? :stopped : :exit
|
78
|
+
ensure
|
79
|
+
::Guard::UI.reset_line
|
80
|
+
::Guard::UI.debug "Interactor was stopped or killed"
|
81
|
+
@terminal_settings.restore
|
82
|
+
end
|
83
|
+
|
84
|
+
def background
|
85
|
+
_kill_pry
|
86
|
+
end
|
87
|
+
|
88
|
+
def handle_interrupt
|
89
|
+
thread = @thread
|
90
|
+
fail Interrupt unless thread
|
91
|
+
thread.raise Interrupt
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
attr_reader :thread
|
97
|
+
|
98
|
+
def _start_pry
|
99
|
+
@mutex.synchronize do
|
100
|
+
unless @thread
|
101
|
+
@thread = Thread.new { Pry.start }
|
102
|
+
@thread.join(0.5) # give pry a chance to start
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def _kill_pry
|
108
|
+
@mutex.synchronize do
|
109
|
+
unless @thread.nil?
|
110
|
+
@thread.kill
|
111
|
+
@thread = nil # set to nil so we know we were killed
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def _setup(options)
|
117
|
+
Pry.config.should_load_rc = false
|
118
|
+
Pry.config.should_load_local_rc = false
|
119
|
+
history_file_path = options[:history_file] || HISTORY_FILE
|
120
|
+
Pry.config.history.file = File.expand_path(history_file_path)
|
121
|
+
|
122
|
+
_add_hooks
|
123
|
+
|
124
|
+
Guard::Commands::All.import
|
125
|
+
Guard::Commands::Change.import
|
126
|
+
Guard::Commands::Notification.import
|
127
|
+
Guard::Commands::Pause.import
|
128
|
+
Guard::Commands::Reload.import
|
129
|
+
Guard::Commands::Show.import
|
130
|
+
Guard::Commands::Scope.import
|
131
|
+
|
132
|
+
_setup_commands
|
133
|
+
_configure_prompt
|
134
|
+
end
|
135
|
+
|
136
|
+
# Add Pry hooks:
|
137
|
+
#
|
138
|
+
# * Load `~/.guardrc` within each new Pry session.
|
139
|
+
# * Load project's `.guardrc` within each new Pry session.
|
140
|
+
# * Restore prompt after each evaluation.
|
141
|
+
#
|
142
|
+
def _add_hooks
|
143
|
+
_add_load_guard_rc_hook
|
144
|
+
_add_load_project_guard_rc_hook
|
145
|
+
_add_restore_visibility_hook if @terminal_settings.configurable?
|
146
|
+
end
|
147
|
+
|
148
|
+
# Add a `when_started` hook that loads a global .guardrc if it exists.
|
149
|
+
#
|
150
|
+
def _add_load_guard_rc_hook
|
151
|
+
Pry.config.hooks.add_hook :when_started, :load_guard_rc do
|
152
|
+
(self.class.options[:guard_rc] || GUARD_RC).tap do |p|
|
153
|
+
load p if File.exist?(File.expand_path(p))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Add a `when_started` hook that loads a project .guardrc if it exists.
|
159
|
+
#
|
160
|
+
def _add_load_project_guard_rc_hook
|
161
|
+
Pry.config.hooks.add_hook :when_started, :load_project_guard_rc do
|
162
|
+
project_guard_rc = Dir.pwd + "/.guardrc"
|
163
|
+
load project_guard_rc if File.exist?(project_guard_rc)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Add a `after_eval` hook that restores visibility after a command is
|
168
|
+
# eval.
|
169
|
+
def _add_restore_visibility_hook
|
170
|
+
Pry.config.hooks.add_hook :after_eval, :restore_visibility do
|
171
|
+
@terminal_settings.echo
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def _setup_commands
|
176
|
+
_replace_reset_command
|
177
|
+
_create_run_all_command
|
178
|
+
_create_command_aliases
|
179
|
+
_create_guard_commands
|
180
|
+
_create_group_commands
|
181
|
+
end
|
182
|
+
|
183
|
+
# Replaces reset defined inside of Pry with a reset that
|
184
|
+
# instead restarts guard.
|
185
|
+
#
|
186
|
+
def _replace_reset_command
|
187
|
+
Pry.commands.command "reset", "Reset the Guard to a clean state." do
|
188
|
+
output.puts "Guard reset."
|
189
|
+
exec "guard"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Creates a command that triggers the `:run_all` action
|
194
|
+
# when the command is empty (just pressing enter on the
|
195
|
+
# beginning of a line).
|
196
|
+
#
|
197
|
+
def _create_run_all_command
|
198
|
+
Pry.commands.block_command(/^$/, "Hit enter to run all") do
|
199
|
+
Pry.run_command "all"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Creates command aliases for the commands: `help`, `reload`, `change`,
|
204
|
+
# `scope`, `notification`, `pause`, `exit` and `quit`, which will be the
|
205
|
+
# first letter of the command.
|
206
|
+
#
|
207
|
+
def _create_command_aliases
|
208
|
+
SHORTCUTS.each do |command, shortcut|
|
209
|
+
Pry.commands.alias_command shortcut, command.to_s
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Create a shorthand command to run the `:run_all`
|
214
|
+
# action on a specific Guard plugin. For example,
|
215
|
+
# when guard-rspec is available, then a command
|
216
|
+
# `rspec` is created that runs `all rspec`.
|
217
|
+
#
|
218
|
+
def _create_guard_commands
|
219
|
+
::Guard.plugins.each do |guard_plugin|
|
220
|
+
cmd = "Run all #{ guard_plugin.title }"
|
221
|
+
Pry.commands.create_command guard_plugin.name, cmd do
|
222
|
+
group "Guard"
|
223
|
+
|
224
|
+
def process
|
225
|
+
Pry.run_command "all #{ match }"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Create a shorthand command to run the `:run_all`
|
232
|
+
# action on a specific Guard group. For example,
|
233
|
+
# when you have a group `frontend`, then a command
|
234
|
+
# `frontend` is created that runs `all frontend`.
|
235
|
+
#
|
236
|
+
def _create_group_commands
|
237
|
+
::Guard.groups.each do |group|
|
238
|
+
next if group.name == :default
|
239
|
+
|
240
|
+
cmd = "Run all #{ group.title }"
|
241
|
+
Pry.commands.create_command group.name.to_s, cmd do
|
242
|
+
group "Guard"
|
243
|
+
|
244
|
+
def process
|
245
|
+
Pry.run_command "all #{ match }"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Configures the pry prompt to see `guard` instead of
|
252
|
+
# `pry`.
|
253
|
+
#
|
254
|
+
def _configure_prompt
|
255
|
+
Pry.config.prompt = [_prompt(">"), _prompt("*")]
|
256
|
+
end
|
257
|
+
|
258
|
+
# Returns the plugins scope, or the groups scope ready for display in the
|
259
|
+
# prompt.
|
260
|
+
#
|
261
|
+
def _scope_for_prompt
|
262
|
+
scope_name = [:plugins, :groups].detect do |name|
|
263
|
+
! ::Guard.scope[name].empty?
|
264
|
+
end
|
265
|
+
scope_name ? "#{_join_scope_for_prompt(scope_name)} " : ""
|
266
|
+
end
|
267
|
+
|
268
|
+
# Joins the scope corresponding to the given scope name with commas.
|
269
|
+
#
|
270
|
+
def _join_scope_for_prompt(scope_name)
|
271
|
+
::Guard.scope[scope_name].map(&:title).join(",")
|
272
|
+
end
|
273
|
+
|
274
|
+
# Returns a proc that will return itself a string ending with the given
|
275
|
+
# `ending_char` when called.
|
276
|
+
#
|
277
|
+
def _prompt(ending_char)
|
278
|
+
proc do |target_self, nest_level, pry|
|
279
|
+
history = pry.input_array.size
|
280
|
+
process = ::Guard.listener.paused? ? "pause" : "guard"
|
281
|
+
level = ":#{ nest_level }" unless nest_level.zero?
|
282
|
+
|
283
|
+
"[#{ history }] #{ _scope_for_prompt }#{ process }"\
|
284
|
+
"(#{ _clip_name(target_self) })#{ level }#{ ending_char } "
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def _clip_name(target)
|
289
|
+
Pry.view_clip(target)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|