tmuxinator 0.6.11 → 0.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.
@@ -4,11 +4,75 @@ module Tmuxinator
4
4
  include Tmuxinator::Deprecations
5
5
  include Tmuxinator::WemuxSupport
6
6
 
7
- attr_reader :yaml, :custom_name
7
+ RBENVRVM_DEP_MSG = <<-M
8
+ DEPRECATION: rbenv/rvm-specific options have been replaced by the
9
+ pre_tab option and will not be supported in 0.8.0.
10
+ M
11
+ TABS_DEP_MSG = <<-M
12
+ DEPRECATION: The tabs option has been replaced by the windows option
13
+ and will not be supported in 0.8.0.
14
+ M
15
+ CLIARGS_DEP_MSG = <<-M
16
+ DEPRECATION: The cli_args option has been replaced by the tmux_options
17
+ option and will not be supported in 0.8.0.
18
+ M
19
+
20
+ attr_reader :yaml
21
+ attr_reader :force_attach
22
+ attr_reader :force_detach
23
+ attr_reader :custom_name
24
+
25
+ def self.load(path, options = {})
26
+ yaml = begin
27
+ raw_content = File.read(path)
28
+
29
+ args = options[:args] || []
30
+ @settings = parse_settings(args)
31
+ @args = args
32
+
33
+ content = Erubis::Eruby.new(raw_content).result(binding)
34
+ YAML.load(content)
35
+ rescue SyntaxError, StandardError
36
+ raise "Failed to parse config file. Please check your formatting."
37
+ end
38
+
39
+ new(yaml, options)
40
+ end
41
+
42
+ def self.parse_settings(args)
43
+ settings = args.select { |x| x.match(/.*=.*/) }
44
+ args.reject! { |x| x.match(/.*=.*/) }
45
+
46
+ settings.map! do |setting|
47
+ parts = setting.split("=")
48
+ [parts[0], parts[1]]
49
+ end
50
+
51
+ Hash[settings]
52
+ end
53
+
54
+ def validate!
55
+ raise "Your project file should include some windows." \
56
+ unless self.windows?
57
+ raise "Your project file didn't specify a 'project_name'" \
58
+ unless self.name?
59
+ self
60
+ end
61
+
62
+ def initialize(yaml, options = {})
63
+ options[:force_attach] = false if options[:force_attach].nil?
64
+ options[:force_detach] = false if options[:force_detach].nil?
8
65
 
9
- def initialize(yaml, custom_name = nil)
10
66
  @yaml = yaml
11
- @custom_name = custom_name
67
+
68
+ @custom_name = options[:custom_name]
69
+
70
+ @force_attach = options[:force_attach]
71
+ @force_detach = options[:force_detach]
72
+
73
+ raise "Cannot force_attach and force_detach at the same time" \
74
+ if @force_attach && @force_detach
75
+
12
76
  load_wemux_overrides if wemux?
13
77
  end
14
78
 
@@ -20,7 +84,7 @@ module Tmuxinator
20
84
  def windows
21
85
  windows_yml = yaml["tabs"] || yaml["windows"]
22
86
 
23
- @windows ||= windows_yml.map.with_index do |window_yml, index|
87
+ @windows ||= (windows_yml || {}).map.with_index do |window_yml, index|
24
88
  Tmuxinator::Window.new(window_yml, index, self)
25
89
  end
26
90
  end
@@ -32,7 +96,7 @@ module Tmuxinator
32
96
 
33
97
  def name
34
98
  name = custom_name || yaml["project_name"] || yaml["name"]
35
- name.blank? ? nil : name.shellescape
99
+ name.blank? ? nil : name.to_s.shellescape
36
100
  end
37
101
 
38
102
  def pre
@@ -44,11 +108,21 @@ module Tmuxinator
44
108
  end
45
109
  end
46
110
 
111
+ def attach?
112
+ if yaml["attach"].nil?
113
+ yaml_attach = true
114
+ else
115
+ yaml_attach = yaml["attach"]
116
+ end
117
+ attach = force_attach || !force_detach && yaml_attach
118
+ attach
119
+ end
120
+
47
121
  def pre_window
48
122
  if rbenv?
49
- "rbenv shell #{yaml["rbenv"]}"
123
+ "rbenv shell #{yaml['rbenv']}"
50
124
  elsif rvm?
