[DRE-commits] [tmuxinator] 01/02: Imported Upstream version 0.7.0

Youhei SASAKI uwabami-guest at moszumanska.debian.org
Sun Dec 6 12:01:42 UTC 2015


This is an automated email from the git hooks/post-receive script.

uwabami-guest pushed a commit to branch master
in repository tmuxinator.

commit d1f90daf8720414aebd1127ae234327e6f794043
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date:   Sun Dec 6 20:55:57 2015 +0900

    Imported Upstream version 0.7.0
---
 .rubocop.yml                              | 1058 +++++++++++++++++++++++++++++
 .travis.yml                               |    4 +-
 CHANGELOG.md                              |   19 +
 Gemfile                                   |   15 +-
 README.md                                 |   54 +-
 Rakefile                                  |   19 +
 bin/tmuxinator                            |   15 +-
 lib/tmuxinator/assets/template.erb        |   12 +-
 lib/tmuxinator/assets/wemux_template.erb  |    2 +-
 lib/tmuxinator/cli.rb                     |  144 +++-
 lib/tmuxinator/config.rb                  |   82 ++-
 lib/tmuxinator/pane.rb                    |   26 +-
 lib/tmuxinator/project.rb                 |  123 +++-
 lib/tmuxinator/version.rb                 |    2 +-
 lib/tmuxinator/wemux_support.rb           |    8 +-
 lib/tmuxinator/window.rb                  |   20 +-
 spec/factories/projects.rb                |   66 +-
 spec/fixtures/{sample.yml => detach.yml}  |    1 +
 spec/fixtures/nameless_window.yml         |    5 +
 spec/fixtures/nowindows.yml               |    3 +
 spec/fixtures/sample.yml                  |    1 +
 spec/fixtures/sample_number_as_name.yml   |    5 +
 spec/lib/tmuxinator/cli_spec.rb           |  221 +++++-
 spec/lib/tmuxinator/config_spec.rb        |  113 ++-
 spec/lib/tmuxinator/project_spec.rb       |  200 +++++-
 spec/lib/tmuxinator/util_spec.rb          |    1 -
 spec/lib/tmuxinator/wemux_support_spec.rb |   47 ++
 spec/lib/tmuxinator/window_spec.rb        |  103 ++-
 spec/spec_helper.rb                       |   31 +-
 29 files changed, 2139 insertions(+), 261 deletions(-)

diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000..746d9ef
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,1058 @@
+AllCops:
+  Include:
+  - "**/*.podspec"
+  - "**/*.jbuilder"
+  - "**/*.opal"
+  - "**/Vagrantfile"
+  - "**/Berksfile"
+  - "**/Cheffile"
+  - "**/Vagabondfile"
+  Exclude:
+  - "vendor/**/*"
+  - "db/schema.rb"
+  RunRailsCops: false
+  DisplayCopNames: false
+  StyleGuideCopsOnly: false
+Style/AccessModifierIndentation:
+  Description: Check indentation of private/protected visibility modifiers.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected
+  Enabled: true
+  EnforcedStyle: indent
+  SupportedStyles:
+  - outdent
+  - indent
+Style/AlignHash:
+  Description: Align the elements of a hash literal if they span more than one line.
+  Enabled: true
+  EnforcedHashRocketStyle: key
+  EnforcedColonStyle: key
+  EnforcedLastArgumentHashStyle: always_inspect
+  SupportedLastArgumentHashStyles:
+  - always_inspect
+  - always_ignore
+  - ignore_implicit
+  - ignore_explicit
+Style/AlignParameters:
+  Description: Align the parameters of a method call if they span more than one line.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-double-indent
+  Enabled: true
+  EnforcedStyle: with_first_parameter
+  SupportedStyles:
+  - with_first_parameter
+  - with_fixed_indentation
+Style/AndOr:
+  Description: Use &&/|| instead of and/or.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-and-or-or
+  Enabled: true
+  EnforcedStyle: always
+  SupportedStyles:
+  - always
+  - conditionals
+Style/BarePercentLiterals:
+  Description: Checks if usage of %() or %Q() matches configuration.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand
+  Enabled: true
+  EnforcedStyle: bare_percent
+  SupportedStyles:
+  - percent_q
+  - bare_percent
+Style/BracesAroundHashParameters:
+  Description: Enforce braces style around hash parameters.
+  Enabled: true
+  EnforcedStyle: no_braces
+  SupportedStyles:
+  - braces
+  - no_braces
+  - context_dependent
+Style/CaseIndentation:
+  Description: Indentation of when in a case/when/[else/]end.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-when-to-case
+  Enabled: true
+  IndentWhenRelativeTo: case
+  SupportedStyles:
+  - case
+  - end
+  IndentOneStep: false
+Style/ClassAndModuleChildren:
+  Description: Checks style of children classes and modules.
+  Enabled: false
+  EnforcedStyle: nested
+  SupportedStyles:
+  - nested
+  - compact
+Style/ClassCheck:
+  Description: Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.
+  Enabled: true
+  EnforcedStyle: is_a?
+  SupportedStyles:
+  - is_a?
+  - kind_of?
+Style/CollectionMethods:
+  Description: Preferred collection methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
+  Enabled: true
+  PreferredMethods:
+    collect: map
+    collect!: map!
+    find: detect
+    find_all: select
+    reduce: inject
+Style/CommentAnnotation:
+  Description: Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK,
+    REVIEW).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#annotate-keywords
+  Enabled: false
+  Keywords:
+  - TODO
+  - FIXME
+  - OPTIMIZE
+  - HACK
+  - REVIEW
+Style/DotPosition:
+  Description: Checks the position of the dot in multi-line method calls.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
+  Enabled: true
+  EnforcedStyle: trailing
+  SupportedStyles:
+  - leading
+  - trailing
+Style/EmptyLineBetweenDefs:
+  Description: Use empty lines between defs.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods
+  Enabled: true
+  AllowAdjacentOneLineDefs: false
+Style/EmptyLinesAroundBlockBody:
+  Description: Keeps track of empty lines around block bodies.
+  Enabled: true
+  EnforcedStyle: no_empty_lines
+  SupportedStyles:
+  - empty_lines
+  - no_empty_lines
+Style/EmptyLinesAroundClassBody:
+  Description: Keeps track of empty lines around class bodies.
+  Enabled: true
+  EnforcedStyle: no_empty_lines
+  SupportedStyles:
+  - empty_lines
+  - no_empty_lines
+Style/EmptyLinesAroundModuleBody:
+  Description: Keeps track of empty lines around module bodies.
+  Enabled: true
+  EnforcedStyle: no_empty_lines
+  SupportedStyles:
+  - empty_lines
+  - no_empty_lines
+Style/Encoding:
+  Description: Use UTF-8 as the source file encoding.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#utf-8
+  Enabled: false
+  EnforcedStyle: always
+  SupportedStyles:
+  - when_needed
+  - always
+Style/FileName:
+  Description: Use snake_case for source file names.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
+  Enabled: false
+  Exclude: []
+Style/FirstParameterIndentation:
+  Description: Checks the indentation of the first parameter in a method call.
+  Enabled: true
+  EnforcedStyle: special_for_inner_method_call_in_parentheses
+  SupportedStyles:
+  - consistent
+  - special_for_inner_method_call
+  - special_for_inner_method_call_in_parentheses
+Style/For:
+  Description: Checks use of for or each in multiline loops.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-for-loops
+  Enabled: true
+  EnforcedStyle: each
+  SupportedStyles:
+  - for
+  - each
+Style/FormatString:
+  Description: Enforce the use of Kernel#sprintf, Kernel#format or String#%.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#sprintf
+  Enabled: false
+  EnforcedStyle: format
+  SupportedStyles:
+  - format
+  - sprintf
+  - percent
+Style/GlobalVars:
+  Description: Do not introduce global variables.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#instance-vars
+  Enabled: false
+  AllowedVariables: []
+Style/GuardClause:
+  Description: Check for conditionals that can be replaced with guard clauses
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
+  Enabled: false
+  MinBodyLength: 1
+Style/HashSyntax:
+  Description: 'Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax { :a =>
+    1, :b => 2 }.'
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-literals
+  Enabled: true
+  EnforcedStyle: ruby19
+  SupportedStyles:
+  - ruby19
+  - hash_rockets
+Style/IfUnlessModifier:
+  Description: Favor modifier if/unless usage when you have a single-line body.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
+  Enabled: false
+  MaxLineLength: 80
+Style/IndentationWidth:
+  Description: Use 2 spaces for indentation.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation
+  Enabled: true
+  Width: 2
+Style/IndentHash:
+  Description: Checks the indentation of the first key in a hash literal.
+  Enabled: true
+  EnforcedStyle: special_inside_parentheses
+  SupportedStyles:
+  - special_inside_parentheses
+  - consistent
+Style/LambdaCall:
+  Description: Use lambda.call(...) instead of lambda.(...).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc-call
+  Enabled: false
+  EnforcedStyle: call
+  SupportedStyles:
+  - call
+  - braces
+Style/Next:
+  Description: Use `next` to skip iteration instead of a condition at the end.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
+  Enabled: false
+  EnforcedStyle: skip_modifier_ifs
+  MinBodyLength: 3
+  SupportedStyles:
+  - skip_modifier_ifs
+  - always
+Style/NonNilCheck:
+  Description: Checks for redundant nil checks.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks
+  Enabled: true
+  IncludeSemanticChanges: false
+Style/MethodDefParentheses:
+  Description: Checks if the method definitions have or don't have parentheses.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens
+  Enabled: true
+  EnforcedStyle: require_parentheses
+  SupportedStyles:
+  - require_parentheses
+  - require_no_parentheses
+Style/MethodName:
+  Description: Use the configured style when naming methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars
+  Enabled: true
+  EnforcedStyle: snake_case
+  SupportedStyles:
+  - snake_case
+  - camelCase
+Style/MultilineOperationIndentation:
+  Description: Checks indentation of binary operations that span more than one line.
+  Enabled: true
+  EnforcedStyle: aligned
+  SupportedStyles:
+  - aligned
+  - indented
+Style/NumericLiterals:
+  Description: Add underscores to large numeric literals to improve their readability.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics
+  Enabled: false
+  MinDigits: 5
+Style/ParenthesesAroundCondition:
+  Description: Don't use parentheses around the condition of an if/unless/while.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-parens-if
+  Enabled: true
+  AllowSafeAssignment: true
+Style/PercentLiteralDelimiters:
+  Description: Use `%`-literal delimiters consistently
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
+  Enabled: false
+  PreferredDelimiters:
+    "%": "()"
+    "%i": "()"
+    "%q": "()"
+    "%Q": "()"
+    "%r": "{}"
+    "%s": "()"
+    "%w": "()"
+    "%W": "()"
+    "%x": "()"
+Style/PercentQLiterals:
+  Description: Checks if uses of %Q/%q match the configured preference.
+  Enabled: true
+  EnforcedStyle: lower_case_q
+  SupportedStyles:
+  - lower_case_q
+  - upper_case_q
+Style/PredicateName:
+  Description: Check the names of predicate methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
+  Enabled: true
+  NamePrefix:
+  - is_
+  - has_
+  - have_
+  NamePrefixBlacklist:
+  - is_
+  Exclude:
+  - spec/**/*
+Style/RaiseArgs:
+  Description: Checks the arguments passed to raise/fail.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
+  Enabled: false
+  EnforcedStyle: exploded
+  SupportedStyles:
+  - compact
+  - exploded
+Style/RedundantReturn:
+  Description: Don't use return where it's not required.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-return
+  Enabled: true
+  AllowMultipleReturnValues: false
+Style/RegexpLiteral:
+  Description: Use %r for regular expressions matching more than `MaxSlashes` '/'
+    characters. Use %r only for regular expressions matching more than `MaxSlashes`
+    '/' character.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-r
+  Enabled: false
+Style/Semicolon:
+  Description: Don't use semicolons to terminate expressions.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon
+  Enabled: true
+  AllowAsExpressionSeparator: false
+Style/SignalException:
+  Description: Checks for proper usage of fail and raise.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
+  Enabled: false
+  EnforcedStyle: semantic
+  SupportedStyles:
+  - only_raise
+  - only_fail
+  - semantic
+Style/SingleLineBlockParams:
+  Description: Enforces the names of some block params.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
+  Enabled: false
+  Methods:
+  - reduce:
+    - a
+    - e
+  - inject:
+    - a
+    - e
+Style/SingleLineMethods:
+  Description: Avoid single-line methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
+  Enabled: false
+  AllowIfMethodIsEmpty: true
+Style/StringLiterals:
+  Description: Checks if uses of quotes match the configured preference.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals
+  Enabled: true
+  EnforcedStyle: double_quotes
+  SupportedStyles:
+  - single_quotes
+  - double_quotes
+Style/StringLiteralsInInterpolation:
+  Description: Checks if uses of quotes inside expressions in interpolated strings
+    match the configured preference.
+  Enabled: true
+  EnforcedStyle: single_quotes
+  SupportedStyles:
+  - single_quotes
+  - double_quotes
+Style/SpaceAroundBlockParameters:
+  Description: Checks the spacing inside and after block parameters pipes.
+  Enabled: true
+  EnforcedStyleInsidePipes: no_space
+  SupportedStyles:
+  - space
+  - no_space
+Style/SpaceAroundEqualsInParameterDefault:
+  Description: Checks that the equals signs in parameter default assignments have
+    or don't have surrounding space depending on configuration.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-around-equals
+  Enabled: true
+  EnforcedStyle: space
+  SupportedStyles:
+  - space
+  - no_space
+Style/SpaceBeforeBlockBraces:
+  Description: Checks that the left block brace has or doesn't have space before it.
+  Enabled: true
+  EnforcedStyle: space
+  SupportedStyles:
+  - space
+  - no_space
+Style/SpaceInsideBlockBraces:
+  Description: Checks that block braces have or don't have surrounding space. For
+    blocks taking parameters, checks that the left brace has or doesn't have trailing
+    space.
+  Enabled: true
+  EnforcedStyle: space
+  SupportedStyles:
+  - space
+  - no_space
+  EnforcedStyleForEmptyBraces: no_space
+  SpaceBeforeBlockParameters: true
+Style/SpaceInsideHashLiteralBraces:
+  Description: Use spaces inside hash literal braces - or don't.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
+  Enabled: true
+  EnforcedStyle: space
+  EnforcedStyleForEmptyBraces: no_space
+  SupportedStyles:
+  - space
+  - no_space
+Style/SymbolProc:
+  Description: Use symbols as procs instead of blocks when possible.
+  Enabled: true
+  IgnoredMethods:
+  - respond_to
+Style/TrailingBlankLines:
+  Description: Checks trailing blank lines and final newline.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#newline-eof
+  Enabled: true
+  EnforcedStyle: final_newline
+  SupportedStyles:
+  - final_newline
+  - final_blank_line
+Style/TrailingComma:
+  Description: Checks for trailing comma in parameter lists and literals.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
+  Enabled: false
+  EnforcedStyleForMultiline: no_comma
+  SupportedStyles:
+  - comma
+  - no_comma
+Style/TrivialAccessors:
+  Description: Prefer attr_* methods to trivial readers/writers.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr_family
+  Enabled: false
+  ExactNameMatch: false
+  AllowPredicates: false
+  AllowDSLWriters: false
+  Whitelist:
+  - to_ary
+  - to_a
+  - to_c
+  - to_enum
+  - to_h
+  - to_hash
+  - to_i
+  - to_int
+  - to_io
+  - to_open
+  - to_path
+  - to_proc
+  - to_r
+  - to_regexp
+  - to_str
+  - to_s
+  - to_sym
+Style/VariableName:
+  Description: Use the configured style when naming variables.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars
+  Enabled: true
+  EnforcedStyle: snake_case
+  SupportedStyles:
+  - snake_case
+  - camelCase
+Style/WhileUntilModifier:
+  Description: Favor modifier while/until usage when you have a single-line body.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier
+  Enabled: false
+  MaxLineLength: 80
+Style/WordArray:
+  Description: Use %w or %W for arrays of words.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-w
+  Enabled: false
+  MinSize: 0
+  WordRegex: !ruby/regexp /\A[\p{Word}]+\z/
+Metrics/AbcSize:
+  Description: A calculated magnitude based on number of assignments, branches, and
+    conditions.
+  Enabled: false
+  Max: 15
+Metrics/BlockNesting:
+  Description: Avoid excessive block nesting
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count
+  Enabled: false
+  Max: 3
+Metrics/ClassLength:
+  Description: Avoid classes longer than 100 lines of code.
+  Enabled: false
+  CountComments: false
+  Max: 100
+Metrics/CyclomaticComplexity:
+  Description: A complexity metric that is strongly correlated to the number of test
+    cases needed to validate a method.
+  Enabled: false
+  Max: 6
+Metrics/LineLength:
+  Description: Limit lines to 80 characters.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#80-character-limits
+  Enabled: true
+  Max: 80
+  AllowURI: true
+  URISchemes:
+  - http
+  - https
+  Exclude:
+    - lib/tmuxinator/window.rb
+Metrics/MethodLength:
+  Description: Avoid methods longer than 10 lines of code.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
+  Enabled: false
+  CountComments: false
+  Max: 10
+Metrics/ParameterLists:
+  Description: Avoid parameter lists longer than three or four parameters.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
+  Enabled: false
+  Max: 5
+  CountKeywordArgs: true
+Metrics/PerceivedComplexity:
+  Description: A complexity metric geared towards measuring complexity for a human
+    reader.
+  Enabled: false
+  Max: 7
+Lint/AssignmentInCondition:
+  Description: Don't use assignment in conditions.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
+  Enabled: false
+  AllowSafeAssignment: true
+Lint/EndAlignment:
+  Description: Align ends correctly.
+  Enabled: true
+  AlignWith: keyword
+  SupportedStyles:
+  - keyword
+  - variable
+Lint/DefEndAlignment:
+  Description: Align ends corresponding to defs correctly.
+  Enabled: true
+  AlignWith: start_of_line
+  SupportedStyles:
+  - start_of_line
+  - def
+Rails/ActionFilter:
+  Description: Enforces consistent use of action filter methods.
+  Enabled: false
+  EnforcedStyle: action
+  SupportedStyles:
+  - action
+  - filter
+  Include:
+  - app/controllers/**/*.rb
+Rails/DefaultScope:
+  Description: Checks if the argument passed to default_scope is a block.
+  Enabled: true
+  Include:
+  - app/models/**/*.rb
+Rails/HasAndBelongsToMany:
+  Description: Prefer has_many :through to has_and_belongs_to_many.
+  Enabled: true
+  Include:
+  - app/models/**/*.rb
+Rails/Output:
+  Description: Checks for calls to puts, print, etc.
+  Enabled: true
+  Include:
+  - app/**/*.rb
+  - config/**/*.rb
+  - db/**/*.rb
+  - lib/**/*.rb
+Rails/ReadWriteAttribute:
+  Description: Checks for read_attribute(:attr) and write_attribute(:attr, val).
+  Enabled: true
+  Include:
+  - app/models/**/*.rb
+Rails/ScopeArgs:
+  Description: Checks the arguments of ActiveRecord scopes.
+  Enabled: true
+  Include:
+  - app/models/**/*.rb
+Rails/Validation:
+  Description: Use validates :attribute, hash of validations.
+  Enabled: true
+  Include:
+  - app/models/**/*.rb
+Style/InlineComment:
+  Description: Avoid inline comments.
+  Enabled: false
+Style/MethodCalledOnDoEndBlock:
+  Description: Avoid chaining a method call on a do...end block.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
+  Enabled: false
+Style/SymbolArray:
+  Description: Use %i or %I for arrays of symbols.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-i
+  Enabled: false
+Style/ExtraSpacing:
+  Description: Do not use unnecessary spacing.
+  Enabled: true
+Style/AccessorMethodName:
+  Description: Check the naming of accessor methods for get_/set_.
+  Enabled: false
+Style/Alias:
+  Description: Use alias_method instead of alias.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
+  Enabled: false
+Style/AlignArray:
+  Description: Align the elements of an array literal if they span more than one line.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays
+  Enabled: true
+Style/ArrayJoin:
+  Description: Use Array#join instead of Array#*.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#array-join
+  Enabled: false
+Style/AsciiComments:
+  Description: Use only ascii symbols in comments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-comments
+  Enabled: false
+Style/AsciiIdentifiers:
+  Description: Use only ascii symbols in identifiers.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-identifiers
+  Enabled: false
+Style/Attr:
+  Description: Checks for uses of Module#attr.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr
+  Enabled: false
+Style/BeginBlock:
+  Description: Avoid the use of BEGIN blocks.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks
+  Enabled: true
+Style/BlockComments:
+  Description: Do not use block comments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-block-comments
+  Enabled: true
+Style/BlockEndNewline:
+  Description: Put end statement of multiline block on its own line.
+  Enabled: true
+# Style/Blocks:
+#   Description: Avoid using {...} for multi-line blocks (multiline chaining is always
+#     ugly). Prefer {...} over do...end for single-line blocks.
+#   StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
+#   Enabled: true
+Style/CaseEquality:
+  Description: Avoid explicit use of the case equality operator(===).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-case-equality
+  Enabled: false
+Style/CharacterLiteral:
+  Description: Checks for uses of character literals.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-character-literals
+  Enabled: false
+Style/ClassAndModuleCamelCase:
+  Description: Use CamelCase for classes and modules.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#camelcase-classes
+  Enabled: true
+Style/ClassMethods:
+  Description: Use self when defining module/class methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#def-self-singletons
+  Enabled: true
+Style/ClassVars:
+  Description: Avoid the use of class variables.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-class-vars
+  Enabled: false
+Style/ColonMethodCall:
+  Description: 'Do not use :: for method call.'
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#double-colons
+  Enabled: false
+Style/CommentIndentation:
+  Description: Indentation of comments.
+  Enabled: true
+Style/ConstantName:
+  Description: Constants should use SCREAMING_SNAKE_CASE.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#screaming-snake-case
+  Enabled: true
+Style/DefWithParentheses:
+  Description: Use def with parentheses when there are arguments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens
+  Enabled: true
+Style/DeprecatedHashMethods:
+  Description: Checks for use of deprecated Hash methods.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-key
+  Enabled: false
+Style/Documentation:
+  Description: Document classes and non-namespace modules.
+  Enabled: false
+Style/DoubleNegation:
+  Description: Checks for uses of double negation (!!).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
+  Enabled: false
+Style/EachWithObject:
+  Description: Prefer `each_with_object` over `inject` or `reduce`.
+  Enabled: false
+Style/ElseAlignment:
+  Description: Align elses and elsifs correctly.
+  Enabled: true
+Style/EmptyElse:
+  Description: Avoid empty else-clauses.
+  Enabled: true
+Style/EmptyLines:
+  Description: Don't use several empty lines in a row.
+  Enabled: true
+Style/EmptyLinesAroundAccessModifier:
+  Description: Keep blank lines around access modifiers.
+  Enabled: true
+Style/EmptyLinesAroundMethodBody:
+  Description: Keeps track of empty lines around method bodies.
+  Enabled: true
+Style/EmptyLiteral:
+  Description: Prefer literals to Array.new/Hash.new/String.new.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
+  Enabled: false
+Style/EndBlock:
+  Description: Avoid the use of END blocks.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-END-blocks
+  Enabled: true
+Style/EndOfLine:
+  Description: Use Unix-style line endings.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#crlf
+  Enabled: true
+Style/EvenOdd:
+  Description: Favor the use of Fixnum#even? && Fixnum#odd?
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods
+  Enabled: false
+Style/FlipFlop:
+  Description: Checks for flip flops
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-flip-flops
+  Enabled: false
+Style/IfWithSemicolon:
+  Description: Do not use if x; .... Use the ternary operator instead.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs
+  Enabled: false
+Style/IndentationConsistency:
+  Description: Keep indentation straight.
+  Enabled: true
+Style/IndentArray:
+  Description: Checks the indentation of the first element in an array literal.
+  Enabled: true
+Style/InfiniteLoop:
+  Description: Use Kernel#loop for infinite loops.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#infinite-loop
+  Enabled: true
+Style/Lambda:
+  Description: Use the new lambda literal syntax for single-line blocks.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#lambda-multi-line
+  Enabled: false
+Style/LeadingCommentSpace:
+  Description: Comments should start with a space.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-space
+  Enabled: true
+Style/LineEndConcatenation:
+  Description: Use \ instead of + or << to concatenate two string literals at line
+    end.
+  Enabled: false
+Style/MethodCallParentheses:
+  Description: Do not use parentheses for method calls with no arguments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-args-no-parens
+  Enabled: true
+Style/ModuleFunction:
+  Description: Checks for usage of `extend self` in modules.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
+  Enabled: false
+Style/MultilineBlockChain:
+  Description: Avoid multi-line chains of blocks.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks
+  Enabled: true
+Style/MultilineBlockLayout:
+  Description: Ensures newlines after multiline block do statements.
+  Enabled: true
+Style/MultilineIfThen:
+  Description: Do not use then for multi-line if/unless.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-then
+  Enabled: true
+Style/MultilineTernaryOperator:
+  Description: 'Avoid multi-line ?: (the ternary operator); use if/unless instead.'
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary
+  Enabled: true
+Style/NegatedIf:
+  Description: Favor unless over if for negative conditions (or control flow or).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#unless-for-negatives
+  Enabled: false
+Style/NegatedWhile:
+  Description: Favor until over while for negative conditions.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#until-for-negatives
+  Enabled: false
+Style/NestedTernaryOperator:
+  Description: Use one expression per branch in a ternary operator.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-ternary
+  Enabled: true
+Style/NilComparison:
+  Description: Prefer x.nil? to x == nil.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods
+  Enabled: false
+Style/Not:
+  Description: Use ! instead of not.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#bang-not-not
+  Enabled: false
+Style/OneLineConditional:
+  Description: Favor the ternary operator(?:) over if/then/else/end constructs.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
+  Enabled: false
+Style/OpMethod:
+  Description: When defining binary operators, name the argument other.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#other-arg
+  Enabled: false
+Style/PerlBackrefs:
+  Description: Avoid Perl-style regex back references.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
+  Enabled: false
+Style/Proc:
+  Description: Use proc instead of Proc.new.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc
+  Enabled: false
+Style/RedundantBegin:
+  Description: Don't use begin blocks when they are not needed.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#begin-implicit
+  Enabled: true
+Style/RedundantException:
+  Description: Checks for an obsolete RuntimeException argument in raise/fail.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror
+  Enabled: true
+Style/RedundantSelf:
+  Description: Don't use self where it's not needed.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-self-unless-required
+  Enabled: true
+Style/RescueModifier:
+  Description: Avoid using rescue in its modifier form.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers
+  Enabled: true
+Style/SelfAssignment:
+  Description: Checks for places where self-assignment shorthand should have been
+    used.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#self-assignment
+  Enabled: false
+Style/SingleSpaceBeforeFirstArg:
+  Description: Checks that exactly one space is used between a method name and the
+    first argument for method calls without parentheses.
+  Enabled: true
+Style/SpaceAfterColon:
+  Description: Use spaces after colons.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
+  Enabled: true
+Style/SpaceAfterComma:
+  Description: Use spaces after commas.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
+  Enabled: true
+Style/SpaceAfterControlKeyword:
+  Description: Use spaces after if/elsif/unless/while/until/case/when.
+  Enabled: true
+Style/SpaceAfterMethodName:
+  Description: Do not put a space between a method name and the opening parenthesis
+    in a method definition.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces
+  Enabled: true
+Style/SpaceAfterNot:
+  Description: Tracks redundant space after the ! operator.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-bang
+  Enabled: true
+Style/SpaceAfterSemicolon:
+  Description: Use spaces after semicolons.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
+  Enabled: true
+Style/SpaceBeforeComma:
+  Description: No spaces before commas.
+  Enabled: true
+Style/SpaceBeforeComment:
+  Description: Checks for missing space between code and a comment on the same line.
+  Enabled: true
+Style/SpaceBeforeSemicolon:
+  Description: No spaces before semicolons.
+  Enabled: true
+Style/SpaceAroundOperators:
+  Description: Use spaces around operators.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators
+  Enabled: true
+Style/SpaceBeforeModifierKeyword:
+  Description: Put a space before the modifier keyword.
+  Enabled: true
+Style/SpaceInsideBrackets:
+  Description: No spaces after [ or before ].
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces
+  Enabled: true
+Style/SpaceInsideParens:
+  Description: No spaces after ( or before ).
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces
+  Enabled: true
+Style/SpaceInsideRangeLiteral:
+  Description: No spaces inside range literals.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals
+  Enabled: true
+Style/SpecialGlobalVars:
+  Description: Avoid Perl-style global variables.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
+  Enabled: false
+Style/StructInheritance:
+  Description: Checks for inheritance from Struct.new.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-extend-struct-new
+  Enabled: true
+Style/Tab:
+  Description: No hard tabs.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation
+  Enabled: true
+Style/TrailingWhitespace:
+  Description: Avoid trailing whitespace.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace
+  Enabled: true
+Style/UnlessElse:
+  Description: Do not use unless with else. Rewrite these with the positive case first.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-else-with-unless
+  Enabled: true
+Style/UnneededCapitalW:
+  Description: Checks for %W when interpolation is not needed.
+  Enabled: true
+Style/UnneededPercentQ:
+  Description: Checks for %q/%Q when single quotes or double quotes would do.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q
+  Enabled: true
+# Style/UnneededPercentX:
+#   Description: Checks for %x when `` would do.
+#   StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-x
+#   Enabled: true
+Style/VariableInterpolation:
+  Description: Don't interpolate global, instance and class variables directly in
+    strings.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
+  Enabled: false
+Style/WhenThen:
+  Description: Use when x then ... for one-line cases.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
+  Enabled: false
+Style/WhileUntilDo:
+  Description: Checks for redundant do after while or until.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do
+  Enabled: true
+Lint/AmbiguousOperator:
+  Description: Checks for ambiguous operators in the first argument of a method invocation
+    without parentheses.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-as-args
+  Enabled: false
+Lint/AmbiguousRegexpLiteral:
+  Description: Checks for ambiguous regexp literals in the first argument of a method
+    invocation without parenthesis.
+  Enabled: false
+Lint/BlockAlignment:
+  Description: Align block ends correctly.
+  Enabled: true
+Lint/ConditionPosition:
+  Description: Checks for condition placed in a confusing position relative to the
+    keyword.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#same-line-condition
+  Enabled: false
+Lint/Debugger:
+  Description: Check for debugger calls.
+  Enabled: true
+Lint/DeprecatedClassMethods:
+  Description: Check for deprecated class method calls.
+  Enabled: false
+Lint/DuplicateMethods:
+  Description: Check for duplicate methods calls.
+  Enabled: true
+Lint/ElseLayout:
+  Description: Check for odd code arrangement in an else block.
+  Enabled: false
+Lint/EmptyEnsure:
+  Description: Checks for empty ensure block.
+  Enabled: true
+Lint/EmptyInterpolation:
+  Description: Checks for empty string interpolation.
+  Enabled: true
+Lint/EndInMethod:
+  Description: END blocks should not be placed inside method definitions.
+  Enabled: true
+Lint/EnsureReturn:
+  Description: Do not use return in an ensure block.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-return-ensure
+  Enabled: true
+Lint/Eval:
+  Description: The use of eval represents a serious security risk.
+  Enabled: true
+Lint/HandleExceptions:
+  Description: Don't suppress exception.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
+  Enabled: false
+Lint/InvalidCharacterLiteral:
+  Description: Checks for invalid character literals with a non-escaped whitespace
+    character.
+  Enabled: false
+Lint/LiteralInCondition:
+  Description: Checks of literals used in conditions.
+  Enabled: false
+Lint/LiteralInInterpolation:
+  Description: Checks for literals used in interpolation.
+  Enabled: false
+Lint/Loop:
+  Description: Use Kernel#loop with break rather than begin/end/until or begin/end/while
+    for post-loop tests.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#loop-with-break
+  Enabled: false
+Lint/ParenthesesAsGroupedExpression:
+  Description: Checks for method calls with a space before the opening parenthesis.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces
+  Enabled: false
+Lint/RequireParentheses:
+  Description: Use parentheses in the method call to avoid confusion about precedence.
+  Enabled: false
+Lint/RescueException:
+  Description: Avoid rescuing the Exception class.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-blind-rescues
+  Enabled: true
+Lint/ShadowingOuterLocalVariable:
+  Description: Do not use the same name as outer local variable for block arguments
+    or block local variables.
+  Enabled: true
+Lint/SpaceBeforeFirstArg:
+  Description: Put a space between a method name and the first argument in a method
+    call without parentheses.
+  Enabled: true
+Lint/StringConversionInInterpolation:
+  Description: Checks for Object#to_s usage in string interpolation.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-to-s
+  Enabled: true
+Lint/UnderscorePrefixedVariableName:
+  Description: Do not use prefix `_` for a variable that is used.
+  Enabled: false
+Lint/UnusedBlockArgument:
+  Description: Checks for unused block arguments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
+  Enabled: true
+Lint/UnusedMethodArgument:
+  Description: Checks for unused method arguments.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
+  Enabled: true
+Lint/UnreachableCode:
+  Description: Unreachable code.
+  Enabled: true
+Lint/UselessAccessModifier:
+  Description: Checks for useless access modifiers.
+  Enabled: true
+Lint/UselessAssignment:
+  Description: Checks for useless assignment to a local variable.
+  StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
+  Enabled: true
+Lint/UselessComparison:
+  Description: Checks for comparison of something with itself.
+  Enabled: true
+Lint/UselessElseWithoutRescue:
+  Description: Checks for useless `else` in `begin..end` without `rescue`.
+  Enabled: true
+Lint/UselessSetterCall:
+  Description: Checks for useless setter call to a local variable.
+  Enabled: true
+Lint/Void:
+  Description: Possible use of operator/literal/variable in void context.
+  Enabled: false
+Rails/Delegate:
+  Description: Prefer delegate method for delegations.
+  Enabled: false
diff --git a/.travis.yml b/.travis.yml
index 855cccd..1adf0af 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,4 +25,6 @@ before_install:
   - ./configure && make && sudo make install
   - cd ..
   - tmux -V
