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 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
@@ -1,3 +1,9 @@
1
+ Add contributors
2
+
3
+ Features:
4
+ pane
5
+ RVM
6
+
1
7
  Later:
2
8
  x. support panes
3
9
  x. install theme
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.2.0
data/lib/tmuxinator.rb CHANGED
@@ -5,5 +5,7 @@ require 'tmuxinator/helper'
5
5
  require 'tmuxinator/cli'
6
6
  require 'tmuxinator/config_writer'
7
7
 
8
+ TMUX_TEMPLATE = "#{File.dirname(__FILE__)}/tmuxinator/assets/tmux_config.tmux"
9
+
8
10
  module Tmuxinator
9
11
  end
@@ -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
- cd <%= @project_root %>
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.each do |tab| %>
10
- <% unless @tabs.index(tab) == 0 %>
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
- <% @tabs.each do |tab| %>
16
- tmux send-keys -t <%= @project_name %>:<%= @tabs.index(tab) + 1 %> '<%= tab.stuff %>' C-m
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 <%= @project_name %>:1
29
+ tmux select-window -t <%= window(1) %>
20
30
 
21
31
  fi
22
32
 
23
- tmux -u attach-session -t <%= @project_name %>
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
@@ -6,7 +6,7 @@ module Tmuxinator
6
6
  class << self
7
7
  include Tmuxinator::Helper
8
8
 
9
- def start(*args)
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(*args)
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(*args)
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(@name)
75
+ open @name
76
76
  end
77
77
  alias :c :copy
78
78
 
79
- def delete(*args)
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(*args)
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(*args)
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(method, *args, &block)
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(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(filename)
12
- @filename = filename
13
- @file_path = "#{root_dir}#{@filename}.yml"
14
- process_config!
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
- template = "#{File.dirname(__FILE__)}/assets/tmux_config.tmux"
19
- erb = ERB.new(IO.read(template)).result(binding)
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_#{@filename}='$SHELL #{config_path}'"
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(@file_path))
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
- t.stuff = value.is_a?(Array) ? value.join(" && ") : value
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(stuff)
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
@@ -1,7 +1,50 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
- describe "Tmuxinator" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
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.1.6"
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-02-02}
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.5.0}
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
- - 1
9
- - 6
10
- version: 0.1.6
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-02-02 00:00:00 +01:00
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.5.0
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.