51
- "rvm use #{yaml["rvm"]}"
125
+ "rvm use #{yaml['rvm']}"
52
126
  elsif pre_tab?
53
127
  yaml["pre_tab"]
54
128
  else
@@ -56,14 +130,6 @@ module Tmuxinator
56
130
  end
57
131
  end
58
132
 
59
- def attach
60
- attach = true
61
- if !yaml["attach"].nil?
62
- attach = yaml["attach"]
63
- end
64
- attach
65
- end
66
-
67
133
  def post
68
134
  post_config = yaml["post"]
69
135
  if post_config.is_a?(Array)
@@ -86,8 +152,6 @@ module Tmuxinator
86
152
  " -S #{socket_path}"
87
153
  elsif socket_name
88
154
  " -L #{socket_name}"
89
- else
90
- nil
91
155
  end
92
156
  end
93
157
 
@@ -101,9 +165,9 @@ module Tmuxinator
101
165
 
102
166
  def tmux_options
103
167
  if cli_args?
104
- " #{yaml["cli_args"].to_s.strip}"
168
+ " #{yaml['cli_args'].to_s.strip}"
105
169
  elsif tmux_options?
106
- " #{yaml["tmux_options"].to_s.strip}"
170
+ " #{yaml['tmux_options'].to_s.strip}"
107
171
  else
108
172
  ""
109
173
  end
@@ -133,15 +197,11 @@ module Tmuxinator
133
197
  !name.nil?
134
198
  end
135
199
 
136
- def attach?
137
- !!attach
138
- end
139
-
140
200
  def window(i)
141
201
  "#{name}:#{i}"
142
202
  end
143
203
 
144
- def send_pane_command(cmd, window_index, pane_index)
204
+ def send_pane_command(cmd, window_index, _pane_index)
145
205
  if cmd.empty?
146
206
  ""
147
207
  else
@@ -151,7 +211,7 @@ module Tmuxinator
151
211
 
152
212
  def send_keys(cmd, window_index)
153
213
  if cmd.empty?
154
- ""
214
+ ""
155
215
  else
156
216
  "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
157
217
  end
@@ -159,9 +219,9 @@ module Tmuxinator
159
219
 
160
220
  def deprecations
161
221
  deprecations = []
162
- deprecations << "DEPRECATION: rbenv/rvm specific options have been replaced by the pre_tab option and will not be supported in 0.8.0." if yaml["rbenv"] || yaml["rvm"]
163
- deprecations << "DEPRECATION: The tabs option has been replaced by the windows option and will not be supported in 0.8.0." if yaml["tabs"]
164
- deprecations << "DEPRECATION: The cli_args option has been replaced by the tmux_options option and will not be supported in 0.8.0." if yaml["cli_args"]
222
+ deprecations << RBENVRVM_DEP_MSG if yaml["rbenv"] || yaml["rvm"]
223
+ deprecations << TABS_DEP_MSG if yaml["tabs"]
224
+ deprecations << CLIARGS_DEP_MSG if yaml["cli_args"]
165
225
  deprecations
166
226
  end
167
227
 
@@ -177,6 +237,11 @@ module Tmuxinator
177
237
  "#{tmux} start-server\\; show-option -g"
178
238
  end
179
239
 
240
+ def tmux_new_session_command
241
+ window = windows.first.tmux_window_name_option
242
+ "#{tmux} new-session -d -s #{name} #{window}"
243
+ end
244
+
180
245
  private
181
246
 
182
247
  def tmux_config
@@ -187,7 +252,7 @@ module Tmuxinator
187
252
  options_hash = {}
188
253
 
189
254
  options_string = `#{show_tmux_options}`
190
- options_string.encode!("UTF-8", :invalid => :replace)
255
+ options_string.encode!("UTF-8", invalid: :replace)
191
256
  options_string.split("\n").map do |entry|
192
257
  key, value = entry.split("\s")
193
258
  options_hash[key] = value
@@ -1,3 +1,3 @@
1
1
  module Tmuxinator
2
- VERSION = "0.6.11"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -5,17 +5,17 @@ module Tmuxinator
5
5
  end
6
6
 
7
7
  def load_wemux_overrides
8
- self.instance_eval do
9
- def render
8
+ class_eval do
9
+ define_method :render do
10
10
  template = File.read(Tmuxinator::Config.wemux_template)
11
11
  Erubis::Eruby.new(template).result(binding)
12
12
  end
13
13
 