-script: bundle exec rspec spec
+script:
+  - bundle exec rspec spec
+  - bundle exec rake rubocop
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c2eea0c..8468ef2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+## 0.7.0
+### New features
+
+- Add support for starting in detached mode #307
+- Support windows without names #292, #323
+- Add per project `.tmuxinator.yml` support #335 :sparkles:
+- Support passing args on the command line #343 :tada:
+
+### Bug fixes and Misc
+- Fix some RSpec deprecations
+- Explain what EBR is in the readme #319
+- Prevent project names containing only numbers from raising a NoMethodError #324
+- Fix YAML syntax highlighting in readme #325
+- Add `asset_path` helper #326
+- Switch to just plain Rubocop instead of hound #339
+- Fix typo in readme #346
+- Fix thor not returning correct exit status #192
+- Add gitter badge
+
 ## 0.6.11
 - Add aliasing of projects to create multiple sessions for a single project #143, #273
 - ERB support for projects #267
diff --git a/Gemfile b/Gemfile
index 6700e4b..5afc8c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,10 +3,11 @@ source "https://rubygems.org"
 # Specify your gem's dependencies in tmuxinator.gemspec
 gemspec
 
-gem 'rake', '~> 10.4'
-gem 'rspec', '~> 3.1'
-gem 'simplecov', '~> 0.9'
-gem 'coveralls', '~> 0.7'
-gem 'awesome_print', '~> 1.2'
-gem 'pry', '~> 0.10'
-gem 'factory_girl', '~> 4.4'
+gem "rake", "~> 10.4"
+gem "rspec", "~> 3.3"
+gem "simplecov", "~> 0.9"
+gem "coveralls", "~> 0.7"
+gem "awesome_print", "~> 1.2"
+gem "pry", "~> 0.10"
+gem "factory_girl", "~> 4.5"
+gem "rubocop", "~> 0.34", require: false
diff --git a/README.md b/README.md
index f9a0090..2fc5f66 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Tmuxinator
 
-[![Gem Version](https://badge.fury.io/rb/tmuxinator.svg)](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://img.shields.io/coveralls/tmuxinator/tmuxinator.svg)](https://coveralls.io/r/tmuxinator/tmuxinator?branch=master) [![Code Climate](https://codeclimate.com/github/tmuxinator/tmuxinator/badges/gpa.svg)](https://codeclimate.com/github/tmuxina [...]
+[![Gem Version](https://badge.fury.io/rb/tmuxinator.svg)](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://img.shields.io/coveralls/tmuxinator/tmuxinator.svg)](https://coveralls.io/r/tmuxinator/tmuxinator?branch=master) [![Code Climate](https://codeclimate.com/github/tmuxinator/tmuxinator/badges/gpa.svg)](https://codeclimate.com/github/tmuxina [...]
 
 Create and manage tmux sessions easily.
 
@@ -123,7 +123,7 @@ 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.
 
-```
+```yaml
 windows:
   - editor: vim
 ```
@@ -132,7 +132,7 @@ windows:
 
 An optional root option can be specified per window:
 
-```
+```yaml
 name: test
 root: ~/projects/company
 
@@ -170,7 +170,7 @@ or [specify your own](http://stackoverflow.com/a/9976282/183537).
 
 To use tmuxinator with rbenv, RVM, NVM etc, use the `pre_window` option.
 
-```
+```yaml
 pre_window: rbenv shell 2.0.0-p247
 ```
 
@@ -178,15 +178,15 @@ These command(s) will run before any subsequent commands in all panes and window
 
 ## Custom attachment and post commands
 
-You can set tmuxiniator to skip auto-attaching to the session by using the `attach` option.
+You can set tmuxinator to skip auto-attaching to the session by using the `attach` option.
 
-```
+```yaml
 attach: false
 ```
 
 You can also run arbitrary commands by using the `post` option. This is useful if you want to attach to tmux in a non-standard way (e.g. for a program that makes use of tmux control mode like iTerm2).
 
-```
+```yaml
 post: tmux -CC attach
 ```
 
@@ -198,7 +198,7 @@ SSH for example.
 
 To support this both the window and pane options can take an array as an argument:
 
-```
+```yaml
 name: sample
 root: ~/
 
@@ -217,12 +217,44 @@ windows:
 
 ## ERB
 
-Project files support ERB for reusability across environments. Eg:
+Project files support [ERB](https://en.wikipedia.org/wiki/ERuby#erb) for reusability across environments. Eg:
 
-```
+```yaml
 root: <%= ENV["MY_CUSTOM_DIR"] %>
 ```
 
+You can also pass arguments to your projects, and access them with ERB. Simple arguments are available in an array named `@args`.
+
+Eg:
+```bash
+$ tmuxinator start project foo
+```
+
+```yaml
+# ~/.tmuxinator/project.yml
+
+name: project
+root: ~/<%= @args[0] %>
+
+...
+```
+
+You can also pass key-value pairs using the format `key=value`. These will be available in a hash named `@settings`.
+
+Eg:
+```bash
+$ tmuxinator start project workspace=~/workspace/todo
+```
+
+```yaml
+# ~/.tmuxinator/project.yml
+
+name: project
+root: ~/<%= @settings["workspace"] %>
+
+...
+```
+
 ## Starting a session
 
 This will fire up tmux with all the tabs and panes you configured.
@@ -235,6 +267,8 @@ If you use the optional `[alias]` argument, it will start a new tmux session
 with the custom alias name provided.  This is to enable reuse of a project
 without tmux session name collision.
 
+If there is a `./.tmuxinator.yml` file in the current working directory but not a named project file in `~/.tmuxinator`, tmuxinator will use the local file.  This is primarily intended to be used for sharing tmux configurations in complex development environments.
+
 ## Shorthand
 
 A shorthand alias for tmuxinator can also be used.
diff --git a/Rakefile b/Rakefile
index 2995527..f3909fb 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1 +1,20 @@
 require "bundler/gem_tasks"
+require "rubocop/rake_task"
+
+RuboCop::RakeTask.new
+
+namespace :hound do
+  BASE_CMD = "git diff --no-commit-id --name-only -r master | grep rb"
+
+  task :count do
+    n = %x{#{BASE_CMD} | wc -l}.chomp
+    puts "Cop'ing #{n} files"
+  end
+
+  task :check do
+    cmd = "#{BASE_CMD} | xargs rubocop"
+    system cmd
+  end
+end
+
+task :check => ["hound:count", "hound:check"]
diff --git a/bin/tmuxinator b/bin/tmuxinator
index 3a7dea8..d83b5ae 100755
--- a/bin/tmuxinator
+++ b/bin/tmuxinator
@@ -4,16 +4,13 @@ $: << File.expand_path("../../lib/", __FILE__)
 require "thor"
 require "tmuxinator"
 
-if ARGV.length == 1
-  name = ARGV[0]
+name = ARGV[0] || nil
 
-  if Tmuxinator::Cli::COMMANDS.keys.include?(name.to_sym)
-    Tmuxinator::Cli.start
-  elsif Tmuxinator::Config.exists?(name)
-    Tmuxinator::Cli.new.start(name)
-  else
-    Tmuxinator::Cli.start
-  end
+if ARGV.length == 0 && Tmuxinator::Config.local?
+  Tmuxinator::Cli.new.local
+elsif name && !Tmuxinator::Cli::COMMANDS.keys.include?(name.to_sym) &&
+      Tmuxinator::Config.exists?(name)
+  Tmuxinator::Cli.new.start(name, *ARGV.drop(1))
 else
   Tmuxinator::Cli.start
 end
diff --git a/lib/tmuxinator/assets/template.erb b/lib/tmuxinator/assets/template.erb
index fb60651..e5eb1ef 100644
--- a/lib/tmuxinator/assets/template.erb
+++ b/lib/tmuxinator/assets/template.erb
@@ -14,7 +14,7 @@ if [ "$?" -eq 1 ]; then
 
   # Create the session and the first window. Manually switch to root
   # directory if required to support tmux < 1.9
-  TMUX= <%= tmux %> new-session -d -s <%= name %> -n <%= windows.first.name %>
+  TMUX= <%= tmux_new_session_command %>
   <% if windows.first.root? %>
   <%= windows.first.tmux_window_command_prefix %> <%= "cd #{windows.first.root}".shellescape %> C-m
   <% end %>
@@ -71,11 +71,11 @@ if [ "$?" -eq 1 ]; then
 fi
 
 <%- if attach? -%>
-if [ -z "$TMUX" ]; then
-  <%= tmux %> -u attach-session -t <%= name %>
-else
-  <%= tmux %> -u switch-client -t <%= name %>
-fi
+  if [ -z "$TMUX" ]; then
+    <%= tmux %> -u attach-session -t <%= name %>
+  else
+    <%= tmux %> -u switch-client -t <%= name %>
+  fi
 <%- end -%>
 
 <%= post %>
diff --git a/lib/tmuxinator/assets/wemux_template.erb b/lib/tmuxinator/assets/wemux_template.erb
index 8fb9947..f60335f 100644
--- a/lib/tmuxinator/assets/wemux_template.erb
+++ b/lib/tmuxinator/assets/wemux_template.erb
@@ -8,7 +8,7 @@ if [ "$?" -eq 127 ]; then
   <%= pre %>
 
   # Create the session and the first window.
-  TMUX= <%= tmux %> new-session -d -s <%= name %> -n <%= windows.first.name %>
+  TMUX= <%= tmux_new_session_command %>
 
   # Set the default path.
   <%- if root? -%>
diff --git a/lib/tmuxinator/cli.rb b/lib/tmuxinator/cli.rb
index 842ecf2..5b0b383 100644
--- a/lib/tmuxinator/cli.rb
+++ b/lib/tmuxinator/cli.rb
@@ -1,5 +1,11 @@
 module Tmuxinator
   class Cli < Thor
+    # By default, Thor returns exit(0) when an error occurs.
+    # Please see: https://github.com/tmuxinator/tmuxinator/issues/192
+    def self.exit_on_failure?
+      true
+    end
+
     include Tmuxinator::Util
 
     COMMANDS = {
@@ -7,9 +13,16 @@ module Tmuxinator
       completions: "Used for shell completion",
       new: "Create a new project file and open it in your editor",
       open: "Alias of new",
-      start: "Start a tmux session using a project's tmuxinator config, with an optional [ALIAS] for project reuse",
+      start: <<-DESC,
+        Start a tmux session using a project's tmuxinator config,
+        with an optional [ALIAS] for project reuse
+      DESC
+      local: "Start a tmux session using ./.tmuxinator.yml",
       debug: "Output the shell commands that are generated by tmuxinator",
-      copy: "Copy an existing project to a new project and open it in your editor",
+      copy: <<-DESC,
+        Copy an existing project to a new project and open it in
+        your editor
+      DESC
       delete: "Deletes given project",
       implode: "Deletes all tmuxinator projects",
       version: "Display installed tmuxinator version",
@@ -17,18 +30,19 @@ module Tmuxinator
       list: "Lists all tmuxinator projects"
     }
 
-    package_name "tmuxinator" unless Gem::Version.create(Thor::VERSION) < Gem::Version.create("0.18")
+    package_name "tmuxinator" \
+      unless Gem::Version.create(Thor::VERSION) < Gem::Version.create("0.18")
 
     desc "commands", COMMANDS[:commands]
 
     def commands(shell = nil)
       out = if shell == "zsh"
-        COMMANDS.map do |command, desc|
-          "#{command}:#{desc}"
-        end.join("\n")
-      else
-        COMMANDS.keys.join("\n")
-      end
+              COMMANDS.map do |command, desc|
+                "#{command}:#{desc}"
+              end.join("\n")
+            else
+              COMMANDS.keys.join("\n")
+            end
 
       puts out
     end
@@ -48,39 +62,100 @@ module Tmuxinator
     map "o" => :new
     map "e" => :new
     map "n" => :new
+    method_option :local, type: :boolean,
+                          aliases: ["-l"],
+                          desc: "Create local project file at ./.tmuxinator.yml"
 
     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) }
+      project_file = if options[:local]
+                       Tmuxinator::Config::LOCAL_DEFAULT
+                     else
+                       Tmuxinator::Config.default_project(name)
+                     end
+      unless Tmuxinator::Config.exists?(project_file)
+        template = Tmuxinator::Config.default? ? :default : :sample
+        content = File.read(Tmuxinator::Config.send(template.to_sym))
+        erb = Erubis::Eruby.new(content).result(binding)
+        File.open(project_file, "w") { |f| f.write(erb) }
       end
 
-      Kernel.system("$EDITOR #{config}") || doctor
+      Kernel.system("$EDITOR #{project_file}") || doctor
     end
 
-    desc "start [PROJECT] [SESSION_NAME]", COMMANDS[:start]
-    map "s" => :start
+    no_commands do
+      def create_project(project_options = {})
+        attach_opt = project_options[:attach]
+        attach = !attach_opt.nil? && attach_opt ? true : false
+        detach = !attach_opt.nil? && !attach_opt ? true : false
+
+        options = {
+          force_attach: attach,
+          force_detach: detach,
+          name: project_options[:name],
+          custom_name: project_options[:custom_name],
+          args: project_options[:args]
+        }
+
+        begin
+          Tmuxinator::Config.validate(options)
+        rescue => e
+          exit! e.message
+        end
+      end
 
-    def start(name, custom_name  = nil)
-      project = Tmuxinator::Config.validate(name, custom_name )
+      def render_project(project)
+        if project.deprecations.any?
+          project.deprecations.each { |deprecation| say deprecation, :red }
+          puts
+          print "Press ENTER to continue."
+          STDIN.getc
+        end
 
-      if project.deprecations.any?
-        project.deprecations.each { |deprecation| say deprecation, :red }
-        puts
-        print "Press ENTER to continue."
-        STDIN.getc
+        Kernel.exec(project.render)
       end
+    end
 
-      Kernel.exec(project.render)
+    desc "start [PROJECT] [ARGS]", COMMANDS[:start]
+    map "s" => :start
+    method_option :attach, type: :boolean,
+                           aliases: "-a",
+                           desc: "Attach to tmux session after creation."
+    method_option :name, aliases: "-n",
+                         desc: "Give the session a different name"
+
+    def start(name, *args)
+      params = {
+        name: name,
+        custom_name: options[:name],
+        attach: options[:attach],
+        args: args
+      }
+      project = create_project(params)
+      render_project(project)
     end
 
-    desc "debug [PROJECT]", COMMANDS[:debug]
+    desc "local", COMMANDS[:local]
+    map "." => :local
+
+    def local
+      render_project(create_project(attach: options[:attach]))
+    end
 
-    def debug(name, custom_name  = nil)
-      project = Tmuxinator::Config.validate(name, custom_name )
+    method_option :attach, type: :boolean,
+                           aliases: "-a",
+                           desc: "Attach to tmux session after creation."
+    method_option :name, aliases: "-n",
+                         desc: "Give the session a different name"
+    desc "debug [PROJECT] [ARGS]", COMMANDS[:debug]
+
+    def debug(name, *args)
+      params = {
+        name: name,
+        custom_name: options[:name],
+        attach: options[:attach],
+        args: args
+      }
+      project = create_project(params)
       puts project.render
     end
 
@@ -92,9 +167,12 @@ module Tmuxinator
       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)
+      exit!("Project #{existing} doesn't exist!") \
+        unless Tmuxinator::Config.exists?(existing)
 
-      if !Tmuxinator::Config.exists?(new) or yes?("#{new} already exists, would you like to overwrite it?", :red)
+      new_exists = Tmuxinator::Config.exists?(new)
+      question = "#{new} already exists, would you like to overwrite it?"
+      if !new_exists || yes?(question, :red)
         say "Overwriting #{new}" if Tmuxinator::Config.exists?(new)
         FileUtils.copy_file(existing_config_path, new_config_path)
       end
@@ -108,7 +186,7 @@ module Tmuxinator
 
     def delete(project)
       if Tmuxinator::Config.exists?(project)
-        config =  "#{Tmuxinator::Config.root}/#{project}.yml"
+        config = "#{Tmuxinator::Config.root}/#{project}.yml"
 
         if yes?("Are you sure you want to delete #{project}?(y/n)", :red)
           FileUtils.rm(config)
@@ -156,7 +234,7 @@ module Tmuxinator
       yes_no Tmuxinator::Config.editor?
 
       say "Checking if $SHELL is set ==> "
-      yes_no  Tmuxinator::Config.shell?
+      yes_no Tmuxinator::Config.shell?
     end
   end
 end
diff --git a/lib/tmuxinator/config.rb b/lib/tmuxinator/config.rb
index 4ba12ee..5637269 100644
--- a/lib/tmuxinator/config.rb
+++ b/lib/tmuxinator/config.rb
@@ -1,17 +1,21 @@
 module Tmuxinator
   class Config
+    LOCAL_DEFAULT = "./.tmuxinator.yml".freeze
+    NO_LOCAL_FILE_MSG = "Project file at ./.tmuxinator.yml doesn't exist."
+
     class << self
       def root
-        Dir.mkdir("#{ENV["HOME"]}/.tmuxinator") unless File.directory?(File.expand_path("~/.tmuxinator"))
-        "#{ENV["HOME"]}/.tmuxinator"
+        root_dir = File.expand_path("~/.tmuxinator")
+        Dir.mkdir("#{ENV['HOME']}/.tmuxinator") unless File.directory?(root_dir)
+        "#{ENV['HOME']}/.tmuxinator"
       end
 
       def sample
-        "#{File.dirname(__FILE__)}/assets/sample.yml"
+        asset_path "sample.yml"
       end
 
       def default
-        "#{ENV["HOME"]}/.tmuxinator/default.yml"
+        "#{ENV['HOME']}/.tmuxinator/default.yml"
       end
 
       def default?
@@ -42,18 +46,33 @@ module Tmuxinator
         File.exists?(project(name))
       end
 
-      def project(name)
+      def project_in_root(name)
         projects = Dir.glob("#{root}/**/*.yml")
-        project_file = projects.detect { |project| File.basename(project, ".yml") == name }
-        project_file || "#{root}/#{name}.yml"
+        projects.detect { |project| File.basename(project, ".yml") == name }
+      end
+
+      def local?
+        project_in_local
+      end
+
+      def project_in_local
+        [LOCAL_DEFAULT].detect { |f| File.exists?(f) }
+      end
+
+      def default_project(name)
+        "#{root}/#{name}.yml"
+      end
+
+      def project(name)
+        project_in_root(name) || project_in_local || default_project(name)
       end
 
       def template
-        "#{File.dirname(__FILE__)}/assets/template.erb"
+        asset_path "template.erb"
       end
 
       def wemux_template
-        "#{File.dirname(__FILE__)}/assets/wemux_template.erb"
+        asset_path "wemux_template.erb"
       end
 
       def configs
@@ -62,34 +81,27 @@ module Tmuxinator
         end
       end
 
-      def validate(name, custom_name = nil)
-        unless Tmuxinator::Config.exists?(name)
-          puts "Project #{name} doesn't exist."
-          exit!
-        end
-
-        config_path = Tmuxinator::Config.project(name)
-
-        yaml = begin
-          YAML.load(Erubis::Eruby.new(File.read(config_path)).result(binding))
-        rescue SyntaxError, StandardError
-          puts "Failed to parse config file. Please check your formatting."
-          exit!
-        end
-
-        project = Tmuxinator::Project.new(yaml, custom_name)
-
-        unless project.windows?
-          puts "Your project file should include some windows."
-          exit!
-        end
+      def validate(options = {})
+        name = options[:name]
+        options[:force_attach] ||= false
+        options[:force_detach] ||= false
+
+        project_file = if name.nil?
+                         raise NO_LOCAL_FILE_MSG \
+                           unless Tmuxinator::Config.local?
+                         project_in_local
+                       else
+                         raise "Project #{name} doesn't exist." \
+                           unless Tmuxinator::Config.exists?(name)
+                         Tmuxinator::Config.project(name)
+                       end
+        Tmuxinator::Project.load(project_file, options).validate!
+      end
 
-        unless project.name?
-          puts "Your project file didn't specify a 'project_name'"
-          exit!
-        end
+      private
 
-        project
+      def asset_path(asset)
+        "#{File.dirname(__FILE__)}/assets/#{asset}"
       end
     end
   end
diff --git a/lib/tmuxinator/pane.rb b/lib/tmuxinator/pane.rb
index 00a9a51..82ba096 100644
--- a/lib/tmuxinator/pane.rb
+++ b/lib/tmuxinator/pane.rb
@@ -10,27 +10,43 @@ module Tmuxinator
     end
 
     def tmux_window_and_pane_target
-      "#{project.name}:#{tab.index + project.base_index}.#{index + project.base_index}"
+      x = tab.index + project.base_index
+      y = index + project.base_index
+      "#{project.name}:#{x}.#{y}"
     end
 
     def tmux_pre_command
       return unless tab.pre
 
-      "#{project.tmux} send-keys -t #{tmux_window_and_pane_target} #{tab.pre.shellescape} C-m"
+      t = tmux_window_and_pane_target
+      e = tab.pre.shellescape
+      "#{project.tmux} send-keys -t #{t} #{e} C-m"
     end
 
     def tmux_pre_window_command
       return unless project.pre_window
 
-      "#{project.tmux} send-keys -t #{tmux_window_and_pane_target} #{project.pre_window.shellescape} C-m"
+      t = tmux_window_and_pane_target
+      e = project.pre_window.shellescape
+      "#{project.tmux} send-keys -t #{t} #{e} 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" : ""
+      if command
+        x = tab.index + project.base_index
+        y = index + tab.project.base_index
+        e = command.shellescape
+        n = project.name
+        "#{project.tmux} send-keys -t #{n}:#{x}.#{y} #{e} C-m"
+      else
+        ""
+      end
     end
 
     def tmux_split_command
-      path = tab.root? ? "#{Tmuxinator::Config.default_path_option} #{tab.root}" : nil
+      path = if tab.root?
+               "#{Tmuxinator::Config.default_path_option} #{tab.root}"
+             end
       "#{project.tmux} splitw #{path} -t #{tab.tmux_window_target}"
     end
 
diff --git a/lib/tmuxinator/project.rb b/lib/tmuxinator/project.rb
index 1ba2931..5cf68c5 100644
--- a/lib/tmuxinator/project.rb
+++ b/lib/tmuxinator/project.rb
@@ -4,11 +4,75 @@ module Tmuxinator
     include Tmuxinator::Deprecations
     include Tmuxinator::WemuxSupport
 
-    attr_reader :yaml, :custom_name
+    RBENVRVM_DEP_MSG = <<-M
+    DEPRECATION: rbenv/rvm-specific options have been replaced by the
+    pre_tab option and will not be supported in 0.8.0.
+    M
+    TABS_DEP_MSG = <<-M
+    DEPRECATION: The tabs option has been replaced by the windows option
+    and will not be supported in 0.8.0.
+    M
+    CLIARGS_DEP_MSG = <<-M
+    DEPRECATION: The cli_args option has been replaced by the tmux_options
+    option and will not be supported in 0.8.0.
+    M
+
+    attr_reader :yaml
+    attr_reader :force_attach
+    attr_reader :force_detach
+    attr_reader :custom_name
+
+    def self.load(path, options = {})
+      yaml = begin
+        raw_content = File.read(path)
+
+        args = options[:args] || []
+        @settings = parse_settings(args)
+        @args = args
+
+        content = Erubis::Eruby.new(raw_content).result(binding)
+        YAML.load(content)
+      rescue SyntaxError, StandardError
+        raise "Failed to parse config file. Please check your formatting."
+      end
+
+      new(yaml, options)
+    end
+
+    def self.parse_settings(args)
+      settings = args.select { |x| x.match(/.*=.*/) }
+      args.reject! { |x| x.match(/.*=.*/) }
+
+      settings.map! do |setting|
+        parts = setting.split("=")
+        [parts[0], parts[1]]
+      end
+
+      Hash[settings]
+    end
+
+    def validate!
+      raise "Your project file should include some windows." \
+        unless self.windows?
+      raise "Your project file didn't specify a 'project_name'" \
+        unless self.name?
+      self
+    end
+
+    def initialize(yaml, options = {})
+      options[:force_attach] = false if options[:force_attach].nil?
+      options[:force_detach] = false if options[:force_detach].nil?
 
-    def initialize(yaml, custom_name = nil)
       @yaml = yaml
-      @custom_name = custom_name
+
+      @custom_name = options[:custom_name]
+
+      @force_attach = options[:force_attach]
+      @force_detach = options[:force_detach]
+
+      raise "Cannot force_attach and force_detach at the same time" \
+        if @force_attach && @force_detach
+
       load_wemux_overrides if wemux?
     end
 
@@ -20,7 +84,7 @@ module Tmuxinator
     def windows
       windows_yml = yaml["tabs"] || yaml["windows"]
 
-      @windows ||= windows_yml.map.with_index do |window_yml, index|
+      @windows ||= (windows_yml || {}).map.with_index do |window_yml, index|
         Tmuxinator::Window.new(window_yml, index, self)
       end
     end
@@ -32,7 +96,7 @@ module Tmuxinator
 
     def name
       name = custom_name || yaml["project_name"] || yaml["name"]
-      name.blank? ? nil : name.shellescape
+      name.blank? ? nil : name.to_s.shellescape
     end
 
     def pre
@@ -44,11 +108,21 @@ module Tmuxinator
       end
     end
 
+    def attach?
+      if yaml["attach"].nil?
+        yaml_attach = true
+      else
+        yaml_attach = yaml["attach"]
+      end
+      attach = force_attach || !force_detach && yaml_attach
+      attach
+    end
+
     def pre_window
       if rbenv?
-        "rbenv shell #{yaml["rbenv"]}"
+        "rbenv shell #{yaml['rbenv']}"
       elsif rvm?
-        "rvm use #{yaml["rvm"]}"
+        "rvm use #{yaml['rvm']}"
       elsif pre_tab?
         yaml["pre_tab"]
       else
@@ -56,14 +130,6 @@ module Tmuxinator
       end
     end
 
-    def attach
-      attach = true
-      if !yaml["attach"].nil?
-        attach = yaml["attach"]
-      end
-      attach
-    end
-
     def post
       post_config = yaml["post"]
       if post_config.is_a?(Array)
@@ -86,8 +152,6 @@ module Tmuxinator
         " -S #{socket_path}"
       elsif socket_name
         " -L #{socket_name}"
-      else
-        nil
       end
     end
 
@@ -101,9 +165,9 @@ module Tmuxinator
 
     def tmux_options
       if cli_args?
-        " #{yaml["cli_args"].to_s.strip}"
+        " #{yaml['cli_args'].to_s.strip}"
       elsif tmux_options?
-        " #{yaml["tmux_options"].to_s.strip}"
+        " #{yaml['tmux_options'].to_s.strip}"
       else
         ""
       end
@@ -133,15 +197,11 @@ module Tmuxinator
       !name.nil?
     end
 
-    def attach?
-      !!attach
-    end
-
     def window(i)
       "#{name}:#{i}"
     end
 
-    def send_pane_command(cmd, window_index, pane_index)
+    def send_pane_command(cmd, window_index, _pane_index)
       if cmd.empty?
         ""
       else
@@ -151,7 +211,7 @@ module Tmuxinator
 
     def send_keys(cmd, window_index)
       if cmd.empty?
-       ""
+        ""
       else
         "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
       end
@@ -159,9 +219,9 @@ module Tmuxinator
 
     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 << RBENVRVM_DEP_MSG if yaml["rbenv"] || yaml["rvm"]
+      deprecations << TABS_DEP_MSG if yaml["tabs"]
+      deprecations << CLIARGS_DEP_MSG if yaml["cli_args"]
       deprecations
     end
 
@@ -177,6 +237,11 @@ module Tmuxinator
       "#{tmux} start-server\\; show-option -g"
     end
 
+    def tmux_new_session_command
+      window = windows.first.tmux_window_name_option
+      "#{tmux} new-session -d -s #{name} #{window}"
+    end
+
     private
 
     def tmux_config
@@ -187,7 +252,7 @@ module Tmuxinator
       options_hash = {}
 
       options_string = `#{show_tmux_options}`
-      options_string.encode!("UTF-8", :invalid => :replace)
+      options_string.encode!("UTF-8", invalid: :replace)
       options_string.split("\n").map do |entry|
         key, value = entry.split("\s")
         options_hash[key] = value
diff --git a/lib/tmuxinator/version.rb b/lib/tmuxinator/version.rb
index f350429..863f7f7 100644
--- a/lib/tmuxinator/version.rb
+++ b/lib/tmuxinator/version.rb
@@ -1,3 +1,3 @@
 module Tmuxinator
-  VERSION = "0.6.11"
+  VERSION = "0.7.0"
 end
diff --git a/lib/tmuxinator/wemux_support.rb b/lib/tmuxinator/wemux_support.rb
index a03a255..793f380 100644
--- a/lib/tmuxinator/wemux_support.rb
+++ b/lib/tmuxinator/wemux_support.rb
@@ -5,17 +5,17 @@ module Tmuxinator
     end
 
     def load_wemux_overrides
-      self.instance_eval do
-        def render
+      class_eval do
+        define_method :render do
           template = File.read(Tmuxinator::Config.wemux_template)
           Erubis::Eruby.new(template).result(binding)
         end
 
-        def name
+        define_method :name do
           "wemux"
         end
 
-        def tmux
+        define_method :tmux do
           "wemux"
         end
       end
diff --git a/lib/tmuxinator/window.rb b/lib/tmuxinator/window.rb
index 899cfe8..0ab8e1b 100644
--- a/lib/tmuxinator/window.rb
+++ b/lib/tmuxinator/window.rb
@@ -5,7 +5,9 @@ module Tmuxinator
     attr_reader :name, :root, :panes, :layout, :commands, :index, :project
 
     def initialize(window_yaml, index, project)
-      @name = !window_yaml.keys.first.nil? ? window_yaml.keys.first.shellescape : nil
+      @name = if !window_yaml.keys.first.nil?
+                window_yaml.keys.first.shellescape
+              end
       @root = nil
       @panes = []
       @layout = nil
@@ -18,7 +20,11 @@ module Tmuxinator
       if value.is_a?(Hash)
         @layout = value["layout"] ? value["layout"].shellescape : nil
         @pre = value["pre"] if value["pre"]
-        @root = value["root"] ? File.expand_path(value["root"]).shellescape : project.root? ? project.root : nil
+        @root = if value["root"]
+                  File.expand_path(value["root"]).shellescape
+                elsif project.root?
+                  project.root
+                end
 
         @panes = build_panes(value["panes"])
       else
@@ -29,7 +35,7 @@ module Tmuxinator
     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|
+          pane_yml.map do |_name, commands|
             Tmuxinator::Pane.new(index, project, self, *commands)
           end
         else
@@ -38,7 +44,7 @@ module Tmuxinator
       end.flatten
     end
 
-    def build_commands(prefix, command_yml)
+    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
@@ -80,9 +86,13 @@ module Tmuxinator
       "#{project.tmux} send-keys -t #{project.name}:#{index + project.base_index}"
     end
 
+    def tmux_window_name_option
+      name ? "-n #{name}" : ""
+    end
+
     def tmux_new_window_command
       path = root? ? "#{Tmuxinator::Config.default_path_option} #{root}" : nil
-      "#{project.tmux} new-window #{path} -t #{tmux_window_target} -n #{name}"
+      "#{project.tmux} new-window #{path} -t #{tmux_window_target} #{tmux_window_name_option}"
     end
 
     def tmux_layout_command
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 236fb63..0f72352 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -1,39 +1,81 @@
+def yaml_load(file)
+  YAML.load(File.read(File.expand_path(file)))
+end
 FactoryGirl.define do
-  factory :project, :class => Tmuxinator::Project do
+  factory :project, class: Tmuxinator::Project do
     transient do
-      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.yml")}")) }
+      file { yaml_load("spec/fixtures/sample.yml") }
     end
 
     initialize_with { Tmuxinator::Project.new(file) }
   end
 
-  factory :project_with_custom_name, :class => Tmuxinator::Project do
-    ignore do
-      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.yml")}")) }
+  factory :project_with_force_attach, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/detach.yml") }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file, force_attach: true) }
+  end
+
+  factory :project_with_force_detach, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/detach.yml") }
     end
