tmuxinator 3.1.2 → 3.2.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/bin/tmuxinator +3 -1
- data/completion/tmuxinator.bash +1 -2
- data/completion/tmuxinator.fish +0 -2
- data/lib/tmuxinator/assets/template.erb +22 -1
- data/lib/tmuxinator/cli.rb +10 -9
- data/lib/tmuxinator/config.rb +19 -7
- data/lib/tmuxinator/deprecations.rb +2 -0
- data/lib/tmuxinator/doctor.rb +2 -0
- data/lib/tmuxinator/hooks/project.rb +5 -3
- data/lib/tmuxinator/hooks.rb +2 -0
- data/lib/tmuxinator/pane.rb +7 -5
- data/lib/tmuxinator/project.rb +74 -11
- data/lib/tmuxinator/tmux_version.rb +3 -1
- data/lib/tmuxinator/util.rb +2 -0
- data/lib/tmuxinator/version.rb +3 -1
- data/lib/tmuxinator/wemux_support.rb +2 -0
- data/lib/tmuxinator/window.rb +2 -0
- data/lib/tmuxinator.rb +3 -1
- data/spec/factories/projects.rb +2 -0
- data/spec/lib/tmuxinator/cli_spec.rb +16 -14
- data/spec/lib/tmuxinator/config_spec.rb +46 -20
- data/spec/lib/tmuxinator/doctor_spec.rb +2 -0
- data/spec/lib/tmuxinator/hooks/project_spec.rb +2 -0
- data/spec/lib/tmuxinator/hooks_spec.rb +2 -0
- data/spec/lib/tmuxinator/pane_spec.rb +4 -2
- data/spec/lib/tmuxinator/project_spec.rb +76 -1
- data/spec/lib/tmuxinator/util_spec.rb +2 -0
- data/spec/lib/tmuxinator/wemux_support_spec.rb +2 -0
- data/spec/lib/tmuxinator/window_spec.rb +2 -0
- data/spec/matchers/pane_matcher.rb +2 -0
- data/spec/spec_helper.rb +3 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 837a353050a6ac064ea463e3e33113a845a1b555a9069c2514045b59440a634b
|
4
|
+
data.tar.gz: '008ef11a9c0734010632d58c06ea63f9ebc1d46eba0cfb4153c1dc63b1c7b6bc'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81c8a46ec5380f78d7db741ee707d69e25ac5d6edb56892e861ebfe06131d1c7d2725f6ce4e8880192564e761ff4e2a4de50087b01addfa0d3a6305df444c4f1
|
7
|
+
data.tar.gz: 39c755d7aa5c61ff52b225ab1a2a3f5f7eef68c58cfefcd421c217f350e304b2b3f920df61af349d004e7cc53eff61d69e84afd9179fd113a4ca86dda185f039
|
data/bin/tmuxinator
CHANGED
data/completion/tmuxinator.bash
CHANGED
data/completion/tmuxinator.fish
CHANGED
@@ -20,5 +20,3 @@ complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_comman
|
|
20
20
|
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command open' -a "(__fish_tmuxinator_program completions open)"
|
21
21
|
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command copy' -a "(__fish_tmuxinator_program completions copy)"
|
22
22
|
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command delete' -a "(__fish_tmuxinator_program completions delete)"
|
23
|
-
|
24
|
-
abbr --add mux "tmuxinator"
|
@@ -21,9 +21,15 @@ cd <%= root || "." %>
|
|
21
21
|
|
22
22
|
# Create the session and the first window. Manually switch to root
|
23
23
|
# directory if required to support tmux < 1.9
|
24
|
-
TMUX= <%= tmux_new_session_command %>
|
25
24
|
<% if windows.first.root? %>
|
25
|
+
<% if Tmuxinator::Config.version < 1.9 %>
|
26
|
+
TMUX= <%= tmux_new_session_command %>
|
26
27
|
<%= windows.first.tmux_window_command_prefix %> <%= "cd #{windows.first.root}".shellescape %> C-m
|
28
|
+
<%- else -%>
|
29
|
+
TMUX= <%= tmux_new_session_command %> -c <%= windows.first.root.shellescape %>
|
30
|
+
<% end %>
|
31
|
+
<%- else -%>
|
32
|
+
TMUX= <%= tmux_new_session_command %>
|
27
33
|
<% end %>
|
28
34
|
|
29
35
|
<% if Tmuxinator::Config.version < 1.7 %>
|
@@ -33,6 +39,15 @@ cd <%= root || "." %>
|
|
33
39
|
<% end %>
|
34
40
|
<% end %>
|
35
41
|
|
42
|
+
<% if enable_pane_titles? %>
|
43
|
+
<% if Tmuxinator::Config.version < 2.6 %>
|
44
|
+
<%= pane_titles_not_supported_warning %>
|
45
|
+
<% end %>
|
46
|
+
<% if pane_title_position? && !pane_title_position_valid? %>
|
47
|
+
<%= pane_title_position_not_valid_warning %>
|
48
|
+
<% end %>
|
49
|
+
<% end %>
|
50
|
+
|
36
51
|
# Create other windows.
|
37
52
|
<% windows.drop(1).each do |window| %>
|
38
53
|
<%= window.tmux_new_window_command %>
|
@@ -44,6 +59,12 @@ cd <%= root || "." %>
|
|
44
59
|
<% if window.synchronize_before? %>
|
45
60
|
<%= window.tmux_synchronize_panes %>
|
46
61
|
<% end %>
|
62
|
+
|
63
|
+
<% if enable_pane_titles? && Tmuxinator::Config.version >= 2.6 %>
|
64
|
+
<%= tmux_set_pane_title_position(window.tmux_window_target) %>
|
65
|
+
<%= tmux_set_pane_title_format(window.tmux_window_target) %>
|
66
|
+
<% end %>
|
67
|
+
|
47
68
|
<% unless window.panes? %>
|
48
69
|
<% if window.project.pre_window %>
|
49
70
|
<%= window.tmux_pre_window_command %>
|
data/lib/tmuxinator/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "open3"
|
2
4
|
|
3
5
|
module Tmuxinator
|
@@ -167,9 +169,8 @@ module Tmuxinator
|
|
167
169
|
end
|
168
170
|
|
169
171
|
def generate_project_file(name, path)
|
170
|
-
|
171
|
-
|
172
|
-
erb = Erubis::Eruby.new(content).result(binding)
|
172
|
+
config = Tmuxinator::Config.default_or_sample
|
173
|
+
erb = Tmuxinator::Project.render_template(config, binding)
|
173
174
|
File.open(path, "w") { |f| f.write(erb) }
|
174
175
|
path
|
175
176
|
end
|
@@ -194,7 +195,7 @@ module Tmuxinator
|
|
194
195
|
|
195
196
|
begin
|
196
197
|
Tmuxinator::Config.validate(options)
|
197
|
-
rescue => e
|
198
|
+
rescue StandardError => e
|
198
199
|
exit! e.message
|
199
200
|
end
|
200
201
|
end
|
@@ -341,12 +342,12 @@ module Tmuxinator
|
|
341
342
|
new_config_path = Tmuxinator::Config.project(new)
|
342
343
|
|
343
344
|
exit!("Project #{existing} doesn't exist!") \
|
344
|
-
unless Tmuxinator::Config.
|
345
|
+
unless Tmuxinator::Config.exist?(name: existing)
|
345
346
|
|
346
|
-
new_exists = Tmuxinator::Config.
|
347
|
+
new_exists = Tmuxinator::Config.exist?(name: new)
|
347
348
|
question = "#{new} already exists, would you like to overwrite it?"
|
348
349
|
if !new_exists || yes?(question, :red)
|
349
|
-
say "Overwriting #{new}" if Tmuxinator::Config.
|
350
|
+
say "Overwriting #{new}" if Tmuxinator::Config.exist?(name: new)
|
350
351
|
FileUtils.copy_file(existing_config_path, new_config_path)
|
351
352
|
end
|
352
353
|
|
@@ -359,7 +360,7 @@ module Tmuxinator
|
|
359
360
|
|
360
361
|
def delete(*projects)
|
361
362
|
projects.each do |project|
|
362
|
-
if Tmuxinator::Config.
|
363
|
+
if Tmuxinator::Config.exist?(name: project)
|
363
364
|
config = Tmuxinator::Config.project(project)
|
364
365
|
|
365
366
|
if yes?("Are you sure you want to delete #{project}?(y/n)", :red)
|
@@ -433,7 +434,7 @@ module Tmuxinator
|
|
433
434
|
if args.empty? && Tmuxinator::Config.local?
|
434
435
|
Tmuxinator::Cli.new.local
|
435
436
|
elsif name && !Tmuxinator::Cli::RESERVED_COMMANDS.include?(name) &&
|
436
|
-
Tmuxinator::Config.
|
437
|
+
Tmuxinator::Config.exist?(name: name)
|
437
438
|
Tmuxinator::Cli.new.start(name, *args.drop(1))
|
438
439
|
else
|
439
440
|
Tmuxinator::Cli.start(args)
|
data/lib/tmuxinator/config.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Tmuxinator
|
2
4
|
class Config
|
3
5
|
LOCAL_DEFAULTS = ["./.tmuxinator.yml", "./.tmuxinator.yaml"].freeze
|
4
|
-
NO_LOCAL_FILE_MSG =
|
5
|
-
|
6
|
-
NO_PROJECT_FOUND_MSG = "Project could not be found.".freeze
|
6
|
+
NO_LOCAL_FILE_MSG = "Project file at ./.tmuxinator.yml doesn't exist."
|
7
|
+
NO_PROJECT_FOUND_MSG = "Project could not be found."
|
7
8
|
TMUX_MASTER_VERSION = Float::INFINITY
|
8
9
|
|
9
10
|
class << self
|
@@ -12,6 +13,7 @@ module Tmuxinator
|
|
12
13
|
return environment if environment?
|
13
14
|
return xdg if xdg?
|
14
15
|
return home if home?
|
16
|
+
|
15
17
|
# No project directory specified or existent, default to XDG:
|
16
18
|
FileUtils::mkdir_p(xdg)
|
17
19
|
xdg
|
@@ -40,6 +42,7 @@ module Tmuxinator
|
|
40
42
|
def environment
|
41
43
|
environment = ENV["TMUXINATOR_CONFIG"]
|
42
44
|
return "" if environment.to_s.empty? # variable is unset (nil) or blank
|
45
|
+
|
43
46
|
FileUtils::mkdir_p(environment) unless File.directory?(environment)
|
44
47
|
environment
|
45
48
|
end
|
@@ -48,6 +51,10 @@ module Tmuxinator
|
|
48
51
|
File.directory?(environment)
|
49
52
|
end
|
50
53
|
|
54
|
+
def default_or_sample
|
55
|
+
default? ? default : sample
|
56
|
+
end
|
57
|
+
|
51
58
|
def sample
|
52
59
|
asset_path "sample.yml"
|
53
60
|
end
|
@@ -57,7 +64,7 @@ module Tmuxinator
|
|
57
64
|
end
|
58
65
|
|
59
66
|
def default?
|
60
|
-
|
67
|
+
exist?(name: "default")
|
61
68
|
end
|
62
69
|
|
63
70
|
def version
|
@@ -76,9 +83,10 @@ module Tmuxinator
|
|
76
83
|
version && version < 1.8 ? "default-path" : "-c"
|
77
84
|
end
|
78
85
|
|
79
|
-
def
|
86
|
+
def exist?(name: nil, path: nil)
|
80
87
|
return File.exist?(path) if path
|
81
88
|
return File.exist?(project(name)) if name
|
89
|
+
|
82
90
|
false
|
83
91
|
end
|
84
92
|
|
@@ -140,21 +148,24 @@ module Tmuxinator
|
|
140
148
|
|
141
149
|
def valid_project_config?(project_config)
|
142
150
|
return false unless project_config
|
143
|
-
unless
|
151
|
+
unless exist?(path: project_config)
|
144
152
|
raise "Project config (#{project_config}) doesn't exist."
|
145
153
|
end
|
154
|
+
|
146
155
|
true
|
147
156
|
end
|
148
157
|
|
149
158
|
def valid_local_project?(name)
|
150
159
|
return false if name
|
151
160
|
raise NO_LOCAL_FILE_MSG unless local?
|
161
|
+
|
152
162
|
true
|
153
163
|
end
|
154
164
|
|
155
165
|
def valid_standard_project?(name)
|
156
166
|
return false unless name
|
157
|
-
raise "Project #{name} doesn't exist." unless
|
167
|
+
raise "Project #{name} doesn't exist." unless exist?(name: name)
|
168
|
+
|
158
169
|
true
|
159
170
|
end
|
160
171
|
|
@@ -193,6 +204,7 @@ module Tmuxinator
|
|
193
204
|
# recursively searching 'directory'
|
194
205
|
def project_in(directory, name)
|
195
206
|
return nil if String(directory).empty?
|
207
|
+
|
196
208
|
projects = Dir.glob("#{directory}/**/*.{yml,yaml}").sort
|
197
209
|
projects.detect { |project| File.basename(project, ".*") == name }
|
198
210
|
end
|
data/lib/tmuxinator/doctor.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Tmuxinator
|
2
4
|
module Hooks
|
3
5
|
module Project
|
@@ -37,6 +39,6 @@ module Tmuxinator
|
|
37
39
|
# this method can only be used from inside Tmuxinator::Project
|
38
40
|
Tmuxinator::Hooks.commands_from self, "on_project_stop"
|
39
41
|
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/tmuxinator/hooks.rb
CHANGED
data/lib/tmuxinator/pane.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Tmuxinator
|
2
4
|
class Pane
|
3
5
|
attr_reader :commands, :project, :index, :tab, :title
|
@@ -7,7 +9,7 @@ module Tmuxinator
|
|
7
9
|
@index = index
|
8
10
|
@project = project
|
9
11
|
@tab = tab
|
10
|
-
@title = title
|
12
|
+
@title = title.to_s.shellescape unless title.nil?
|
11
13
|
end
|
12
14
|
|
13
15
|
def tmux_window_and_pane_target
|
@@ -61,12 +63,12 @@ module Tmuxinator
|
|
61
63
|
|
62
64
|
private
|
63
65
|
|
64
|
-
def _send_target(
|
65
|
-
_send_keys(tmux_window_and_pane_target,
|
66
|
+
def _send_target(keys)
|
67
|
+
_send_keys(tmux_window_and_pane_target, keys)
|
66
68
|
end
|
67
69
|
|
68
|
-
def _send_keys(
|
69
|
-
"#{project.tmux} send-keys -t #{
|
70
|
+
def _send_keys(target, keys)
|
71
|
+
"#{project.tmux} send-keys -t #{target} #{keys} C-m"
|
70
72
|
end
|
71
73
|
|
72
74
|
def _set_title(title)
|
data/lib/tmuxinator/project.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Tmuxinator
|
2
4
|
class Project
|
3
5
|
include Tmuxinator::Util
|
@@ -41,16 +43,14 @@ module Tmuxinator
|
|
41
43
|
|
42
44
|
def self.load(path, options = {})
|
43
45
|
yaml = begin
|
44
|
-
raw_content = File.read(path)
|
45
|
-
|
46
46
|
args = options[:args] || []
|
47
47
|
@settings = parse_settings(args)
|
48
48
|
@args = args
|
49
49
|
|
50
|
-
content =
|
50
|
+
content = render_template(path, binding)
|
51
51
|
YAML.safe_load(content, aliases: true)
|
52
|
-
|
53
|
-
|
52
|
+
rescue SyntaxError, StandardError => error
|
53
|
+
raise "Failed to parse config file: #{error.message}"
|
54
54
|
end
|
55
55
|
|
56
56
|
new(yaml, options)
|
@@ -73,6 +73,7 @@ module Tmuxinator
|
|
73
73
|
unless windows?
|
74
74
|
raise "Your project file didn't specify a 'project_name'" \
|
75
75
|
unless name?
|
76
|
+
|
76
77
|
self
|
77
78
|
end
|
78
79
|
|
@@ -103,7 +104,7 @@ module Tmuxinator
|
|
103
104
|
|
104
105
|
def self.render_template(template, bndg)
|
105
106
|
content = File.read(template)
|
106
|
-
|
107
|
+
bndg.eval(Erubi::Engine.new(content).src)
|
107
108
|
end
|
108
109
|
|
109
110
|
def windows
|
@@ -239,8 +240,8 @@ module Tmuxinator
|
|
239
240
|
!name.nil?
|
240
241
|
end
|
241
242
|
|
242
|
-
def window(
|
243
|
-
"#{name}:#{
|
243
|
+
def window(index)
|
244
|
+
"#{name}:#{index}"
|
244
245
|
end
|
245
246
|
|
246
247
|
def send_pane_command(cmd, window_index, _pane_index)
|
@@ -336,6 +337,44 @@ module Tmuxinator
|
|
336
337
|
"#{tmux} kill-session -t #{name}"
|
337
338
|
end
|
338
339
|
|
340
|
+
def enable_pane_titles?
|
341
|
+
yaml["enable_pane_titles"]
|
342
|
+
end
|
343
|
+
|
344
|
+
def tmux_set_pane_title_position(tmux_window_target)
|
345
|
+
command = set_window_option(tmux_window_target)
|
346
|
+
if pane_title_position? && pane_title_position_valid?
|
347
|
+
"#{command} pane-border-status #{yaml['pane_title_position']}"
|
348
|
+
else
|
349
|
+
"#{command} pane-border-status top"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def tmux_set_pane_title_format(tmux_window_target)
|
354
|
+
command = set_window_option(tmux_window_target)
|
355
|
+
if pane_title_format?
|
356
|
+
"#{command} pane-border-format \"#{yaml['pane_title_format']}\""
|
357
|
+
else
|
358
|
+
"#{command} pane-border-format \"\#{pane_index}: \#{pane_title}\""
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def pane_title_position_not_valid_warning
|
363
|
+
print_warning(
|
364
|
+
"The specified pane title position " +
|
365
|
+
"\"#{yaml['pane_title_position']}\" is not valid. " +
|
366
|
+
"Please choose one of: top, bottom, or off."
|
367
|
+
)
|
368
|
+
end
|
369
|
+
|
370
|
+
def pane_titles_not_supported_warning
|
371
|
+
print_warning(
|
372
|
+
"You have enabled pane titles in your configuration, " +
|
373
|
+
"but the feature is not supported by your version of tmux.\n" +
|
374
|
+
"Please consider upgrading to a version that supports it (tmux >=2.6)."
|
375
|
+
)
|
376
|
+
end
|
377
|
+
|
339
378
|
private
|
340
379
|
|
341
380
|
def blank?(object)
|
@@ -349,9 +388,10 @@ module Tmuxinator
|
|
349
388
|
def extract_tmux_config
|
350
389
|
options_hash = {}
|
351
390
|
|
352
|
-
|
353
|
-
|
354
|
-
|
391
|
+
`#{show_tmux_options}`.
|
392
|
+
encode("UTF-8", invalid: :replace).
|
393
|
+
split("\n").
|
394
|
+
map do |entry|
|
355
395
|
key, value = entry.split("\s")
|
356
396
|
options_hash[key] = value
|
357
397
|
options_hash
|
@@ -381,5 +421,28 @@ module Tmuxinator
|
|
381
421
|
def wemux?
|
382
422
|
yaml["tmux_command"] == "wemux"
|
383
423
|
end
|
424
|
+
|
425
|
+
def pane_title_position?
|
426
|
+
yaml["pane_title_position"]
|
427
|
+
end
|
428
|
+
|
429
|
+
def pane_title_position_valid?
|
430
|
+
["top", "bottom", "off"].include? yaml["pane_title_position"]
|
431
|
+
end
|
432
|
+
|
433
|
+
def pane_title_format?
|
434
|
+
yaml["pane_title_format"]
|
435
|
+
end
|
436
|
+
|
437
|
+
def print_warning(message)
|
438
|
+
yellow = '\033[1;33m'
|
439
|
+
no_color = '\033[0m'
|
440
|
+
msg = "WARNING: #{message}\n"
|
441
|
+
"printf \"#{yellow}#{msg}#{no_color}\""
|
442
|
+
end
|
443
|
+
|
444
|
+
def set_window_option(tmux_window_target)
|
445
|
+
"#{tmux} set-window-option -t #{tmux_window_target}"
|
446
|
+
end
|
384
447
|
end
|
385
448
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Tmuxinator
|
2
4
|
module TmuxVersion
|
3
5
|
SUPPORTED_TMUX_VERSIONS = [
|
@@ -29,7 +31,7 @@ module Tmuxinator
|
|
29
31
|
1.6,
|
30
32
|
1.5,
|
31
33
|
].freeze
|
32
|
-
UNSUPPORTED_VERSION_MSG = <<-MSG
|
34
|
+
UNSUPPORTED_VERSION_MSG = <<-MSG
|
33
35
|
WARNING: You are running tmuxinator with an unsupported version of tmux.
|
34
36
|
Please consider using a supported version:
|
35
37
|
(#{SUPPORTED_TMUX_VERSIONS.join(', ')})
|
data/lib/tmuxinator/util.rb
CHANGED
data/lib/tmuxinator/version.rb
CHANGED
data/lib/tmuxinator/window.rb
CHANGED
data/lib/tmuxinator.rb
CHANGED
data/spec/factories/projects.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Tmuxinator::Cli do
|
@@ -15,7 +17,7 @@ describe Tmuxinator::Cli do
|
|
15
17
|
File.new(local_project_path, "w").tap do |f|
|
16
18
|
f.write content
|
17
19
|
end.close
|
18
|
-
expect(File.
|
20
|
+
expect(File.exist?(local_project_path)).to be_truthy
|
19
21
|
expect(File.read(local_project_path)).to eq content
|
20
22
|
end
|
21
23
|
|
@@ -26,7 +28,7 @@ describe Tmuxinator::Cli do
|
|
26
28
|
|
27
29
|
subject(:cli) { described_class }
|
28
30
|
|
29
|
-
let(:fixtures_dir) { File.expand_path("
|
31
|
+
let(:fixtures_dir) { File.expand_path("../../fixtures", __dir__) }
|
30
32
|
let(:project) { FactoryBot.build(:project) }
|
31
33
|
let(:project_config) do
|
32
34
|
File.join(fixtures_dir, "sample_with_project_config.yml")
|
@@ -93,7 +95,7 @@ describe Tmuxinator::Cli do
|
|
93
95
|
context "a tmuxinator project name" do
|
94
96
|
before do
|
95
97
|
expect(Tmuxinator::Config).to \
|
96
|
-
receive(:
|
98
|
+
receive(:exist?).with(name: arg1) { true }
|
97
99
|
end
|
98
100
|
|
99
101
|
it "should call #start" do
|
@@ -127,7 +129,7 @@ describe Tmuxinator::Cli do
|
|
127
129
|
context "something else" do
|
128
130
|
before do
|
129
131
|
expect(Tmuxinator::Config).to \
|
130
|
-
receive(:
|
132
|
+
receive(:exist?).with(name: arg1) { false }
|
131
133
|
end
|
132
134
|
|
133
135
|
it "should call ::start" do
|
@@ -622,7 +624,7 @@ describe Tmuxinator::Cli do
|
|
622
624
|
describe "#copy" do
|
623
625
|
before do
|
624
626
|
ARGV.replace(["copy", "foo", "bar"])
|
625
|
-
allow(Tmuxinator::Config).to receive(:
|
627
|
+
allow(Tmuxinator::Config).to receive(:exist?) { true }
|
626
628
|
end
|
627
629
|
|
628
630
|
context "new project already exists" do
|
@@ -638,7 +640,7 @@ describe Tmuxinator::Cli do
|
|
638
640
|
|
639
641
|
context "existing project doesn't exist" do
|
640
642
|
before do
|
641
|
-
allow(Tmuxinator::Config).to receive(:
|
643
|
+
allow(Tmuxinator::Config).to receive(:exist?) { false }
|
642
644
|
end
|
643
645
|
|
644
646
|
it "exit with error code" do
|
@@ -714,7 +716,7 @@ describe Tmuxinator::Cli do
|
|
714
716
|
|
715
717
|
context "project exists" do
|
716
718
|
before do
|
717
|
-
allow(Tmuxinator::Config).to receive(:
|
719
|
+
allow(Tmuxinator::Config).to receive(:exist?) { true }
|
718
720
|
end
|
719
721
|
|
720
722
|
it "deletes the project" do
|
@@ -725,7 +727,7 @@ describe Tmuxinator::Cli do
|
|
725
727
|
|
726
728
|
context "local project exists" do
|
727
729
|
before do
|
728
|
-
allow(Tmuxinator::Config).to receive(:
|
730
|
+
allow(Tmuxinator::Config).to receive(:exist?) { true }
|
729
731
|
expect(Tmuxinator::Config).to receive(:project) { "local" }
|
730
732
|
end
|
731
733
|
|
@@ -737,7 +739,7 @@ describe Tmuxinator::Cli do
|
|
737
739
|
|
738
740
|
context "project doesn't exist" do
|
739
741
|
before do
|
740
|
-
allow(Tmuxinator::Config).to receive(:
|
742
|
+
allow(Tmuxinator::Config).to receive(:exist?) { false }
|
741
743
|
end
|
742
744
|
|
743
745
|
it "outputs an error message" do
|
@@ -754,7 +756,7 @@ describe Tmuxinator::Cli do
|
|
754
756
|
|
755
757
|
context "all projects exist" do
|
756
758
|
before do
|
757
|
-
allow(Tmuxinator::Config).to receive(:
|
759
|
+
allow(Tmuxinator::Config).to receive(:exist?).and_return(true)
|
758
760
|
end
|
759
761
|
|
760
762
|
it "deletes the projects" do
|
@@ -765,10 +767,10 @@ describe Tmuxinator::Cli do
|
|
765
767
|
|
766
768
|
context "only one project exists" do
|
767
769
|
before do
|
768
|
-
allow(Tmuxinator::Config).to receive(:
|
770
|
+
allow(Tmuxinator::Config).to receive(:exist?).with(name: "foo") {
|
769
771
|
true
|
770
772
|
}
|
771
|
-
allow(Tmuxinator::Config).to receive(:
|
773
|
+
allow(Tmuxinator::Config).to receive(:exist?).with(name: "bar") {
|
772
774
|
false
|
773
775
|
}
|
774
776
|
end
|
@@ -785,7 +787,7 @@ describe Tmuxinator::Cli do
|
|
785
787
|
|
786
788
|
context "all projects do not exist" do
|
787
789
|
before do
|
788
|
-
allow(Tmuxinator::Config).to receive(:
|
790
|
+
allow(Tmuxinator::Config).to receive(:exist?).and_return(false)
|
789
791
|
end
|
790
792
|
|
791
793
|
it "outputs multiple error messages" do
|
@@ -952,7 +954,7 @@ describe Tmuxinator::Cli do
|
|
952
954
|
let(:name) { "sample" }
|
953
955
|
let(:custom_name) { nil }
|
954
956
|
let(:cli_options) { {} }
|
955
|
-
let(:path) { File.expand_path("
|
957
|
+
let(:path) { File.expand_path("../../fixtures", __dir__) }
|
956
958
|
|
957
959
|
shared_examples_for :a_proper_project do
|
958
960
|
it "should create a valid project" do
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Tmuxinator::Config do
|
4
|
-
let(:fixtures_dir) { File.expand_path("
|
6
|
+
let(:fixtures_dir) { File.expand_path("../../fixtures", __dir__) }
|
5
7
|
let(:xdg_config_dir) { "#{fixtures_dir}/xdg-tmuxinator" }
|
6
8
|
let(:home_config_dir) { "#{fixtures_dir}/dot-tmuxinator" }
|
7
9
|
|
@@ -150,6 +152,30 @@ describe Tmuxinator::Config do
|
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|
155
|
+
describe "#default_or_sample" do
|
156
|
+
context "with default? true" do
|
157
|
+
before do
|
158
|
+
allow(described_class).to receive(:default?).and_return true
|
159
|
+
allow(described_class).to receive(:default).and_return("default_path")
|
160
|
+
end
|
161
|
+
|
162
|
+
it "gets the default config when it exists" do
|
163
|
+
expect(described_class.default_or_sample).to eq "default_path"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "with default? false" do
|
168
|
+
before do
|
169
|
+
allow(described_class).to receive(:default?)
|
170
|
+
allow(described_class).to receive(:sample).and_return("sample_path")
|
171
|
+
end
|
172
|
+
|
173
|
+
it "falls back to the sample config when the default is missing" do
|
174
|
+
expect(described_class.default_or_sample).to eq "sample_path"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
153
179
|
describe "#version" do
|
154
180
|
subject { described_class.version }
|
155
181
|
|
@@ -160,25 +186,25 @@ describe Tmuxinator::Config do
|
|
160
186
|
end
|
161
187
|
|
162
188
|
version_mapping = {
|
163
|
-
"0.8"
|
164
|
-
"1.0"
|
165
|
-
"1.9"
|
166
|
-
"1.9a"
|
167
|
-
"2.4"
|
168
|
-
"2.9a"
|
169
|
-
"3.0-rc5"
|
189
|
+
"0.8" => 0.8,
|
190
|
+
"1.0" => 1.0,
|
191
|
+
"1.9" => 1.9,
|
192
|
+
"1.9a" => 1.9,
|
193
|
+
"2.4" => 2.4,
|
194
|
+
"2.9a" => 2.9,
|
195
|
+
"3.0-rc5" => 3.0,
|
170
196
|
"next-3.1" => 3.1,
|
171
|
-
"master"
|
197
|
+
"master" => Float::INFINITY,
|
172
198
|
# Failsafes
|
173
|
-
"foobar"
|
174
|
-
"-123-"
|
175
|
-
"5935"
|
176
|
-
""
|
177
|
-
"!@#^%"
|
178
|
-
"2.9ä"
|
179
|
-
"v3.5"
|
180
|
-
"v3.12.0"
|
181
|
-
"v3.12.5"
|
199
|
+
"foobar" => 0.0,
|
200
|
+
"-123-" => 123.0,
|
201
|
+
"5935" => 5935.0,
|
202
|
+
"" => 0.0,
|
203
|
+
"!@#^%" => 0.0,
|
204
|
+
"2.9ä" => 2.9,
|
205
|
+
"v3.5" => 3.5,
|
206
|
+
"v3.12.0" => 3.12,
|
207
|
+
"v3.12.5" => 3.12
|
182
208
|
}.freeze
|
183
209
|
|
184
210
|
version_mapping.each do |string_version, parsed_numeric_version|
|
@@ -262,14 +288,14 @@ describe Tmuxinator::Config do
|
|
262
288
|
end
|
263
289
|
end
|
264
290
|
|
265
|
-
describe "#
|
291
|
+
describe "#exist?" do
|
266
292
|
before do
|
267
293
|
allow(File).to receive_messages(exist?: true)
|
268
294
|
allow(described_class).to receive_messages(project: "")
|
269
295
|
end
|
270
296
|
|
271
297
|
it "checks if the given project exists" do
|
272
|
-
expect(described_class.
|
298
|
+
expect(described_class.exist?(name: "test")).to be_truthy
|
273
299
|
end
|
274
300
|
end
|
275
301
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Tmuxinator::Pane do
|
@@ -10,7 +12,7 @@ describe Tmuxinator::Pane do
|
|
10
12
|
let(:project) { double }
|
11
13
|
let(:window) { double }
|
12
14
|
let(:commands) { ["vim", "bash"] }
|
13
|
-
let(:title) { "test" }
|
15
|
+
let(:title) { "test (a test)" }
|
14
16
|
|
15
17
|
before do
|
16
18
|
allow(project).to receive(:name).and_return "foo"
|
@@ -39,7 +41,7 @@ describe Tmuxinator::Pane do
|
|
39
41
|
|
40
42
|
it "sets pane title" do
|
41
43
|
expect(subject.tmux_set_title).to eql(
|
42
|
-
"tmux select-pane -t foo:0.1 -T test"
|
44
|
+
"tmux select-pane -t foo:0.1 -T test\\ \\(a\\ test\\)"
|
43
45
|
)
|
44
46
|
end
|
45
47
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Tmuxinator::Project do
|
@@ -589,7 +591,7 @@ describe Tmuxinator::Project do
|
|
589
591
|
end
|
590
592
|
|
591
593
|
describe "::load" do
|
592
|
-
let(:path) { File.expand_path("
|
594
|
+
let(:path) { File.expand_path("../../fixtures/sample.yml", __dir__) }
|
593
595
|
let(:options) { {} }
|
594
596
|
|
595
597
|
it "should raise if the project file doesn't parse" do
|
@@ -635,4 +637,77 @@ describe Tmuxinator::Project do
|
|
635
637
|
end.to raise_error RuntimeError, %r{didn't.specify.a.'project_name'}
|
636
638
|
end
|
637
639
|
end
|
640
|
+
|
641
|
+
describe "#pane_titles" do
|
642
|
+
before do
|
643
|
+
allow(project).to receive(:tmux).and_return "tmux"
|
644
|
+
end
|
645
|
+
|
646
|
+
context "pane_titles not enabled" do
|
647
|
+
before { project.yaml["enable_pane_titles"] = false }
|
648
|
+
|
649
|
+
it "returns false" do
|
650
|
+
expect(project.enable_pane_titles?).to be false
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
context "pane_titles enabled" do
|
655
|
+
before { project.yaml["enable_pane_titles"] = true }
|
656
|
+
|
657
|
+
it "returns true" do
|
658
|
+
expect(project.enable_pane_titles?).to be true
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
context "pane_title_position not configured" do
|
663
|
+
before { project.yaml["pane_title_position"] = nil }
|
664
|
+
|
665
|
+
it "configures a default position of top" do
|
666
|
+
expect(project.tmux_set_pane_title_position("x")).to eq(
|
667
|
+
"tmux set-window-option -t x pane-border-status top"
|
668
|
+
)
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
context "pane_title_position configured" do
|
673
|
+
before { project.yaml["pane_title_position"] = "bottom" }
|
674
|
+
|
675
|
+
it "configures a position of bottom" do
|
676
|
+
expect(project.tmux_set_pane_title_position("x")).to eq(
|
677
|
+
"tmux set-window-option -t x pane-border-status bottom"
|
678
|
+
)
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
context "pane_title_position invalid" do
|
683
|
+
before { project.yaml["pane_title_position"] = "other" }
|
684
|
+
|
685
|
+
it "configures the default position" do
|
686
|
+
expect(project.tmux_set_pane_title_position("x")).to eq(
|
687
|
+
"tmux set-window-option -t x pane-border-status top"
|
688
|
+
)
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
context "pane_title_format not configured" do
|
693
|
+
before { project.yaml["pane_title_format"] = nil }
|
694
|
+
|
695
|
+
it "configures a default format" do
|
696
|
+
resp = ""\
|
697
|
+
"tmux set-window-option -t x pane-border-format"\
|
698
|
+
" \"\#{pane_index}: \#{pane_title}\""
|
699
|
+
expect(project.tmux_set_pane_title_format("x")).to eq(resp)
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
context "pane_title_format configured" do
|
704
|
+
before { project.yaml["pane_title_format"] = " [ #T ] " }
|
705
|
+
|
706
|
+
it "configures the provided format" do
|
707
|
+
expect(project.tmux_set_pane_title_format("x")).to eq(
|
708
|
+
'tmux set-window-option -t x pane-border-format " [ #T ] "'
|
709
|
+
)
|
710
|
+
end
|
711
|
+
end
|
712
|
+
end
|
638
713
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "coveralls"
|
2
4
|
require "pry"
|
3
5
|
require "simplecov"
|
@@ -39,7 +41,7 @@ def capture_io
|
|
39
41
|
|
40
42
|
yield
|
41
43
|
|
42
|
-
|
44
|
+
[captured_stdout.string, captured_stderr.string]
|
43
45
|
ensure
|
44
46
|
$stdout = orig_stdout
|
45
47
|
$stderr = orig_stderr
|
metadata
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tmuxinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1
|
4
|
+
version: 3.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Allen Bargi
|
8
8
|
- Christopher Chow
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-05-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: erubi
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '1.7'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '1.7'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: thor
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -177,14 +177,14 @@ dependencies:
|
|
177
177
|
requirements:
|
178
178
|
- - "~>"
|
179
179
|
- !ruby/object:Gem::Version
|
180
|
-
version: 0.
|
180
|
+
version: 0.61.1
|
181
181
|
type: :development
|
182
182
|
prerelease: false
|
183
183
|
version_requirements: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
185
|
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version: 0.
|
187
|
+
version: 0.61.1
|
188
188
|
- !ruby/object:Gem::Dependency
|
189
189
|
name: simplecov
|
190
190
|
requirement: !ruby/object:Gem::Requirement
|
@@ -302,8 +302,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
302
302
|
- !ruby/object:Gem::Version
|
303
303
|
version: 1.8.23
|
304
304
|
requirements: []
|
305
|
-
rubygems_version: 3.
|
306
|
-
signing_key:
|
305
|
+
rubygems_version: 3.2.15
|
306
|
+
signing_key:
|
307
307
|
specification_version: 4
|
308
308
|
summary: Create and manage complex tmux sessions easily.
|
309
309
|
test_files:
|