14
- def name
14
+ define_method :name do
15
15
  "wemux"
16
16
  end
17
17
 
18
- def tmux
18
+ define_method :tmux do
19
19
  "wemux"
20
20
  end
21
21
  end
@@ -5,7 +5,9 @@ module Tmuxinator
5
5
  attr_reader :name, :root, :panes, :layout, :commands, :index, :project
6
6
 
7
7
  def initialize(window_yaml, index, project)
8
- @name = !window_yaml.keys.first.nil? ? window_yaml.keys.first.shellescape : nil
8
+ @name = if !window_yaml.keys.first.nil?
9
+ window_yaml.keys.first.shellescape
10
+ end
9
11
  @root = nil
10
12
  @panes = []
11
13
  @layout = nil
@@ -18,7 +20,11 @@ module Tmuxinator
18
20
  if value.is_a?(Hash)
19
21
  @layout = value["layout"] ? value["layout"].shellescape : nil
20
22
  @pre = value["pre"] if value["pre"]
21
- @root = value["root"] ? File.expand_path(value["root"]).shellescape : project.root? ? project.root : nil
23
+ @root = if value["root"]
24
+ File.expand_path(value["root"]).shellescape
25
+ elsif project.root?
26
+ project.root
27
+ end
22
28
 
23
29
  @panes = build_panes(value["panes"])
24
30
  else
@@ -29,7 +35,7 @@ module Tmuxinator
29
35
  def build_panes(panes_yml)
30
36
  Array(panes_yml).map.with_index do |pane_yml, index|
31
37
  if pane_yml.is_a?(Hash)
32
- pane_yml.map do |name, commands|
38
+ pane_yml.map do |_name, commands|
33
39
  Tmuxinator::Pane.new(index, project, self, *commands)
34
40
  end
35
41
  else
@@ -38,7 +44,7 @@ module Tmuxinator
38
44
  end.flatten
39
45
  end
40
46
 
41
- def build_commands(prefix, command_yml)
47
+ def build_commands(_prefix, command_yml)
42
48
  if command_yml.is_a?(Array)
43
49
  command_yml.map do |command|
44
50
  "#{tmux_window_command_prefix} #{command.shellescape} C-m" if command
@@ -80,9 +86,13 @@ module Tmuxinator
80
86
  "#{project.tmux} send-keys -t #{project.name}:#{index + project.base_index}"
81
87
  end
82
88
 
89
+ def tmux_window_name_option
90
+ name ? "-n #{name}" : ""
91
+ end
92
+
83
93
  def tmux_new_window_command
84
94
  path = root? ? "#{Tmuxinator::Config.default_path_option} #{root}" : nil
85
- "#{project.tmux} new-window #{path} -t #{tmux_window_target} -n #{name}"
95
+ "#{project.tmux} new-window #{path} -t #{tmux_window_target} #{tmux_window_name_option}"
86
96
  end
87
97
 
88
98
  def tmux_layout_command
@@ -1,39 +1,81 @@
1
+ def yaml_load(file)
2
+ YAML.load(File.read(File.expand_path(file)))
3
+ end
1
4
  FactoryGirl.define do
2
- factory :project, :class => Tmuxinator::Project do
5
+ factory :project, class: Tmuxinator::Project do
6
+ transient do
7
+ file { yaml_load("spec/fixtures/sample.yml") }
8
+ end
9
+
10
+ initialize_with { Tmuxinator::Project.new(file) }
11
+ end
12
+
13
+ factory :project_with_force_attach, class: Tmuxinator::Project do
14
+ transient do
15
+ file { yaml_load("spec/fixtures/detach.yml") }
16
+ end
17
+
18
+ initialize_with { Tmuxinator::Project.new(file, force_attach: true) }
19
+ end
20
+
21
+ factory :project_with_force_detach, class: Tmuxinator::Project do
22
+ transient do
23
+ file { yaml_load("spec/fixtures/detach.yml") }
24
+ end
25
+ initialize_with { Tmuxinator::Project.new(file, force_detach: true) }
26
+ end
27
+
28
+ factory :project_with_custom_name, class: Tmuxinator::Project do
29
+ transient do
30
+ file { yaml_load("spec/fixtures/sample.yml") }
31
+ end
32
+
33
+ initialize_with { Tmuxinator::Project.new(file, custom_name: "custom") }
34
+ end
35
+
36
+ factory :project_with_number_as_name, class: Tmuxinator::Project do
3
37
  transient do