+    initialize_with { Tmuxinator::Project.new(file, force_detach: true) }
+  end
 
-    initialize_with { Tmuxinator::Project.new(file, "custom") }
+  factory :project_with_custom_name, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/sample.yml") }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file, custom_name: "custom") }
+  end
+
+  factory :project_with_number_as_name, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/sample_number_as_name.yml") }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
+  end
+
+  factory :project_with_deprecations, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/sample.deprecations.yml") }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
+  end
+
+  factory :wemux_project, class: Tmuxinator::Project do
+    transient do
+      file { yaml_load("spec/fixtures/sample_wemux.yml") }
+    end
+
+    initialize_with { Tmuxinator::Project.new(file) }
   end
 
-  factory :project_with_deprecations, :class => Tmuxinator::Project do
+  factory :noname_project, class: Tmuxinator::Project do
     transient do
-      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample.deprecations.yml")}")) }
+      file { yaml_load("spec/fixtures/noname.yml") }
     end
 
     initialize_with { Tmuxinator::Project.new(file) }
   end
 
-  factory :wemux_project, :class => Tmuxinator::Project do
+  factory :nowindows_project, class: Tmuxinator::Project do
     transient do
-      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/sample_wemux.yml")}")) }
+      file { yaml_load("spec/fixtures/nowindows.yml") }
     end
 
     initialize_with { Tmuxinator::Project.new(file) }
   end
 
