tmuxinator 0.1.6 → 0.2.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.
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.