4
- file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.yml")}")) }
38
+ file { yaml_load("spec/fixtures/sample_number_as_name.yml") }
5
39
  end
6
40
 
7
41
  initialize_with { Tmuxinator::Project.new(file) }
8
42
  end
9
43
 
10
- factory :project_with_custom_name, :class => Tmuxinator::Project do
44
+ factory :project_with_deprecations, class: Tmuxinator::Project do
11
45
  transient do
12
- file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.yml")}")) }
46
+ file { yaml_load("spec/fixtures/sample.deprecations.yml") }
13
47
  end
14
48
 
15
- initialize_with { Tmuxinator::Project.new(file, "custom") }
49
+ initialize_with { Tmuxinator::Project.new(file) }
50
+ end
51
+
52
+ factory :wemux_project, class: Tmuxinator::Project do
53
+ transient do
54
+ file { yaml_load("spec/fixtures/sample_wemux.yml") }
55
+ end
56
+
57
+ initialize_with { Tmuxinator::Project.new(file) }
16
58
  end
17
59
 
18
- factory :project_with_deprecations, :class => Tmuxinator::Project do
60
+ factory :noname_project, class: Tmuxinator::Project do
19
61
  transient do
20
- file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.deprecations.yml")}")) }
62
+ file { yaml_load("spec/fixtures/noname.yml") }
21
63
  end
22
64
 
23
65
  initialize_with { Tmuxinator::Project.new(file) }
24
66
  end
25
67
 
26
- factory :wemux_project, :class => Tmuxinator::Project do
68
+ factory :nowindows_project, class: Tmuxinator::Project do
27
69
  transient do
28
- file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample_wemux.yml")}")) }
70
+ file { yaml_load("spec/fixtures/nowindows.yml") }
29
71
  end
30
72
 
31
73
  initialize_with { Tmuxinator::Project.new(file) }
32
74
  end
33
75
 
34
- factory :noname_project, :class => Tmuxinator::Project do
76
+ factory :nameless_window_project, class: Tmuxinator::Project do
35
77
  transient do
36
- file { YAML.load(File.read("#{File.expand_path("spec/fixtures/noname.yml")}")) }
78
+ file { yaml_load("spec/fixtures/nameless_window.yml") }
37
79
  end
38
80
 
39
81
  initialize_with { Tmuxinator::Project.new(file) }
@@ -0,0 +1,41 @@
1
+ # ~/.tmuxinator/sample.yml
2
+ # you can make as many tabs as you wish...
3
+
4
+ name: sample
5
+ root: ~/test
6
+ socket_name: foo # Remove to use default socket
7
+ pre: sudo /etc/rc.d/mysqld start # Runs before everything
8
+ pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane
9
+ tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux
10
+ attach: false
11
+ windows:
12
+ - editor:
13
+ pre:
14
+ - echo "I get run in each pane, before each pane command!"
15
+ -
16
+ layout: main-vertical
17
+ panes:
18
+ - vim
19
+ - #empty, will just run plain bash
20
+ - top
21
+ - pane_with_multiple_commands:
22
+ - ssh server
23
+ - echo "Hello"
24
+ - shell:
25
+ - git pull
26
+ - git merge
27
+ - guard:
28
+ layout: tiled
29
+ pre:
30
+ - echo "I get run in each pane."
31
+ - echo "Before each pane command!"
32
+ panes:
33
+ -
34
+ - #empty, will just run plain bash
35
+ -
36
+ - database: bundle exec rails db
37
+ - server: bundle exec rails s
38
+ - logs: tail -f log/development.log
39
+ - console: bundle exec rails c
40
+ - capistrano:
41
+ - server: ssh user@example.com
@@ -0,0 +1,5 @@
1
+ name: nameless_window
2
+ root: ~/
3
+ windows:
4
+ - ~: echo "this is a window with no name"
5
+ - other: echo "this window has a name"
@@ -0,0 +1,3 @@
1
+ name: no_windows
2
+ root: ~/
3
+
@@ -7,6 +7,7 @@ socket_name: foo # Remove to use default socket
7
7
  pre: sudo /etc/rc.d/mysqld start # Runs before everything
8
8
  pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane
9
9
  tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux
10
+ tmux_detached: false
10
11
  windows:
11
12
  - editor:
12
13
  pre: