tmuxinator 3.3.3 → 3.3.5
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/completion/tmuxinator.fish +13 -18
- data/lib/tmuxinator/assets/template.erb +8 -6
- data/lib/tmuxinator/cli.rb +83 -66
- data/lib/tmuxinator/config.rb +16 -4
- data/lib/tmuxinator/project.rb +86 -43
- data/lib/tmuxinator/util.rb +4 -0
- data/lib/tmuxinator/version.rb +1 -1
- data/lib/tmuxinator/window.rb +2 -2
- data/lib/tmuxinator.rb +0 -1
- data/spec/factories/projects.rb +8 -0
- data/spec/lib/tmuxinator/cli_spec.rb +44 -20
- data/spec/lib/tmuxinator/config_spec.rb +5 -5
- data/spec/lib/tmuxinator/project_spec.rb +59 -1
- data/spec/lib/tmuxinator/wemux_support_spec.rb +1 -1
- data/spec/spec_helper.rb +13 -9
- metadata +24 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e954effc3cf016798540aa6c25ddf5465797a6653fb9400616d288892bde9c9c
|
4
|
+
data.tar.gz: b501066e62a1cb5b46d286e86bfc866ebeefbbadf157e588a4934dbdd41eb7d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e29c29f221505b683afb040e11b9e771a3a6b4526e5f716c8c52fe06c27dc642577c6e1f02ff2ead907bcac72ce81b778e65c9763b1adfc0b5d3d4c621b5caad
|
7
|
+
data.tar.gz: 4429eb7736ef16c2d78acb2a70c27df6843bd7dcb1d6abef1940e7852735436e6d8d709e5ac8b6de5041968232cd062b727a03dd3f92af9eb31ba7944677c33d
|
data/completion/tmuxinator.fish
CHANGED
@@ -1,22 +1,17 @@
|
|
1
1
|
function __fish_tmuxinator_using_command
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
set cmd (commandline -opc)
|
3
|
+
if [ (count $cmd) -gt 1 ]
|
4
|
+
if [ $argv[1] = $cmd[2] ]
|
5
|
+
return 0
|
6
|
+
end
|
6
7
|
end
|
7
|
-
|
8
|
-
return 1
|
8
|
+
return 1
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
complete -
|
18
|
-
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_use_subcommand' -x -a "(__fish_tmuxinator_program commands)"
|
19
|
-
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command start' -a "(__fish_tmuxinator_program completions start)"
|
20
|
-
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command open' -a "(__fish_tmuxinator_program completions open)"
|
21
|
-
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command copy' -a "(__fish_tmuxinator_program completions copy)"
|
22
|
-
complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command delete' -a "(__fish_tmuxinator_program completions delete)"
|
11
|
+
complete --no-files --command tmuxinator --condition __fish_use_subcommand --exclusive --argument "(tmuxinator commands)"
|
12
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command start' --argument "(tmuxinator completions start)"
|
13
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command open' --argument "(tmuxinator completions open)"
|
14
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command edit' --argument "(tmuxinator completions open)"
|
15
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command copy' --argument "(tmuxinator completions copy)"
|
16
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command delete' --argument "(tmuxinator completions delete)"
|
17
|
+
complete --no-files --command tmuxinator --condition '__fish_tmuxinator_using_command debug' --argument "(tmuxinator completions start)"
|
@@ -1,17 +1,19 @@
|
|
1
1
|
#!<%= ENV["SHELL"] || "/bin/bash" %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
unset
|
3
|
+
<%- if !append? -%>
|
4
|
+
# Clear rbenv variables before starting tmux
|
5
|
+
unset RBENV_VERSION
|
6
|
+
unset RBENV_DIR
|
6
7
|
|
7
|
-
<%= tmux %> start-server;
|
8
|
+
<%= tmux %> start-server;
|
9
|
+
<%- end -%>
|
8
10
|
|
9
11
|
cd <%= root || "." %>
|
10
12
|
|
11
13
|
# Run on_project_start command.
|
12
14
|
<%= hook_on_project_start %>
|
13
15
|
|
14
|
-
<%- if !tmux_has_session?
|
16
|
+
<%- if append? || !tmux_has_session?(name) -%>
|
15
17
|
|
16
18
|
# Run pre command.
|
17
19
|
<%= pre %>
|
@@ -98,7 +100,7 @@ cd <%= root || "." %>
|
|
98
100
|
<%= hook_on_project_restart %>
|
99
101
|
<%- end -%>
|
100
102
|
|
101
|
-
<%- if attach? -%>
|
103
|
+
<%- if attach? && !append? -%>
|
102
104
|
if [ -z "$TMUX" ]; then
|
103
105
|
<%= tmux %> -u attach-session -t <%= name %>
|
104
106
|
else
|
data/lib/tmuxinator/cli.rb
CHANGED
@@ -15,25 +15,26 @@ module Tmuxinator
|
|
15
15
|
COMMANDS = {
|
16
16
|
commands: "Lists commands available in tmuxinator",
|
17
17
|
completions: "Used for shell completion",
|
18
|
-
|
18
|
+
copy: %w{
|
19
|
+
Copy an existing project to a new project and
|
20
|
+
open it in your editor
|
21
|
+
}.join(" "),
|
22
|
+
debug: "Output the shell commands that are generated by tmuxinator",
|
23
|
+
delete: "Deletes given project",
|
24
|
+
doctor: "Look for problems in your configuration",
|
19
25
|
edit: "Alias of new",
|
26
|
+
implode: "Deletes all tmuxinator projects",
|
27
|
+
local: "Start a tmux session using ./.tmuxinator.y[a]ml",
|
28
|
+
list: "Lists all tmuxinator projects",
|
29
|
+
new: "Create a new project file and open it in your editor",
|
20
30
|
open: "Alias of new",
|
21
31
|
start: %w{
|
22
32
|
Start a tmux session using a project's name (with an optional [ALIAS]
|
23
33
|
for project reuse) or a path to a project config file (via the -p flag)
|
24
34
|
}.join(" "),
|
25
35
|
stop: "Stop a tmux session using a project's tmuxinator config",
|
26
|
-
|
27
|
-
debug: "Output the shell commands that are generated by tmuxinator",
|
28
|
-
copy: %w{
|
29
|
-
Copy an existing project to a new project and
|
30
|
-
open it in your editor
|
31
|
-
}.join(" "),
|
32
|
-
delete: "Deletes given project",
|
33
|
-
implode: "Deletes all tmuxinator projects",
|
36
|
+
stop_all: "Stop all tmux sessions which are using tmuxinator projects",
|
34
37
|
version: "Display installed tmuxinator version",
|
35
|
-
doctor: "Look for problems in your configuration",
|
36
|
-
list: "Lists all tmuxinator projects"
|
37
38
|
}.freeze
|
38
39
|
|
39
40
|
# For future reference: due to how tmuxinator currently consumes
|
@@ -93,7 +94,7 @@ module Tmuxinator
|
|
93
94
|
|
94
95
|
no_commands do
|
95
96
|
def new_project(name)
|
96
|
-
project_file = find_project_file(name, options[:local])
|
97
|
+
project_file = find_project_file(name, local: options[:local])
|
97
98
|
Kernel.system("$EDITOR #{project_file}") || doctor
|
98
99
|
end
|
99
100
|
|
@@ -145,14 +146,14 @@ module Tmuxinator
|
|
145
146
|
end
|
146
147
|
}
|
147
148
|
|
148
|
-
path = config_path(name, options[:local])
|
149
|
+
path = config_path(name, local: options[:local])
|
149
150
|
File.open(path, "w") do |f|
|
150
151
|
f.write(YAML.dump(yaml))
|
151
152
|
end
|
152
153
|
end
|
153
154
|
|
154
|
-
def find_project_file(name, local
|
155
|
-
path = config_path(name, local)
|
155
|
+
def find_project_file(name, local: false)
|
156
|
+
path = config_path(name, local: local)
|
156
157
|
if File.exist?(path)
|
157
158
|
path
|
158
159
|
else
|
@@ -160,7 +161,7 @@ module Tmuxinator
|
|
160
161
|
end
|
161
162
|
end
|
162
163
|
|
163
|
-
def config_path(name, local
|
164
|
+
def config_path(name, local: false)
|
164
165
|
if local
|
165
166
|
Tmuxinator::Config::LOCAL_DEFAULTS[0]
|
166
167
|
else
|
@@ -176,28 +177,22 @@ module Tmuxinator
|
|
176
177
|
end
|
177
178
|
|
178
179
|
def create_project(project_options = {})
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
options = {
|
180
|
+
Tmuxinator::Config.validate(project_create_options(project_options))
|
181
|
+
rescue StandardError => e
|
182
|
+
exit! e.message
|
183
|
+
end
|
184
|
+
|
185
|
+
def project_create_options(project_options)
|
186
|
+
{
|
188
187
|
args: project_options[:args],
|
189
188
|
custom_name: project_options[:custom_name],
|
190
|
-
force_attach: attach,
|
191
|
-
force_detach:
|
189
|
+
force_attach: project_options[:attach] == true,
|
190
|
+
force_detach: project_options[:attach] == false,
|
192
191
|
name: project_options[:name],
|
193
|
-
project_config: project_options[:project_config]
|
192
|
+
project_config: project_options[:project_config],
|
193
|
+
append: project_options[:append],
|
194
|
+
no_pre_window: project_options[:no_pre_window],
|
194
195
|
}
|
195
|
-
|
196
|
-
begin
|
197
|
-
Tmuxinator::Config.validate(options)
|
198
|
-
rescue StandardError => e
|
199
|
-
exit! e.message
|
200
|
-
end
|
201
196
|
end
|
202
197
|
|
203
198
|
def render_project(project)
|
@@ -221,12 +216,31 @@ module Tmuxinator
|
|
221
216
|
def show_continuation_prompt
|
222
217
|
say
|
223
218
|
print "Press ENTER to continue."
|
224
|
-
|
219
|
+
$stdin.getc
|
225
220
|
end
|
226
221
|
|
227
222
|
def kill_project(project)
|
228
223
|
Kernel.exec(project.kill)
|
229
224
|
end
|
225
|
+
|
226
|
+
def start_params(name = nil, *args)
|
227
|
+
# project-config takes precedence over a named project in the case that
|
228
|
+
# both are provided.
|
229
|
+
if options["project-config"]
|
230
|
+
args.unshift name if name
|
231
|
+
name = nil
|
232
|
+
end
|
233
|
+
|
234
|
+
{
|
235
|
+
args: args,
|
236
|
+
attach: options[:attach],
|
237
|
+
custom_name: options[:name],
|
238
|
+
name: name,
|
239
|
+
project_config: options["project-config"],
|
240
|
+
append: options["append"],
|
241
|
+
no_pre_window: options["no-pre-window"],
|
242
|
+
}
|
243
|
+
end
|
230
244
|
end
|
231
245
|
|
232
246
|
desc "start [PROJECT] [ARGS]", COMMANDS[:start]
|
@@ -240,22 +254,13 @@ module Tmuxinator
|
|
240
254
|
desc: "Path to project config file"
|
241
255
|
method_option "suppress-tmux-version-warning",
|
242
256
|
desc: "Don't show a warning for unsupported tmux versions"
|
243
|
-
|
257
|
+
method_option :append, type: :boolean,
|
258
|
+
desc: "Appends the project windows and panes in " \
|
259
|
+
"the current session"
|
260
|
+
method_option "no-pre-window", type: :boolean, default: false,
|
261
|
+
desc: "Skip pre_window commands"
|
244
262
|
def start(name = nil, *args)
|
245
|
-
|
246
|
-
# both are provided.
|
247
|
-
if options["project-config"]
|
248
|
-
args.unshift name if name
|
249
|
-
name = nil
|
250
|
-
end
|
251
|
-
|
252
|
-
params = {
|
253
|
-
args: args,
|
254
|
-
attach: options[:attach],
|
255
|
-
custom_name: options[:name],
|
256
|
-
name: name,
|
257
|
-
project_config: options["project-config"]
|
258
|
-
}
|
263
|
+
params = start_params(name, *args)
|
259
264
|
|
260
265
|
show_version_warning if version_warning?(
|
261
266
|
options["suppress-tmux-version-warning"]
|
@@ -291,6 +296,26 @@ module Tmuxinator
|
|
291
296
|
kill_project(project)
|
292
297
|
end
|
293
298
|
|
299
|
+
desc "stop-all", COMMANDS[:stop_all]
|
300
|
+
method_option :noconfirm, type: :boolean,
|
301
|
+
default: false,
|
302
|
+
aliases: "-y",
|
303
|
+
desc: "Skip confirmation"
|
304
|
+
def stop_all
|
305
|
+
# We only need to stop active projects
|
306
|
+
configs = Tmuxinator::Config.configs(active: true)
|
307
|
+
|
308
|
+
unless options[:noconfirm]
|
309
|
+
say "Stop all active projects:\n\n", :yellow
|
310
|
+
say configs.join("\n")
|
311
|
+
say "\n"
|
312
|
+
|
313
|
+
return unless yes?("Are you sure? (n/y)")
|
314
|
+
end
|
315
|
+
|
316
|
+
Project.stop_all
|
317
|
+
end
|
318
|
+
|
294
319
|
desc "local", COMMANDS[:local]
|
295
320
|
map "." => :local
|
296
321
|
method_option "suppress-tmux-version-warning",
|
@@ -312,24 +337,16 @@ module Tmuxinator
|
|
312
337
|
desc: "Give the session a different name"
|
313
338
|
method_option "project-config", aliases: "-p",
|
314
339
|
desc: "Path to project config file"
|
315
|
-
|
340
|
+
method_option :append, type: :boolean,
|
341
|
+
desc: "Appends the project windows and panes in " \
|
342
|
+
"the current session"
|
343
|
+
method_option "no-pre-window", type: :boolean, default: false,
|
344
|
+
desc: "Skip pre_window commands"
|
316
345
|
def debug(name = nil, *args)
|
317
|
-
|
318
|
-
# both are provided.
|
319
|
-
if options["project-config"]
|
320
|
-
args.unshift name if name
|
321
|
-
name = nil
|
322
|
-
end
|
323
|
-
|
324
|
-
params = {
|
325
|
-
args: args,
|
326
|
-
attach: options[:attach],
|
327
|
-
custom_name: options[:name],
|
328
|
-
name: name,
|
329
|
-
project_config: options["project-config"]
|
330
|
-
}
|
346
|
+
params = start_params(name, *args)
|
331
347
|
|
332
348
|
project = create_project(params)
|
349
|
+
|
333
350
|
say project.render
|
334
351
|
end
|
335
352
|
|
@@ -439,7 +456,7 @@ module Tmuxinator
|
|
439
456
|
Tmuxinator::Cli.new.local
|
440
457
|
elsif name && !Tmuxinator::Cli::RESERVED_COMMANDS.include?(name) &&
|
441
458
|
Tmuxinator::Config.exist?(name: name)
|
442
|
-
Tmuxinator::Cli.
|
459
|
+
Tmuxinator::Cli.start([:start, *args])
|
443
460
|
else
|
444
461
|
Tmuxinator::Cli.start(args)
|
445
462
|
end
|
data/lib/tmuxinator/config.rb
CHANGED
@@ -20,7 +20,7 @@ module Tmuxinator
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def home
|
23
|
-
ENV[
|
23
|
+
"#{ENV['HOME']}/.tmuxinator"
|
24
24
|
end
|
25
25
|
|
26
26
|
def home?
|
@@ -31,7 +31,9 @@ module Tmuxinator
|
|
31
31
|
# a custom value. (e.g. if $XDG_CONFIG_HOME is set to ~/my-config, the
|
32
32
|
# return value will be ~/my-config/tmuxinator)
|
33
33
|
def xdg
|
34
|
-
|
34
|
+
xdg_config_directory = ENV.fetch("XDG_CONFIG_HOME", "~/.config")
|
35
|
+
config_home = File.expand_path(xdg_config_directory)
|
36
|
+
File.join(config_home, "tmuxinator")
|
35
37
|
end
|
36
38
|
|
37
39
|
def xdg?
|
@@ -131,7 +133,7 @@ module Tmuxinator
|
|
131
133
|
`tmux list-sessions -F "#S"`.split("\n")
|
132
134
|
end
|
133
135
|
|
134
|
-
# Sorted list of all project
|
136
|
+
# Sorted list of all project file basenames, including duplicates.
|
135
137
|
#
|
136
138
|
# @param active filter configs by active project sessions
|
137
139
|
# @return [Array<String>] list of project names
|
@@ -147,6 +149,16 @@ module Tmuxinator
|
|
147
149
|
configs
|
148
150
|
end
|
149
151
|
|
152
|
+
# List the names of all config files relative to the config directory.
|
153
|
+
#
|
154
|
+
# If sub-folders are used, those are part of the name too.
|
155
|
+
#
|
156
|
+
# Example:
|
157
|
+
# $CONFIG_DIR/project.yml -> project
|
158
|
+
# $CONFIG_DIR/sub/project.yml -> sub/project
|
159
|
+
# $HOME_CONFIG_DIR/project.yml -> project
|
160
|
+
#
|
161
|
+
# @return [Array<String] a list of config file names
|
150
162
|
def config_file_basenames
|
151
163
|
directories.flat_map do |directory|
|
152
164
|
Dir["#{directory}/**/*.yml"].map do |path|
|
@@ -193,7 +205,7 @@ module Tmuxinator
|
|
193
205
|
name = options[:name]
|
194
206
|
options[:force_attach] ||= false
|
195
207
|
options[:force_detach] ||= false
|
196
|
-
project_config = options.fetch(:project_config
|
208
|
+
project_config = options.fetch(:project_config, false)
|
197
209
|
project_file = if valid_project_config?(project_config)
|
198
210
|
project_config
|
199
211
|
elsif valid_local_project?(name)
|
data/lib/tmuxinator/project.rb
CHANGED
@@ -36,36 +36,49 @@ module Tmuxinator
|
|
36
36
|
`on_project_exit`) and will be removed in a future release.
|
37
37
|
M
|
38
38
|
|
39
|
-
attr_reader :yaml
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
attr_reader :yaml, :force_attach, :force_detach, :custom_name,
|
40
|
+
:no_pre_window
|
41
|
+
|
42
|
+
class << self
|
43
|
+
include Tmuxinator::Util
|
44
|
+
|
45
|
+
def load(path, options = {})
|
46
|
+
yaml = begin
|
47
|
+
args = options[:args] || []
|
48
|
+
@settings = parse_settings(args)
|
49
|
+
@args = args
|
50
|
+
|
51
|
+
content = render_template(path, binding)
|
52
|
+
YAML.safe_load(content, aliases: true)
|
53
|
+
rescue SyntaxError, StandardError => e
|
54
|
+
raise "Failed to parse config file: #{e.message}"
|
55
|
+
end
|
56
|
+
|
57
|
+
new(yaml, options)
|
54
58
|
end
|
55
59
|
|
56
|
-
|
57
|
-
|
60
|
+
def parse_settings(args)
|
61
|
+
settings = args.select { |x| x.match(/.*=.*/) }
|
62
|
+
args.reject! { |x| x.match(/.*=.*/) }
|
63
|
+
|
64
|
+
settings.map! do |setting|
|
65
|
+
parts = setting.split("=", 2)
|
66
|
+
[parts[0], parts[1]]
|
67
|
+
end
|
58
68
|
|
59
|
-
|
60
|
-
|
61
|
-
args.reject! { |x| x.match(/.*=.*/) }
|
69
|
+
Hash[settings]
|
70
|
+
end
|
62
71
|
|
63
|
-
|
64
|
-
|
65
|
-
|
72
|
+
def active
|
73
|
+
Tmuxinator::Config.configs(active: true).
|
74
|
+
map { |config| Config.validate(name: config) }
|
66
75
|
end
|
67
76
|
|
68
|
-
|
77
|
+
def stop_all
|
78
|
+
active.
|
79
|
+
sort_by { |project| project.name == current_session_name ? 1 : 0 }.
|
80
|
+
each { |project| Kernel.system(project.kill) }
|
81
|
+
end
|
69
82
|
end
|
70
83
|
|
71
84
|
def validate!
|
@@ -83,15 +96,29 @@ module Tmuxinator
|
|
83
96
|
|
84
97
|
@yaml = yaml
|
85
98
|
|
86
|
-
|
99
|
+
set_instance_variables_from_options(options)
|
87
100
|
|
101
|
+
validate_options
|
102
|
+
|
103
|
+
extend Tmuxinator::WemuxSupport if wemux?
|
104
|
+
end
|
105
|
+
|
106
|
+
def set_instance_variables_from_options(options)
|
107
|
+
@custom_name = options[:custom_name]
|
88
108
|
@force_attach = options[:force_attach]
|
89
109
|
@force_detach = options[:force_detach]
|
110
|
+
@append = options[:append]
|
111
|
+
@no_pre_window = options[:no_pre_window]
|
112
|
+
end
|
90
113
|
|
91
|
-
|
92
|
-
|
114
|
+
def validate_options
|
115
|
+
if @force_attach && @force_detach
|
116
|
+
raise "Cannot force_attach and force_detach at the same time"
|
117
|
+
end
|
93
118
|
|
94
|
-
|
119
|
+
if append? && !tmux_has_session?(name)
|
120
|
+
raise "Cannot append to a session that does not exist"
|
121
|
+
end
|
95
122
|
end
|
96
123
|
|
97
124
|
def render
|
@@ -121,26 +148,33 @@ module Tmuxinator
|
|
121
148
|
end
|
122
149
|
|
123
150
|
def name
|
124
|
-
name =
|
151
|
+
name =
|
152
|
+
if append?
|
153
|
+
current_session_name
|
154
|
+
else
|
155
|
+
custom_name || yaml["project_name"] || yaml["name"]
|
156
|
+
end
|
157
|
+
|
125
158
|
blank?(name) ? nil : name.to_s.shellescape
|
126
159
|
end
|
127
160
|
|
161
|
+
def append?
|
162
|
+
@append
|
163
|
+
end
|
164
|
+
|
128
165
|
def pre
|
129
166
|
pre_config = yaml["pre"]
|
130
167
|
parsed_parameters(pre_config)
|
131
168
|
end
|
132
169
|
|
133
170
|
def attach?
|
134
|
-
yaml_attach =
|
135
|
-
|
136
|
-
else
|
137
|
-
yaml["attach"]
|
138
|
-
end
|
139
|
-
attach = force_attach || !force_detach && yaml_attach
|
140
|
-
attach
|
171
|
+
yaml_attach = yaml["attach"].nil? || yaml["attach"]
|
172
|
+
force_attach || !force_detach && yaml_attach
|
141
173
|
end
|
142
174
|
|
143
175
|
def pre_window
|
176
|
+
return if no_pre_window
|
177
|
+
|
144
178
|
params = if rbenv?
|
145
179
|
"rbenv shell #{yaml['rbenv']}"
|
146
180
|
elsif rvm?
|
@@ -167,6 +201,8 @@ module Tmuxinator
|
|
167
201
|
end
|
168
202
|
|
169
203
|
def tmux_has_session?(name)
|
204
|
+
return false unless name
|
205
|
+
|
170
206
|
# Redirect stderr to /dev/null in order to prevent "failed to connect
|
171
207
|
# to server: Connection refused" error message and non-zero exit status
|
172
208
|
# if no tmux sessions exist.
|
@@ -208,7 +244,13 @@ module Tmuxinator
|
|
208
244
|
end
|
209
245
|
end
|
210
246
|
|
247
|
+
def last_window_index
|
248
|
+
`tmux list-windows -F '#I'`.split.last.to_i
|
249
|
+
end
|
250
|
+
|
211
251
|
def base_index
|
252
|
+
return last_window_index + 1 if append?
|
253
|
+
|
212
254
|
get_base_index.to_i
|
213
255
|
end
|
214
256
|
|
@@ -241,7 +283,7 @@ module Tmuxinator
|
|
241
283
|
end
|
242
284
|
|
243
285
|
def window(index)
|
244
|
-
"#{name}:#{index}"
|
286
|
+
append? ? ":#{index}" : "#{name}:#{index}"
|
245
287
|
end
|
246
288
|
|
247
289
|
def send_pane_command(cmd, window_index, _pane_index)
|
@@ -329,6 +371,8 @@ module Tmuxinator
|
|
329
371
|
end
|
330
372
|
|
331
373
|
def tmux_new_session_command
|
374
|
+
return if append?
|
375
|
+
|
332
376
|
window = windows.first.tmux_window_name_option
|
333
377
|
"#{tmux} new-session -d -s #{name} #{window}"
|
334
378
|
end
|
@@ -361,17 +405,16 @@ module Tmuxinator
|
|
361
405
|
|
362
406
|
def pane_title_position_not_valid_warning
|
363
407
|
print_warning(
|
364
|
-
"The specified pane title position "
|
365
|
-
"
|
366
|
-
"Please choose one of: top, bottom, or off."
|
408
|
+
"The specified pane title position '#{yaml['pane_title_position']}' " \
|
409
|
+
"is not valid. Please choose one of: top, bottom, or off."
|
367
410
|
)
|
368
411
|
end
|
369
412
|
|
370
413
|
def pane_titles_not_supported_warning
|
371
414
|
print_warning(
|
372
|
-
"You have enabled pane titles in your configuration, "
|
373
|
-
"
|
374
|
-
"
|
415
|
+
"You have enabled pane titles in your configuration, but the " \
|
416
|
+
"feature is not supported by your version of tmux.\nPlease consider " \
|
417
|
+
"upgrading to a version that supports it (tmux >=2.6)."
|
375
418
|
)
|
376
419
|
end
|
377
420
|
|
data/lib/tmuxinator/util.rb
CHANGED
data/lib/tmuxinator/version.rb
CHANGED
data/lib/tmuxinator/window.rb
CHANGED
@@ -29,7 +29,7 @@ module Tmuxinator
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def layout
|
32
|
-
yaml["layout"]
|
32
|
+
yaml["layout"]&.shellescape
|
33
33
|
end
|
34
34
|
|
35
35
|
def synchronize
|
@@ -139,7 +139,7 @@ module Tmuxinator
|
|
139
139
|
end
|
140
140
|
|
141
141
|
def synchronize_before?
|
142
|
-
|
142
|
+
[true, "before"].include?(synchronize)
|
143
143
|
end
|
144
144
|
|
145
145
|
def synchronize_after?
|
data/lib/tmuxinator.rb
CHANGED
data/spec/factories/projects.rb
CHANGED
@@ -115,4 +115,12 @@ FactoryBot.define do
|
|
115
115
|
|
116
116
|
initialize_with { Tmuxinator::Project.load(file) }
|
117
117
|
end
|
118
|
+
|
119
|
+
factory :project_with_append, class: Tmuxinator::Project do
|
120
|
+
transient do
|
121
|
+
file { "spec/fixtures/sample.yml" }
|
122
|
+
end
|
123
|
+
|
124
|
+
initialize_with { Tmuxinator::Project.load(file, append: true) }
|
125
|
+
end
|
118
126
|
end
|
@@ -99,11 +99,18 @@ describe Tmuxinator::Cli do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
it "should call #start" do
|
102
|
-
|
103
|
-
expect(cli).to receive(:new).and_return(instance)
|
104
|
-
expect(instance).to receive(:start).with(*args)
|
102
|
+
expect(cli).to receive(:start).with([:start, *args])
|
105
103
|
subject
|
106
104
|
end
|
105
|
+
|
106
|
+
context "and the append option is passed" do
|
107
|
+
let(:args) { ["sample", "--append"] }
|
108
|
+
|
109
|
+
it "should call #start" do
|
110
|
+
expect(cli).to receive(:start).with([:start, *args])
|
111
|
+
subject
|
112
|
+
end
|
113
|
+
end
|
107
114
|
end
|
108
115
|
|
109
116
|
context "a thor command" do
|
@@ -191,21 +198,24 @@ describe Tmuxinator::Cli do
|
|
191
198
|
|
192
199
|
it "lists the commands" do
|
193
200
|
out, _err = capture_io { cli.start }
|
194
|
-
expected = %w(
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
201
|
+
expected = %w(
|
202
|
+
commands
|
203
|
+
completions
|
204
|
+
copy
|
205
|
+
debug
|
206
|
+
delete
|
207
|
+
doctor
|
208
|
+
edit
|
209
|
+
implode
|
210
|
+
local
|
211
|
+
list
|
212
|
+
new
|
213
|
+
open
|
214
|
+
start
|
215
|
+
stop
|
216
|
+
stop_all
|
217
|
+
version
|
218
|
+
)
|
209
219
|
expect(out).to eq "#{expected.join("\n")}\n"
|
210
220
|
end
|
211
221
|
end
|
@@ -372,6 +382,20 @@ describe Tmuxinator::Cli do
|
|
372
382
|
end
|
373
383
|
end
|
374
384
|
|
385
|
+
describe "#stop_all" do
|
386
|
+
before do
|
387
|
+
allow(Tmuxinator::Config).to receive_messages(validate: project)
|
388
|
+
allow(Tmuxinator::Config).to receive_messages(version: 1.9)
|
389
|
+
end
|
390
|
+
|
391
|
+
it "stops all projects" do
|
392
|
+
ARGV.replace(["stop-all", "--noconfirm"])
|
393
|
+
out, err = capture_io { cli.start }
|
394
|
+
expect(err).to eq ""
|
395
|
+
expect(out).to eq ""
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
375
399
|
describe "#local" do
|
376
400
|
before do
|
377
401
|
allow(Tmuxinator::Config).to receive_messages(validate: project)
|
@@ -900,7 +924,7 @@ describe Tmuxinator::Cli do
|
|
900
924
|
end
|
901
925
|
|
902
926
|
it "should generate a project file" do
|
903
|
-
new_path = described_class.new.find_project_file(name, false)
|
927
|
+
new_path = described_class.new.find_project_file(name, local: false)
|
904
928
|
expect(new_path).to eq path
|
905
929
|
expect(File).to exist new_path
|
906
930
|
end
|
@@ -922,7 +946,7 @@ describe Tmuxinator::Cli do
|
|
922
946
|
end
|
923
947
|
|
924
948
|
it "should _not_ generate a new project file" do
|
925
|
-
new_path = described_class.new.find_project_file(name, false)
|
949
|
+
new_path = described_class.new.find_project_file(name, local: false)
|
926
950
|
expect(new_path).to eq path
|
927
951
|
expect(File).to exist new_path
|
928
952
|
expect(File.read(new_path)).to match %r{#{extra}}
|
@@ -55,7 +55,8 @@ describe Tmuxinator::Config do
|
|
55
55
|
|
56
56
|
Dir.mktmpdir do |dir|
|
57
57
|
config_parent = "#{dir}/non_existent_parent/s"
|
58
|
-
allow(
|
58
|
+
allow(ENV).to receive(:fetch).with("XDG_CONFIG_HOME", "~/.config").
|
59
|
+
and_return config_parent
|
59
60
|
expect(described_class.directory).
|
60
61
|
to eq "#{config_parent}/tmuxinator"
|
61
62
|
expect(File.directory?("#{config_parent}/tmuxinator")).to be true
|
@@ -69,7 +70,6 @@ describe Tmuxinator::Config do
|
|
69
70
|
it "is $TMUXINATOR_CONFIG" do
|
70
71
|
allow(ENV).to receive(:[]).with("TMUXINATOR_CONFIG").
|
71
72
|
and_return "expected"
|
72
|
-
# allow(XDG).to receive(:[]).with("CONFIG").and_return "expected"
|
73
73
|
allow(File).to receive(:directory?).and_return true
|
74
74
|
expect(described_class.environment).to eq "expected"
|
75
75
|
end
|
@@ -87,7 +87,6 @@ describe Tmuxinator::Config do
|
|
87
87
|
|
88
88
|
context "environment variable $TMUXINATOR_CONFIG is set and empty" do
|
89
89
|
it "is an empty string" do
|
90
|
-
allow(XDG).to receive(:[]).with("CONFIG").and_return ""
|
91
90
|
allow(ENV).to receive(:[]).with("TMUXINATOR_CONFIG").and_return ""
|
92
91
|
expect(described_class.environment).to eq ""
|
93
92
|
end
|
@@ -136,7 +135,7 @@ describe Tmuxinator::Config do
|
|
136
135
|
|
137
136
|
describe "#xdg" do
|
138
137
|
it "is $XDG_CONFIG_HOME/tmuxinator" do
|
139
|
-
expect(described_class.xdg).to eq "
|
138
|
+
expect(described_class.xdg).to eq File.expand_path("~/.config/tmuxinator")
|
140
139
|
end
|
141
140
|
end
|
142
141
|
|
@@ -181,7 +180,8 @@ describe Tmuxinator::Config do
|
|
181
180
|
|
182
181
|
before do
|
183
182
|
expect(Tmuxinator::Doctor).to receive(:installed?).and_return(true)
|
184
|
-
allow_any_instance_of(Kernel).to receive(:`).
|
183
|
+
allow_any_instance_of(Kernel).to receive(:`).
|
184
|
+
with(/tmux\s-V/).
|
185
185
|
and_return("tmux #{version}")
|
186
186
|
end
|
187
187
|
|
@@ -37,6 +37,10 @@ describe Tmuxinator::Project do
|
|
37
37
|
FactoryBot.build(:project_with_alias)
|
38
38
|
end
|
39
39
|
|
40
|
+
let(:project_with_append) do
|
41
|
+
FactoryBot.build(:project_with_append)
|
42
|
+
end
|
43
|
+
|
40
44
|
it "should include Hooks" do
|
41
45
|
expect(project).to be_kind_of(Tmuxinator::Hooks::Project)
|
42
46
|
end
|
@@ -46,6 +50,21 @@ describe Tmuxinator::Project do
|
|
46
50
|
it "creates an instance" do
|
47
51
|
expect(project).to be_a(Tmuxinator::Project)
|
48
52
|
end
|
53
|
+
|
54
|
+
it "validates append outside a current session" do
|
55
|
+
Tmuxinator::Project.any_instance.stub(tmux_has_session?: false)
|
56
|
+
expect { project_with_append }.to(
|
57
|
+
raise_error(
|
58
|
+
RuntimeError,
|
59
|
+
"Cannot append to a session that does not exist"
|
60
|
+
)
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "validates append within a current session" do
|
65
|
+
Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
|
66
|
+
expect { project_with_append }.to_not raise_error
|
67
|
+
end
|
49
68
|
end
|
50
69
|
end
|
51
70
|
|
@@ -262,6 +281,16 @@ describe Tmuxinator::Project do
|
|
262
281
|
end
|
263
282
|
end
|
264
283
|
end
|
284
|
+
|
285
|
+
context "no_pre_window option is true" do
|
286
|
+
before do
|
287
|
+
allow(project).to receive_messages(no_pre_window: true)
|
288
|
+
end
|
289
|
+
|
290
|
+
it "returns nil" do
|
291
|
+
expect(pre_window).to be_nil
|
292
|
+
end
|
293
|
+
end
|
265
294
|
end
|
266
295
|
|
267
296
|
describe "#socket" do
|
@@ -368,6 +397,17 @@ describe Tmuxinator::Project do
|
|
368
397
|
expect(project.base_index).to eq 0
|
369
398
|
end
|
370
399
|
end
|
400
|
+
|
401
|
+
context "with append set" do
|
402
|
+
before do
|
403
|
+
Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
|
404
|
+
project_with_append.stub(last_window_index: 3)
|
405
|
+
end
|
406
|
+
|
407
|
+
it "defaults to the next window index" do
|
408
|
+
expect(project_with_append.base_index).to eq 4
|
409
|
+
end
|
410
|
+
end
|
371
411
|
end
|
372
412
|
|
373
413
|
describe "#startup_window" do
|
@@ -410,6 +450,13 @@ describe Tmuxinator::Project do
|
|
410
450
|
it "gets the window and index for tmux" do
|
411
451
|
expect(project.window(1)).to eq "sample:1"
|
412
452
|
end
|
453
|
+
|
454
|
+
context "with append set" do
|
455
|
+
it "excludes the session name" do
|
456
|
+
Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
|
457
|
+
expect(project_with_append.window(1)).to eq ":1"
|
458
|
+
end
|
459
|
+
end
|
413
460
|
end
|
414
461
|
|
415
462
|
describe "#name?" do
|
@@ -576,6 +623,13 @@ describe Tmuxinator::Project do
|
|
576
623
|
expect(project.tmux_new_session_command).to eq command
|
577
624
|
end
|
578
625
|
end
|
626
|
+
|
627
|
+
context "with append set" do
|
628
|
+
it "returns nothing" do
|
629
|
+
Tmuxinator::Project.any_instance.stub(tmux_has_session?: true)
|
630
|
+
expect(project_with_append.tmux_new_session_command).to be_nil
|
631
|
+
end
|
632
|
+
end
|
579
633
|
end
|
580
634
|
|
581
635
|
describe "tmux_kill_session_command" do
|
@@ -611,7 +665,7 @@ describe Tmuxinator::Project do
|
|
611
665
|
end
|
612
666
|
|
613
667
|
describe "::parse_settings" do
|
614
|
-
let(:args) { ["one", "two=three"] }
|
668
|
+
let(:args) { ["one", "two=three", "four=five=six"] }
|
615
669
|
|
616
670
|
it "returns settings in a hash" do
|
617
671
|
expect(described_class.parse_settings(args)["two"]).to eq("three")
|
@@ -621,6 +675,10 @@ describe Tmuxinator::Project do
|
|
621
675
|
described_class.parse_settings(args)
|
622
676
|
expect(args).to eq(["one"])
|
623
677
|
end
|
678
|
+
|
679
|
+
it "handles equals signs in values" do
|
680
|
+
expect(described_class.parse_settings(args)["four"]).to eq("five=six")
|
681
|
+
end
|
624
682
|
end
|
625
683
|
|
626
684
|
describe "#validate!" do
|
@@ -12,7 +12,7 @@ describe Tmuxinator::WemuxSupport do
|
|
12
12
|
it "renders the template" do
|
13
13
|
expect(File).to receive(:read).at_least(:once) { "wemux ls 2>/dev/null" }
|
14
14
|
|
15
|
-
expect(instance.render).to match %r{wemux.ls.2
|
15
|
+
expect(instance.render).to match %r{wemux.ls.2>/dev/null}
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "coveralls"
|
4
3
|
require "pry"
|
5
4
|
require "simplecov"
|
6
|
-
require "xdg"
|
7
5
|
|
8
|
-
formatters = [
|
9
|
-
SimpleCov::Formatter::HTMLFormatter,
|
10
|
-
Coveralls::SimpleCov::Formatter
|
11
|
-
]
|
12
|
-
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatters)
|
13
6
|
SimpleCov.start do
|
7
|
+
if ENV["CI"]
|
8
|
+
formatter SimpleCov::Formatter::SimpleFormatter
|
9
|
+
else
|
10
|
+
formatter SimpleCov::Formatter::MultiFormatter.new(
|
11
|
+
[
|
12
|
+
SimpleCov::Formatter::HTMLFormatter,
|
13
|
+
SimpleCov::Formatter::SimpleFormatter,
|
14
|
+
]
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
14
18
|
add_filter "vendor/cache"
|
15
19
|
end
|
16
20
|
|
@@ -54,11 +58,11 @@ def tmux_config(options = {})
|
|
54
58
|
"bell-on-alert off",
|
55
59
|
]
|
56
60
|
|
57
|
-
if base_index = options.fetch(:base_index
|
61
|
+
if base_index = options.fetch(:base_index, 1)
|
58
62
|
standard_options << "base-index #{base_index}"
|
59
63
|
end
|
60
64
|
|
61
|
-
if pane_base_index = options.fetch(:pane_base_index
|
65
|
+
if pane_base_index = options.fetch(:pane_base_index, 1)
|
62
66
|
standard_options << "pane-base-index #{pane_base_index}"
|
63
67
|
end
|
64
68
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tmuxinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Allen Bargi
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-08-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erubi
|
@@ -17,62 +17,42 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '1.
|
20
|
+
version: '1.13'
|
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: '1.
|
27
|
+
version: '1.13'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: thor
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 1.
|
34
|
+
version: 1.4.0
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.
|
41
|
+
version: 1.4.0
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
43
|
+
name: amazing_print
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
49
|
-
- - ">="
|
50
|
-
- !ruby/object:Gem::Version
|
51
|
-
version: 2.2.5
|
52
|
-
type: :runtime
|
53
|
-
prerelease: false
|
54
|
-
version_requirements: !ruby/object:Gem::Requirement
|
55
|
-
requirements:
|
56
|
-
- - "~>"
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
version: '2.2'
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 2.2.5
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: awesome_print
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.2'
|
48
|
+
version: '1.8'
|
69
49
|
type: :development
|
70
50
|
prerelease: false
|
71
51
|
version_requirements: !ruby/object:Gem::Requirement
|
72
52
|
requirements:
|
73
53
|
- - "~>"
|
74
54
|
- !ruby/object:Gem::Version
|
75
|
-
version: '1.
|
55
|
+
version: '1.8'
|
76
56
|
- !ruby/object:Gem::Dependency
|
77
57
|
name: bundler
|
78
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -87,118 +67,90 @@ dependencies:
|
|
87
67
|
- - ">="
|
88
68
|
- !ruby/object:Gem::Version
|
89
69
|
version: '1.3'
|
90
|
-
- !ruby/object:Gem::Dependency
|
91
|
-
name: coveralls
|
92
|
-
requirement: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0.8'
|
97
|
-
type: :development
|
98
|
-
prerelease: false
|
99
|
-
version_requirements: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0.8'
|
104
70
|
- !ruby/object:Gem::Dependency
|
105
71
|
name: factory_bot
|
106
72
|
requirement: !ruby/object:Gem::Requirement
|
107
73
|
requirements:
|
108
74
|
- - "~>"
|
109
75
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
76
|
+
version: '6.5'
|
111
77
|
type: :development
|
112
78
|
prerelease: false
|
113
79
|
version_requirements: !ruby/object:Gem::Requirement
|
114
80
|
requirements:
|
115
81
|
- - "~>"
|
116
82
|
- !ruby/object:Gem::Version
|
117
|
-
version: '
|
83
|
+
version: '6.5'
|
118
84
|
- !ruby/object:Gem::Dependency
|
119
85
|
name: pry
|
120
86
|
requirement: !ruby/object:Gem::Requirement
|
121
87
|
requirements:
|
122
88
|
- - "~>"
|
123
89
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
90
|
+
version: '0.15'
|
125
91
|
type: :development
|
126
92
|
prerelease: false
|
127
93
|
version_requirements: !ruby/object:Gem::Requirement
|
128
94
|
requirements:
|
129
95
|
- - "~>"
|
130
96
|
- !ruby/object:Gem::Version
|
131
|
-
version: '0.
|
97
|
+
version: '0.15'
|
132
98
|
- !ruby/object:Gem::Dependency
|
133
99
|
name: rake
|
134
100
|
requirement: !ruby/object:Gem::Requirement
|
135
101
|
requirements:
|
136
102
|
- - "~>"
|
137
103
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
104
|
+
version: '13.3'
|
139
105
|
type: :development
|
140
106
|
prerelease: false
|
141
107
|
version_requirements: !ruby/object:Gem::Requirement
|
142
108
|
requirements:
|
143
109
|
- - "~>"
|
144
110
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
111
|
+
version: '13.3'
|
146
112
|
- !ruby/object:Gem::Dependency
|
147
113
|
name: rspec
|
148
114
|
requirement: !ruby/object:Gem::Requirement
|
149
115
|
requirements:
|
150
116
|
- - "~>"
|
151
117
|
- !ruby/object:Gem::Version
|
152
|
-
version: '3.
|
118
|
+
version: '3.13'
|
153
119
|
type: :development
|
154
120
|
prerelease: false
|
155
121
|
version_requirements: !ruby/object:Gem::Requirement
|
156
122
|
requirements:
|
157
123
|
- - "~>"
|
158
124
|
- !ruby/object:Gem::Version
|
159
|
-
version: '3.
|
125
|
+
version: '3.13'
|
160
126
|
- !ruby/object:Gem::Dependency
|
161
127
|
name: rubocop
|
162
128
|
requirement: !ruby/object:Gem::Requirement
|
163
129
|
requirements:
|
164
130
|
- - "~>"
|
165
131
|
- !ruby/object:Gem::Version
|
166
|
-
version:
|
132
|
+
version: '1.79'
|
167
133
|
type: :development
|
168
134
|
prerelease: false
|
169
135
|
version_requirements: !ruby/object:Gem::Requirement
|
170
136
|
requirements:
|
171
137
|
- - "~>"
|
172
138
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
139
|
+
version: '1.79'
|
174
140
|
- !ruby/object:Gem::Dependency
|
175
141
|
name: simplecov
|
176
142
|
requirement: !ruby/object:Gem::Requirement
|
177
143
|
requirements:
|
178
144
|
- - "~>"
|
179
145
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0.
|
146
|
+
version: '0.22'
|
181
147
|
type: :development
|
182
148
|
prerelease: false
|
183
149
|
version_requirements: !ruby/object:Gem::Requirement
|
184
150
|
requirements:
|
185
151
|
- - "~>"
|
186
152
|
- !ruby/object:Gem::Version
|
187
|
-
version: '0.
|
188
|
-
- !ruby/object:Gem::Dependency
|
189
|
-
name: unicode-display_width
|
190
|
-
requirement: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - "~>"
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '1.3'
|
195
|
-
type: :development
|
196
|
-
prerelease: false
|
197
|
-
version_requirements: !ruby/object:Gem::Requirement
|
198
|
-
requirements:
|
199
|
-
- - "~>"
|
200
|
-
- !ruby/object:Gem::Version
|
201
|
-
version: '1.3'
|
153
|
+
version: '0.22'
|
202
154
|
description: Create and manage complex tmux sessions easily.
|
203
155
|
email:
|
204
156
|
- allen.bargi@gmail.com
|
@@ -281,14 +233,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
281
233
|
requirements:
|
282
234
|
- - ">="
|
283
235
|
- !ruby/object:Gem::Version
|
284
|
-
version: 2.
|
236
|
+
version: '2.7'
|
285
237
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
286
238
|
requirements:
|
287
239
|
- - ">="
|
288
240
|
- !ruby/object:Gem::Version
|
289
|
-
version:
|
241
|
+
version: '2.7'
|
290
242
|
requirements: []
|
291
|
-
rubygems_version: 3.5.
|
243
|
+
rubygems_version: 3.5.22
|
292
244
|
signing_key:
|
293
245
|
specification_version: 4
|
294
246
|
summary: Create and manage complex tmux sessions easily.
|