changeset 0:39b72942a4d2

Clone tmuxinator from github https://github.com/tmuxinator/tmuxinator/tree/67140f4abfcf640f433f76310d6b927de06a58ac
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Mon, 21 Jul 2014 08:04:55 +0900
parents
children 107d94e009cc
files .gitignore .rspec .travis.yml CHANGELOG.md CONTRIBUTING.md Gemfile LICENSE README.md Rakefile bin/mux bin/tmuxinator completion/tmuxinator.bash completion/tmuxinator.fish completion/tmuxinator.zsh lib/tmuxinator.rb lib/tmuxinator/assets/sample.yml lib/tmuxinator/assets/template.erb lib/tmuxinator/assets/wemux_template.erb lib/tmuxinator/cli.rb lib/tmuxinator/config.rb lib/tmuxinator/deprecations.rb lib/tmuxinator/pane.rb lib/tmuxinator/project.rb lib/tmuxinator/util.rb lib/tmuxinator/version.rb lib/tmuxinator/wemux_support.rb lib/tmuxinator/window.rb spec/factories/projects.rb spec/fixtures/sample.deprecations.yml spec/fixtures/sample.yml spec/fixtures/sample_wemux.yml spec/lib/tmuxinator/cli_spec.rb spec/lib/tmuxinator/config_spec.rb spec/lib/tmuxinator/pane_spec.rb spec/lib/tmuxinator/project_spec.rb spec/lib/tmuxinator/util_spec.rb spec/lib/tmuxinator/window_spec.rb spec/spec_helper.rb tmuxinator.gemspec
diffstat 39 files changed, 2432 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,19 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+.coveralls.yml
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+tmp
+db
+vendor/
+tags
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.rspec	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,1 @@
+--color --format=documentation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.travis.yml	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,26 @@
+language: ruby
+rvm:
+  - "1.9.3"
+  - "2.0.0"
+  - "2.1.2"
+env:
+  - TMUX_VERSION=master
+  - TMUX_VERSION=1.9
+  - TMUX_VERSION=1.8
+  - TMUX_VERSION=1.7
+  - TMUX_VERSION=1.6
+  - TMUX_VERSION=1.5
+matrix:
+  allow_failures:
+    - env: TMUX_VERSION=1.7
+before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -qq libevent-dev libncurses-dev
+  - git clone git://git.code.sf.net/p/tmux/tmux-code tmux
+  - cd tmux
+  - git checkout $TMUX_VERSION
+  - sh autogen.sh
+  - ./configure && make && sudo make install
+  - cd ..
+  - tmux -V
+script: bundle exec rspec spec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG.md	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,97 @@
+## 0.6.8
+- Remove some duplication #212
+- Add wemux support #88 - Thanks to Andrew Thal (@athal7)
+- Fix typos in readme #217, #216
+- Fix encoding bug #229
+- Fix specs not running due to changes in thor
+
+## 0.6.7
+- Remove use of grep for base-index #171
+- Fix bugs in `Tmuxinator::Config.default?` #169
+- Fix path for Rails log in directory sample #177
+- Add completions for fish shell #179
+- Fix grammar in readme #184
+- Make commands take precedence over project names #182
+- Improve error messages when $EDITOR isn't set #186, #194
+- Add confirmation to deletion prompt #197
+- Fix broken badge references after organisation move
+- Remove dependancy on ActiveSupport #199
+- Fix compatability with tmux 1.9
+
+## 0.6.6
+- Fix a bug caused by not escaping the root path #145
+- Fix bash completion with a single argument #148
+- Fix regression where an array of commands for a window wasn't working #149
+- Add an option to call tmux wrappers or derivatives #154
+- Refactor build\_panes to always return an array #157
+- Clean up some branching code using `.presence` #163
+- Setup TravisCI test matrix for different tmux versions #164
+- Fix some grammar and spelling in readme #166
+- Make multiple commands use tmux's `send-keys` rather than just using `&&` for both panes and windows #100
+
+## 0.6.5
+- Change deprecation continue message from any key to just the enter key
+- Dramatically clean up the readme to be clearer for new users
+- Update the contributing guide with references to the GitHub styleguide and add examples of how to leave good commit messages
+- Use Erubis to render the project sample and fix a bad binding reference
+- Update the sample project to be much simpler
+- Fix not working delete command #142
+- Fix an error in the bash completion script
+- Fix an issue where the wrong project path was being returned
+- Fix an issue where command aliases were being ignored
+
+## 0.6.4
+- Fixes broken backwards compatibility of multiple pre commands #129
+- Fixes tmuxinator ignoring project root when started from within a tmux session #132
+- Add gem version badge
+
+## 0.6.3
+- Remove stray pry #128
+- Allow starting a tmuxinator project while inside a tmux session #130
+- Set the tmux layout after pane creation to avoid pane too small errors #131
+- Check for both pane-base-index and base-index #126
+
+## 0.6.2
+- Also pass command line options to the `base_index` lookup.
+- Fixed bug #116.
+
+## 0.6.1
+- Remove stray binding.pry
+- Fix nil error when creating a new project.
+
+## 0.6.0
+
+- Rewrote core functionality with proper abstractions and unit tests
+- Fixed outstanding bugs #72 #89 #90 #93 #101 #102 #103 #104 #109
+- Switched to thor for command line argument parsing
+- Switched to Erubis for more Rails like ERB
+- Added simplecov for test coverage
+- Added debug command line option to view generated shell commands
+- Added commands and completion options for completion scripts
+- Added `pre_window` option for running commands before all panes and windows
+- Deprecated `rbenv` in favour of `pre_window`
+- Deprecated `rvm` in favour of `pre_window`
+- Deprecated `cli_args` in favour of `tmux_options`
+- Deprecated `tabs` in favour of `windows`
+- Dropped support for Ruby 1.9.2
+
+## 0.5.0
+- Added optional socket name support (Thanks to Adam Walters)
+- Added auto completion (Thanks to Jose Pablo Barrantes)
+
+## 0.4.0
+- Does not crash if given an invalid yaml file format. report it and exit gracefully.
+- Removed clunky scripts & shell aliases (Thanks to Dane O'Connor)
+- Config files are now rendered JIT (Thanks to Dane O'Connor)
+- Can now start sessions from cli (Thanks to Dane O'Connor)
+
+## 0.3.0
+- Added pre command (Thanks to Ian Yang)
+- Added multiple pre command (Thanks to Bjørn Arild Mæland)
+- Using tmux set default-path for project root
+- New aliases
+
+## 0.2.0
+- Added pane support (Thanks to Aaron Spiegel)
+- RVM support (Thanks to Jay Adkisoon)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CONTRIBUTING.md	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,42 @@
+# Contributing
+
+## First
+
+* Check if the issue you're going to submit isn't already submitted in
+  the [Issues](https://github.com/aziz/tmuxinator/issues) page.
+
+## Issues
+
+* Submit a ticket for your issue, assuming one does not already exist.
+* The issue must:
+  * Clearly describe the problem including steps to reproduce when it is a bug.
+  * Also include all the information you can to make it easier for us to reproduce it,
+    like OS version, gem versions, rbenv or rvm versions etc...
+  * Even better, provide a failing test case for it.
+
+## Pull Requests
+
+If you've gone the extra mile and have a patch that fixes the issue, you
+should submit a Pull Request!
+
+* Please follow the [GitHub Styleguide](https://github.com/styleguide/ruby) for
+  Ruby in both implementation and tests!
+* Fork the repo on Github.
+* Create a topic branch from where you want to base your work.
+* Add a test for your change. Only refactoring and documentation changes
+  require no new tests. If you are adding functionality or fixing a bug,
+  we need a test!
+* Run _all_ the tests to assure nothine else was broken. We only take pull requests with passing tests.
+* Check for unnecessary whitespace with `git diff --check` before committing.
+* Structure your commit messages like this:
+
+```
+Summarize clearly in one line what the commit is about
+
+Describe the problem the commit solves or the use
+case for a new feature. Justify why you chose
+the particular solution.
+```
+
+* Use "fix", "add", "change" instead of "fixed", "added", "changed" in your commit messages.
+* Push to your fork and submit a pull request.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Gemfile	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,5 @@
+source "https://rubygems.org"
+
+
+# Specify your gem's dependencies in tmuxinator.gemspec
+gemspec
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LICENSE	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,20 @@
+Copyright (c) 2010-2013 Allen Bargi
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,251 @@
+# Tmuxinator
+
+[![Gem Version](https://badge.fury.io/rb/tmuxinator.png)](http://badge.fury.io/rb/tmuxinator) [![Build Status](https://secure.travis-ci.org/tmuxinator/tmuxinator.png)](http://travis-ci.org/tmuxinator/tmuxinator?branch=master) [![Coverage Status](https://coveralls.io/repos/tmuxinator/tmuxinator/badge.png)](https://coveralls.io/r/tmuxinator/tmuxinator) [![Code Climate](https://codeclimate.com/github/tmuxinator/tmuxinator.png)](https://codeclimate.com/github/tmuxinator/tmuxinator) [![Dependency Status](https://gemnasium.com/tmuxinator/tmuxinator.png)](https://gemnasium.com/tmuxinator/tmuxinator)
+
+Create and manage tmux sessions easily.
+
+![Screenshot](https://f.cloud.github.com/assets/141213/916084/065fef7c-fe82-11e2-9c23-a9622c7d83c3.png)
+
+## Installation
+
+```
+gem install tmuxinator
+```
+
+## Editor and Shell
+
+tmuxinator uses your shell's default editor for opening files. If you're not
+sure what that is type:
+
+``` bash
+echo $EDITOR
+```
+
+For me that produces "vim" If you want to change your default editor simply
+put a line in ~/.bashrc that changes it. Mine looks like this:
+
+```
+export EDITOR='vim'
+```
+
+## tmux
+
+The recommended version of tmux to use is 1.8. Your mileage may vary for
+earlier versions. Refer to the FAQ for any odd behaviour.
+
+### base-index
+
+If you use a `base-index` other than the default, please be sure to also set the `pane-base-index`
+
+```
+set-window-option -g pane-base-index 1
+```
+
+## Completion
+
+Download the appropriate completion file from the repo and `source` the file.
+The following are example where the completion file has been downloaded into
+`~/.bin`.
+
+### bash
+
+Add the following to your `~/.bashrc`:
+
+    source ~/.bin/tmuxinator.bash
+
+### zsh
+
+Add the following to your `~/.zshrc`:
+
+    source ~/.bin/tmuxinator.zsh
+
+### fish
+
+Move `tmuxinator.fish` to your `completions` folder:
+
+    cp ~/.bin/tmuxinator.fish ~/.config/completions/
+
+## Usage
+
+A working knowledge of tmux is assumed. You should understand what windows and
+panes are in tmux. If not please consult the [man pages](http://manpages.ubuntu.com/manpages/precise/en/man1/tmux.1.html#contenttoc6) for tmux.
+
+### Create a project
+
+Create or edit your projects with:
+
+```
+tmuxinator new [project]
+```
+
+For editing you can also use `tmuxinator open [project]`. `new` is aliased to
+`o`,`open` and `n`. Your default editor (`$EDITOR`) is used to open the file.
+If this is a new project you will see this default config:
+
+```yaml
+# ~/.tmuxinator/sample.yml
+
+name: sample
+root: ~/
+
+# Optional. tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux.  This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+windows:
+  - editor:
+      layout: main-vertical
+      panes:
+        - vim
+        - guard
+  - server: bundle exec rails s
+  - logs: tail -f log/development.log
+```
+
+## Windows
+
+The windows option allows the specification of any number of tmux windows. Each window is denoted by a YAML array entry, followed by a name
+and command to be run.
+
+```
+windows:
+  - editor: vim
+```
+
+## Panes
+
+**_Note that if you wish to use panes, make sure that you do not have `.` in your project name. tmux uses `.` to delimit between window and pane indices,
+and tmuxinator uses the project name in combination with these indices to target the correct pane or window._**
+
+Panes are optional and are children of window entries, but unlike windows, they do not need a name. In the following example, the `editor` window has 2 panes, one running vim, the other guard.
+
+```yaml
+windows:
+  - editor:
+      layout: main-vertical
+      panes:
+        - vim
+        - guard
+```
+
+The layout setting gets handed down to tmux directly, so you can choose from
+one of [the five standard layouts](http://manpages.ubuntu.com/manpages/precise/en/man1/tmux.1.html#contenttoc6)
+or [specify your own](http://stackoverflow.com/a/9976282/183537).
+
+## Interpreter Managers & Environment Variables
+
+To use tmuxinator with rbenv, RVM, NVM etc, use the `pre_window` option.
+
+```
+pre_window: rbenv shell 2.0.0-p247
+```
+
+These command(s) will run before any subsequent commands in all panes and windows.
+
+## Passing directly to send-keys
+
+tmuxinator passes commands directly to send keys. This differs from simply chaining commands together using `&&` or `;`, in that
+tmux will directly send the commands to a shell as if you typed them in. This allows commands to be executed on a remote server over
+SSH for example.
+
+To support this both the window and pane options can take an array as an argument:
+
+```
+name: sample
+root: ~/
+
+windows:
+  - stats:
+    - ssh stats@example.com
+    - tail -f /var/log/stats.log
+  - logs:
+    layout: main-vertical
+    panes:
+      - logs:
+        - ssh logs@example.com
+        - cd /var/logs
+        - tail -f development.log
+```
+
+## Starting a session
+
+This will fire up tmux with all the tabs and panes you configured.
+
+```
+tmuxinator start [project]
+```
+
+## Shorthand
+
+A shorthand alias for tmuxinator can also be used.
+
+```
+mux [command]
+```
+
+## Other Commands
+
+Copy an existing project. Aliased to `c` and `cp`
+```
+tmuxinator copy [existing] [new]
+```
+
+List all the projects you have configured. Aliased to `l` and `ls`
+```
+tmuxinator list
+```
+
+Remove a project. Aliased to `rm`
+```
+tmuxinator delete [project]
+```
+
+Remove all tmuxinator configs, aliases and scripts. Aliased to `i`
+```
+tmuxinator implode
+```
+
+Examines your environment and identifies problems with your configuration
+```
+tmuxinator doctor
+```
+
+Shows tmuxinator's help. Aliased to `h`
+```
+tmuxinator help
+```
+
+Shows the shell commands that get executed for a project
+```
+tmuxinator debug [project]
+```
+
+Shows tmuxinator's version.
+```
+tmuxinator version
+```
+
+## FAQ
+
+### Window names are not displaying properly?
+
+Add `export DISABLE_AUTO_TITLE=true` to your `.zshrc` or `.bashrc`
+
+## Contributing
+
+To contribute, please read the [contributing guide](https://github.com/tmuxinator/tmuxinator/blob/master/CONTRIBUTING.md).
+
+## Copyright
+
+Copyright (c) 2010-2013 Allen Bargi. See LICENSE for further details.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rakefile	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,1 @@
+require "bundler/gem_tasks"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/mux	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,1 @@
+tmuxinator
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/tmuxinator	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+$: << File.expand_path("../../lib/", __FILE__)
+
+require "thor"
+require "tmuxinator"
+
+if ARGV.length == 1
+  name = ARGV[0]
+
+  if Tmuxinator::Cli.new.command_list.include?(name)
+    Tmuxinator::Cli.start
+  elsif Tmuxinator::Config.exists?(name)
+    Tmuxinator::Cli.new.start(name)
+  else
+    Tmuxinator::Cli.start
+  end
+else
+  Tmuxinator::Cli.start
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/completion/tmuxinator.bash	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+_tmuxinator() {
+    COMPREPLY=()
+    local word="${COMP_WORDS[COMP_CWORD]}"
+
+    if [ "$COMP_CWORD" -eq 1 ]; then
+        local commands="$(compgen -W "$(tmuxinator commands)" -- "$word")"
+        local projects="$(compgen -W "$(tmuxinator completions start)" -- "$word")"
+
+        COMPREPLY=( $commands $projects )
+    else
+        local words=("${COMP_WORDS[@]}")
+        unset words[0]
+        unset words[$COMP_CWORD]
+        local completions=$(tmuxinator completions "${words[@]}")
+        COMPREPLY=( $(compgen -W "$completions" -- "$word") )
+    fi
+}
+
+complete -F _tmuxinator tmuxinator mux
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/completion/tmuxinator.fish	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,16 @@
+function __fish_tmuxinator_using_command
+  set cmd (commandline -opc)
+  if [ (count $cmd) -gt 1 ]
+    if [ $argv[1] = $cmd[2] ]
+      return 0
+    end
+  end
+  return 1
+end
+
+complete -f -c tmuxinator -a '(tmuxinator completions start)'
+complete -f -c tmuxinator -a '(tmuxinator commands)'
+complete -f -c tmuxinator -n '__fish_tmuxinator_using_command start' -a '(tmuxinator completions start)'
+complete -f -c tmuxinator -n '__fish_tmuxinator_using_command open' -a '(tmuxinator completions open)'
+complete -f -c tmuxinator -n '__fish_tmuxinator_using_command copy' -a '(tmuxinator completions copy)'
+complete -f -c tmuxinator -n '__fish_tmuxinator_using_command delete' -a '(tmuxinator completions delete)'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/completion/tmuxinator.zsh	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,20 @@
+#!/usr/bin/env zsh
+
+if [[ ! -o interactive ]]; then
+    return
+fi
+
+compctl -K _tmuxinator tmuxinator mux
+
+_tmuxinator() {
+  local words completions
+  read -cA words
+
+  if [ "${#words}" -eq 2 ]; then
+    completions="$(tmuxinator commands)"
+  else
+    completions="$(tmuxinator completions ${words[2,-2]})"
+  fi
+
+  reply=("${(ps:\n:)completions}")
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,24 @@
+require "yaml"
+require "erubis"
+require "shellwords"
+require "thor"
+require "thor/version"
+
+require "tmuxinator/util"
+require "tmuxinator/deprecations"
+require "tmuxinator/wemux_support"
+require "tmuxinator/cli"
+require "tmuxinator/config"
+require "tmuxinator/pane"
+require "tmuxinator/project"
+require "tmuxinator/window"
+require "tmuxinator/version"
+
+module Tmuxinator
+end
+
+class Object
+  def blank?
+    respond_to?(:empty?) ? !!empty? : !self
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/assets/sample.yml	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,28 @@
+# ~/.tmuxinator/<%= name %>.yml
+
+name: <%= name %>
+root: ~/
+
+# Optional tmux socket
+# socket_name: foo
+
+# Runs before everything. Use it to start daemons etc.
+# pre: sudo /etc/rc.d/mysqld start
+
+# Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.
+# pre_window: rbenv shell 2.0.0-p247
+
+# Pass command line options to tmux. Useful for specifying a different tmux.conf.
+# tmux_options: -f ~/.tmux.mac.conf
+
+# Change the command to call tmux.  This can be used by derivatives/wrappers like byobu.
+# tmux_command: byobu
+
+windows:
+  - editor:
+      layout: main-vertical
+      panes:
+        - vim
+        - guard
+  - server: bundle exec rails s
+  - logs: tail -f log/development.log
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/assets/template.erb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,67 @@
+#!<%= ENV["SHELL"] || "/bin/bash" %>
+
+# Clear rbenv variables before starting tmux
+unset RBENV_VERSION
+unset RBENV_DIR
+
+<%= tmux %> start-server\; has-session -t <%= name %> 2>/dev/null
+
+if [ "$?" -eq 1 ]; then
+  cd <%= root || "." %>
+
+  # Run pre command.
+  <%= pre %>
+
+  # Create the session and the first window.
+  TMUX= <%= tmux %> new-session -d -s <%= name %> -n <%= windows.first.name %>
+
+  <%- if Tmuxinator::Config.version < 1.7 -%>
+  # Set the default path for versions prior to 1.7
+  <%- if root? -%>
+  <%= tmux %> set-option -t <%= name %> <%= Tmuxinator::Config.default_path_option %> <%= root.shellescape -%> 1>/dev/null
+  <%- end -%>
+  <%- end -%>
+
+  # Create other windows.
+  <%- windows.drop(1).each do |window| -%>
+  <%= window.tmux_new_window_command %>
+  <%- end -%>
+
+  <%- windows.each do |window| -%>
+
+  # Window "<%= window.name %>"
+    <%- unless window.panes? -%>
+  <%= window.tmux_pre_window_command %>
+      <%- window.commands.each do |command| -%>
+  <%= command %>
+      <%- end -%>
+    <%- else -%>
+      <%- window.panes.each do |pane| -%>
+  <%= pane.tmux_pre_window_command %>
+  <%= pane.tmux_pre_command %>
+        <%- if pane.multiple_commands? %>
+          <%- pane.commands.each do |command| -%>
+  <%= pane.tmux_main_command(command) %>
+          <%- end -%>
+        <%- else -%>
+  <%= pane.tmux_main_command(commands.first) %>
+        <%- end -%>
+
+      <%- unless pane.last? -%>
+  <%= pane.tmux_split_command %>
+      <%- end -%>
+  <%= window.tmux_layout_command %>
+    <%- end -%>
+
+  <%= window.tmux_select_first_pane %>
+    <%- end -%>
+  <%- end -%>
+
+  <%= tmux %> select-window -t <%= base_index %>
+fi
+
+if [ -z "$TMUX" ]; then
+  <%= tmux %> -u attach-session -t <%= name %>
+else
+  <%= tmux %> -u switch-client -t <%= name %>
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/assets/wemux_template.erb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,56 @@
+#!<%= ENV["SHELL"] || "/bin/bash" %>
+wemux ls 2>/dev/null
+
+if [ "$?" -eq 127 ]; then
+  cd <%= root || "." %>
+
+  # Run pre command.
+  <%= pre %>
+
+  # Create the session and the first window.
+  TMUX= <%= tmux %> new-session -d -s <%= name %> -n <%= windows.first.name %>
+
+  # Set the default path.
+  <%- if root? -%>
+  <%= tmux %> set-option -t <%= name %> <%= Tmuxinator::Config.default_path_option %> <%= root.shellescape -%> 1>/dev/null
+  <%- end -%>
+
+  # Create other windows.
+  <%- windows.drop(1).each do |window| -%>
+  <%= window.tmux_new_window_command %>
+  <%- end -%>
+
+  <%- windows.each do |window| -%>
+
+  # Window "<%= window.name %>"
+    <%- unless window.panes? -%>
+  <%= window.tmux_pre_window_command %>
+    <%- window.commands.each do |command| -%>
+  <%= command %>
+    <%- end -%>
+    <%- else -%>
+      <%- window.panes.each do |pane| -%>
+  <%= pane.tmux_pre_window_command %>
+  <%= pane.tmux_pre_command %>
+    <%- if pane.multiple_commands? %>
+          <%- pane.commands.each do |command| -%>
+  <%= pane.tmux_main_command(command) %>
+          <%- end -%>
+        <%- else -%>
+  <%= pane.tmux_main_command(commands.first) %>
+        <%- end -%>
+
+      <%- unless pane.last? -%>
+  <%= pane.tmux_split_command %>
+      <%- end -%>
+  <%= window.tmux_layout_command %>
+    <%- end -%>
+
+  <%= window.tmux_select_first_pane %>
+    <%- end -%>
+  <%- end -%>
+
+  <%= tmux %> select-window -t <%= base_index %>
+fi
+
+wemux attach
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/cli.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,147 @@
+module Tmuxinator
+  class Cli < Thor
+    include Tmuxinator::Util
+
+    attr_reader :command_list
+
+    def initialize(*args)
+      super
+      @command_list = %w(commands copy debug delete doctor help implode list start version)
+    end
+
+    package_name "tmuxinator" unless Gem::Version.create(Thor::VERSION) < Gem::Version.create("0.18")
+
+    desc "commands", "Lists commands available in tmuxinator"
+
+    def commands
+      puts command_list.join("\n")
+    end
+
+    desc "completions [arg1 arg2]", "Used for shell completion"
+
+    def completions(arg)
+      if %w(start open copy delete).include?(arg)
+        configs = Tmuxinator::Config.configs
+        puts configs
+      end
+    end
+
+    desc "new [PROJECT]", "Create a new project file and open it in your editor"
+    map "open" => :new
+    map "o" => :new
+    map "n" => :new
+
+    def new(name)
+      config = Tmuxinator::Config.project(name)
+
+      unless Tmuxinator::Config.exists?(name)
+        template = Tmuxinator::Config.default? ? Tmuxinator::Config.default : Tmuxinator::Config.sample
+        erb  = Erubis::Eruby.new(File.read(template)).result(binding)
+        File.open(config, "w") { |f| f.write(erb) }
+      end
+
+      Kernel.system("$EDITOR #{config}") || doctor
+    end
+
+    desc "start [PROJECT]", "Start a tmux session using a project's tmuxinator config"
+    map "s" => :start
+
+    def start(name)
+      project = Tmuxinator::Config.validate(name)
+
+      if project.deprecations.any?
+        project.deprecations.each { |deprecation| say deprecation, :red }
+        puts
+        print "Press ENTER to continue."
+        STDIN.getc
+      end
+
+      Kernel.exec(project.render)
+    end
+
+    desc "debug [PROJECT]", "Output the shell commands that are generated by tmuxinator"
+
+    def debug(name)
+      project = Tmuxinator::Config.validate(name)
+      puts project.render
+    end
+
+    desc "copy [EXISTING] [NEW]", "Copy an existing project to a new project and open it in your editor"
+    map "c" => :copy
+    map "cp" => :copy
+
+    def copy(existing, new)
+      existing_config_path = Tmuxinator::Config.project(existing)
+      new_config_path = Tmuxinator::Config.project(new)
+
+      exit!("Project #{existing} doesn't exist!") unless Tmuxinator::Config.exists?(existing)
+
+      if Tmuxinator::Config.exists?(new)
+        if yes?("#{new} already exists, would you like to overwrite it?", :red)
+          FileUtils.rm(new_config_path)
+          say "Overwriting #{new}"
+        end
+      end
+
+      FileUtils.copy_file(existing_config_path, new_config_path)
+      Kernel.system("$EDITOR #{new_config_path}")
+    end
+
+    desc "delete [PROJECT]", "Deletes given project"
+    map "d" => :delete
+    map "rm" => :delete
+
+    def delete(project)
+      if Tmuxinator::Config.exists?(project)
+        config =  "#{Tmuxinator::Config.root}/#{project}.yml"
+
+        if yes?("Are you sure you want to delete #{project}?(y/n)", :red)
+          FileUtils.rm(config)
+          say "Deleted #{project}"
+        end
+      else
+        exit! "That file doesn't exist."
+      end
+    end
+
+    desc "implode", "Deletes all tmuxinator projects"
+    map "i" => :implode
+
+    def implode
+      if yes?("Are you sure you want to delete all tmuxinator configs?", :red)
+        FileUtils.remove_dir(Tmuxinator::Config.root)
+        say "Deleted all tmuxinator projects."
+      end
+    end
+
+    desc "list", "Lists all tmuxinator projects"
+    map "l" => :list
+    map "ls" => :list
+
+    def list
+      say "tmuxinator projects:"
+
+      print_in_columns Tmuxinator::Config.configs
+    end
+
+    desc "version", "Display installed tmuxinator version"
+    map "-v" => :version
+
+    def version
+      say "tmuxinator #{Tmuxinator::VERSION}"
+    end
+
+    desc "doctor", "Look for problems in your configuration"
+
+    def doctor
+      say "Checking if tmux is installed ==> "
+      yes_no Tmuxinator::Config.installed?
+
+      say "Checking if $EDITOR is set ==> "
+      yes_no Tmuxinator::Config.editor?
+
+      say "Checking if $SHELL is set ==> "
+      yes_no  Tmuxinator::Config.shell?
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/config.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,96 @@
+module Tmuxinator
+  class Config
+    class << self
+      def root
+        Dir.mkdir("#{ENV["HOME"]}/.tmuxinator") unless File.directory?(File.expand_path("~/.tmuxinator"))
+        "#{ENV["HOME"]}/.tmuxinator"
+      end
+
+      def sample
+        "#{File.dirname(__FILE__)}/assets/sample.yml"
+      end
+
+      def default
+        "#{ENV["HOME"]}/.tmuxinator/default.yml"
+      end
+
+      def default?
+        exists?("default")
+      end
+
+      def installed?
+        Kernel.system("type tmux > /dev/null")
+      end
+
+      def version
+        `tmux -V`.split(" ")[1].to_f if installed?
+      end
+
+      def default_path_option
+        version && version < 1.7 ? "default-path" : "-c"
+      end
+
+      def editor?
+        !ENV["EDITOR"].nil? && !ENV["EDITOR"].empty?
+      end
+
+      def shell?
+        !ENV["SHELL"].nil? && !ENV["SHELL"].empty?
+      end
+
+      def exists?(name)
+        File.exists?(project(name))
+      end
+
+      def project(name)
+        projects = Dir.glob("#{root}/**/*.yml")
+        project_file = projects.detect { |project| project =~ /^#{name}.yml$/ }
+        project_file || "#{root}/#{name}.yml"
+      end
+
+      def template
+        "#{File.dirname(__FILE__)}/assets/template.erb"
+      end
+
+      def wemux_template
+        "#{File.dirname(__FILE__)}/assets/wemux_template.erb"
+      end
+
+      def configs
+        Dir["#{Tmuxinator::Config.root}/*.yml"].sort.map do |path|
+          File.basename(path, ".yml")
+        end
+      end
+
+      def validate(name)
+        unless Tmuxinator::Config.exists?(name)
+          puts "Project #{name} doesn't exist."
+          exit!
+        end
+
+        config_path = Tmuxinator::Config.project(name)
+
+        yaml = begin
+          YAML.load(File.read(config_path))
+        rescue SyntaxError, StandardError
+          puts "Failed to parse config file. Please check your formatting."
+          exit!
+        end
+
+        project = Tmuxinator::Project.new(yaml)
+
+        unless project.windows?
+          puts "Your project file should include some windows."
+          exit!
+        end
+
+        unless project.name?
+          puts "Your project file didn't specify a 'project_name'"
+          exit!
+        end
+
+        project
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/deprecations.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,19 @@
+module Tmuxinator
+  module Deprecations
+    def rvm?
+      yaml["rvm"]
+    end
+
+    def rbenv?
+      yaml["rbenv"]
+    end
+
+    def pre_tab?
+      yaml["pre_tab"]
+    end
+
+    def cli_args?
+      yaml["cli_args"]
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/pane.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,40 @@
+module Tmuxinator
+  class Pane
+    attr_reader :commands, :project, :index, :project, :tab
+
+    def initialize(index, project, tab, *commands)
+      @commands = commands
+      @index = index
+      @project = project
+      @tab = tab
+    end
+
+    def tmux_window_and_pane_target
+      "#{project.name}:#{tab.index + project.base_index}.#{index + project.base_index}"
+    end
+
+    def tmux_pre_command
+      tab.pre ? "#{project.tmux} send-keys -t #{tmux_window_and_pane_target} #{tab.pre.shellescape} C-m" : ""
+    end
+
+    def tmux_pre_window_command
+      project.pre_window ? "#{project.tmux} send-keys -t #{tmux_window_and_pane_target} #{project.pre_window.shellescape} C-m" : ""
+    end
+
+    def tmux_main_command(command)
+      command ? "#{project.tmux} send-keys -t #{project.name}:#{tab.index + project.base_index}.#{index + tab.project.base_index} #{command.shellescape} C-m" : ""
+    end
+
+    def tmux_split_command
+      "#{project.tmux} splitw -t #{tab.tmux_window_target}"
+    end
+
+    def last?
+      index == tab.panes.length - 1
+    end
+
+    def multiple_commands?
+      commands && commands.length > 0
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/project.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,174 @@
+module Tmuxinator
+  class Project
+    include Tmuxinator::Util
+    include Tmuxinator::Deprecations
+    include Tmuxinator::WemuxSupport
+
+    attr_reader :yaml
+
+    def initialize(yaml)
+      @yaml = yaml
+      load_wemux_overrides if wemux?
+    end
+
+    def render
+      template = File.read(Tmuxinator::Config.template)
+      Erubis::Eruby.new(template).result(binding)
+    end
+
+    def windows
+      windows_yml = yaml["tabs"] || yaml["windows"]
+
+      @windows ||= windows_yml.map.with_index do |window_yml, index|
+        Tmuxinator::Window.new(window_yml, index, self)
+      end
+    end
+
+    def root
+      root = yaml["project_root"] || yaml["root"]
+      root.blank? ? nil : File.expand_path(root)
+    end
+
+    def name
+      name = yaml["project_name"] || yaml["name"]
+      name.shellescape
+    end
+
+    def pre
+      pre_config = yaml["pre"]
+      if pre_config.is_a?(Array)
+        pre_config.join("; ")
+      else
+        pre_config
+      end
+    end
+
+    def pre_window
+      if rbenv?
+        "rbenv shell #{yaml["rbenv"]}"
+      elsif rvm?
+        "rvm use #{yaml["rvm"]}"
+      elsif pre_tab?
+        yaml["pre_tab"]
+      else
+        yaml["pre_window"]
+      end
+    end
+
+    def tmux
+      "#{tmux_command}#{tmux_options}#{socket}"
+    end
+
+    def tmux_command
+      yaml["tmux_command"] || "tmux"
+    end
+
+    def socket
+      if socket_path
+        " -S #{socket_path}"
+      elsif socket_name
+        " -L #{socket_name}"
+      else
+        nil
+      end
+    end
+
+    def socket_name
+      yaml["socket_name"]
+    end
+
+    def socket_path
+      yaml["socket_path"]
+    end
+
+    def tmux_options
+      if cli_args?
+        " #{yaml["cli_args"].to_s.strip}"
+      elsif tmux_options?
+        " #{yaml["tmux_options"].to_s.strip}"
+      else
+        ""
+      end
+    end
+
+    def base_index
+      get_pane_base_index ? get_pane_base_index.to_i : get_base_index.to_i
+    end
+
+    def tmux_options?
+      yaml["tmux_options"]
+    end
+
+    def windows?
+      windows.any?
+    end
+
+    def root?
+      !root.nil?
+    end
+
+    def name?
+      !name.nil?
+    end
+
+    def window(i)
+      "#{name}:#{i}"
+    end
+
+    def send_pane_command(cmd, window_index, pane_index)
+      if cmd.empty?
+        ""
+      else
+        "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
+      end
+    end
+
+    def send_keys(cmd, window_index)
+      if cmd.empty?
+       ""
+      else
+        "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
+      end
+    end
+
+    def deprecations
+      deprecations = []
+      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"]
+      deprecations << "DEPRECATION: The tabs option has been replaced by the windows option and will not be supported in 0.8.0." if yaml["tabs"]
+      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"]
+      deprecations
+    end
+
+    def get_pane_base_index
+      tmux_config["pane-base-index"]
+    end
+
+    def get_base_index
+      tmux_config["base-index"]
+    end
+
+    def show_tmux_options
+      "#{tmux} start-server\\; show-option -g"
+    end
+
+    private
+
+    def tmux_config
+      @tmux_config ||= extract_tmux_config
+    end
+
+    def extract_tmux_config
+      options_hash = {}
+
+      options_string = `#{show_tmux_options}`
+      options_string.encode!("UTF-8", :invalid => :replace)
+      options_string.split("\n").map do |entry|
+        key, value = entry.split("\s")
+        options_hash[key] = value
+        options_hash
+      end
+
+      options_hash
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/util.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,14 @@
+module Tmuxinator
+  module Util
+    include Thor::Actions
+
+    def exit!(msg)
+      puts msg
+      Kernel.exit(1)
+    end
+
+    def yes_no(condition)
+      condition ? say("Yes", :green) : say("No", :red)
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/version.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,3 @@
+module Tmuxinator
+  VERSION = "0.6.8"
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/wemux_support.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,24 @@
+module Tmuxinator
+  module WemuxSupport
+    def wemux?
+      yaml["tmux_command"] == "wemux"
+    end
+
+    def load_wemux_overrides
+      self.instance_eval do
+        def render
+          template = File.read(Tmuxinator::Config.wemux_template)
+          Erubis::Eruby.new(template).result(binding)
+        end
+
+        def name
+          "wemux"
+        end
+
+        def tmux
+          "wemux"
+        end
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/tmuxinator/window.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,90 @@
+module Tmuxinator
+  class Window
+    include Tmuxinator::Util
+
+    attr_reader :name, :panes, :layout, :commands, :index, :project
+
+    def initialize(window_yaml, index, project)
+      @name = !window_yaml.keys.first.nil? ? window_yaml.keys.first.shellescape : nil
+      @panes = []
+      @layout = nil
+      @pre = nil
+      @project = project
+      @index = index
+
+      value = window_yaml.values.first
+
+      if value.is_a?(Hash)
+        @layout = value["layout"] ? value["layout"].shellescape : nil
+        @pre = value["pre"] if value["pre"]
+
+        @panes = build_panes(value["panes"])
+      else
+        @commands = build_commands(tmux_window_command_prefix, value)
+      end
+    end
+
+    def build_panes(panes_yml)
+      Array(panes_yml).map.with_index do |pane_yml, index|
+        if pane_yml.is_a?(Hash)
+          pane_yml.map do |name, commands|
+            Tmuxinator::Pane.new(index, project, self, *commands)
+          end
+        else
+          Tmuxinator::Pane.new(index, project, self, pane_yml)
+        end
+      end.flatten
+    end
+
+    def build_commands(prefix, command_yml)
+      if command_yml.is_a?(Array)
+        command_yml.map do |command|
+          "#{tmux_window_command_prefix} #{command.shellescape} C-m" if command
+        end.compact
+      elsif command_yml.is_a?(String) && !command_yml.empty?
+        ["#{tmux_window_command_prefix} #{command_yml.shellescape} C-m"]
+      else
+        []
+      end
+    end
+
+    def pre
+      if @pre.is_a?(Array)
+        @pre.join(" && ")
+      elsif @pre.is_a?(String)
+        @pre
+      else
+        ""
+      end
+    end
+
+    def panes?
+      panes.any?
+    end
+
+    def tmux_window_target
+      "#{project.name}:#{index + project.base_index}"
+    end
+
+    def tmux_pre_window_command
+      project.pre_window ? "#{project.tmux} send-keys -t #{tmux_window_target} #{project.pre_window.shellescape} C-m" : ""
+    end
+
+    def tmux_window_command_prefix
+      "#{project.tmux} send-keys -t #{project.name}:#{index + project.base_index}"
+    end
+
+    def tmux_new_window_command
+      path = project.root? ? "#{Tmuxinator::Config.default_path_option} #{File.expand_path(project.root).shellescape}" : nil
+      "#{project.tmux} new-window #{path} -t #{tmux_window_target} -n #{name}"
+    end
+
+    def tmux_layout_command
+      "#{project.tmux} select-layout -t #{tmux_window_target} #{layout}"
+    end
+
+    def tmux_select_first_pane
+      "#{project.tmux} select-pane -t #{tmux_window_target}.#{panes.first.index + project.base_index}"
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/factories/projects.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,25 @@
+FactoryGirl.define do
+  factory :project, :class => Tmuxinator::Project do
+    ignore do
+      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.yml")}")) }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
+  end
+
+  factory :project_with_deprecations, :class => Tmuxinator::Project do
+    ignore do
+      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.deprecations.yml")}")) }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
+  end
+
+  factory :wemux_project, :class => Tmuxinator::Project do
+    ignore do
+      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample_wemux.yml")}")) }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/fixtures/sample.deprecations.yml	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,34 @@
+# ~/.tmuxinator/sample.deprecations.yml
+
+project_name: sample
+project_root: ~/test
+socket_name: foo # Remove to use default socket
+pre: sudo /etc/rc.d/mysqld start # Runs before everything
+rbenv: 2.0.0-p247
+cli_args: -f ~/.tmux.mac.conf # Pass arguments to tmux
+tabs:
+  - editor:
+      pre:
+        - echo "I get run in each pane, before each pane command!"
+        -
+      layout: main-vertical
+      panes:
+        - vim
+        - #empty, will just run plain bash
+        - top
+  - shell: git pull
+  - guard:
+      layout: tiled
+      pre:
+        - echo "I get run in each pane."
+        - echo "Before each pane command!"
+      panes:
+        -
+        - #empty, will just run plain bash
+        -
+  - database: bundle exec rails db
+  - server: bundle exec rails s
+  - logs: tail -f log/development.log
+  - console: bundle exec rails c
+  - capistrano:
+  - server: ssh user@example.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/fixtures/sample.yml	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,40 @@
+# ~/.tmuxinator/sample.yml
+# you can make as many tabs as you wish...
+
+name: sample
+root: ~/test
+socket_name: foo # Remove to use default socket
+pre: sudo /etc/rc.d/mysqld start # Runs before everything
+pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane
+tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux
+windows:
+  - editor:
+      pre:
+        - echo "I get run in each pane, before each pane command!"
+        -
+      layout: main-vertical
+      panes:
+        - vim
+        - #empty, will just run plain bash
+        - top
+        - pane_with_multiple_commands:
+            - ssh server
+            - echo "Hello"
+  - shell:
+    - git pull
+    - git merge
+  - guard:
+      layout: tiled
+      pre:
+        - echo "I get run in each pane."
+        - echo "Before each pane command!"
+      panes:
+        -
+        - #empty, will just run plain bash
+        -
+  - database: bundle exec rails db
+  - server: bundle exec rails s
+  - logs: tail -f log/development.log
+  - console: bundle exec rails c
+  - capistrano:
+  - server: ssh user@example.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/fixtures/sample_wemux.yml	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,37 @@
+# ~/.tmuxinator/sample_wemux.yml
+# you can make as many tabs as you wish...
+
+name: sample
+root: ~/test
+pre: sudo /etc/rc.d/mysqld start # Runs before everything
+pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane
+tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux
+tmux_command: wemux
+windows:
+  - editor:
+      pre:
+        - echo "I get run in each pane, before each pane command!"
+        -
+      layout: main-vertical
+      panes:
+        - vim
+        - #empty, will just run plain bash
+        - top
+  - shell:
+    - git pull
+    - git merge
+  - guard:
+      layout: tiled
+      pre:
+        - echo "I get run in each pane."
+        - echo "Before each pane command!"
+      panes:
+        -
+        - #empty, will just run plain bash
+        -
+  - database: bundle exec rails db
+  - server: bundle exec rails s
+  - logs: tail -f log/development.log
+  - console: bundle exec rails c
+  - capistrano:
+  - server: ssh user@example.com
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/cli_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,231 @@
+require "spec_helper"
+describe Tmuxinator::Cli do
+  let(:cli) { Tmuxinator::Cli }
+
+  before do
+    ARGV.clear
+    allow(Kernel).to receive(:system)
+    allow(FileUtils).to receive(:copy_file)
+    allow(FileUtils).to receive(:rm)
+    allow(FileUtils).to receive(:remove_dir)
+  end
+
+  context "no arguments" do
+    it "runs without error" do
+      _, err = capture_io { cli.start }
+      expect(err).to be_empty
+    end
+  end
+
+  describe "#completions" do
+    before do
+      ARGV.replace(["completions", "start"])
+      allow(Tmuxinator::Config).to receive_messages(:configs => ["test.yml"])
+    end
+
+    it "gets completions" do
+      out, _ = capture_io { cli.start }
+      expect(out).to include("test.yml")
+    end
+  end
+
+  describe "#commands" do
+    before do
+      ARGV.replace(["commands"])
+    end
+
+    it "lists the commands" do
+      out, _ = capture_io { cli.start }
+      expect(out).to eq "#{%w(commands copy debug delete doctor help implode list start version).join("\n")}\n"
+    end
+  end
+
+  describe "#start" do
+    before do
+      ARGV.replace(["start", "foo"])
+      allow(Tmuxinator::Config).to receive_messages(:validate => project)
+      allow(Tmuxinator::Config).to receive_messages(:version => 1.9)
+      allow(Kernel).to receive(:exec)
+    end
+
+    context "no deprecations" do
+      let(:project) { FactoryGirl.build(:project) }
+
+      it "starts the project" do
+        expect(Kernel).to receive(:exec)
+        capture_io { cli.start }
+      end
+    end
+
+    context "deprecations" do
+      before do
+        allow($stdin).to receive_messages(:getc => "y")
+      end
+
+      let(:project) { FactoryGirl.build(:project_with_deprecations) }
+
+      it "prints the deprecations" do
+        out, _ = capture_io { cli.start }
+        expect(out).to include "DEPRECATION"
+      end
+    end
+  end
+
+  describe "#new" do
+    let(:file) { StringIO.new }
+
+    before do
+      ARGV.replace(["new", "test"])
+      allow(File).to receive(:open) { |&block| block.yield file }
+    end
+
+    context "existing project doesn't exist" do
+      before do
+        allow(Tmuxinator::Config).to receive_messages(:exists? => false)
+      end
+
+      it "creates a new tmuxinator project file" do
+        capture_io { cli.start }
+        expect(file.string).to_not be_empty
+      end
+    end
+
+    context "files exists" do
+      before do
+        allow(File).to receive_messages(:exists? => true)
+      end
+
+      it "just opens the file" do
+        expect(Kernel).to receive(:system)
+        capture_io { cli.start }
+      end
+    end
+  end
+
+  describe "#copy" do
+    before do
+      ARGV.replace(["copy", "foo", "bar"])
+      allow(Tmuxinator::Config).to receive(:exists?) { true }
+    end
+
+    context "new project already exists" do
+      before do
+        allow(Thor::LineEditor).to receive_messages(:readline => "y")
+      end
+
+      it "prompts user to confirm overwrite" do
+        expect(FileUtils).to receive(:rm)
+        capture_io { cli.start }
+      end
+
+      it "copies the config" do
+        expect(FileUtils).to receive(:copy_file)
+        capture_io { cli.start }
+      end
+    end
+
+    context "existing project doens't exist" do
+      before do
+        allow(Tmuxinator::Config).to receive(:exists?) { false }
+      end
+
+      it "exit with error code" do
+        expect { capture_io { cli.start } }.to raise_error SystemExit
+      end
+    end
+  end
+
+  describe "#debug" do
+    let(:project) { FactoryGirl.build(:project) }
+
+    before do
+      ARGV.replace(["debug", "foo"])
+      allow(Tmuxinator::Config).to receive_messages(:validate => project)
+    end
+
+    it "renders the project" do
+      expect(project).to receive(:render)
+      capture_io { cli.start }
+    end
+  end
+
+  describe "#delete" do
+    before do
+      ARGV.replace(["delete", "foo"])
+      allow(Thor::LineEditor).to receive_messages(:readline => "y")
+    end
+
+    context "project exists" do
+      before do
+        allow(Tmuxinator::Config).to receive(:exists?) { true }
+      end
+
+      it "deletes the project" do
+        expect(FileUtils).to receive(:rm)
+        capture_io { cli.start }
+      end
+    end
+
+    context "project doesn't exist" do
+      before do
+        allow(Thor::LineEditor).to receive_messages(:readline => "y")
+      end
+
+      it "exits with error message" do
+        expect { capture_io { cli.start } }.to raise_error SystemExit
+      end
+    end
+  end
+
+  describe "#implode" do
+    before do
+      ARGV.replace(["implode"])
+      allow(Thor::LineEditor).to receive_messages(:readline => "y")
+    end
+
+    it "confirms deletion of all projects" do
+      expect(Thor::LineEditor).to receive(:readline).and_return("y")
+      capture_io { cli.start }
+    end
+
+    it "deletes all projects" do
+      expect(FileUtils).to receive(:remove_dir)
+      capture_io { cli.start }
+    end
+  end
+
+  describe "#list" do
+    before do
+      ARGV.replace(["list"])
+      allow(Dir).to receive_messages(:[] => ["/path/to/project.yml"])
+    end
+
+    it "lists all projects" do
+      expect { capture_io { cli.start } }.to_not raise_error
+    end
+  end
+
+  describe "#version" do
+    before do
+      ARGV.replace(["version"])
+    end
+
+    it "prints the current version" do
+      out, _ = capture_io { cli.start }
+      expect(out).to eq "tmuxinator #{Tmuxinator::VERSION}\n"
+    end
+  end
+
+  describe "#doctor" do
+    before do
+      ARGV.replace(["doctor"])
+    end
+
+    it "checks requirements" do
+      expect(Tmuxinator::Config).to receive(:installed?)
+      expect(Tmuxinator::Config).to receive(:editor?)
+      expect(Tmuxinator::Config).to receive(:shell?)
+      capture_io { cli.start }
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/config_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,153 @@
+require "spec_helper"
+
+describe Tmuxinator::Config do
+  describe "#root" do
+    it "is ~/.tmuxintaor" do
+      expect(Tmuxinator::Config.root).to eq "#{ENV["HOME"]}/.tmuxinator"
+    end
+  end
+
+  describe "#sample" do
+    it "gets the path of the sample project" do
+      expect(Tmuxinator::Config.sample).to include("sample.yml")
+    end
+  end
+
+  describe "#default" do
+    it "gets the path of the default config" do
+      expect(Tmuxinator::Config.default).to include("default.yml")
+    end
+  end
+
+  describe "#default?" do
+    let(:root) { Tmuxinator::Config.root }
+
+    context "when the file exists" do
+      before do
+        allow(File).to receive(:exists?).with(Tmuxinator::Config.default) { true }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.default?).to be_truthy
+      end
+    end
+
+    context "when the file doesn't exist" do
+      before do
+        allow(File).to receive(:exists?).with(Tmuxinator::Config.default) { false }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.default?).to be_falsey
+      end
+    end
+  end
+
+  describe "#configs" do
+    before do
+      allow(Dir).to receive_messages(:[] => ["test.yml"])
+    end
+
+    it "gets a list of all projects" do
+      expect(Tmuxinator::Config.configs).to include("test")
+    end
+  end
+
+  describe "#installed?" do
+    context "tmux is installed" do
+      before do
+        allow(Kernel).to receive(:system) { true }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.installed?).to be_truthy
+      end
+    end
+
+    context "tmux is not installed" do
+      before do
+        allow(Kernel).to receive(:system) { false }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.installed?).to be_falsey
+      end
+    end
+  end
+
+  describe "#editor?" do
+    context "$EDITOR is set" do
+      before do
+        allow(ENV).to receive(:[]).with("EDITOR") { "vim" }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.editor?).to be_truthy
+      end
+    end
+
+    context "$EDITOR is not set" do
+      before do
+        allow(ENV).to receive(:[]).with("EDITOR") { nil }
+      end
+
+      it "returns false" do
+        expect(Tmuxinator::Config.editor?).to be_falsey
+      end
+    end
+  end
+
+  describe "#shell?" do
+    context "$SHELL is set" do
+      before do
+        allow(ENV).to receive(:[]).with("SHELL") { "vim" }
+      end
+
+      it "returns true" do
+        expect(Tmuxinator::Config.shell?).to be_truthy
+      end
+    end
+
+    context "$SHELL is not set" do
+      before do
+        allow(ENV).to receive(:[]).with("SHELL") { nil }
+      end
+
+      it "returns false" do
+        expect(Tmuxinator::Config.shell?).to be_falsey
+      end
+    end
+  end
+
+  describe "#exists?" do
+    before do
+      allow(File).to receive_messages(:exists? => true)
+      allow(Tmuxinator::Config).to receive_messages(:project => "")
+    end
+
+    it "checks if the given project exists" do
+      expect(Tmuxinator::Config.exists?("test")).to be_truthy
+    end
+  end
+
+  describe "#project" do
+    let(:root) { Tmuxinator::Config.root }
+
+    before do
+      path = File.expand_path("../../../fixtures/", __FILE__)
+      allow(Tmuxinator::Config).to receive_messages(:root => path)
+    end
+
+    context "with project yml" do
+      it "gets the project as path to the yml file" do
+        expect(Tmuxinator::Config.project("sample")).to eq "#{root}/sample.yml"
+      end
+    end
+
+    context "without project yml" do
+      it "gets the project as path to the yml file" do
+        expect(Tmuxinator::Config.project("new-project")).to eq "#{root}/new-project.yml"
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/pane_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,7 @@
+require "spec_helper"
+
+describe Tmuxinator::Pane do
+  it "creates an instance" do
+    expect(Tmuxinator::Pane.new("vim", 0, nil, nil)).to be_a(Tmuxinator::Pane)
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/project_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,313 @@
+require "spec_helper"
+
+describe Tmuxinator::Project do
+  let(:project) { FactoryGirl.build(:project) }
+  let(:project_with_deprecations) { FactoryGirl.build(:project_with_deprecations) }
+  let(:wemux_project) { FactoryGirl.build(:wemux_project) }
+
+  describe "#initialize" do
+    context "valid yaml" do
+      it "creates an instance" do
+        expect(project).to be_a(Tmuxinator::Project)
+      end
+    end
+  end
+
+  describe "#render" do
+    it "renders the tmux config" do
+      expect(project.render).to_not be_empty
+    end
+
+    context "wemux" do
+      it "renders the wemux config" do
+        expect(wemux_project.render).to_not be_empty
+      end
+    end
+  end
+
+  describe "#windows" do
+    context "without deprecations" do
+      it "gets the list of windows" do
+        expect(project.windows).to_not be_empty
+      end
+    end
+
+    context "with deprecations" do
+      it "still gets the list of windows" do
+        expect(project_with_deprecations.windows).to_not be_empty
+      end
+    end
+  end
+
+  describe "#root" do
+    context "without deprecations" do
+      it "gets the root" do
+        expect(project.root).to include("test")
+      end
+    end
+
+    context "with deprecations" do
+      it "still gets the root" do
+        expect(project_with_deprecations.root).to include("test")
+      end
+    end
+  end
+
+  describe "#name" do
+    context "without deprecations" do
+      it "gets the name" do
+        expect(project.name).to eq "sample"
+      end
+    end
+
+    context "with deprecations" do
+      it "still gets the name" do
+        expect(project_with_deprecations.name).to eq "sample"
+      end
+    end
+
+    context "wemux" do
+      it "is wemux" do
+        expect(wemux_project.name).to eq "wemux"
+      end
+    end
+  end
+
+  describe "#pre_window" do
+    it "gets the pre_window command" do
+      expect(project.pre_window).to eq "rbenv shell 2.0.0-p247"
+    end
+
+    context "with deprecations" do
+      context "rbenv option is present" do
+        before do
+          allow(project).to receive_messages(:rbenv? => true)
+          allow(project).to receive_message_chain(:yaml, :[]).and_return("2.0.0-p247")
+        end
+
+        it "still gets the correct pre_window command" do
+          expect(project.pre_window).to eq "rbenv shell 2.0.0-p247"
+        end
+      end
+
+      context "rvm option is present" do
+        before do
+          allow(project).to receive_messages(:rbenv? => false)
+          allow(project).to receive_message_chain(:yaml, :[]).and_return("ruby-2.0.0-p247")
+        end
+
+        it "still gets the correct pre_window command" do
+          expect(project.pre_window).to eq "rvm use ruby-2.0.0-p247"
+        end
+      end
+
+      context "pre_tab is present" do
+        before do
+          allow(project).to receive_messages(:rbenv? => false)
+          allow(project).to receive_messages(:pre_tab? => true)
+        end
+
+        it "still gets the correct pre_window command" do
+          expect(project.pre_window).to be_nil
+        end
+      end
+    end
+  end
+
+  describe "#socket" do
+    context "socket path is present" do
+      before do
+        allow(project).to receive_messages(:socket_path => "/tmp")
+      end
+
+      it "gets the socket path" do
+        expect(project.socket).to eq " -S /tmp"
+      end
+    end
+  end
+
+  describe "#tmux_command" do
+    context "tmux_command specified" do
+      before do
+        project.yaml["tmux_command"] = "byobu"
+      end
+
+      it "gets the custom tmux command" do
+        expect(project.tmux_command).to eq "byobu"
+      end
+    end
+
+    context "tmux_command is not specified" do
+      it "returns the default" do
+        expect(project.tmux_command).to eq "tmux"
+      end
+    end
+  end
+
+  describe "#tmux_options" do
+    context "no tmux options" do
+      before do
+        allow(project).to receive_messages(:tmux_options? => false)
+      end
+
+      it "returns nothing" do
+        expect(project.tmux_options).to eq ""
+      end
+    end
+
+    context "with deprecations" do
+      before do
+        allow(project_with_deprecations).to receive_messages(:cli_args? => true)
+      end
+
+      it "still gets the tmux options" do
+        expect(project_with_deprecations.tmux_options).to eq " -f ~/.tmux.mac.conf"
+      end
+    end
+  end
+
+  describe "#get_pane_base_index" do
+    it "extracts the pane_base_index from tmux_options" do
+      allow(project).to receive_messages(show_tmux_options: tmux_config(pane_base_index: 3))
+
+      expect(project.get_pane_base_index).to eq("3")
+    end
+  end
+
+  describe "#get_base_index" do
+    it "extracts the base index from options" do
+      allow(project).to receive_messages(show_tmux_options: tmux_config(base_index: 1))
+
+      expect(project.get_base_index).to eq("1")
+    end
+  end
+
+  describe "#base_index" do
+    context "pane base index present" do
+      before do
+        allow(project).to receive_messages(:get_pane_base_index => "1")
+        allow(project).to receive_messages(:get_base_index => "1")
+      end
+
+      it "gets the pane base index" do
+        expect(project.base_index).to eq 1
+      end
+    end
+
+    context "pane base index no present" do
+      before do
+        allow(project).to receive_messages(:get_pane_base_index => nil)
+        allow(project).to receive_messages(:get_base_index => "0")
+      end
+
+      it "gets the base index" do
+        expect(project.base_index).to eq 0
+      end
+    end
+  end
+
+  describe "#window" do
+    it "gets the window and index for tmux" do
+      expect(project.window(1)).to eq "sample:1"
+    end
+  end
+
+  describe "#name?" do
+    context "name is present" do
+      it "returns true" do
+        expect(project.name?).to be_truthy
+      end
+    end
+  end
+
+  describe "#windows?" do
+    context "windows are present" do
+      it "returns true" do
+        expect(project.windows?).to be_truthy
+      end
+    end
+  end
+
+  describe "#root?" do
+    context "root are present" do
+      it "returns true" do
+        expect(project.root?).to be_truthy
+      end
+    end
+  end
+
+  describe "#send_keys" do
+    context "no command for window" do
+      it "returns empty string" do
+        expect(project.send_keys("", 1)).to be_empty
+      end
+    end
+
+    context "command for window is not empty" do
+      it "returns the tmux command" do
+        expect(project.send_keys("vim", 1)).to eq "tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 vim C-m"
+      end
+    end
+  end
+
+  describe "#send_pane_command" do
+    context "no command for pane" do
+      it "returns empty string" do
+        expect(project.send_pane_command("", 0, 0)).to be_empty
+      end
+    end
+
+    context "command for pane is not empty" do
+      it "returns the tmux command" do
+        expect(project.send_pane_command("vim", 1, 0)).to eq "tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 vim C-m"
+      end
+    end
+  end
+
+  describe "#deprecations" do
+    context "without deprecations" do
+      it "is empty" do
+        expect(project.deprecations).to be_empty
+      end
+    end
+
+    context "with deprecations" do
+      it "is not empty" do
+        expect(project_with_deprecations.deprecations).to_not be_empty
+      end
+    end
+  end
+
+  describe "#commands" do
+    let(:window) { project.windows.keep_if { |w| w.name == "shell" }.first }
+
+    it "splits commands into an array" do
+      expect(window.commands).to eq(["tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 git\\ pull C-m", "tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 git\\ merge C-m"])
+    end
+  end
+
+  describe "#pre" do
+    subject(:pre) { project.pre }
+
+    context "pre in yaml is string" do
+      before { project.yaml["pre"] = "mysql.server start" }
+
+      it "returns the string" do
+        expect(pre).to eq("mysql.server start")
+      end
+    end
+
+    context "pre in yaml is Array" do
+      before {
+        project.yaml["pre"] = [
+          "mysql.server start",
+          "memcached -d"
+        ]
+      }
+
+      it "joins array using ;" do
+        expect(pre).to eq("mysql.server start; memcached -d")
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/util_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,6 @@
+require "spec_helper"
+
+describe Tmuxinator::Util do
+  let(:util) { Object.new.extend(Tmuxinator::Util) }
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/lib/tmuxinator/window_spec.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,154 @@
+require "spec_helper"
+
+describe Tmuxinator::Window do
+  let(:project) { double }
+  let(:panes) { ["vim", nil, "top"] }
+  let(:yaml) do
+    {
+      "editor" => {
+        "pre" => ["echo 'I get run in each pane.  Before each pane command!'", nil],
+        "layout" => "main-vertical",
+        "panes" => panes
+      }
+    }
+  end
+
+  let(:window) { Tmuxinator::Window.new(yaml, 0, project) }
+
+  before do
+    allow(project).to receive_messages(:tmux => "tmux", :name => "test", :base_index => 1)
+  end
+
+  describe "#initialize" do
+    it "creates an instance" do
+      expect(window).to be_a(Tmuxinator::Window)
+    end
+  end
+
+  describe "#panes" do
+    let(:pane) { double(:pane) }
+
+    before do
+      allow(Tmuxinator::Pane).to receive_messages :new => pane
+    end
+
+    context "with a three element Array" do
+      let(:panes) { ["vim", nil, "top"] }
+
+      it "creates three panes" do
+        expect(Tmuxinator::Pane).to receive(:new).exactly(3).times
+        window.panes
+      end
+
+      it "returns three panes" do
+        expect(window.panes).to eql [pane, pane, pane]
+      end
+    end
+
+    context "with a String" do
+      let(:panes) { "vim" }
+
+      it "creates one pane" do
+        expect(Tmuxinator::Pane).to receive(:new).once
+        window.panes
+      end
+
+      it "returns one pane in an Array" do
+        expect(window.panes).to eql [pane]
+      end
+    end
+
+    context "with nil" do
+      let(:panes) { nil }
+
+      it "doesn't create any panes" do
+        expect(Tmuxinator::Pane).to_not receive(:new)
+        window.panes
+      end
+
+      it "returns an empty Array" do
+        expect(window.panes).to be_empty
+      end
+    end
+  end
+
+  describe "#pre" do
+    context "pre is a string" do
+      before do
+        yaml["editor"]["pre"] = "vim"
+      end
+
+      it "returns the pre command" do
+        expect(window.pre).to eq "vim"
+      end
+    end
+
+
+    context "pre is not present" do
+      before do
+        yaml["editor"].delete("pre")
+      end
+
+      it "returns an empty string" do
+        expect(window.pre).to eq ""
+      end
+    end
+  end
+
+  describe "#build_commands" do
+    context "command is an array" do
+      before do
+        yaml["editor"] = ["git fetch", "git status"]
+      end
+
+      it "returns the flattened command" do
+        expect(window.commands).to eq ["tmux send-keys -t test:1 git\\ fetch C-m", "tmux send-keys -t test:1 git\\ status C-m"]
+      end
+    end
+
+    context "command is a string" do
+      before do
+        yaml["editor"] = "vim"
+      end
+
+      it "returns the command" do
+        expect(window.commands).to eq ["tmux send-keys -t test:1 vim C-m"]
+      end
+    end
+
+    context "command is empty" do
+      before do
+        yaml["editor"] = ""
+      end
+
+      it "returns an empty array" do
+        expect(window.commands).to be_empty
+      end
+    end
+  end
+
+  describe "#tmux_new_window_command" do
+    let(:project) { double(:project) }
+    let(:window) { Tmuxinator::Window.new(yaml, 0, project) }
+
+    before do
+      allow(project).to receive_messages(
+        :name => "",
+        :tmux => "tmux",
+        :root => "/project/tmuxinator",
+        :root? => true,
+        :base_index => 1
+      )
+    end
+
+    context "tmux 1.6 and below" do
+      before do
+        allow(Tmuxinator::Config).to receive_messages(:version => 1.6)
+      end
+
+      it "specifies root path by passing default-path to tmux" do
+        expect(window.tmux_new_window_command).to include("default-path /project/tmuxinator")
+      end
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spec/spec_helper.rb	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,58 @@
+require "coveralls"
+require "simplecov"
+require "pry"
+
+SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
+  SimpleCov::Formatter::HTMLFormatter,
+  Coveralls::SimpleCov::Formatter
+]
+SimpleCov.start do
+  add_filter 'vendor/cache'
+end
+
+require "tmuxinator"
+require "factory_girl"
+
+
+FactoryGirl.find_definitions
+
+RSpec.configure do |config|
+  config.order = "random"
+end
+
+# Copied from minitest.
+def capture_io
+  begin
+    require 'stringio'
+
+    captured_stdout, captured_stderr = StringIO.new, StringIO.new
+
+    orig_stdout, orig_stderr = $stdout, $stderr
+    $stdout, $stderr         = captured_stdout, captured_stderr
+
+    yield
+
+    return captured_stdout.string, captured_stderr.string
+  ensure
+    $stdout = orig_stdout
+    $stderr = orig_stderr
+  end
+end
+
+def tmux_config(options = {})
+  standard_options = [
+    "assume-paste-time 1",
+    "bell-action any",
+    "bell-on-alert off",
+  ]
+
+  if base_index  = options.fetch(:base_index) {1}
+    standard_options << "base-index #{base_index}"
+  end
+
+  if pane_base_index  = options.fetch(:pane_base_index) {1}
+    standard_options << "pane-base-index #{pane_base_index}"
+  end
+
+  "echo '#{standard_options.join("\n")}'"
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tmuxinator.gemspec	Mon Jul 21 08:04:55 2014 +0900
@@ -0,0 +1,53 @@
+# coding: utf-8
+lib = File.expand_path("../lib", __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require "tmuxinator/version"
+
+Gem::Specification.new do |s|
+  s.name          = "tmuxinator"
+  s.version       = Tmuxinator::VERSION
+  s.authors       = ["Allen Bargi"]
+  s.email         = ["allen.bargi@gmail.com"]
+  s.description   = %q{Create and manage complex tmux sessions easily.}
+  s.summary       = %q{Create and manage complex tmux sessions easily.}
+  s.homepage      = "https://github.com/aziz/tmuxinator"
+  s.license       = "MIT"
+
+  s.files         = Dir["lib/**/*", "spec/**/*", "bin/*"]
+  s.executables   = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
+  s.test_files    = s.files.grep(%r{^(test|spec|features)/})
+  s.require_paths = ["lib"]
+
+  s.post_install_message = %q{
+    __________________________________________________________
+    ..........................................................
+
+    Thank you for installing tmuxinator.
+
+    Make sure that you've set these variables in your ENV:
+
+      $EDITOR, $SHELL
+
+    You can run `tmuxinator doctor` to make sure everything is set.
+    Happy tmuxing with tmuxinator!
+
+    ..........................................................
+    __________________________________________________________
+  }
+
+  s.required_rubygems_version = ">= 1.8.23"
+
+  s.add_dependency "thor", "~> 0.19", ">= 0.15.0"
+  s.add_dependency "erubis"
+
+  s.add_development_dependency "bundler", "~> 1.3"
+  s.add_development_dependency "rspec", "~> 3.0.0"
+  s.add_development_dependency "simplecov"
+  s.add_development_dependency "coveralls"
+  s.add_development_dependency "awesome_print"
+  s.add_development_dependency "pry"
+  s.add_development_dependency "pry-nav"
+  s.add_development_dependency "factory_girl"
+  s.add_development_dependency "transpec"
+end
+