tmuxinator-0.7.0/0000755000175000017500000000000012620456173013572 5ustar uwabamiuwabamitmuxinator-0.7.0/.rspec0000644000175000017500000000003712620456173014707 0ustar uwabamiuwabami--color --format=documentation tmuxinator-0.7.0/.gitignore0000644000175000017500000000023712620456173015564 0ustar uwabamiuwabami*.gem *.rbc .bundle .config .yardoc .coveralls.yml Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports tmp db vendor/ tags tmuxinator-0.7.0/completion/0000755000175000017500000000000012620456173015743 5ustar uwabamiuwabamitmuxinator-0.7.0/completion/tmuxinator.zsh0000755000175000017500000000117512620456173020712 0ustar uwabamiuwabami#compdef tmuxinator mux _tmuxinator() { local commands projects commands=(${(f)"$(tmuxinator commands zsh)"}) projects=(${(f)"$(tmuxinator completions start)"}) if (( CURRENT == 2 )); then _describe -t commands "tmuxinator subcommands" commands _describe -t projects "tmuxinator projects" projects elif (( CURRENT == 3)); then case $words[2] in copy|debug|delete|open|start) _arguments '*:projects:($projects)' ;; esac fi return } _tmuxinator # Local Variables: # mode: Shell-Script # sh-indentation: 2 # indent-tabs-mode: nil # sh-basic-offset: 2 # End: # vim: ft=zsh sw=2 ts=2 et tmuxinator-0.7.0/completion/mux.fish0000777000175000017500000000000012620456173022511 2tmuxinator.fishustar uwabamiuwabamitmuxinator-0.7.0/completion/tmuxinator.bash0000755000175000017500000000126612620456173021024 0ustar uwabamiuwabami#!/usr/bin/env bash _tmuxinator() { COMPREPLY=() local word word="${COMP_WORDS[COMP_CWORD]}" if [ "$COMP_CWORD" -eq 1 ]; then local commands="$(compgen -W "$(tmuxinator commands)" -- "$word")" local projects="$(compgen -W "$(tmuxinator completions start)" -- "$word")" COMPREPLY=( $commands $projects ) elif [ "$COMP_CWORD" -eq 2 ]; then local words words=("${COMP_WORDS[@]}") unset words[0] unset words[$COMP_CWORD] local completions completions=$(tmuxinator completions "${words[@]}") COMPREPLY=( $(compgen -W "$completions" -- "$word") ) fi } complete -F _tmuxinator tmuxinator mux tmuxinator-0.7.0/completion/tmuxinator.fish0000644000175000017500000000222012620456173021024 0ustar uwabamiuwabamifunction __fish_tmuxinator_using_command set cmd (commandline -opc) if [ (count $cmd) -gt 1 ] if [ $argv[1] = $cmd[2] ] return 0 end end return 1 end set __fish_tmuxinator_program_cmd (commandline -o)[1] function __fish_tmuxinator_program eval "$__fish_tmuxinator_program_cmd $argv" end complete -f -c $__fish_tmuxinator_program_cmd -a '(__fish_tmuxinator_program completions start)' complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_use_subcommand' -x -a "(__fish_tmuxinator_program commands)" complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command start' -a "(__fish_tmuxinator_program completions start)" complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command open' -a "(__fish_tmuxinator_program completions open)" complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command copy' -a "(__fish_tmuxinator_program completions copy)" complete -f -c $__fish_tmuxinator_program_cmd -n '__fish_tmuxinator_using_command delete' -a "(__fish_tmuxinator_program completions delete)" tmuxinator-0.7.0/bin/0000755000175000017500000000000012620456173014342 5ustar uwabamiuwabamitmuxinator-0.7.0/bin/mux0000777000175000017500000000000012620456173017230 2tmuxinatorustar uwabamiuwabamitmuxinator-0.7.0/bin/tmuxinator0000755000175000017500000000061512620456173016504 0ustar uwabamiuwabami#!/usr/bin/env ruby $: << File.expand_path("../../lib/", __FILE__) require "thor" require "tmuxinator" name = ARGV[0] || nil 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 tmuxinator-0.7.0/LICENSE0000644000175000017500000000206612620456173014603 0ustar uwabamiuwabamiCopyright (c) 2010-2014 Allen Bargi, Christopher Chow Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. tmuxinator-0.7.0/lib/0000755000175000017500000000000012620456173014340 5ustar uwabamiuwabamitmuxinator-0.7.0/lib/tmuxinator.rb0000644000175000017500000000071012620456173017075 0ustar uwabamiuwabamirequire "yaml" require "erubis" require "shellwords" require "thor" require "thor/version" require "tmuxinator/util" require "tmuxinator/deprecations" require "tmuxinator/wemux_support" require "tmuxinator/cli" require "tmuxinator/config" require "tmuxinator/pane" require "tmuxinator/project" require "tmuxinator/window" require "tmuxinator/version" module Tmuxinator end class Object def blank? respond_to?(:empty?) ? !!empty? : !self end end tmuxinator-0.7.0/lib/tmuxinator/0000755000175000017500000000000012620456173016552 5ustar uwabamiuwabamitmuxinator-0.7.0/lib/tmuxinator/assets/0000755000175000017500000000000012620456173020054 5ustar uwabamiuwabamitmuxinator-0.7.0/lib/tmuxinator/assets/sample.yml0000644000175000017500000000212112620456173022054 0ustar uwabamiuwabami# ~/.tmuxinator/<%= name %>.yml name: <%= name %> root: ~/ # Optional tmux socket # socket_name: foo # Runs before everything. Use it to start daemons etc. # pre: sudo /etc/rc.d/mysqld start # Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions. # pre_window: rbenv shell 2.0.0-p247 # Pass command line options to tmux. Useful for specifying a different tmux.conf. # tmux_options: -f ~/.tmux.mac.conf # Change the command to call tmux. This can be used by derivatives/wrappers like byobu. # tmux_command: byobu # Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used. # startup_window: logs # Controls whether the tmux session should be attached to automatically. Defaults to true. # attach: false # Runs after everything. Use it to attach to tmux with custom options etc. # post: tmux -CC attach -t <%= name %> windows: - editor: layout: main-vertical panes: - vim - guard - server: bundle exec rails s - logs: tail -f log/development.log tmuxinator-0.7.0/lib/tmuxinator/assets/template.erb0000644000175000017500000000411212620456173022357 0ustar uwabamiuwabami#!<%= ENV["SHELL"] || "/bin/bash" %> # Clear rbenv variables before starting tmux unset RBENV_VERSION unset RBENV_DIR <%= tmux %> start-server\; has-session -t <%= name %> 2>/dev/null if [ "$?" -eq 1 ]; then cd <%= root || "." %> # Run pre command. <%= pre %> # Create the session and the first window. Manually switch to root # directory if required to support tmux < 1.9 TMUX= <%= tmux_new_session_command %> <% if windows.first.root? %> <%= windows.first.tmux_window_command_prefix %> <%= "cd #{windows.first.root}".shellescape %> C-m <% end %> <% if Tmuxinator::Config.version < 1.7 %> # Set the default path for versions prior to 1.7 <% if root? %> <%= tmux %> set-option -t <%= name %> <%= Tmuxinator::Config.default_path_option %> <%= root -%> 1>/dev/null <% end %> <% end %> # Create other windows. <% windows.drop(1).each do |window| %> <%= window.tmux_new_window_command %> <% end %> <% windows.each do |window| %> # Window "<%= window.name %>" <% unless window.panes? %> <% if window.project.pre_window %> <%= window.tmux_pre_window_command %> <% end %> <% window.commands.each do |command| %> <%= command %> <% end %> <% else %> <% window.panes.each do |pane| %> <% if pane.project.pre_window %> <%= pane.tmux_pre_window_command %> <% end %> <% if pane.tab.pre %> <%= pane.tmux_pre_command %> <% end %> <% if pane.multiple_commands? %> <% pane.commands.each do |command| %> <%= pane.tmux_main_command(command) %> <% end %> <% else %> <%= pane.tmux_main_command(commands.first) %> <% end %> <% unless pane.last? %> <%= pane.tmux_split_command %> <% end %> <%= window.tmux_layout_command %> <% end %> <%= window.tmux_select_first_pane %> <% end %> <% end %> <%= tmux %> select-window -t <%= startup_window %> fi <%- if attach? -%> if [ -z "$TMUX" ]; then <%= tmux %> -u attach-session -t <%= name %> else <%= tmux %> -u switch-client -t <%= name %> fi <%- end -%> <%= post %> tmuxinator-0.7.0/lib/tmuxinator/assets/wemux_template.erb0000644000175000017500000000255712620456173023617 0ustar uwabamiuwabami#!<%= ENV["SHELL"] || "/bin/bash" %> wemux ls 2>/dev/null if [ "$?" -eq 127 ]; then cd <%= root || "." %> # Run pre command. <%= pre %> # Create the session and the first window. TMUX= <%= tmux_new_session_command %> # Set the default path. <%- if root? -%> <%= tmux %> set-option -t <%= name %> <%= Tmuxinator::Config.default_path_option %> <%= root -%> 1>/dev/null <%- end -%> # Create other windows. <%- windows.drop(1).each do |window| -%> <%= window.tmux_new_window_command %> <%- end -%> <%- windows.each do |window| -%> # Window "<%= window.name %>" <%- unless window.panes? -%> <%= window.tmux_pre_window_command %> <%- window.commands.each do |command| -%> <%= command %> <%- end -%> <%- else -%> <%- window.panes.each do |pane| -%> <%= pane.tmux_pre_window_command %> <%= pane.tmux_pre_command %> <%- if pane.multiple_commands? %> <%- pane.commands.each do |command| -%> <%= pane.tmux_main_command(command) %> <%- end -%> <%- else -%> <%= pane.tmux_main_command(commands.first) %> <%- end -%> <%- unless pane.last? -%> <%= pane.tmux_split_command %> <%- end -%> <%= window.tmux_layout_command %> <%- end -%> <%= window.tmux_select_first_pane %> <%- end -%> <%- end -%> <%= tmux %> select-window -t <%= startup_window %> fi wemux attach tmuxinator-0.7.0/lib/tmuxinator/deprecations.rb0000644000175000017500000000034712620456173021563 0ustar uwabamiuwabamimodule Tmuxinator module Deprecations def rvm? yaml["rvm"] end def rbenv? yaml["rbenv"] end def pre_tab? yaml["pre_tab"] end def cli_args? yaml["cli_args"] end end end tmuxinator-0.7.0/lib/tmuxinator/wemux_support.rb0000644000175000017500000000072412620456173022043 0ustar uwabamiuwabamimodule Tmuxinator module WemuxSupport def wemux? yaml["tmux_command"] == "wemux" end def load_wemux_overrides class_eval do define_method :render do template = File.read(Tmuxinator::Config.wemux_template) Erubis::Eruby.new(template).result(binding) end define_method :name do "wemux" end define_method :tmux do "wemux" end end end end end tmuxinator-0.7.0/lib/tmuxinator/pane.rb0000644000175000017500000000264112620456173020025 0ustar uwabamiuwabamimodule Tmuxinator class Pane attr_reader :commands, :project, :index, :tab def initialize(index, project, tab, *commands) @commands = commands @index = index @project = project @tab = tab end def tmux_window_and_pane_target x = tab.index + project.base_index y = index + project.base_index "#{project.name}:#{x}.#{y}" end def tmux_pre_command return unless tab.pre 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 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) 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 = if tab.root? "#{Tmuxinator::Config.default_path_option} #{tab.root}" end "#{project.tmux} splitw #{path} -t #{tab.tmux_window_target}" end def last? index == tab.panes.length - 1 end def multiple_commands? commands && commands.length > 0 end end end tmuxinator-0.7.0/lib/tmuxinator/config.rb0000644000175000017500000000514012620456173020344 0ustar uwabamiuwabamimodule Tmuxinator class Config LOCAL_DEFAULT = "./.tmuxinator.yml".freeze NO_LOCAL_FILE_MSG = "Project file at ./.tmuxinator.yml doesn't exist." class << self def root root_dir = File.expand_path("~/.tmuxinator") Dir.mkdir("#{ENV['HOME']}/.tmuxinator") unless File.directory?(root_dir) "#{ENV['HOME']}/.tmuxinator" end def sample asset_path "sample.yml" end def default "#{ENV['HOME']}/.tmuxinator/default.yml" end def default? exists?("default") end def installed? Kernel.system("type tmux > /dev/null") end def version `tmux -V`.split(" ")[1].to_f if installed? end def default_path_option version && version < 1.8 ? "default-path" : "-c" end def editor? !ENV["EDITOR"].nil? && !ENV["EDITOR"].empty? end def shell? !ENV["SHELL"].nil? && !ENV["SHELL"].empty? end def exists?(name) File.exists?(project(name)) end def project_in_root(name) projects = Dir.glob("#{root}/**/*.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 asset_path "template.erb" end def wemux_template asset_path "wemux_template.erb" end def configs Dir["#{Tmuxinator::Config.root}/**/*.yml"].sort.map do |path| path.gsub("#{Tmuxinator::Config.root}/", "").gsub(".yml", "") end 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 private def asset_path(asset) "#{File.dirname(__FILE__)}/assets/#{asset}" end end end end tmuxinator-0.7.0/lib/tmuxinator/util.rb0000644000175000017500000000033612620456173020056 0ustar uwabamiuwabamimodule Tmuxinator module Util include Thor::Actions def exit!(msg) puts msg Kernel.exit(1) end def yes_no(condition) condition ? say("Yes", :green) : say("No", :red) end end end tmuxinator-0.7.0/lib/tmuxinator/version.rb0000644000175000017500000000005212620456173020561 0ustar uwabamiuwabamimodule Tmuxinator VERSION = "0.7.0" end tmuxinator-0.7.0/lib/tmuxinator/window.rb0000644000175000017500000000542412620456173020413 0ustar uwabamiuwabamimodule Tmuxinator class Window include Tmuxinator::Util attr_reader :name, :root, :panes, :layout, :commands, :index, :project def initialize(window_yaml, index, project) @name = if !window_yaml.keys.first.nil? window_yaml.keys.first.shellescape end @root = nil @panes = [] @layout = nil @pre = nil @project = project @index = index value = window_yaml.values.first if value.is_a?(Hash) @layout = value["layout"] ? value["layout"].shellescape : nil @pre = value["pre"] if value["pre"] @root = if value["root"] File.expand_path(value["root"]).shellescape elsif project.root? project.root end @panes = build_panes(value["panes"]) else @commands = build_commands(tmux_window_command_prefix, value) end end def build_panes(panes_yml) Array(panes_yml).map.with_index do |pane_yml, index| if pane_yml.is_a?(Hash) pane_yml.map do |_name, commands| Tmuxinator::Pane.new(index, project, self, *commands) end else Tmuxinator::Pane.new(index, project, self, pane_yml) end end.flatten end def build_commands(_prefix, command_yml) if command_yml.is_a?(Array) command_yml.map do |command| "#{tmux_window_command_prefix} #{command.shellescape} C-m" if command end.compact elsif command_yml.is_a?(String) && !command_yml.empty? ["#{tmux_window_command_prefix} #{command_yml.shellescape} C-m"] else [] end end def pre if @pre.is_a?(Array) @pre.join(" && ") elsif @pre.is_a?(String) @pre end end def root? !root.nil? end def panes? panes.any? end def tmux_window_target "#{project.name}:#{index + project.base_index}" end def tmux_pre_window_command return unless project.pre_window "#{project.tmux} send-keys -t #{tmux_window_target} #{project.pre_window.shellescape} C-m" end def tmux_window_command_prefix "#{project.tmux} send-keys -t #{project.name}:#{index + project.base_index}" end def tmux_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} #{tmux_window_name_option}" end def tmux_layout_command "#{project.tmux} select-layout -t #{tmux_window_target} #{layout}" end def tmux_select_first_pane "#{project.tmux} select-pane -t #{tmux_window_target}.#{panes.first.index + project.base_index}" end end end tmuxinator-0.7.0/lib/tmuxinator/cli.rb0000644000175000017500000001546512620456173017661 0ustar uwabamiuwabamimodule 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 = { commands: "Lists commands available in tmuxinator", completions: "Used for shell completion", new: "Create a new project file and open it in your editor", open: "Alias of new", 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: <<-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", doctor: "Look for problems in your configuration", list: "Lists all tmuxinator projects" } 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 puts out end desc "completions [arg1 arg2]", COMMANDS[:completions] def completions(arg) if %w(start open copy delete).include?(arg) configs = Tmuxinator::Config.configs puts configs end end desc "new [PROJECT]", COMMANDS[:new] map "open" => :new map "edit" => :new 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) 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 #{project_file}") || doctor end 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 render_project(project) if project.deprecations.any? project.deprecations.each { |deprecation| say deprecation, :red } puts print "Press ENTER to continue." STDIN.getc end Kernel.exec(project.render) end end 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 "local", COMMANDS[:local] map "." => :local def local render_project(create_project(attach: options[:attach])) end 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 desc "copy [EXISTING] [NEW]", COMMANDS[:copy] map "c" => :copy map "cp" => :copy def copy(existing, new) existing_config_path = Tmuxinator::Config.project(existing) new_config_path = Tmuxinator::Config.project(new) exit!("Project #{existing} doesn't exist!") \ unless Tmuxinator::Config.exists?(existing) 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 Kernel.system("$EDITOR #{new_config_path}") end desc "delete [PROJECT]", COMMANDS[:delete] map "d" => :delete map "rm" => :delete def delete(project) if Tmuxinator::Config.exists?(project) config = "#{Tmuxinator::Config.root}/#{project}.yml" if yes?("Are you sure you want to delete #{project}?(y/n)", :red) FileUtils.rm(config) say "Deleted #{project}" end else exit!("That file doesn't exist.") end end desc "implode", COMMANDS[:implode] map "i" => :implode def implode if yes?("Are you sure you want to delete all tmuxinator configs?", :red) FileUtils.remove_dir(Tmuxinator::Config.root) say "Deleted all tmuxinator projects." end end desc "list", COMMANDS[:list] map "l" => :list map "ls" => :list def list say "tmuxinator projects:" print_in_columns Tmuxinator::Config.configs end desc "version", COMMANDS[:version] map "-v" => :version def version say "tmuxinator #{Tmuxinator::VERSION}" end desc "doctor", COMMANDS[:doctor] def doctor say "Checking if tmux is installed ==> " yes_no Tmuxinator::Config.installed? say "Checking if $EDITOR is set ==> " yes_no Tmuxinator::Config.editor? say "Checking if $SHELL is set ==> " yes_no Tmuxinator::Config.shell? end end end tmuxinator-0.7.0/lib/tmuxinator/project.rb0000644000175000017500000001344312620456173020552 0ustar uwabamiuwabamimodule Tmuxinator class Project include Tmuxinator::Util include Tmuxinator::Deprecations include Tmuxinator::WemuxSupport 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? @yaml = yaml @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 def render template = File.read(Tmuxinator::Config.template) Erubis::Eruby.new(template).result(binding) end def windows windows_yml = yaml["tabs"] || yaml["windows"] @windows ||= (windows_yml || {}).map.with_index do |window_yml, index| Tmuxinator::Window.new(window_yml, index, self) end end def root root = yaml["project_root"] || yaml["root"] root.blank? ? nil : File.expand_path(root).shellescape end def name name = custom_name || yaml["project_name"] || yaml["name"] name.blank? ? nil : name.to_s.shellescape end def pre pre_config = yaml["pre"] if pre_config.is_a?(Array) pre_config.join("; ") else pre_config 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']}" elsif rvm? "rvm use #{yaml['rvm']}" elsif pre_tab? yaml["pre_tab"] else yaml["pre_window"] end end def post post_config = yaml["post"] if post_config.is_a?(Array) post_config.join("; ") else post_config end end def tmux "#{tmux_command}#{tmux_options}#{socket}" end def tmux_command yaml["tmux_command"] || "tmux" end def socket if socket_path " -S #{socket_path}" elsif socket_name " -L #{socket_name}" end end def socket_name yaml["socket_name"] end def socket_path yaml["socket_path"] end def tmux_options if cli_args? " #{yaml['cli_args'].to_s.strip}" elsif tmux_options? " #{yaml['tmux_options'].to_s.strip}" else "" end end def base_index get_pane_base_index ? get_pane_base_index.to_i : get_base_index.to_i end def startup_window yaml["startup_window"] || base_index end def tmux_options? yaml["tmux_options"] end def windows? windows.any? end def root? !root.nil? end def name? !name.nil? end def window(i) "#{name}:#{i}" end def send_pane_command(cmd, window_index, _pane_index) if cmd.empty? "" else "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m" end end def send_keys(cmd, window_index) if cmd.empty? "" else "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m" end end def deprecations deprecations = [] deprecations << 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 def get_pane_base_index tmux_config["pane-base-index"] end def get_base_index tmux_config["base-index"] end def show_tmux_options "#{tmux} start-server\\; show-option -g" end def tmux_new_session_command window = windows.first.tmux_window_name_option "#{tmux} new-session -d -s #{name} #{window}" end private def tmux_config @tmux_config ||= extract_tmux_config end def extract_tmux_config options_hash = {} options_string = `#{show_tmux_options}` options_string.encode!("UTF-8", invalid: :replace) options_string.split("\n").map do |entry| key, value = entry.split("\s") options_hash[key] = value options_hash end options_hash end end end tmuxinator-0.7.0/.rubocop.yml0000644000175000017500000010743512620456173016056 0ustar uwabamiuwabamiAllCops: 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 tmuxinator-0.7.0/.travis.yml0000644000175000017500000000115612620456173015706 0ustar uwabamiuwabamilanguage: ruby rvm: - "1.9.3" - "2.0.0" - "2.1.6" - "2.2.2" env: - TMUX_VERSION=master - TMUX_VERSION=2.0 - TMUX_VERSION=1.9 - TMUX_VERSION=1.8 - TMUX_VERSION=1.7 - TMUX_VERSION=1.6 - TMUX_VERSION=1.5 matrix: allow_failures: - env: TMUX_VERSION=1.7 before_install: - sudo apt-get update -qq - sudo apt-get install -qq libevent-dev libncurses-dev - git clone https://github.com/tmux/tmux.git tmux - cd tmux - git checkout $TMUX_VERSION - sh autogen.sh - ./configure && make && sudo make install - cd .. - tmux -V script: - bundle exec rspec spec - bundle exec rake rubocop tmuxinator-0.7.0/CHANGELOG.md0000644000175000017500000001303312620456173015403 0ustar uwabamiuwabami## 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 - Post and attach options #293 - Fix typo in gemspec #294 - Fix completions not searching subdirectory #295 - Remove duplicate attribute #298 - Fix support for tmux 1.8 and below - Project cleanup #311 - Fix error when no project name is provided #303 ## 0.6.10 - Interpret config file as ERB template #255 - Fix zsh completions #262 - Alias `e` to edit and `o` to open #275 - Fix fish completions #280 - Add `startup_window` #282 - Add per window root option #283 - Fix project path detection #274 - Include completions in gemspec #270 ## 0.6.9 - Update to RSpec 3.x - Allow for earlier versions of thor #234, #235 - Remove dependency on git and fix warnings in gemspec #232, #233, #239 - Switch from `which` to `type` to stop errors in OSX 10.10 #236, #237 - Optional project root #185, #144 - Clear rbenv environment variables before starting tmux #208 - Update readme with correct fish completions path #247 - Escape path to deal with special characters #251, #256, #257 - Fix `copy` overwriting files #254, #258 ## 0.6.8 - Remove some duplication #212 - Add wemux support #88 - Thanks to Andrew Thal (@athal7) - Fix typos in readme #217, #216 - Fix encoding bug #229 - Fix specs not running due to changes in thor ## 0.6.7 - Remove use of grep for base-index #171 - Fix bugs in `Tmuxinator::Config.default?` #169 - Fix path for Rails log in directory sample #177 - Add completions for fish shell #179 - Fix grammar in readme #184 - Make commands take precedence over project names #182 - Improve error messages when $EDITOR isn't set #186, #194 - Add confirmation to deletion prompt #197 - Fix broken badge references after organisation move - Remove dependancy on ActiveSupport #199 - Fix compatability with tmux 1.9 ## 0.6.6 - Fix a bug caused by not escaping the root path #145 - Fix bash completion with a single argument #148 - Fix regression where an array of commands for a window wasn't working #149 - Add an option to call tmux wrappers or derivatives #154 - Refactor build\_panes to always return an array #157 - Clean up some branching code using `.presence` #163 - Setup TravisCI test matrix for different tmux versions #164 - Fix some grammar and spelling in readme #166 - Make multiple commands use tmux's `send-keys` rather than just using `&&` for both panes and windows #100 ## 0.6.5 - Change deprecation continue message from any key to just the enter key - Dramatically clean up the readme to be clearer for new users - Update the contributing guide with references to the GitHub styleguide and add examples of how to leave good commit messages - Use Erubis to render the project sample and fix a bad binding reference - Update the sample project to be much simpler - Fix not working delete command #142 - Fix an error in the bash completion script - Fix an issue where the wrong project path was being returned - Fix an issue where command aliases were being ignored ## 0.6.4 - Fixes broken backwards compatibility of multiple pre commands #129 - Fixes tmuxinator ignoring project root when started from within a tmux session #132 - Add gem version badge ## 0.6.3 - Remove stray pry #128 - Allow starting a tmuxinator project while inside a tmux session #130 - Set the tmux layout after pane creation to avoid pane too small errors #131 - Check for both pane-base-index and base-index #126 ## 0.6.2 - Also pass command line options to the `base_index` lookup. - Fixed bug #116. ## 0.6.1 - Remove stray binding.pry - Fix nil error when creating a new project. ## 0.6.0 - Rewrote core functionality with proper abstractions and unit tests - Fixed outstanding bugs #72 #89 #90 #93 #101 #102 #103 #104 #109 - Switched to thor for command line argument parsing - Switched to Erubis for more Rails like ERB - Added simplecov for test coverage - Added debug command line option to view generated shell commands - Added commands and completion options for completion scripts - Added `pre_window` option for running commands before all panes and windows - Deprecated `rbenv` in favour of `pre_window` - Deprecated `rvm` in favour of `pre_window` - Deprecated `cli_args` in favour of `tmux_options` - Deprecated `tabs` in favour of `windows` - Dropped support for Ruby 1.9.2 ## 0.5.0 - Added optional socket name support (Thanks to Adam Walters) - Added auto completion (Thanks to Jose Pablo Barrantes) ## 0.4.0 - Does not crash if given an invalid yaml file format. report it and exit gracefully. - Removed clunky scripts & shell aliases (Thanks to Dane O'Connor) - Config files are now rendered JIT (Thanks to Dane O'Connor) - Can now start sessions from cli (Thanks to Dane O'Connor) ## 0.3.0 - Added pre command (Thanks to Ian Yang) - Added multiple pre command (Thanks to Bjørn Arild Mæland) - Using tmux set default-path for project root - New aliases ## 0.2.0 - Added pane support (Thanks to Aaron Spiegel) - RVM support (Thanks to Jay Adkisoon) tmuxinator-0.7.0/CONTRIBUTING.md0000644000175000017500000000307512620456173016030 0ustar uwabamiuwabami# Contributing ## First * Check if the issue you're going to submit isn't already submitted in the [Issues](https://github.com/aziz/tmuxinator/issues) page. ## Issues * Submit a ticket for your issue, assuming one does not already exist. * The issue must: * Clearly describe the problem including steps to reproduce when it is a bug. * Also include all the information you can to make it easier for us to reproduce it, like OS version, gem versions, rbenv or rvm versions etc... * Even better, provide a failing test case for it. ## Pull Requests If you've gone the extra mile and have a patch that fixes the issue, you should submit a Pull Request! * Please follow the [GitHub Styleguide](https://github.com/styleguide/ruby) for Ruby in both implementation and tests! * Fork the repo on Github. * Create a topic branch from where you want to base your work. * Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, we need a test! * Run _all_ the tests to assure nothine else was broken. We only take pull requests with passing tests. * Check for unnecessary whitespace with `git diff --check` before committing. * Structure your commit messages like this: ``` Summarize clearly in one line what the commit is about Describe the problem the commit solves or the use case for a new feature. Justify why you chose the particular solution. ``` * Use "fix", "add", "change" instead of "fixed", "added", "changed" in your commit messages. * Push to your fork and submit a pull request. tmuxinator-0.7.0/Rakefile0000644000175000017500000000061112620456173015235 0ustar uwabamiuwabamirequire "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"] tmuxinator-0.7.0/tmuxinator.gemspec0000644000175000017500000000306012620456173017350 0ustar uwabamiuwabami# coding: utf-8 lib = File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "tmuxinator/version" Gem::Specification.new do |s| s.name = "tmuxinator" s.version = Tmuxinator::VERSION s.authors = ["Allen Bargi", "Christopher Chow"] s.email = ["allen.bargi@gmail.com", "chris@chowie.net"] s.description = %q{Create and manage complex tmux sessions easily.} s.summary = %q{Create and manage complex tmux sessions easily.} s.homepage = "https://github.com/tmuxinator/tmuxinator" s.license = "MIT" s.files = Dir["lib/**/*", "spec/**/*", "bin/*", "completion/*"] s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } s.test_files = s.files.grep(%r{^(test|spec|features)/}) s.require_paths = ["lib"] s.post_install_message = %q{ __________________________________________________________ .......................................................... Thank you for installing tmuxinator. Make sure that you've set these variables in your ENV: $EDITOR, $SHELL You can run `tmuxinator doctor` to make sure everything is set. Happy tmuxing with tmuxinator! .......................................................... __________________________________________________________ } s.required_rubygems_version = ">= 1.8.23" s.required_ruby_version = ">= 1.9.3" s.add_dependency "thor", "~> 0.19", ">= 0.15.0" s.add_dependency "erubis", "~> 2.6" s.add_development_dependency "bundler", "~> 1.3" end tmuxinator-0.7.0/spec/0000755000175000017500000000000012620456173014524 5ustar uwabamiuwabamitmuxinator-0.7.0/spec/spec_helper.rb0000644000175000017500000000220012620456173017334 0ustar uwabamiuwabamirequire "coveralls" require "simplecov" require "pry" SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter ] SimpleCov.start do add_filter "vendor/cache" end require "tmuxinator" require "factory_girl" FactoryGirl.find_definitions RSpec.configure do |config| config.order = "random" end # Copied from minitest. def capture_io require "stringio" captured_stdout = StringIO.new captured_stderr = StringIO.new orig_stdout = $stdout orig_stderr = $stderr $stdout = captured_stdout $stderr = captured_stderr yield return captured_stdout.string, captured_stderr.string ensure $stdout = orig_stdout $stderr = orig_stderr end def tmux_config(options = {}) standard_options = [ "assume-paste-time 1", "bell-action any", "bell-on-alert off", ] if base_index = options.fetch(:base_index) { 1 } standard_options << "base-index #{base_index}" end if pane_base_index = options.fetch(:pane_base_index) { 1 } standard_options << "pane-base-index #{pane_base_index}" end "echo '#{standard_options.join("\n")}'" end tmuxinator-0.7.0/spec/lib/0000755000175000017500000000000012620456173015272 5ustar uwabamiuwabamitmuxinator-0.7.0/spec/lib/tmuxinator/0000755000175000017500000000000012620456173017504 5ustar uwabamiuwabamitmuxinator-0.7.0/spec/lib/tmuxinator/cli_spec.rb0000644000175000017500000002451212620456173021616 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Cli do let(:cli) { Tmuxinator::Cli } before do ARGV.clear allow(Kernel).to receive(:system) allow(FileUtils).to receive(:copy_file) allow(FileUtils).to receive(:rm) allow(FileUtils).to receive(:remove_dir) end context "no arguments" do it "runs without error" do _, err = capture_io { cli.start } expect(err).to be_empty end end describe "#completions" do before do ARGV.replace(["completions", "start"]) allow(Tmuxinator::Config).to receive_messages(configs: ["test.yml"]) end it "gets completions" do out, _err = capture_io { cli.start } expect(out).to include("test.yml") end end describe "#commands" do before do ARGV.replace(["commands"]) end it "lists the commands" do out, _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(Kernel).to receive(:exec) end context "no deprecations" do let(:project) { FactoryGirl.build(:project) } it "starts the project" do expect(Kernel).to receive(:exec) capture_io { cli.start } end 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") end let(:project) { FactoryGirl.build(:project_with_deprecations) } it "prints the deprecations" do 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(Kernel).to receive(:exec) end context "no deprecations" do let(:project) { FactoryGirl.build(:project) } it "starts the project" do expect(Kernel).to receive(:exec) capture_io { cli.start } end end end describe "#new" do let(:file) { StringIO.new } let(:name) { "test" } before do allow(File).to receive(:open) { |&block| block.yield file } end context "without the --local option" do before do ARGV.replace(["new", name]) end 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 "with the --local option" do before do ARGV.replace ["new", name, "--local"] end 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 describe "#copy" do before do ARGV.replace(["copy", "foo", "bar"]) allow(Tmuxinator::Config).to receive(:exists?) { true } end context "new project already exists" do before do allow(Thor::LineEditor).to receive_messages(readline: "y") end it "prompts user to confirm overwrite" do expect(FileUtils).to receive(:copy_file) capture_io { cli.start } end end context "existing project doens't exist" do before do allow(Tmuxinator::Config).to receive(:exists?) { false } end it "exit with error code" do expect { capture_io { cli.start } }.to raise_error SystemExit end end end describe "#debug" do let(:project) { FactoryGirl.build(:project) } 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 allow(Tmuxinator::Config).to receive_messages(validate: project) expect(project).to receive(:render) end it "renders the project" do 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"]) capture_io { cli.start } end end describe "#delete" do before do ARGV.replace(["delete", "foo"]) allow(Thor::LineEditor).to receive_messages(readline: "y") end context "project exists" do before do allow(Tmuxinator::Config).to receive(:exists?) { true } end it "deletes the project" do expect(FileUtils).to receive(:rm) capture_io { cli.start } end end context "project doesn't exist" do before do allow(Tmuxinator::Config).to receive(:exists?) { false } allow(Thor::LineEditor).to receive_messages(readline: "y") end it "exits with error message" do expect { capture_io { cli.start } }.to raise_error SystemExit end end end describe "#implode" do before do ARGV.replace(["implode"]) allow(Thor::LineEditor).to receive_messages(readline: "y") end it "confirms deletion of all projects" do expect(Thor::LineEditor).to receive(:readline).and_return("y") capture_io { cli.start } end it "deletes all projects" do expect(FileUtils).to receive(:remove_dir) capture_io { cli.start } end end describe "#list" do before do ARGV.replace(["list"]) allow(Dir).to receive_messages(:[] => ["/path/to/project.yml"]) end it "lists all projects" do expect { capture_io { cli.start } }.to_not raise_error end end describe "#version" do before do ARGV.replace(["version"]) end it "prints the current version" do out, _err = capture_io { cli.start } expect(out).to eq "tmuxinator #{Tmuxinator::VERSION}\n" end end describe "#doctor" do before do ARGV.replace(["doctor"]) end it "checks requirements" do expect(Tmuxinator::Config).to receive(:installed?) expect(Tmuxinator::Config).to receive(:editor?) expect(Tmuxinator::Config).to receive(:shell?) capture_io { cli.start } end end 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 tmuxinator-0.7.0/spec/lib/tmuxinator/window_spec.rb0000644000175000017500000001312512620456173022354 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Window do let(:project) { double } let(:panes) { ["vim", nil, "top"] } let(:window_name) { "editor" } let(:yaml) do { window_name => { "pre" => [ "echo 'I get run in each pane. Before each pane command!'", nil ], "layout" => "main-vertical", "panes" => panes } } end let(:yaml_root) do { "editor" => { "root" => "/project/override", "root?" => true, "pre" => [ "echo 'I get run in each pane. Before each pane command!'", nil ], "layout" => "main-vertical", "panes" => panes } } end let(:window) { Tmuxinator::Window.new(yaml, 0, project) } let(:window_root) { Tmuxinator::Window.new(yaml_root, 0, project) } before do allow(project).to receive_messages( tmux: "tmux", name: "test", base_index: 1, root: "/project/tmuxinator", root?: true ) end describe "#initialize" do it "creates an instance" do expect(window).to be_a(Tmuxinator::Window) end end describe "#root" do context "without window root" do it "gets the project root" do expect(window.root).to include("/project/tmuxinator") end end context "with window root" do it "gets the window root" do expect(window_root.root).to include("/project/override") end end end describe "#panes" do let(:pane) { double(:pane) } before do allow(Tmuxinator::Pane).to receive_messages new: pane end context "with a three element Array" do let(:panes) { ["vim", nil, "top"] } it "creates three panes" do expect(Tmuxinator::Pane).to receive(:new).exactly(3).times window.panes end it "returns three panes" do expect(window.panes).to eql [pane, pane, pane] end end context "with a String" do let(:panes) { "vim" } it "creates one pane" do expect(Tmuxinator::Pane).to receive(:new).once window.panes end it "returns one pane in an Array" do expect(window.panes).to eql [pane] end end context "with nil" do let(:panes) { nil } it "doesn't create any panes" do expect(Tmuxinator::Pane).to_not receive(:new) window.panes end it "returns an empty Array" do expect(window.panes).to be_empty end end end describe "#pre" do context "pre is a string" do before do yaml["editor"]["pre"] = "vim" end it "returns the pre command" do expect(window.pre).to eq "vim" end end context "pre is not present" do before do yaml["editor"].delete("pre") end it "returns nil" do expect(window.pre).to be_nil end end end describe "#build_commands" do context "command is an array" do before do yaml["editor"] = ["git fetch", "git status"] end it "returns the flattened command" do expect(window.commands).to eq [ "tmux send-keys -t test:1 git\\ fetch C-m", "tmux send-keys -t test:1 git\\ status C-m" ] end end context "command is a string" do before do yaml["editor"] = "vim" end it "returns the command" do expect(window.commands).to eq ["tmux send-keys -t test:1 vim C-m"] end end context "command is empty" do before do yaml["editor"] = "" end it "returns an empty array" do expect(window.commands).to be_empty end end end describe "#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: "test", tmux: "tmux", root: root, root?: root?, base_index: 1 ) end 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 "does not set name option" do expect(window.tmux_new_window_command).to eq full_command end end end end tmuxinator-0.7.0/spec/lib/tmuxinator/config_spec.rb0000644000175000017500000001653712620456173022324 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Config do describe "#root" do it "is ~/.tmuxintaor" do expect(Tmuxinator::Config.root).to eq "#{ENV['HOME']}/.tmuxinator" end end describe "#sample" do it "gets the path of the sample project" do expect(Tmuxinator::Config.sample).to include("sample.yml") end end describe "#default" do it "gets the path of the default config" do expect(Tmuxinator::Config.default).to include("default.yml") end end describe "#default_path_option" do context ">= 1.8" do before do allow(Tmuxinator::Config).to receive(:version).and_return(1.8) end it "returns -c" do expect(Tmuxinator::Config.default_path_option).to eq "-c" end end context "< 1.8" do before do allow(Tmuxinator::Config).to receive(:version).and_return(1.7) end it "returns default-path" do expect(Tmuxinator::Config.default_path_option).to eq "default-path" end end end 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(local_default) { false } allow(File).to receive(:exists?).with(proj_default) { true } end it "returns true" do expect(Tmuxinator::Config.default?).to be_truthy end end context "when the file doesn't exist" do before do allow(File).to receive(:exists?).with(local_default) { false } allow(File).to receive(:exists?).with(proj_default) { false } end it "returns true" do expect(Tmuxinator::Config.default?).to be_falsey end end end describe "#configs" do before do allow(Dir).to receive_messages(:[] => ["test.yml"]) end it "gets a list of all projects" do expect(Tmuxinator::Config.configs).to include("test") end end describe "#installed?" do context "tmux is installed" do before do allow(Kernel).to receive(:system) { true } end it "returns true" do expect(Tmuxinator::Config.installed?).to be_truthy end end context "tmux is not installed" do before do allow(Kernel).to receive(:system) { false } end it "returns true" do expect(Tmuxinator::Config.installed?).to be_falsey end end end describe "#editor?" do context "$EDITOR is set" do before do allow(ENV).to receive(:[]).with("EDITOR") { "vim" } end it "returns true" do expect(Tmuxinator::Config.editor?).to be_truthy end end context "$EDITOR is not set" do before do allow(ENV).to receive(:[]).with("EDITOR") { nil } end it "returns false" do expect(Tmuxinator::Config.editor?).to be_falsey end end end describe "#shell?" do context "$SHELL is set" do before do allow(ENV).to receive(:[]).with("SHELL") { "vim" } end it "returns true" do expect(Tmuxinator::Config.shell?).to be_truthy end end context "$SHELL is not set" do before do allow(ENV).to receive(:[]).with("SHELL") { nil } end it "returns false" do expect(Tmuxinator::Config.shell?).to be_falsey end end end describe "#exists?" do before do allow(File).to receive_messages(exists?: true) allow(Tmuxinator::Config).to receive_messages(project: "") end it "checks if the given project exists" do expect(Tmuxinator::Config.exists?("test")).to be_truthy end end describe "#project_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) 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 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 end tmuxinator-0.7.0/spec/lib/tmuxinator/util_spec.rb0000644000175000017500000000015512620456173022021 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Util do let(:util) { Object.new.extend(Tmuxinator::Util) } end tmuxinator-0.7.0/spec/lib/tmuxinator/pane_spec.rb0000644000175000017500000000025312620456173021766 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Pane do it "creates an instance" do expect(Tmuxinator::Pane.new("vim", 0, nil, nil)).to be_a(Tmuxinator::Pane) end end tmuxinator-0.7.0/spec/lib/tmuxinator/project_spec.rb0000644000175000017500000003146712620456173022524 0ustar uwabamiuwabamirequire "spec_helper" describe Tmuxinator::Project do let(:project) { FactoryGirl.build(:project) } 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 it "creates an instance" do expect(project).to be_a(Tmuxinator::Project) end end end describe "#render" do it "renders the tmux config" do expect(project.render).to_not be_empty end context "wemux" do it "renders the wemux config" do expect(wemux_project.render).to_not be_empty end end context "custom name" do it "renders the tmux config with custom name" do rendered = project_with_custom_name.render expect(rendered).to_not be_empty expect(rendered).to include("custom") expect(rendered).to_not include("sample") end end end describe "#windows" do context "without deprecations" do it "gets the list of windows" do expect(project.windows).to_not be_empty end end context "with deprecations" do it "still gets the list of windows" do expect(project_with_deprecations.windows).to_not be_empty end end end describe "#root" do context "without deprecations" do it "gets the root" do expect(project.root).to include("test") end end context "with deprecations" do it "still gets the root" do expect(project_with_deprecations.root).to include("test") end end context "without root" do it "doesn't throw an error" do expect { noname_project.root }.to_not raise_error end end end describe "#name" do context "without deprecations" do it "gets the name" do expect(project.name).to eq "sample" end end context "with deprecations" do it "still gets the name" do expect(project_with_deprecations.name).to eq "sample" end end context "wemux" do it "is wemux" do expect(wemux_project.name).to eq "wemux" end end context "without name" do it "displays error message" do 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 describe "#pre_window" do it "gets the pre_window command" do expect(project.pre_window).to eq "rbenv shell 2.0.0-p247" end context "with deprecations" do context "rbenv option is present" do before do allow(project).to receive_messages(rbenv?: true) allow(project).to \ receive_message_chain(:yaml, :[]).and_return("2.0.0-p247") end it "still gets the correct pre_window command" do expect(project.pre_window).to eq "rbenv shell 2.0.0-p247" end end context "rvm option is present" do before do allow(project).to receive_messages(rbenv?: false) allow(project).to \ receive_message_chain(:yaml, :[]).and_return("ruby-2.0.0-p247") end it "still gets the correct pre_window command" do expect(project.pre_window).to eq "rvm use ruby-2.0.0-p247" end end context "pre_tab is present" do before do allow(project).to receive_messages(rbenv?: false) allow(project).to receive_messages(pre_tab?: true) end it "still gets the correct pre_window command" do expect(project.pre_window).to be_nil end end end end describe "#socket" do context "socket path is present" do before do allow(project).to receive_messages(socket_path: "/tmp") end it "gets the socket path" do expect(project.socket).to eq " -S /tmp" end end end describe "#tmux_command" do context "tmux_command specified" do before do project.yaml["tmux_command"] = "byobu" end it "gets the custom tmux command" do expect(project.tmux_command).to eq "byobu" end end context "tmux_command is not specified" do it "returns the default" do expect(project.tmux_command).to eq "tmux" end end end describe "#tmux_options" do context "no tmux options" do before do allow(project).to receive_messages(tmux_options?: false) end it "returns nothing" do expect(project.tmux_options).to eq "" end end context "with deprecations" do before do allow(project_with_deprecations).to receive_messages(cli_args?: true) end it "still gets the tmux options" do expect(project_with_deprecations.tmux_options).to \ eq " -f ~/.tmux.mac.conf" end end end describe "#get_pane_base_index" do it "extracts the pane_base_index from tmux_options" do allow(project).to \ receive_messages(show_tmux_options: tmux_config(pane_base_index: 3)) expect(project.get_pane_base_index).to eq("3") end end describe "#get_base_index" do it "extracts the base index from options" do allow(project).to \ receive_messages(show_tmux_options: tmux_config(base_index: 1)) expect(project.get_base_index).to eq("1") end end describe "#base_index" do context "pane base index present" do before do allow(project).to receive_messages(get_pane_base_index: "1") allow(project).to receive_messages(get_base_index: "1") end it "gets the pane base index" do expect(project.base_index).to eq 1 end end context "pane base index no present" do before do allow(project).to receive_messages(get_pane_base_index: nil) allow(project).to receive_messages(get_base_index: "0") end it "gets the base index" do expect(project.base_index).to eq 0 end end end describe "#startup_window" do context "startup window specified" do it "gets the startup window from project config" do project.yaml["startup_window"] = "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) expect(project.startup_window).to eq 8 end end end describe "#window" do it "gets the window and index for tmux" do expect(project.window(1)).to eq "sample:1" end end describe "#name?" do context "name is present" do it "returns true" do expect(project.name?).to be_truthy end end end describe "#windows?" do context "windows are present" do it "returns true" do expect(project.windows?).to be_truthy end end end describe "#root?" do context "root are present" do it "returns true" do expect(project.root?).to be_truthy end end end describe "#send_keys" do context "no command for window" do it "returns empty string" do expect(project.send_keys("", 1)).to be_empty end end context "command for window is not empty" do it "returns the tmux command" do expect(project.send_keys("vim", 1)).to \ eq "tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 vim C-m" end end end describe "#send_pane_command" do context "no command for pane" do it "returns empty string" do expect(project.send_pane_command("", 0, 0)).to be_empty end end context "command for pane is not empty" do it "returns the tmux command" do expect(project.send_pane_command("vim", 1, 0)).to \ eq "tmux -f ~/.tmux.mac.conf -L foo send-keys -t sample:1 vim C-m" end end end describe "#deprecations" do context "without deprecations" do it "is empty" do expect(project.deprecations).to be_empty end end context "with deprecations" do it "is not empty" do expect(project_with_deprecations.deprecations).to_not be_empty end end end describe "#commands" do let(:window) { project.windows.keep_if { |w| w.name == "shell" }.first } it "splits commands into an array" do 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 describe "#pre" do subject(:pre) { project.pre } context "pre in yaml is string" do before { project.yaml["pre"] = "mysql.server start" } it "returns the string" do expect(pre).to eq("mysql.server start") end end context "pre in yaml is Array" do before 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 tmuxinator-0.7.0/spec/lib/tmuxinator/wemux_support_spec.rb0000644000175000017500000000214312620456173024004 0ustar uwabamiuwabamirequire "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 tmuxinator-0.7.0/spec/factories/0000755000175000017500000000000012620456173016503 5ustar uwabamiuwabamitmuxinator-0.7.0/spec/factories/projects.rb0000644000175000017500000000427212620456173020666 0ustar uwabamiuwabamidef yaml_load(file) YAML.load(File.read(File.expand_path(file))) end FactoryGirl.define do factory :project, class: Tmuxinator::Project do transient do file { yaml_load("spec/fixtures/sample.yml") } end initialize_with { Tmuxinator::Project.new(file) } end 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 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 :noname_project, class: Tmuxinator::Project do transient do file { yaml_load("spec/fixtures/noname.yml") } end initialize_with { Tmuxinator::Project.new(file) } end factory :nowindows_project, class: Tmuxinator::Project do transient do file { yaml_load("spec/fixtures/nowindows.yml") } end initialize_with { Tmuxinator::Project.new(file) } end factory :nameless_window_project, class: Tmuxinator::Project do transient do file { yaml_load("spec/fixtures/nameless_window.yml") } end initialize_with { Tmuxinator::Project.new(file) } end end tmuxinator-0.7.0/spec/fixtures/0000755000175000017500000000000012620456173016375 5ustar uwabamiuwabamitmuxinator-0.7.0/spec/fixtures/sample.deprecations.yml0000644000175000017500000000157112620456173023064 0ustar uwabamiuwabami# ~/.tmuxinator/sample.deprecations.yml project_name: sample project_root: ~/test socket_name: foo # Remove to use default socket pre: sudo /etc/rc.d/mysqld start # Runs before everything rbenv: 2.0.0-p247 cli_args: -f ~/.tmux.mac.conf # Pass arguments to tmux tabs: - editor: pre: - echo "I get run in each pane, before each pane command!" - layout: main-vertical panes: - vim - #empty, will just run plain bash - top - shell: git pull - guard: layout: tiled pre: - echo "I get run in each pane." - echo "Before each pane command!" panes: - - #empty, will just run plain bash - - database: bundle exec rails db - server: bundle exec rails s - logs: tail -f log/development.log - console: bundle exec rails c - capistrano: - server: ssh user@example.com tmuxinator-0.7.0/spec/fixtures/sample.yml0000644000175000017500000000210112620456173020373 0ustar uwabamiuwabami# ~/.tmuxinator/sample.yml # you can make as many tabs as you wish... name: sample root: ~/test socket_name: foo # Remove to use default socket pre: sudo /etc/rc.d/mysqld start # Runs before everything pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux tmux_detached: false windows: - editor: pre: - echo "I get run in each pane, before each pane command!" - layout: main-vertical panes: - vim - #empty, will just run plain bash - top - pane_with_multiple_commands: - ssh server - echo "Hello" - shell: - git pull - git merge - guard: layout: tiled pre: - echo "I get run in each pane." - echo "Before each pane command!" panes: - - #empty, will just run plain bash - - database: bundle exec rails db - server: bundle exec rails s - logs: tail -f log/development.log - console: bundle exec rails c - capistrano: - server: ssh user@example.com tmuxinator-0.7.0/spec/fixtures/noname.yml0000644000175000017500000000016012620456173020372 0ustar uwabamiuwabami# ~/.tmuxinator/noname.yml # you can make as many tabs as you wish... root: ~/test windows: - test: echo foo tmuxinator-0.7.0/spec/fixtures/nowindows.yml0000644000175000017500000000003312620456173021143 0ustar uwabamiuwabaminame: no_windows root: ~/ tmuxinator-0.7.0/spec/fixtures/detach.yml0000644000175000017500000000207212620456173020351 0ustar uwabamiuwabami# ~/.tmuxinator/sample.yml # you can make as many tabs as you wish... name: sample root: ~/test socket_name: foo # Remove to use default socket pre: sudo /etc/rc.d/mysqld start # Runs before everything pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux attach: false windows: - editor: pre: - echo "I get run in each pane, before each pane command!" - layout: main-vertical panes: - vim - #empty, will just run plain bash - top - pane_with_multiple_commands: - ssh server - echo "Hello" - shell: - git pull - git merge - guard: layout: tiled pre: - echo "I get run in each pane." - echo "Before each pane command!" panes: - - #empty, will just run plain bash - - database: bundle exec rails db - server: bundle exec rails s - logs: tail -f log/development.log - console: bundle exec rails c - capistrano: - server: ssh user@example.com tmuxinator-0.7.0/spec/fixtures/nameless_window.yml0000644000175000017500000000017512620456173022321 0ustar uwabamiuwabaminame: nameless_window root: ~/ windows: - ~: echo "this is a window with no name" - other: echo "this window has a name" tmuxinator-0.7.0/spec/fixtures/sample_number_as_name.yml0000644000175000017500000000014612620456173023435 0ustar uwabamiuwabami# ~/.tmuxinator/sample_number_as_name.yml name: 222 windows: - number: echo number as name fixture tmuxinator-0.7.0/spec/fixtures/sample_wemux.yml0000644000175000017500000000167312620456173021635 0ustar uwabamiuwabami# ~/.tmuxinator/sample_wemux.yml # you can make as many tabs as you wish... name: sample root: ~/test pre: sudo /etc/rc.d/mysqld start # Runs before everything pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane tmux_options: -f ~/.tmux.mac.conf # Pass arguments to tmux tmux_command: wemux windows: - editor: pre: - echo "I get run in each pane, before each pane command!" - layout: main-vertical panes: - vim - #empty, will just run plain bash - top - shell: - git pull - git merge - guard: layout: tiled pre: - echo "I get run in each pane." - echo "Before each pane command!" panes: - - #empty, will just run plain bash - - database: bundle exec rails db - server: bundle exec rails s - logs: tail -f log/development.log - console: bundle exec rails c - capistrano: - server: ssh user@example.com tmuxinator-0.7.0/Gemfile0000644000175000017500000000047112620456173015067 0ustar uwabamiuwabamisource "https://rubygems.org" # Specify your gem's dependencies in tmuxinator.gemspec gemspec 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 tmuxinator-0.7.0/README.md0000644000175000017500000002110312620456173015046 0ustar uwabamiuwabami# 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/tmuxinator/tmuxinator) [![Dependency Status](https://gemnasium.com/tmuxinator/tmuxinator.svg)](https://gemnasium.com/tmuxinator/tmuxinator) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tmuxinator/tmuxinator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) Create and manage tmux sessions easily. ![Screenshot](https://f.cloud.github.com/assets/141213/916084/065fef7c-fe82-11e2-9c23-a9622c7d83c3.png) ## Installation ``` gem install tmuxinator ``` ## Editor and Shell tmuxinator uses your shell's default editor for opening files. If you're not sure what that is type: ``` bash echo $EDITOR ``` For me that produces "vim" If you want to change your default editor simply put a line in ~/.bashrc that changes it. Mine looks like this: ``` export EDITOR='vim' ``` ## tmux The recommended version of tmux to use is 1.8. Your mileage may vary for earlier versions. Refer to the FAQ for any odd behaviour. ### base-index If you use a `base-index` other than the default, please be sure to also set the `pane-base-index` ``` set-window-option -g pane-base-index 1 ``` ## Completion Download the appropriate completion file from the repo and `source` the file. The following are example where the completion file has been downloaded into `~/.bin`. ### bash Add the following to your `~/.bashrc`: source ~/.bin/tmuxinator.bash ### zsh Add the following to your `~/.zshrc`: source ~/.bin/tmuxinator.zsh ### fish Move `tmuxinator.fish` to your `completions` folder: cp ~/.bin/tmuxinator.fish ~/.config/fish/completions/ ## Usage A working knowledge of tmux is assumed. You should understand what windows and panes are in tmux. If not please consult the [man pages](http://manpages.ubuntu.com/manpages/precise/en/man1/tmux.1.html#contenttoc6) for tmux. ### Create a project Create or edit your projects with: ``` tmuxinator new [project] ``` For editing you can also use `tmuxinator open [project]`. `new` is aliased to `o`,`open`, `e`, `edit` and `n`. Please note that dots can't be used in project names as tmux uses them internally to delimit between windows and panes. Your default editor (`$EDITOR`) is used to open the file. If this is a new project you will see this default config: ```yaml # ~/.tmuxinator/sample.yml name: sample root: ~/ # Optional. tmux socket # socket_name: foo # Runs before everything. Use it to start daemons etc. # pre: sudo /etc/rc.d/mysqld start # Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions. # pre_window: rbenv shell 2.0.0-p247 # Pass command line options to tmux. Useful for specifying a different tmux.conf. # tmux_options: -f ~/.tmux.mac.conf # Change the command to call tmux. This can be used by derivatives/wrappers like byobu. # tmux_command: byobu # Specifies (by name or index) which window will be selected on project startup. If not set, the first window is used. # startup_window: logs windows: - editor: layout: main-vertical panes: - vim - guard - server: bundle exec rails s - logs: tail -f log/development.log ``` ## Windows The windows option allows the specification of any number of tmux windows. Each window is denoted by a YAML array entry, followed by a name and command to be run. ```yaml windows: - editor: vim ``` ### Window specific root An optional root option can be specified per window: ```yaml name: test root: ~/projects/company windows: - small_project: root: ~/projects/company/small_project panes: - start this - start that ``` This takes precedence over the main root option. ## Panes **_Note that if you wish to use panes, make sure that you do not have `.` in your project name. tmux uses `.` to delimit between window and pane indices, and tmuxinator uses the project name in combination with these indices to target the correct pane or window._** Panes are optional and are children of window entries, but unlike windows, they do not need a name. In the following example, the `editor` window has 2 panes, one running vim, the other guard. ```yaml windows: - editor: layout: main-vertical panes: - vim - guard ``` The layout setting gets handed down to tmux directly, so you can choose from one of [the five standard layouts](http://manpages.ubuntu.com/manpages/precise/en/man1/tmux.1.html#contenttoc6) or [specify your own](http://stackoverflow.com/a/9976282/183537). ## Interpreter Managers & Environment Variables To use tmuxinator with rbenv, RVM, NVM etc, use the `pre_window` option. ```yaml pre_window: rbenv shell 2.0.0-p247 ``` These command(s) will run before any subsequent commands in all panes and windows. ## Custom attachment and post commands 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 ``` ## Passing directly to send-keys tmuxinator passes commands directly to send keys. This differs from simply chaining commands together using `&&` or `;`, in that tmux will directly send the commands to a shell as if you typed them in. This allows commands to be executed on a remote server over SSH for example. To support this both the window and pane options can take an array as an argument: ```yaml name: sample root: ~/ windows: - stats: - ssh stats@example.com - tail -f /var/log/stats.log - logs: layout: main-vertical panes: - logs: - ssh logs@example.com - cd /var/logs - tail -f development.log ``` ## ERB 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. ``` tmuxinator start [project] [alias] ``` 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. ``` mux [command] ``` ## Other Commands Copy an existing project. Aliased to `c` and `cp` ``` tmuxinator copy [existing] [new] ``` List all the projects you have configured. Aliased to `l` and `ls` ``` tmuxinator list ``` Remove a project. Aliased to `rm` ``` tmuxinator delete [project] ``` Remove all tmuxinator configs, aliases and scripts. Aliased to `i` ``` tmuxinator implode ``` Examines your environment and identifies problems with your configuration ``` tmuxinator doctor ``` Shows tmuxinator's help. Aliased to `h` ``` tmuxinator help ``` Shows the shell commands that get executed for a project ``` tmuxinator debug [project] ``` Shows tmuxinator's version. ``` tmuxinator version ``` ## FAQ ### Window names are not displaying properly? Add `export DISABLE_AUTO_TITLE=true` to your `.zshrc` or `.bashrc` ## Contributing To contribute, please read the [contributing guide](https://github.com/tmuxinator/tmuxinator/blob/master/CONTRIBUTING.md). ## Copyright Copyright (c) 2010-2014 Allen Bargi, Christopher Chow. See LICENSE for further details.