tmuxinator 0.9.0 → 0.10.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/bin/tmuxinator +1 -1
- data/lib/tmuxinator.rb +6 -7
- data/lib/tmuxinator/assets/sample.yml +13 -1
- data/lib/tmuxinator/assets/template-stop.erb +11 -0
- data/lib/tmuxinator/assets/template.erb +15 -1
- data/lib/tmuxinator/cli.rb +85 -15
- data/lib/tmuxinator/config.rb +74 -30
- data/lib/tmuxinator/deprecations.rb +8 -0
- data/lib/tmuxinator/doctor.rb +17 -0
- data/lib/tmuxinator/hooks.rb +14 -0
- data/lib/tmuxinator/hooks/project.rb +42 -0
- data/lib/tmuxinator/pane.rb +26 -18
- data/lib/tmuxinator/project.rb +113 -48
- data/lib/tmuxinator/version.rb +1 -1
- data/lib/tmuxinator/wemux_support.rb +18 -9
- data/lib/tmuxinator/window.rb +42 -26
- data/spec/fixtures/TMUXINATOR_CONFIG/TMUXINATOR_CONFIG.yml +0 -0
- data/spec/fixtures/dot-tmuxinator/both.yml +0 -0
- data/spec/fixtures/dot-tmuxinator/dup/local-dup.yml +0 -0
- data/spec/fixtures/dot-tmuxinator/home.yml +0 -0
- data/spec/fixtures/dot-tmuxinator/local-dup.yml +0 -0
- data/spec/fixtures/sample.yml +0 -1
- data/spec/fixtures/xdg-tmuxinator/both.yml +0 -0
- data/spec/fixtures/xdg-tmuxinator/xdg.yml +0 -0
- data/spec/lib/tmuxinator/cli_spec.rb +87 -13
- data/spec/lib/tmuxinator/config_spec.rb +163 -91
- data/spec/lib/tmuxinator/doctor_spec.rb +69 -0
- data/spec/lib/tmuxinator/hooks/project_spec.rb +63 -0
- data/spec/lib/tmuxinator/hooks_spec.rb +31 -0
- data/spec/lib/tmuxinator/pane_spec.rb +24 -1
- data/spec/lib/tmuxinator/project_spec.rb +58 -23
- data/spec/lib/tmuxinator/window_spec.rb +8 -6
- data/spec/spec_helper.rb +2 -1
- metadata +177 -7
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tmuxinator
|
2
|
+
class Doctor
|
3
|
+
class << self
|
4
|
+
def editor?
|
5
|
+
!ENV["EDITOR"].nil? && !ENV["EDITOR"].empty?
|
6
|
+
end
|
7
|
+
|
8
|
+
def installed?
|
9
|
+
Kernel.system("type tmux > /dev/null")
|
10
|
+
end
|
11
|
+
|
12
|
+
def shell?
|
13
|
+
!ENV["SHELL"].nil? && !ENV["SHELL"].empty?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Tmuxinator
|
2
|
+
module Hooks
|
3
|
+
module Project
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# Commands specified in this hook run when "tmuxinator start project"
|
7
|
+
# command is issued
|
8
|
+
def hook_on_project_start
|
9
|
+
# this method can only be used from inside Tmuxinator::Project
|
10
|
+
Tmuxinator::Hooks.commands_from self, "on_project_start"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Commands specified in this hook run when "tmuxinator start project"
|
14
|
+
# command is issued and there is no tmux session available named "project"
|
15
|
+
def hook_on_project_first_start
|
16
|
+
# this method can only be used from inside Tmuxinator::Project
|
17
|
+
Tmuxinator::Hooks.commands_from self, "on_project_first_start"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Commands specified in this hook run when "tmuxinator start project"
|
21
|
+
# command is issued and there is no tmux session available named "project"
|
22
|
+
def hook_on_project_restart
|
23
|
+
# this method can only be used from inside Tmuxinator::Project
|
24
|
+
Tmuxinator::Hooks.commands_from self, "on_project_restart"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Commands specified in this hook run when you exit from a project ( aka
|
28
|
+
# detach from a tmux session )
|
29
|
+
def hook_on_project_exit
|
30
|
+
# this method can only be used from inside Tmuxinator::Project
|
31
|
+
Tmuxinator::Hooks.commands_from self, "on_project_exit"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Command specified in this hook run when "tmuxinator stop project"
|
35
|
+
# command is issued
|
36
|
+
def hook_on_project_stop
|
37
|
+
# this method can only be used from inside Tmuxinator::Project
|
38
|
+
Tmuxinator::Hooks.commands_from self, "on_project_stop"
|
39
|
+
end
|
40
|
+
end # End Project
|
41
|
+
end # End Hooks
|
42
|
+
end # End Tmuxinator
|
data/lib/tmuxinator/pane.rb
CHANGED
@@ -10,39 +10,37 @@ module Tmuxinator
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def tmux_window_and_pane_target
|
13
|
-
|
14
|
-
y = index + project.base_index
|
15
|
-
"#{project.name}:#{x}.#{y}"
|
13
|
+
"#{project.name}:#{window_index}.#{pane_index}"
|
16
14
|
end
|
17
15
|
|
18
16
|
def tmux_pre_command
|
19
|
-
|
20
|
-
|
21
|
-
t = tmux_window_and_pane_target
|
22
|
-
e = tab.pre.shellescape
|
23
|
-
"#{project.tmux} send-keys -t #{t} #{e} C-m"
|
17
|
+
_send_target(tab.pre.shellescape) if tab.pre
|
24
18
|
end
|
25
19
|
|
26
20
|
def tmux_pre_window_command
|
27
|
-
|
28
|
-
|
29
|
-
t = tmux_window_and_pane_target
|
30
|
-
e = project.pre_window.shellescape
|
31
|
-
"#{project.tmux} send-keys -t #{t} #{e} C-m"
|
21
|
+
_send_target(project.pre_window.shellescape) if project.pre_window
|
32
22
|
end
|
33
23
|
|
34
24
|
def tmux_main_command(command)
|
35
25
|
if command
|
36
|
-
|
37
|
-
y = index + tab.project.base_index
|
38
|
-
e = command.shellescape
|
39
|
-
n = project.name
|
40
|
-
"#{project.tmux} send-keys -t #{n}:#{x}.#{y} #{e} C-m"
|
26
|
+
_send_target(command.shellescape)
|
41
27
|
else
|
42
28
|
""
|
43
29
|
end
|
44
30
|
end
|
45
31
|
|
32
|
+
def name
|
33
|
+
project.name
|
34
|
+
end
|
35
|
+
|
36
|
+
def window_index
|
37
|
+
tab.index + project.base_index
|
38
|
+
end
|
39
|
+
|
40
|
+
def pane_index
|
41
|
+
index + tab.project.base_index
|
42
|
+
end
|
43
|
+
|
46
44
|
def tmux_split_command
|
47
45
|
path = if tab.root?
|
48
46
|
"#{Tmuxinator::Config.default_path_option} #{tab.root}"
|
@@ -53,5 +51,15 @@ module Tmuxinator
|
|
53
51
|
def last?
|
54
52
|
index == tab.panes.length - 1
|
55
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def _send_target(e)
|
58
|
+
_send_keys(tmux_window_and_pane_target, e)
|
59
|
+
end
|
60
|
+
|
61
|
+
def _send_keys(t, e)
|
62
|
+
"#{project.tmux} send-keys -t #{t} #{e} C-m"
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
data/lib/tmuxinator/project.rb
CHANGED
@@ -2,6 +2,7 @@ module Tmuxinator
|
|
2
2
|
class Project
|
3
3
|
include Tmuxinator::Util
|
4
4
|
include Tmuxinator::Deprecations
|
5
|
+
include Tmuxinator::Hooks::Project
|
5
6
|
include Tmuxinator::WemuxSupport
|
6
7
|
|
7
8
|
RBENVRVM_DEP_MSG = <<-M
|
@@ -19,12 +20,20 @@ module Tmuxinator
|
|
19
20
|
SYNC_DEP_MSG = <<-M
|
20
21
|
DEPRECATION: The synchronize option's current default behaviour is to
|
21
22
|
enable pane synchronization before running commands. In a future release,
|
22
|
-
the default
|
23
|
+
the default synchronization option will be `after`, i.e. synchronization of
|
23
24
|
panes will occur after the commands described in each of the panes
|
24
25
|
have run. At that time, the current behavior will need to be explicitly
|
25
26
|
enabled, using the `synchronize: before` option. To use this behaviour
|
26
27
|
now, use the 'synchronize: after' option.
|
27
28
|
M
|
29
|
+
PRE_DEP_MSG = <<-M
|
30
|
+
DEPRECATION: the pre option has been replaced by project hooks and will
|
31
|
+
not be supported anymore.
|
32
|
+
M
|
33
|
+
POST_DEP_MSG = <<-M
|
34
|
+
DEPRECATION: the post option has been replaced by project hooks and will
|
35
|
+
not be supported anymore.
|
36
|
+
M
|
28
37
|
|
29
38
|
attr_reader :yaml
|
30
39
|
attr_reader :force_attach
|
@@ -41,8 +50,8 @@ module Tmuxinator
|
|
41
50
|
|
42
51
|
content = Erubis::Eruby.new(raw_content).result(binding)
|
43
52
|
YAML.load(content)
|
44
|
-
rescue SyntaxError, StandardError
|
45
|
-
raise "Failed to parse config file
|
53
|
+
rescue SyntaxError, StandardError => error
|
54
|
+
raise "Failed to parse config file: #{error.message}"
|
46
55
|
end
|
47
56
|
|
48
57
|
new(yaml, options)
|
@@ -62,9 +71,9 @@ module Tmuxinator
|
|
62
71
|
|
63
72
|
def validate!
|
64
73
|
raise "Your project file should include some windows." \
|
65
|
-
unless
|
74
|
+
unless windows?
|
66
75
|
raise "Your project file didn't specify a 'project_name'" \
|
67
|
-
unless
|
76
|
+
unless name?
|
68
77
|
self
|
69
78
|
end
|
70
79
|
|
@@ -86,8 +95,16 @@ module Tmuxinator
|
|
86
95
|
end
|
87
96
|
|
88
97
|
def render
|
89
|
-
|
90
|
-
|
98
|
+
self.class.render_template(Tmuxinator::Config.template, binding)
|
99
|
+
end
|
100
|
+
|
101
|
+
def kill
|
102
|
+
self.class.render_template(Tmuxinator::Config.stop_template, binding)
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.render_template(template, bndg)
|
106
|
+
content = File.read(template)
|
107
|
+
Erubis::Eruby.new(content).result(bndg)
|
91
108
|
end
|
92
109
|
|
93
110
|
def windows
|
@@ -100,52 +117,45 @@ module Tmuxinator
|
|
100
117
|
|
101
118
|
def root
|
102
119
|
root = yaml["project_root"] || yaml["root"]
|
103
|
-
|
120
|
+
blank?(root) ? nil : File.expand_path(root).shellescape
|
104
121
|
end
|
105
122
|
|
106
123
|
def name
|
107
124
|
name = custom_name || yaml["project_name"] || yaml["name"]
|
108
|
-
|
125
|
+
blank?(name) ? nil : name.to_s.shellescape
|
109
126
|
end
|
110
127
|
|
111
128
|
def pre
|
112
129
|
pre_config = yaml["pre"]
|
113
|
-
|
114
|
-
pre_config.join("; ")
|
115
|
-
else
|
116
|
-
pre_config
|
117
|
-
end
|
130
|
+
parsed_parameters(pre_config)
|
118
131
|
end
|
119
132
|
|
120
133
|
def attach?
|
121
|
-
if yaml["attach"].nil?
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
134
|
+
yaml_attach = if yaml["attach"].nil?
|
135
|
+
true
|
136
|
+
else
|
137
|
+
yaml["attach"]
|
138
|
+
end
|
126
139
|
attach = force_attach || !force_detach && yaml_attach
|
127
140
|
attach
|
128
141
|
end
|
129
142
|
|
130
143
|
def pre_window
|
131
|
-
if rbenv?
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
144
|
+
params = if rbenv?
|
145
|
+
"rbenv shell #{yaml['rbenv']}"
|
146
|
+
elsif rvm?
|
147
|
+
"rvm use #{yaml['rvm']}"
|
148
|
+
elsif pre_tab?
|
149
|
+
yaml["pre_tab"]
|
150
|
+
else
|
151
|
+
yaml["pre_window"]
|
152
|
+
end
|
153
|
+
parsed_parameters(params)
|
140
154
|
end
|
141
155
|
|
142
156
|
def post
|
143
157
|
post_config = yaml["post"]
|
144
|
-
|
145
|
-
post_config.join("; ")
|
146
|
-
else
|
147
|
-
post_config
|
148
|
-
end
|
158
|
+
parsed_parameters(post_config)
|
149
159
|
end
|
150
160
|
|
151
161
|
def tmux
|
@@ -192,7 +202,7 @@ module Tmuxinator
|
|
192
202
|
end
|
193
203
|
|
194
204
|
def base_index
|
195
|
-
|
205
|
+
get_base_index.to_i
|
196
206
|
end
|
197
207
|
|
198
208
|
def pane_base_index
|
@@ -200,11 +210,11 @@ module Tmuxinator
|
|
200
210
|
end
|
201
211
|
|
202
212
|
def startup_window
|
203
|
-
yaml[
|
213
|
+
"#{name}:#{yaml['startup_window'] || base_index}"
|
204
214
|
end
|
205
215
|
|
206
216
|
def startup_pane
|
207
|
-
yaml[
|
217
|
+
"#{startup_window}.#{yaml['startup_pane'] || pane_base_index}"
|
208
218
|
end
|
209
219
|
|
210
220
|
def tmux_options?
|
@@ -228,11 +238,7 @@ module Tmuxinator
|
|
228
238
|
end
|
229
239
|
|
230
240
|
def send_pane_command(cmd, window_index, _pane_index)
|
231
|
-
|
232
|
-
""
|
233
|
-
else
|
234
|
-
"#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
|
235
|
-
end
|
241
|
+
send_keys(cmd, window_index)
|
236
242
|
end
|
237
243
|
|
238
244
|
def send_keys(cmd, window_index)
|
@@ -244,12 +250,61 @@ module Tmuxinator
|
|
244
250
|
end
|
245
251
|
|
246
252
|
def deprecations
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
+
deprecation_checks.zip(deprecation_messages).
|
254
|
+
inject([]) do |deps, (chk, msg)|
|
255
|
+
deps << msg if chk
|
256
|
+
deps
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def deprecation_checks
|
261
|
+
[
|
262
|
+
rvm_or_rbenv?,
|
263
|
+
tabs?,
|
264
|
+
cli_args?,
|
265
|
+
legacy_synchronize?,
|
266
|
+
pre?,
|
267
|
+
post?
|
268
|
+
]
|
269
|
+
end
|
270
|
+
|
271
|
+
def deprecation_messages
|
272
|
+
[
|
273
|
+
RBENVRVM_DEP_MSG,
|
274
|
+
TABS_DEP_MSG,
|
275
|
+
CLIARGS_DEP_MSG,
|
276
|
+
SYNC_DEP_MSG,
|
277
|
+
PRE_DEP_MSG,
|
278
|
+
POST_DEP_MSG
|
279
|
+
]
|
280
|
+
end
|
281
|
+
|
282
|
+
def rbenv?
|
283
|
+
yaml["rbenv"]
|
284
|
+
end
|
285
|
+
|
286
|
+
def rvm?
|
287
|
+
yaml["rvm"]
|
288
|
+
end
|
289
|
+
|
290
|
+
def rvm_or_rbenv?
|
291
|
+
rvm? || rbenv?
|
292
|
+
end
|
293
|
+
|
294
|
+
def tabs?
|
295
|
+
yaml["tabs"]
|
296
|
+
end
|
297
|
+
|
298
|
+
def cli_args?
|
299
|
+
yaml["cli_args"]
|
300
|
+
end
|
301
|
+
|
302
|
+
def pre?
|
303
|
+
yaml["pre"]
|
304
|
+
end
|
305
|
+
|
306
|
+
def post?
|
307
|
+
yaml["post"]
|
253
308
|
end
|
254
309
|
|
255
310
|
def get_pane_base_index
|
@@ -261,7 +316,9 @@ module Tmuxinator
|
|
261
316
|
end
|
262
317
|
|
263
318
|
def show_tmux_options
|
264
|
-
"#{tmux} start-server\\;
|
319
|
+
"#{tmux} start-server\\; " \
|
320
|
+
"show-option -g base-index\\; " \
|
321
|
+
"show-window-option -g pane-base-index\\;"
|
265
322
|
end
|
266
323
|
|
267
324
|
def tmux_new_session_command
|
@@ -275,6 +332,10 @@ module Tmuxinator
|
|
275
332
|
|
276
333
|
private
|
277
334
|
|
335
|
+
def blank?(object)
|
336
|
+
(object.respond_to?(:empty?) && object.empty?) || !object
|
337
|
+
end
|
338
|
+
|
278
339
|
def tmux_config
|
279
340
|
@tmux_config ||= extract_tmux_config
|
280
341
|
end
|
@@ -306,5 +367,9 @@ module Tmuxinator
|
|
306
367
|
def window_options
|
307
368
|
yaml["windows"].map(&:values).flatten
|
308
369
|
end
|
370
|
+
|
371
|
+
def parsed_parameters(parameters)
|
372
|
+
parameters.is_a?(Array) ? parameters.join("; ") : parameters
|
373
|
+
end
|
309
374
|
end
|
310
375
|
end
|
data/lib/tmuxinator/version.rb
CHANGED
@@ -1,22 +1,31 @@
|
|
1
1
|
module Tmuxinator
|
2
2
|
module WemuxSupport
|
3
|
+
COMMAND = "wemux".freeze
|
4
|
+
|
3
5
|
def wemux?
|
4
|
-
yaml["tmux_command"] ==
|
6
|
+
yaml["tmux_command"] == COMMAND
|
5
7
|
end
|
6
8
|
|
7
9
|
def load_wemux_overrides
|
10
|
+
override_render!
|
11
|
+
override_commands!
|
12
|
+
end
|
13
|
+
|
14
|
+
def override_render!
|
8
15
|
class_eval do
|
9
16
|
define_method :render do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
define_method :name do
|
15
|
-
"wemux"
|
17
|
+
Tmuxinator::Project.render_template(
|
18
|
+
Tmuxinator::Config.wemux_template,
|
19
|
+
binding
|
20
|
+
)
|
16
21
|
end
|
22
|
+
end
|
23
|
+
end
|
17
24
|
|
18
|
-
|
19
|
-
|
25
|
+
def override_commands!
|
26
|
+
class_eval do
|
27
|
+
%i[name tmux].each do |m|
|
28
|
+
define_method(m) { COMMAND }
|
20
29
|
end
|
21
30
|
end
|
22
31
|
end
|