tmuxinator 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +31 -3
- data/TODO +6 -0
- data/VERSION +1 -1
- data/lib/tmuxinator.rb +2 -0
- data/lib/tmuxinator/assets/sample.yml +7 -0
- data/lib/tmuxinator/assets/tmux_config.tmux +25 -11
- data/lib/tmuxinator/cli.rb +8 -9
- data/lib/tmuxinator/config_writer.rb +56 -14
- data/spec/spec_helper.rb +2 -0
- data/spec/tmuxinator_spec.rb +46 -3
- data/tmuxinator.gemspec +3 -3
- metadata +9 -9
data/README.md
CHANGED
@@ -42,6 +42,7 @@ Create or edit your projects with this command. aliased to `o`. Your default edi
|
|
42
42
|
|
43
43
|
project_name: tmuxinator
|
44
44
|
project_root: ~/code/rails_project
|
45
|
+
rvm: 1.9.2@rails_project
|
45
46
|
tabs:
|
46
47
|
- shell: git pull
|
47
48
|
- database: rails db
|
@@ -50,12 +51,26 @@ Create or edit your projects with this command. aliased to `o`. Your default edi
|
|
50
51
|
- cd logs
|
51
52
|
- tail -f development.log
|
52
53
|
- ssh: ssh me@myhost
|
53
|
-
|
54
|
+
- window_with_panes
|
55
|
+
layout: main-vertical
|
56
|
+
panes:
|
57
|
+
- vim
|
58
|
+
- #empty, will just run plain bash
|
59
|
+
- top
|
54
60
|
|
55
61
|
If a tab contains multiple commands, they will be 'joined' together with '&&'.
|
56
|
-
|
57
62
|
If you want to have your own default config, place it into $HOME/.tmuxinator/default.yml
|
58
63
|
|
64
|
+
## Panes Support
|
65
|
+
you can define your own panes inside a window likes this:
|
66
|
+
|
67
|
+
- window_with_panes
|
68
|
+
layout: main-vertical
|
69
|
+
panes:
|
70
|
+
- vim
|
71
|
+
- #empty, will just run plain bash
|
72
|
+
- top
|
73
|
+
|
59
74
|
|
60
75
|
## Starting a project
|
61
76
|
|
@@ -111,6 +126,19 @@ shows tmuxinator's help. aliased to `h`
|
|
111
126
|
|
112
127
|
I would love to hear your feedback on this project! Send me a message!
|
113
128
|
|
129
|
+
## Contributors:
|
130
|
+
|
131
|
+
* [Aaron Spiegel](https://github.com/spiegela)
|
132
|
+
* [Jay Adkisson](https://github.com/jayferd)
|
133
|
+
* [Chris Lerum](https://github.com/chrislerum)
|
134
|
+
* [David Bolton](https://github.com/lightningdb)
|
135
|
+
* [Thibault Duplessis](https://github.com/ornicar)
|
136
|
+
|
137
|
+
## History
|
138
|
+
###v. 0.2.0
|
139
|
+
* added pane support (Thanks to Aaron Spiegel)
|
140
|
+
* RVM support (Thanks to Jay Adkisoon)
|
141
|
+
|
114
142
|
## Contributing to tmuxinator
|
115
143
|
|
116
144
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
@@ -123,4 +151,4 @@ I would love to hear your feedback on this project! Send me a message!
|
|
123
151
|
|
124
152
|
## Copyright
|
125
153
|
|
126
|
-
Copyright (c) 2010 Allen Bargi. See LICENSE.txt for further details.
|
154
|
+
Copyright (c) 2010 Allen Bargi. See LICENSE.txt for further details.
|
data/TODO
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/tmuxinator.rb
CHANGED
@@ -3,7 +3,14 @@
|
|
3
3
|
|
4
4
|
project_name: Tmuxinator
|
5
5
|
project_root: ~/code/rails_project
|
6
|
+
rvm: 1.9.2@rails_project
|
6
7
|
tabs:
|
8
|
+
- editor:
|
9
|
+
layout: main-vertical
|
10
|
+
panes:
|
11
|
+
- vim
|
12
|
+
- #empty, will just run plain bash
|
13
|
+
- top
|
7
14
|
- shell: git pull
|
8
15
|
- database: rails db
|
9
16
|
- server: rails s
|
@@ -1,23 +1,37 @@
|
|
1
|
-
|
1
|
+
#!<%= ENV['SHELL'] || '/bin/bash' %>
|
2
|
+
cd <%=s @project_root %>
|
2
3
|
tmux start-server
|
3
4
|
|
4
|
-
if ! $(tmux has-session -t <%= @project_name %>); then
|
5
|
+
if ! $(tmux has-session -t <%=s @project_name %>); then
|
5
6
|
|
7
|
+
tmux new-session -d -s <%=s @project_name %> -n <%=s @tabs[0].name %>
|
6
8
|
tmux set-option base-index 1
|
7
|
-
tmux new-session -d -s <%= @project_name %> -n <%= @tabs[0].name %>
|
8
9
|
|
9
|
-
<% @tabs.
|
10
|
-
|
11
|
-
tmux new-window -t <%= @project_name %>:<%= @tabs.index(tab) + 1 %> -n <%= tab.name %>
|
12
|
-
<% end %>
|
10
|
+
<% @tabs[1..-1].each_with_index do |tab, i| %>
|
11
|
+
tmux new-window -t <%= window(i+2) %> -n <%=s tab.name %>
|
13
12
|
<% end %>
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
# set up tabs and panes
|
15
|
+
<% @tabs.each_with_index do |tab, i| %>
|
16
|
+
# tab "<%= tab.name %>"
|
17
|
+
<% if tab.command %>
|
18
|
+
<%= send_keys(tab.command, i+1) %>
|
19
|
+
<% elsif tab.panes %>
|
20
|
+
<%= send_keys(tab.panes.shift, i+1) %>
|
21
|
+
<% tab.panes.each do |pane| %>
|
22
|
+
tmux splitw -t <%= window(i+1) %>
|
23
|
+
<%= send_keys(pane, i+1) %>
|
24
|
+
<% end %>
|
25
|
+
tmux select-layout -t <%= window(i+1) %> <%=s tab.layout %>
|
26
|
+
<% end %>
|
17
27
|
<% end %>
|
18
28
|
|
19
|
-
tmux select-window -t <%=
|
29
|
+
tmux select-window -t <%= window(1) %>
|
20
30
|
|
21
31
|
fi
|
22
32
|
|
23
|
-
|
33
|
+
if [ -z $TMUX ]; then
|
34
|
+
tmux -u attach-session -t <%=s @project_name %>
|
35
|
+
else
|
36
|
+
tmux -u switch-client -t <%=s @project_name %>
|
37
|
+
fi
|
data/lib/tmuxinator/cli.rb
CHANGED
@@ -6,7 +6,7 @@ module Tmuxinator
|
|
6
6
|
class << self
|
7
7
|
include Tmuxinator::Helper
|
8
8
|
|
9
|
-
def start
|
9
|
+
def start *args
|
10
10
|
if args.empty?
|
11
11
|
self.usage
|
12
12
|
else
|
@@ -40,7 +40,7 @@ module Tmuxinator
|
|
40
40
|
alias :h :usage
|
41
41
|
|
42
42
|
# Open a config file, it's created if it doesn't exist already.
|
43
|
-
def open
|
43
|
+
def open *args
|
44
44
|
exit!("You must specify a name for the new project") unless args.size > 0
|
45
45
|
puts "warning: passing multiple arguments to open will be ignored" if args.size > 1
|
46
46
|
@name = args.shift
|
@@ -56,7 +56,7 @@ module Tmuxinator
|
|
56
56
|
end
|
57
57
|
alias :o :open
|
58
58
|
|
59
|
-
def copy
|
59
|
+
def copy *args
|
60
60
|
@copy = args.shift
|
61
61
|
@name = args.shift
|
62
62
|
@config_to_copy = "#{root_dir}#{@copy}.yml"
|
@@ -72,11 +72,11 @@ module Tmuxinator
|
|
72
72
|
puts "Overwriting #{@name}"
|
73
73
|
end
|
74
74
|
end
|
75
|
-
open
|
75
|
+
open @name
|
76
76
|
end
|
77
77
|
alias :c :copy
|
78
78
|
|
79
|
-
def delete
|
79
|
+
def delete *args
|
80
80
|
puts "warning: passing multiple arguments to delete will be ignored" if args.size > 1
|
81
81
|
filename = args.shift
|
82
82
|
file_path = "#{root_dir}#{filename}.yml"
|
@@ -92,7 +92,7 @@ module Tmuxinator
|
|
92
92
|
end
|
93
93
|
alias :d :delete
|
94
94
|
|
95
|
-
def implode
|
95
|
+
def implode *args
|
96
96
|
exit!("delete_all doesn't accapt any arguments!") unless args.empty?
|
97
97
|
confirm!("Are you sure you want to delete all tmuxinator configs? (type yes or no):") do
|
98
98
|
FileUtils.remove_dir(root_dir)
|
@@ -101,7 +101,7 @@ module Tmuxinator
|
|
101
101
|
end
|
102
102
|
alias :i :implode
|
103
103
|
|
104
|
-
def list
|
104
|
+
def list *args
|
105
105
|
verbose = args.include?("-v")
|
106
106
|
puts "tmuxinator configs:"
|
107
107
|
Dir["#{root_dir}**"].each do |path|
|
@@ -123,7 +123,6 @@ module Tmuxinator
|
|
123
123
|
Dir["#{root_dir}*.tmux"].each {|p| FileUtils.rm(p) }
|
124
124
|
aliases = []
|
125
125
|
Dir["#{root_dir}*.yml"].each do |path|
|
126
|
-
path = File.basename(path, '.yml')
|
127
126
|
aliases << Tmuxinator::ConfigWriter.new(path).write!
|
128
127
|
end
|
129
128
|
Tmuxinator::ConfigWriter.write_aliases(aliases)
|
@@ -145,7 +144,7 @@ module Tmuxinator
|
|
145
144
|
}
|
146
145
|
end
|
147
146
|
|
148
|
-
def method_missing
|
147
|
+
def method_missing method, *args, &block
|
149
148
|
puts "There's no command called #{method} in tmuxinator"
|
150
149
|
usage
|
151
150
|
end
|
@@ -1,26 +1,34 @@
|
|
1
1
|
module Tmuxinator
|
2
2
|
|
3
3
|
class ConfigWriter
|
4
|
+
attr :file_name, :file_path, :project_name, :project_root, :rvm, :tabs
|
4
5
|
|
5
6
|
include Tmuxinator::Helper
|
6
7
|
|
7
|
-
def self.write_aliases
|
8
|
+
def self.write_aliases aliases
|
8
9
|
File.open("#{ENV["HOME"]}/.tmuxinator/scripts/tmuxinator", 'w') {|f| f.write(aliases.join("\n")) }
|
9
10
|
end
|
10
11
|
|
11
|
-
def initialize
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def initialize this_full_path=nil
|
13
|
+
self.file_path = this_full_path if this_full_path
|
14
|
+
end
|
15
|
+
|
16
|
+
def file_path= full_path
|
17
|
+
@file_path = full_path
|
18
|
+
@file_name = File.basename full_path, '.yml'
|
19
|
+
process_config! if full_path && File.exist?(full_path)
|
15
20
|
end
|
16
21
|
|
17
22
|
def write!
|
18
|
-
|
19
|
-
erb = ERB.new(IO.read(
|
20
|
-
config_path = "#{root_dir}#{@filename}.tmux"
|
23
|
+
raise "Unable to write with out a file_name defined" unless self.file_name
|
24
|
+
erb = ERB.new(IO.read(TMUX_TEMPLATE)).result(binding)
|
21
25
|
tmp = File.open(config_path, 'w') {|f| f.write(erb) }
|
22
26
|
|
23
|
-
"alias start_#{
|
27
|
+
"alias start_#{file_name}='$SHELL #{config_path}'"
|
28
|
+
end
|
29
|
+
|
30
|
+
def config_path
|
31
|
+
"#{root_dir}#{file_name}.tmux" if file_name
|
24
32
|
end
|
25
33
|
|
26
34
|
private
|
@@ -30,7 +38,7 @@ module Tmuxinator
|
|
30
38
|
end
|
31
39
|
|
32
40
|
def process_config!
|
33
|
-
yaml = YAML.load(File.read(
|
41
|
+
yaml = YAML.load(File.read(file_path))
|
34
42
|
|
35
43
|
exit!("Your configuration file should include some tabs.") if yaml["tabs"].nil?
|
36
44
|
exit!("Your configuration file didn't specify a 'project_root'") if yaml["project_root"].nil?
|
@@ -38,21 +46,55 @@ module Tmuxinator
|
|
38
46
|
|
39
47
|
@project_name = yaml["project_name"]
|
40
48
|
@project_root = yaml["project_root"]
|
49
|
+
@rvm = yaml["rvm"]
|
41
50
|
@tabs = []
|
42
51
|
|
43
52
|
yaml["tabs"].each do |tab|
|
44
53
|
t = OpenStruct.new
|
45
54
|
t.name = tab.keys.first
|
46
55
|
value = tab.values.first
|
47
|
-
|
56
|
+
case value
|
57
|
+
when Array
|
58
|
+
value.unshift "rvm use #{@rvm}" if @rvm
|
59
|
+
t.command = value.join(" && ")
|
60
|
+
when String
|
61
|
+
value = "rvm use #{@rvm} && #{value}" if @rvm
|
62
|
+
t.command = value
|
63
|
+
when Hash
|
64
|
+
t.panes = (value["panes"] || ['']).map do |pane|
|
65
|
+
if pane.is_a? Array
|
66
|
+
pane.unshift! "rvm use #{@rvm}" if @rvm
|
67
|
+
pane = pane.join(' && ')
|
68
|
+
end
|
69
|
+
pane = "rvm use #{@rvm} && #{pane}" if @rvm
|
70
|
+
pane
|
71
|
+
end
|
72
|
+
t.layout = value["layout"]
|
73
|
+
end
|
48
74
|
@tabs << t
|
49
75
|
end
|
50
|
-
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_tabs tab_list
|
51
79
|
end
|
52
80
|
|
53
|
-
def write_alias
|
81
|
+
def write_alias stuff
|
54
82
|
File.open("#{root_dir}scripts/#{@filename}", 'w') {|f| f.write(stuff) }
|
55
83
|
end
|
84
|
+
|
85
|
+
def shell_escape str
|
86
|
+
"'#{str.to_s.gsub("'") { %('\'') }}'"
|
87
|
+
end
|
88
|
+
alias s shell_escape
|
89
|
+
|
90
|
+
def window(i)
|
91
|
+
"#{s @project_name}:#{i}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def send_keys cmd, window_number
|
95
|
+
return '' unless cmd
|
96
|
+
"tmux send-keys -t #{window(window_number)} #{s cmd} C-m"
|
97
|
+
end
|
56
98
|
end
|
57
99
|
|
58
|
-
end
|
100
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -7,6 +7,8 @@ require 'tmuxinator'
|
|
7
7
|
# in ./support/ and its subdirectories.
|
8
8
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
9
|
|
10
|
+
SAMPLE_CONFIG = File.join(File.dirname(__FILE__), '..', 'lib', 'tmuxinator', 'assets', 'sample.yml')
|
11
|
+
|
10
12
|
RSpec.configure do |config|
|
11
13
|
|
12
14
|
end
|
data/spec/tmuxinator_spec.rb
CHANGED
@@ -1,7 +1,50 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
3
|
+
describe Tmuxinator::ConfigWriter do
|
4
|
+
context "With no defined filename" do
|
5
|
+
its(:file_path){ should be_nil }
|
6
|
+
its(:project_name){ should be_nil }
|
7
|
+
its(:project_root){ should be_nil }
|
8
|
+
its(:rvm){ should be_nil }
|
9
|
+
its(:tabs){ should be_nil }
|
10
|
+
its(:config_path){ should be_nil }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "While Defining the filename on init" do
|
14
|
+
subject{ Tmuxinator::ConfigWriter.new(SAMPLE_CONFIG) }
|
15
|
+
its(:file_path){ should eql SAMPLE_CONFIG }
|
16
|
+
its(:file_name){ should eql "sample" }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "After filename has been defined" do
|
20
|
+
before do
|
21
|
+
subject.file_path = SAMPLE_CONFIG
|
22
|
+
end
|
23
|
+
|
24
|
+
its(:file_path){ should eql SAMPLE_CONFIG }
|
25
|
+
its(:file_name){ should eql File.basename(SAMPLE_CONFIG, '.yml')}
|
26
|
+
its(:project_name){ should eql 'Tmuxinator' }
|
27
|
+
its(:project_root){ should eql '~/code/rails_project' }
|
28
|
+
its(:rvm){ should eql '1.9.2@rails_project' }
|
29
|
+
its(:tabs){ should be_an Array }
|
30
|
+
|
31
|
+
let(:first_tab){ subject.tabs[0] }
|
32
|
+
|
33
|
+
specify{ first_tab.should be_an OpenStruct }
|
34
|
+
specify{ first_tab.name.should eql "editor" }
|
35
|
+
specify{ first_tab.layout.should eql "main-vertical" }
|
36
|
+
specify{ first_tab.panes.should be_an Array }
|
37
|
+
|
38
|
+
it "should prepend each pane with the rvm string" do
|
39
|
+
first_tab.panes.map{|p| p.split(/ && /)[0] }.should eql ["rvm use 1.9.2@rails_project"] * 3
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should append each pane with the command string" do
|
43
|
+
first_tab.panes.map{|p| p.split(/ && /)[1] }.should eql ["vim", nil, "top"]
|
44
|
+
end
|
45
|
+
|
46
|
+
let(:second_tab){ subject.tabs[1] }
|
47
|
+
specify{ second_tab.name.should eql "shell" }
|
48
|
+
specify{ second_tab.command.should eql "rvm use 1.9.2@rails_project && git pull"}
|
6
49
|
end
|
7
50
|
end
|
data/tmuxinator.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tmuxinator}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Allen Bargi"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-03-08}
|
13
13
|
s.default_executable = %q{tmuxinator}
|
14
14
|
s.description = %q{Create and manage complex tmux sessions easily.}
|
15
15
|
s.email = %q{allen.bargi@gmail.com}
|
@@ -63,7 +63,7 @@ Gem::Specification.new do |s|
|
|
63
63
|
|
64
64
|
}
|
65
65
|
s.require_paths = ["lib"]
|
66
|
-
s.rubygems_version = %q{1.
|
66
|
+
s.rubygems_version = %q{1.6.1}
|
67
67
|
s.summary = %q{Create and manage complex tmux sessions easily.}
|
68
68
|
s.test_files = [
|
69
69
|
"spec/spec_helper.rb",
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Allen Bargi
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-03-08 00:00:00 +01:00
|
19
19
|
default_executable: tmuxinator
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -31,8 +31,8 @@ dependencies:
|
|
31
31
|
- 1
|
32
32
|
- 0
|
33
33
|
version: 2.1.0
|
34
|
-
name: rspec
|
35
34
|
version_requirements: *id001
|
35
|
+
name: rspec
|
36
36
|
prerelease: false
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
type: :development
|
@@ -47,8 +47,8 @@ dependencies:
|
|
47
47
|
- 0
|
48
48
|
- 0
|
49
49
|
version: 1.0.0
|
50
|
-
name: bundler
|
51
50
|
version_requirements: *id002
|
51
|
+
name: bundler
|
52
52
|
prerelease: false
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
type: :development
|
@@ -63,8 +63,8 @@ dependencies:
|
|
63
63
|
- 5
|
64
64
|
- 1
|
65
65
|
version: 1.5.1
|
66
|
-
name: jeweler
|
67
66
|
version_requirements: *id003
|
67
|
+
name: jeweler
|
68
68
|
prerelease: false
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
type: :development
|
@@ -77,8 +77,8 @@ dependencies:
|
|
77
77
|
segments:
|
78
78
|
- 0
|
79
79
|
version: "0"
|
80
|
-
name: rcov
|
81
80
|
version_requirements: *id004
|
81
|
+
name: rcov
|
82
82
|
prerelease: false
|
83
83
|
description: Create and manage complex tmux sessions easily.
|
84
84
|
email: allen.bargi@gmail.com
|
@@ -140,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
140
|
requirements: []
|
141
141
|
|
142
142
|
rubyforge_project:
|
143
|
-
rubygems_version: 1.
|
143
|
+
rubygems_version: 1.6.1
|
144
144
|
signing_key:
|
145
145
|
specification_version: 3
|
146
146
|
summary: Create and manage complex tmux sessions easily.
|