-  factory :noname_project, :class => Tmuxinator::Project do
+  factory :nameless_window_project, class: Tmuxinator::Project do
     transient do
-      file { YAML.load(File.read("#{File.expand_path("spec/fixtures/noname.yml")}")) }
+      file { yaml_load("spec/fixtures/nameless_window.yml") }
     end
 
     initialize_with { Tmuxinator::Project.new(file) }
diff --git a/spec/fixtures/sample.yml b/spec/fixtures/detach.yml
similarity index 98%
copy from spec/fixtures/sample.yml
copy to spec/fixtures/detach.yml
index bac06cb..0a00cc3 100644
--- a/spec/fixtures/sample.yml
+++ b/spec/fixtures/detach.yml
@@ -7,6 +7,7 @@ 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
+attach: false
 windows:
   - editor:
       pre:
diff --git a/spec/fixtures/nameless_window.yml b/spec/fixtures/nameless_window.yml
new file mode 100644
index 0000000..a6d4779
--- /dev/null
+++ b/spec/fixtures/nameless_window.yml
@@ -0,0 +1,5 @@
+name: nameless_window
+root: ~/
+windows:
+  - ~: echo "this is a window with no name"
+  - other: echo "this window has a name"
diff --git a/spec/fixtures/nowindows.yml b/spec/fixtures/nowindows.yml
new file mode 100644
index 0000000..fe580de
--- /dev/null
+++ b/spec/fixtures/nowindows.yml
@@ -0,0 +1,3 @@
+name: no_windows
+root: ~/
+
diff --git a/spec/fixtures/sample.yml b/spec/fixtures/sample.yml
index bac06cb..b9332cb 100644
--- a/spec/fixtures/sample.yml
+++ b/spec/fixtures/sample.yml
@@ -7,6 +7,7 @@ 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
+tmux_detached: false
 windows:
   - editor:
       pre:
diff --git a/spec/fixtures/sample_number_as_name.yml b/spec/fixtures/sample_number_as_name.yml
new file mode 100644
index 0000000..0463ddc
--- /dev/null
+++ b/spec/fixtures/sample_number_as_name.yml
@@ -0,0 +1,5 @@
+# ~/.tmuxinator/sample_number_as_name.yml
+
+name: 222
+windows:
+  - number: echo number as name fixture
diff --git a/spec/lib/tmuxinator/cli_spec.rb b/spec/lib/tmuxinator/cli_spec.rb
index 951fa8a..8b7b9f1 100644
--- a/spec/lib/tmuxinator/cli_spec.rb
+++ b/spec/lib/tmuxinator/cli_spec.rb
@@ -20,11 +20,11 @@ describe Tmuxinator::Cli do
   describe "#completions" do
     before do
       ARGV.replace(["completions", "start"])
-      allow(Tmuxinator::Config).to receive_messages(:configs => ["test.yml"])
+      allow(Tmuxinator::Config).to receive_messages(configs: ["test.yml"])
     end
 
     it "gets completions" do
-      out, _ = capture_io { cli.start }
+      out, _err = capture_io { cli.start }
       expect(out).to include("test.yml")
     end
   end
@@ -35,16 +35,29 @@ describe Tmuxinator::Cli do
     end
 
     it "lists the commands" do
-      out, _ = capture_io { cli.start }
-      expect(out).to eq "#{%w(commands completions new open start debug copy delete implode version doctor list).join("\n")}\n"
+      out, _err = capture_io { cli.start }
+      expected = %w(commands
+                    completions
+                    new
+                    open
+                    start
+                    local
+                    debug
+                    copy
+                    delete
+                    implode
+                    version
+                    doctor
+                    list)
+      expect(out).to eq "#{expected.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(Tmuxinator::Config).to receive_messages(validate: project)
+      allow(Tmuxinator::Config).to receive_messages(version: 1.9)
       allow(Kernel).to receive(:exec)
     end
 
@@ -55,27 +68,74 @@ describe Tmuxinator::Cli do
         expect(Kernel).to receive(:exec)
         capture_io { cli.start }
       end
+
+      it "accepts a flag for alternate name" do
+        ARGV.replace(["start", "foo" "--name=bar"])
+
+        expect(Kernel).to receive(:exec)
+        capture_io { cli.start }
+      end
+
+      it "accepts additional arguments" do
+        ARGV.replace(["start", "foo", "bar", "three=four"])
+
+        expect(Kernel).to receive(:exec)
+        capture_io { cli.start }
+      end
     end
 
     context "deprecations" do
       before do
-        allow($stdin).to receive_messages(:getc => "y")
+        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 }
+        out, _err = capture_io { cli.start }
         expect(out).to include "DEPRECATION"
       end
     end
   end
 
+  describe "#local" do
+    shared_examples_for :local_project do
+      before do
+        allow(Tmuxinator::Config).to receive_messages(validate: project)
+        allow(Tmuxinator::Config).to receive_messages(version: 1.9)
+        allow(Kernel).to receive(:exec)
+      end
+
+      let(:project) { FactoryGirl.build(:project) }
+
+      it "starts the project" do
+        expect(Kernel).to receive(:exec)
+        out, err = capture_io { cli.start }
+        expect(err).to eq ""
+        expect(out).to eq ""
+      end
+    end
+
+    context "when the command used is 'local'" do
+      before do
+        ARGV.replace ["local"]
+      end
+      it_should_behave_like :local_project
+    end
+
+    context "when the command used is '.'" do
+      before do
+        ARGV.replace ["."]
+      end
+      it_should_behave_like :local_project
+    end
+  end
+
   describe "#start(custom_name)" do
     before do
       ARGV.replace(["start", "foo", "bar"])
-      allow(Tmuxinator::Config).to receive_messages(:validate => project)
-      allow(Tmuxinator::Config).to receive_messages(:version => 1.9)
+      allow(Tmuxinator::Config).to receive_messages(validate: project)
+      allow(Tmuxinator::Config).to receive_messages(version: 1.9)
       allow(Kernel).to receive(:exec)
     end
 
@@ -91,31 +151,70 @@ describe Tmuxinator::Cli do
 
   describe "#new" do
     let(:file) { StringIO.new }
+    let(:name) { "test" }
 
     before do
-      ARGV.replace(["new", "test"])
       allow(File).to receive(:open) { |&block| block.yield file }
     end
 
-    context "existing project doesn't exist" do
+    context "without the --local option" do
       before do
-        allow(Tmuxinator::Config).to receive_messages(:exists? => false)
+        ARGV.replace(["new", name])
       end
 
-      it "creates a new tmuxinator project file" do
-        capture_io { cli.start }
-        expect(file.string).to_not be_empty
+      context "existing project doesn't exist" do
+        before do
+          expect(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
+        let(:command) { "#{ENV['HOME']}\/\.tmuxinator\/#{name}\.yml" }
+
+        before do
+          expect(Tmuxinator::Config).to receive_messages(exists?: true)
+        end
+
+        it "just opens the file" do
+          expect(Kernel).to receive(:system).with(%r{#{command}})
+          capture_io { cli.start }
+        end
       end
     end
 
-    context "files exists" do
+    context "with the --local option" do
       before do
-        allow(File).to receive_messages(:exists? => true)
+        ARGV.replace ["new", name, "--local"]
       end
 
-      it "just opens the file" do
-        expect(Kernel).to receive(:system)
-        capture_io { cli.start }
+      context "existing project doesn't exist" do
+        before do
+          expect(Tmuxinator::Config).to receive(:exists?).at_least(:once) do
+            false
+          end
+        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
+        let(:path) { Tmuxinator::Config::LOCAL_DEFAULT }
+        before do
+          expect(Tmuxinator::Config).to receive(:exists?).with(path) { true }
+        end
+
+        it "just opens the file" do
+          expect(Kernel).to receive(:system).with(%r{#{path}})
+          capture_io { cli.start }
+        end
       end
     end
   end
@@ -128,7 +227,7 @@ describe Tmuxinator::Cli do
 
     context "new project already exists" do
       before do
-        allow(Thor::LineEditor).to receive_messages(:readline => "y")
+        allow(Thor::LineEditor).to receive_messages(readline: "y")
       end
 
       it "prompts user to confirm overwrite" do
@@ -150,20 +249,40 @@ describe Tmuxinator::Cli do
 
   describe "#debug" do
     let(:project) { FactoryGirl.build(:project) }
+    let(:project_with_force_attach) do
+      FactoryGirl.build(:project_with_force_attach)
+    end
+    let(:project_with_force_detach) do
+      FactoryGirl.build(:project_with_force_detach)
+    end
 
     before do
-      ARGV.replace(["debug", "foo"])
-      allow(Tmuxinator::Config).to receive_messages(:validate => project)
+      allow(Tmuxinator::Config).to receive_messages(validate: project)
+      expect(project).to receive(:render)
     end
 
     it "renders the project" do
-      expect(project).to receive(:render)
+      ARGV.replace(["debug", "foo"])
       capture_io { cli.start }
     end
 
+    it "force attach renders the project with attach code" do
+      ARGV.replace(["debug", "--attach=true", "sample"])
+      capture_io { cli.start }
+      # Currently no project is rendered at all,
+      #   because the project file is not found
+      # expect(out).to include "attach-session"
+    end
+
+    it "force detach renders the project without attach code" do
+      ARGV.replace(["debug", "--attach=false", "sample"])
+      capture_io { cli.start }
+      # Currently no project is rendered at all
+      # expect(out).to_not include "attach-session"
+    end
+
     it "renders the project with custom session" do
       ARGV.replace(["debug", "sample", "bar"])
-      expect(project).to receive(:render)
       capture_io { cli.start }
     end
   end
@@ -171,7 +290,7 @@ describe Tmuxinator::Cli do
   describe "#delete" do
     before do
       ARGV.replace(["delete", "foo"])
-      allow(Thor::LineEditor).to receive_messages(:readline => "y")
+      allow(Thor::LineEditor).to receive_messages(readline: "y")
     end
 
     context "project exists" do
@@ -188,7 +307,7 @@ describe Tmuxinator::Cli do
     context "project doesn't exist" do
       before do
         allow(Tmuxinator::Config).to receive(:exists?) { false }
-        allow(Thor::LineEditor).to receive_messages(:readline => "y")
+        allow(Thor::LineEditor).to receive_messages(readline: "y")
       end
 
       it "exits with error message" do
@@ -200,7 +319,7 @@ describe Tmuxinator::Cli do
   describe "#implode" do
     before do
       ARGV.replace(["implode"])
-      allow(Thor::LineEditor).to receive_messages(:readline => "y")
+      allow(Thor::LineEditor).to receive_messages(readline: "y")
     end
 
     it "confirms deletion of all projects" do
@@ -231,7 +350,7 @@ describe Tmuxinator::Cli do
     end
 
     it "prints the current version" do
-      out, _ = capture_io { cli.start }
+      out, _err = capture_io { cli.start }
       expect(out).to eq "tmuxinator #{Tmuxinator::VERSION}\n"
     end
   end
@@ -248,4 +367,46 @@ describe Tmuxinator::Cli do
       capture_io { cli.start }
     end
   end
+
+  describe "#create_project" do
+    shared_examples_for :a_proper_project do
+      it "should create a valid project" do
+        expect(subject).to be_a Tmuxinator::Project
+        expect(subject.name).to eq name
+      end
+    end
+
+    let(:name) { "sample" }
+    let(:custom_name) { nil }
+    let(:cli_options) { {} }
+    let(:path) { File.expand_path("../../../fixtures", __FILE__) }
+
+    context "when creating a traditional named project" do
+      let(:params) do
+        {
+          name: name,
+          custom_name: custom_name
+        }
+      end
+      subject { described_class.new.create_project(params) }
+
+      before do
+        allow(Tmuxinator::Config).to receive_messages(root: path)
+      end
+
+      it_should_behave_like :a_proper_project
+    end
+  end
+
+  context "exit status" do
+    before do
+      ARGV.replace(["non-existent-command"])
+    end
+
+    it "returns a non-zero status when an error occurs" do
+      expect { capture_io { cli.start } }.to raise_error(SystemExit) do |e|
+        expect(e.status).to eq 1
+      end
+    end
+  end
 end
diff --git a/spec/lib/tmuxinator/config_spec.rb b/spec/lib/tmuxinator/config_spec.rb
index 0600a40..bdf685c 100644
--- a/spec/lib/tmuxinator/config_spec.rb
+++ b/spec/lib/tmuxinator/config_spec.rb
@@ -3,7 +3,7 @@ require "spec_helper"
 describe Tmuxinator::Config do
   describe "#root" do
     it "is ~/.tmuxintaor" do
-      expect(Tmuxinator::Config.root).to eq "#{ENV["HOME"]}/.tmuxinator"
+      expect(Tmuxinator::Config.root).to eq "#{ENV['HOME']}/.tmuxinator"
     end
   end
 
@@ -43,10 +43,13 @@ describe Tmuxinator::Config do
 
   describe "#default?" do
     let(:root) { Tmuxinator::Config.root }
+    let(:local_default) { Tmuxinator::Config::LOCAL_DEFAULT }
+    let(:proj_default) { Tmuxinator::Config.default }
 
     context "when the file exists" do
       before do
-        allow(File).to receive(:exists?).with(Tmuxinator::Config.default) { true }
+        allow(File).to receive(:exists?).with(local_default) { false }
+        allow(File).to receive(:exists?).with(proj_default) { true }
       end
 
       it "returns true" do
@@ -56,7 +59,8 @@ describe Tmuxinator::Config do
 
     context "when the file doesn't exist" do
       before do
-        allow(File).to receive(:exists?).with(Tmuxinator::Config.default) { false }
+        allow(File).to receive(:exists?).with(local_default) { false }
+        allow(File).to receive(:exists?).with(proj_default) { false }
       end
 
       it "returns true" do
@@ -143,8 +147,8 @@ describe Tmuxinator::Config do
 
   describe "#exists?" do
     before do
-      allow(File).to receive_messages(:exists? => true)
-      allow(Tmuxinator::Config).to receive_messages(:project => "")
+      allow(File).to receive_messages(exists?: true)
+      allow(Tmuxinator::Config).to receive_messages(project: "")
     end
 
     it "checks if the given project exists" do
@@ -152,23 +156,116 @@ describe Tmuxinator::Config do
     end
   end
 
-  describe "#project" do
+  describe "#project_in_root" do
     let(:root) { Tmuxinator::Config.root }
+    let(:base) { "#{root}/sample.yml" }
 
     before do
       path = File.expand_path("../../../fixtures/", __FILE__)
-      allow(Tmuxinator::Config).to receive_messages(:root => path)
+      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_in_root("sample")).to eq base
+      end
+    end
+
+    context "without project yml" do
+      it "gets the project as path to the yml file" do
+        expect(Tmuxinator::Config.project_in_root("new-project")).to be_nil
+      end
+    end
+  end
+
+  describe "#local?" do
+    it "checks if the given project exists" do
+      path = Tmuxinator::Config::LOCAL_DEFAULT
+      expect(File).to receive(:exists?).with(path) { true }
+      expect(Tmuxinator::Config.local?).to be_truthy
+    end
+  end
+
+  describe "#project_in_local" do
+    let(:default) { Tmuxinator::Config::LOCAL_DEFAULT }
+
+    context "with a project yml" do
+      it "gets the project as path to the yml file" do
+        expect(File).to receive(:exists?).with(default) { true }
+        expect(Tmuxinator::Config.project_in_local).to eq default
+      end
+    end
+
+    context "without project yml" do
+      it "gets the project as path to the yml file" do
+        expect(Tmuxinator::Config.project_in_local).to be_nil
+      end
+    end
+  end
+
+  describe "#project" do
+    let(:root) { Tmuxinator::Config.root }
+    let(:path) { File.expand_path("../../../fixtures/", __FILE__) }
+    let(:default) { Tmuxinator::Config::LOCAL_DEFAULT }
+
+    context "with project yml in the root directory" do
+      before do
+        allow(Tmuxinator::Config).to receive_messages(root: path)
+      end
+
+      it "gets the project as path to the yml file" do
         expect(Tmuxinator::Config.project("sample")).to eq "#{root}/sample.yml"
       end
     end
 
+    context "with a local project, but no project in root" do
+      it "gets the project as path to the yml file" do
+        expect(File).to receive(:exists?).with(default) { true }
+        expect(Tmuxinator::Config.project("sample")).to eq "./.tmuxinator.yml"
+      end
+    end
+
     context "without project yml" do
+      let(:expected) { "#{root}/new-project.yml" }
       it "gets the project as path to the yml file" do
-        expect(Tmuxinator::Config.project("new-project")).to eq "#{root}/new-project.yml"
+        expect(Tmuxinator::Config.project("new-project")).to eq expected
+      end
+    end
+  end
+
+  describe "#validate" do
+    let(:path) { File.expand_path("../../../fixtures", __FILE__) }
+    let(:default) { Tmuxinator::Config::LOCAL_DEFAULT }
+
+    context "when a project name is provided" do
+      it "should raise if the project file can't be found" do
+        expect do
+          Tmuxinator::Config.validate(name: "sample")
+        end.to raise_error RuntimeError, %r{Project.+doesn't.exist}
+      end
+
+      it "should load and validate the project" do
+        expect(Tmuxinator::Config).to receive_messages(root: path)
+        expect(Tmuxinator::Config.validate(name: "sample")).to \
+          be_a Tmuxinator::Project
+      end
+    end
+
+    context "when no project name is provided" do
+      it "should raise if the local project file doesn't exist" do
+        expect(File).to receive(:exists?).with(default) { false }
+        expect do
+          Tmuxinator::Config.validate
+        end.to raise_error RuntimeError, %r{Project.+doesn't.exist}
+      end
+
+      it "should load and validate the project" do
+        content = File.read(File.join(path, "sample.yml"))
+
+        expect(File).to receive(:exists?).with(default).at_least(:once) { true }
+        expect(File).to receive(:read).with(default).and_return(content)
+
+        expect(Tmuxinator::Config.validate).to be_a Tmuxinator::Project
       end
     end
   end
diff --git a/spec/lib/tmuxinator/project_spec.rb b/spec/lib/tmuxinator/project_spec.rb
index 619ded8..b8f14fa 100644
--- a/spec/lib/tmuxinator/project_spec.rb
+++ b/spec/lib/tmuxinator/project_spec.rb
@@ -2,10 +2,27 @@ require "spec_helper"
 
 describe Tmuxinator::Project do
   let(:project) { FactoryGirl.build(:project) }
-  let(:project_with_custom_name) { FactoryGirl.build(:project_with_custom_name) }
-  let(:project_with_deprecations) { FactoryGirl.build(:project_with_deprecations) }
+  let(:project_with_custom_name) do
+    FactoryGirl.build(:project_with_custom_name)
+  end
+  let(:project_with_number_as_name) do
+    FactoryGirl.build(:project_with_number_as_name)
+  end
+  let(:project_with_deprecations) do
+    FactoryGirl.build(:project_with_deprecations)
+  end
+  let(:project_with_force_attach) do
+    FactoryGirl.build(:project_with_force_attach)
+  end
+  let(:project_with_force_detach) do
+    FactoryGirl.build(:project_with_force_detach)
+  end
+
   let(:wemux_project) { FactoryGirl.build(:wemux_project) }
   let(:noname_project) { FactoryGirl.build(:noname_project) }
+  let(:nameless_window_project) do
+    FactoryGirl.build(:nameless_window_project)
+  end
 
   describe "#initialize" do
     context "valid yaml" do
@@ -65,7 +82,7 @@ describe Tmuxinator::Project do
 
     context "without root" do
       it "doesn't throw an error" do
-        expect{noname_project.root}.to_not raise_error
+        expect { noname_project.root }.to_not raise_error
       end
     end
   end
@@ -91,7 +108,14 @@ describe Tmuxinator::Project do
 
     context "without name" do
       it "displays error message" do
-        expect{noname_project.name}.to_not raise_error
+        expect { noname_project.name }.to_not raise_error
+      end
+    end
+
+    context "as number" do
+      it "will gracefully handle a name given as a number" do
+        rendered = project_with_number_as_name
+        expect(rendered.name.to_i).to_not equal 0
       end
     end
   end
@@ -104,8 +128,9 @@ describe Tmuxinator::Project do
     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")
+          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
@@ -115,8 +140,9 @@ describe Tmuxinator::Project do
 
       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")
+          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
@@ -126,8 +152,8 @@ describe Tmuxinator::Project do
 
       context "pre_tab is present" do
         before do
-          allow(project).to receive_messages(:rbenv? => false)
-          allow(project).to receive_messages(:pre_tab? => true)
+          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
@@ -140,7 +166,7 @@ describe Tmuxinator::Project do
   describe "#socket" do
     context "socket path is present" do
       before do
-        allow(project).to receive_messages(:socket_path => "/tmp")
+        allow(project).to receive_messages(socket_path: "/tmp")
       end
 
       it "gets the socket path" do
@@ -170,7 +196,7 @@ describe Tmuxinator::Project do
   describe "#tmux_options" do
     context "no tmux options" do
       before do
-        allow(project).to receive_messages(:tmux_options? => false)
+        allow(project).to receive_messages(tmux_options?: false)
       end
 
       it "returns nothing" do
@@ -180,18 +206,20 @@ describe Tmuxinator::Project do
 
     context "with deprecations" do
       before do
-        allow(project_with_deprecations).to receive_messages(:cli_args? => true)
+        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"
+        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))
+      allow(project).to \
+        receive_messages(show_tmux_options: tmux_config(pane_base_index: 3))
 
       expect(project.get_pane_base_index).to eq("3")
     end
@@ -199,7 +227,8 @@ describe Tmuxinator::Project do
 
   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))
+      allow(project).to \
+        receive_messages(show_tmux_options: tmux_config(base_index: 1))
 
       expect(project.get_base_index).to eq("1")
     end
@@ -208,8 +237,8 @@ describe Tmuxinator::Project do
   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")
+        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
@@ -219,8 +248,8 @@ describe Tmuxinator::Project do
 
     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")
+        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
@@ -234,15 +263,15 @@ describe Tmuxinator::Project do
       it "gets the startup window from project config" do
         project.yaml["startup_window"] = "logs"
 
-	expect(project.startup_window).to eq("logs")
+        expect(project.startup_window).to eq("logs")
       end
     end
 
     context "startup window not specified" do
       it "returns base index instead" do
-        allow(project).to receive_messages(:base_index => 8)
+        allow(project).to receive_messages(base_index: 8)
 
-	expect(project.startup_window).to eq 8
+        expect(project.startup_window).to eq 8
       end
     end
   end
@@ -286,7 +315,8 @@ describe Tmuxinator::Project do
 
     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"
+        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
@@ -300,7 +330,8 @@ describe Tmuxinator::Project do
 
     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"
+        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
@@ -323,7 +354,11 @@ describe Tmuxinator::Project 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"])
+      commands = [
+        "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"
+      ]
+      expect(window.commands).to eq(commands)
     end
   end
 
@@ -339,16 +374,125 @@ describe Tmuxinator::Project do
     end
 
     context "pre in yaml is Array" do
-      before {
+      before do
         project.yaml["pre"] = [
           "mysql.server start",
           "memcached -d"
         ]
-      }
+      end
 
       it "joins array using ;" do
         expect(pre).to eq("mysql.server start; memcached -d")
       end
     end
   end
+
+  describe "#attach?" do
+    context "attach is true in yaml" do
+      before { project.yaml["attach"] = true }
+
+      it "returns true" do
+        expect(project.attach?).to be_truthy
+      end
+    end
+
+    context "attach is not defined in yaml" do
+      it "returns true" do
+        expect(project.attach?).to be_truthy
+      end
+    end
+
+    context "attach is false in yaml" do
+      before { project.yaml["attach"] = false }
+      it "returns false" do
+        expect(project.attach?).to be_falsey
+      end
+    end
+
+    context "attach is true in yaml, but command line forces detach" do
+      before { project_with_force_attach.yaml["attach"] = true }
+
+      it "returns false" do
+        expect(project_with_force_detach.attach?).to be_falsey
+      end
+    end
+
+    context "attach is false in yaml, but command line forces attach" do
+      before { project_with_force_detach.yaml["attach"] = false }
+
+      it "returns true" do
+        expect(project_with_force_attach.attach?).to be_truthy
+      end
+    end
+  end
+
+  describe "tmux_new_session_command" do
+    let(:command) { "#{executable} new-session -d -s #{session} -n #{window}" }
+    let(:executable) { project.tmux }
+    let(:session) { project.name }
+    let(:window) { project.windows.first.name }
+
+    context "when first window has a name" do
+      it "returns command to start a new detatched session" do
+        expect(project.tmux_new_session_command).to eq command
+      end
+    end
+
+    context "when first window is nameless" do
+      let(:project) { nameless_window_project }
+      let(:command) { "#{project.tmux} new-session -d -s #{project.name} " }
+
+      it "returns command to for new detatched session without a window name" do
+        expect(project.tmux_new_session_command).to eq command
+      end
+    end
+  end
+
+  describe "::load" do
+    let(:path) { File.expand_path("../../../fixtures/sample.yml", __FILE__) }
+    let(:options) { {} }
+
+    it "should raise if the project file doesn't parse" do
+      bad_yaml = <<-Y
+      name: "foo"
+        subkey:
+      Y
+      expect(File).to receive(:read).with(path) { bad_yaml }
+      expect do
+        described_class.load(path, options)
+      end.to raise_error RuntimeError, %r{Failed.to.parse.config.file}
+    end
+
+    it "should return an instance of the class if the file loads" do
+      expect(described_class.load(path, options)).to be_a Tmuxinator::Project
+    end
+  end
+
+  describe "::parse_settings" do
+    let(:args) { ["one", "two=three"] }
+
+    it "returns settings in a hash" do
+      expect(described_class.parse_settings(args)["two"]).to eq("three")
+    end
+
+    it "removes settings from args" do
+      described_class.parse_settings(args)
+      expect(args).to eq(["one"])
+    end
+  end
+
+  describe "#validate!" do
+    it "should raise if there are no windows defined" do
+      nowindows_project = FactoryGirl.build(:nowindows_project)
+      expect do
+        nowindows_project.validate!
+      end.to raise_error RuntimeError, %r{should.include.some.windows}
+    end
+
+    it "should raise if there is not a project name" do
+      expect do
+        noname_project.validate!
+      end.to raise_error RuntimeError, %r{didn't.specify.a.'project_name'}
+    end
+  end
 end
diff --git a/spec/lib/tmuxinator/util_spec.rb b/spec/lib/tmuxinator/util_spec.rb
index 2c11363..27abab8 100644
--- a/spec/lib/tmuxinator/util_spec.rb
+++ b/spec/lib/tmuxinator/util_spec.rb
@@ -2,5 +2,4 @@ require "spec_helper"
 
 describe Tmuxinator::Util do
   let(:util) { Object.new.extend(Tmuxinator::Util) }
-
 end
diff --git a/spec/lib/tmuxinator/wemux_support_spec.rb b/spec/lib/tmuxinator/wemux_support_spec.rb
new file mode 100644
index 0000000..a7b9624
--- /dev/null
+++ b/spec/lib/tmuxinator/wemux_support_spec.rb
@@ -0,0 +1,47 @@
+require "spec_helper"
+
+describe Tmuxinator::WemuxSupport do
+  let(:klass) { Class.new { include Tmuxinator::WemuxSupport } }
+  let(:instance) { klass.new }
+
+  it { expect(instance).to respond_to :wemux? }
+  it { expect(instance).to respond_to :load_wemux_overrides }
+
+  describe "#load_wemux_overrides" do
+    before { instance.load_wemux_overrides }
+
+    it "adds a render method" do
+      expect(instance).to respond_to :render
+    end
+
+    it "adds a name method" do
+      expect(instance).to respond_to :name
+    end
+
+    it "adds a tmux method" do
+      expect(instance).to respond_to :tmux
+    end
+  end
+
+  describe "#render" do
+    before { instance.load_wemux_overrides }
+
+    it "renders the template" do
+      expect(File).to receive(:read).at_least(:once) { "wemux ls 2>/dev/null" }
+
+      expect(instance.render).to match %r{wemux.ls.2>\/dev\/null}
+    end
+  end
+
+  describe "#name" do
+    before { instance.load_wemux_overrides }
+
+    it { expect(instance.name).to eq "wemux" }
+  end
+
+  describe "#tmux" do
+    before { instance.load_wemux_overrides }
+
+    it { expect(instance.tmux).to eq "wemux" }
+  end
+end
diff --git a/spec/lib/tmuxinator/window_spec.rb b/spec/lib/tmuxinator/window_spec.rb
index 0c5613f..5e1f074 100644
--- a/spec/lib/tmuxinator/window_spec.rb
+++ b/spec/lib/tmuxinator/window_spec.rb
@@ -3,10 +3,14 @@ require "spec_helper"
 describe Tmuxinator::Window do
   let(:project) { double }
   let(:panes) { ["vim", nil, "top"] }
+  let(:window_name) { "editor" }
   let(:yaml) do
     {
-      "editor" => {
-        "pre" => ["echo 'I get run in each pane.  Before each pane command!'", nil],
+      window_name => {
+        "pre" => [
+          "echo 'I get run in each pane.  Before each pane command!'",
+          nil
+        ],
         "layout" => "main-vertical",
         "panes" => panes
       }
@@ -17,7 +21,10 @@ describe Tmuxinator::Window do
       "editor" => {
         "root" => "/project/override",
         "root?" => true,
-        "pre" => ["echo 'I get run in each pane.  Before each pane command!'", nil],
+        "pre" => [
+          "echo 'I get run in each pane.  Before each pane command!'",
+          nil
+        ],
         "layout" => "main-vertical",
         "panes" => panes
       }
@@ -29,12 +36,12 @@ describe Tmuxinator::Window do
 
   before do
     allow(project).to receive_messages(
-       :tmux => "tmux",
-       :name => "test",
-       :base_index => 1,
-       :root => "/project/tmuxinator",
-       :root? => true
-     )
+      tmux: "tmux",
+      name: "test",
+      base_index: 1,
+      root: "/project/tmuxinator",
+      root?: true
+    )
   end
 
   describe "#initialize" do
@@ -61,7 +68,7 @@ describe Tmuxinator::Window do
     let(:pane) { double(:pane) }
 
     before do
-      allow(Tmuxinator::Pane).to receive_messages :new => pane
+      allow(Tmuxinator::Pane).to receive_messages new: pane
     end
 
     context "with a three element Array" do
@@ -133,7 +140,10 @@ describe Tmuxinator::Window do
       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"]
+        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
 
@@ -158,27 +168,78 @@ describe Tmuxinator::Window do
     end
   end
 
+  describe "#name_options" do
+    context "with a name" do
+      let(:window_name) { "editor" }
+
+      it "specifies name with tmux name option" do
+        expect(window.tmux_window_name_option).to eq "-n #{window_name}"
+      end
+    end
+
+    context "without a name" do
+      let(:window_name) { nil }
+
+      it "specifies no tmux name option" do
+        expect(window.tmux_window_name_option).to be_empty
+      end
+    end
+  end
+
   describe "#tmux_new_window_command" do
     let(:project) { double(:project) }
     let(:window) { Tmuxinator::Window.new(yaml, 0, project) }
+    let(:root?) { true }
+    let(:root) { "/project/tmuxinator" }
 
     before do
       allow(project).to receive_messages(
-        :name => "",
-        :tmux => "tmux",
-        :root => "/project/tmuxinator",
-        :root? => true,
-        :base_index => 1
+        name: "test",
+        tmux: "tmux",
+        root: root,
+        root?: root?,
+        base_index: 1
       )
     end
 
-    context "tmux 1.6 and below" do
-      before do
-        allow(Tmuxinator::Config).to receive_messages(:version => 1.6)
+    let(:tmux_part) { project.tmux }
+    let(:window_part) { "new-window" }
+    let(:name_part) { window.tmux_window_name_option }
+    let(:target_part) { "-t #{window.tmux_window_target}" }
+    let(:path_part) { "#{path_option} #{project.root}" }
+
+    let(:path_option) { "-c" }
+    let(:full_command) do
+      "#{tmux_part} #{window_part} #{path_part} #{target_part} #{name_part}"
+    end
+
+    before do
+      allow(Tmuxinator::Config).to receive(:default_path_option) { path_option }
+    end
+
+    it "contstructs window command with path, target, and name options" do
+      expect(window.tmux_new_window_command).to eq full_command
+    end
+
+    context "root not set" do
+      let(:root?) { false }
+      let(:root) { nil }
+
+      let(:path_part) { nil }
+
+      it "has an extra space instead of path_part" do
+        expect(window.tmux_new_window_command).to eq full_command
+      end
+    end
+
+    context "name not set" do
+      let(:window_name) { nil }
+      let(:full_command) do
+        "#{tmux_part} #{window_part} #{path_part} #{target_part} "
       end
 
-      it "specifies root path by passing default-path to tmux" do
-        expect(window.tmux_new_window_command).to include("default-path /project/tmuxinator")
+      it "does not set name option" do
+        expect(window.tmux_new_window_command).to eq full_command
       end
     end
   end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 57a6cdb..2a4b73f 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -7,13 +7,12 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
   Coveralls::SimpleCov::Formatter
 ]
 SimpleCov.start do
-  add_filter 'vendor/cache'
+  add_filter "vendor/cache"
 end
 
 require "tmuxinator"
 require "factory_girl"
 
-
 FactoryGirl.find_definitions
 
 RSpec.configure do |config|
@@ -22,21 +21,23 @@ end
 
 # Copied from minitest.
 def capture_io
-  begin
-    require 'stringio'
+  require "stringio"
 
-    captured_stdout, captured_stderr = StringIO.new, StringIO.new
+  captured_stdout = StringIO.new
+  captured_stderr = StringIO.new
 
-    orig_stdout, orig_stderr = $stdout, $stderr
-    $stdout, $stderr         = captured_stdout, captured_stderr
+  orig_stdout = $stdout
+  orig_stderr = $stderr
 
-    yield
+  $stdout = captured_stdout
+  $stderr = captured_stderr
 
-    return captured_stdout.string, captured_stderr.string
-  ensure
-    $stdout = orig_stdout
-    $stderr = orig_stderr
-  end
+  yield
+
+  return captured_stdout.string, captured_stderr.string
+ensure
+  $stdout = orig_stdout
+  $stderr = orig_stderr
 end
 
 def tmux_config(options = {})
@@ -46,11 +47,11 @@ def tmux_config(options = {})
     "bell-on-alert off",
   ]
 
-  if base_index  = options.fetch(:base_index) {1}
+  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}
+  if pane_base_index = options.fetch(:pane_base_index) { 1 }
     standard_options << "pane-base-index #{pane_base_index}"
   end
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/tmuxinator.git



More information about the Pkg-ruby-extras-commits mailing list