class Tmuxinator::Cli

Constants

COMMANDS
RESERVED_COMMANDS
THOR_COMMANDS

For future reference: due to how tmuxinator currently consumes command-line arguments (see ::bootstrap, below), invocations of Thor’s base commands (i.e. ‘help’, etc) can be instead routed to start (rather than to ::start). In order to prevent this, the THOR_COMMANDS and RESERVED_COMMANDS constants have been introduced. The former enumerates any/all Thor commands we want to insure get passed through to Thor.start. The latter is the superset of the Thor commands and any tmuxinator commands, defined in COMMANDS, above.

Public Class Methods

bootstrap(args = []) click to toggle source

This method was defined as something of a workaround… Previously the conditional contained within was in the executable (i.e. bin/tmuxinator). It has been moved here so as to be testable. A couple of notes:

  • ::start (defined in Thor::Base) expects the first argument to be an

array or ARGV, not a varargs. Perhaps ::bootstrap should as well?

  • ::start has a different purpose from start and hence a different

signature

# File lib/tmuxinator/cli.rb, line 432
def self.bootstrap(args = [])
  name = args[0] || nil
  if args.empty? && Tmuxinator::Config.local?
    Tmuxinator::Cli.new.local
  elsif name && !Tmuxinator::Cli::RESERVED_COMMANDS.include?(name) &&
        Tmuxinator::Config.exist?(name: name)
    Tmuxinator::Cli.start([:start, *args])
  else
    Tmuxinator::Cli.start(args)
  end
end
exit_on_failure?() click to toggle source

By default, Thor returns exit(0) when an error occurs. Please see: github.com/tmuxinator/tmuxinator/issues/192

# File lib/tmuxinator/cli.rb, line 9
def self.exit_on_failure?
  true
end

Public Instance Methods

commands(shell = nil) click to toggle source
# File lib/tmuxinator/cli.rb, line 55
def commands(shell = nil)
  out = if shell == "zsh"
          COMMANDS.map do |command, desc|
            "#{command}:#{desc}"
          end.join("\n")
        else
          COMMANDS.keys.join("\n")
        end

  say out
end
completions(arg) click to toggle source
# File lib/tmuxinator/cli.rb, line 69
def completions(arg)
  if %w(start stop edit open copy delete).include?(arg)
    configs = Tmuxinator::Config.configs
    say configs.join("\n")
  end
end
config_path(name, local = false) click to toggle source
# File lib/tmuxinator/cli.rb, line 163
def config_path(name, local = false)
  if local
    Tmuxinator::Config::LOCAL_DEFAULTS[0]
  else
    Tmuxinator::Config.default_project(name)
  end
end
copy(existing, new) click to toggle source
# File lib/tmuxinator/cli.rb, line 336
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.exist?(name: existing)

  new_exists = Tmuxinator::Config.exist?(name: new)
  question = "#{new} already exists, would you like to overwrite it?"
  if !new_exists || yes?(question, :red)
    say "Overwriting #{new}" if Tmuxinator::Config.exist?(name: new)
    FileUtils.copy_file(existing_config_path, new_config_path)
  end

  Kernel.system("$EDITOR #{new_config_path}")
end
create_project(project_options = {}) click to toggle source
# File lib/tmuxinator/cli.rb, line 178
def create_project(project_options = {})
  Tmuxinator::Config.validate(project_create_options(project_options))
rescue StandardError => e
  exit! e.message
end
debug(name = nil, *args) click to toggle source
# File lib/tmuxinator/cli.rb, line 324
def debug(name = nil, *args)
  params = start_params(name, *args)

  project = create_project(params)

  say project.render
end
delete(*projects) click to toggle source
# File lib/tmuxinator/cli.rb, line 357
def delete(*projects)
  projects.each do |project|
    if Tmuxinator::Config.exist?(name: project)
      config = Tmuxinator::Config.project(project)

      if yes?("Are you sure you want to delete #{project}?(y/n)", :red)
        FileUtils.rm(config)
        say "Deleted #{project}"
      end
    else
      say "#{project} does not exist!"
    end
  end
end
doctor() click to toggle source
# File lib/tmuxinator/cli.rb, line 413
def doctor
  say "Checking if tmux is installed ==> "
  yes_no Tmuxinator::Doctor.installed?

  say "Checking if $EDITOR is set ==> "
  yes_no Tmuxinator::Doctor.editor?

  say "Checking if $SHELL is set ==> "
  yes_no Tmuxinator::Doctor.shell?
end
find_project_file(name, local = false) click to toggle source
# File lib/tmuxinator/cli.rb, line 154
def find_project_file(name, local = false)
  path = config_path(name, local)
  if File.exist?(path)
    path
  else
    generate_project_file(name, path)
  end
end
generate_project_file(name, path) click to toggle source
# File lib/tmuxinator/cli.rb, line 171
def generate_project_file(name, path)
  config = Tmuxinator::Config.default_or_sample
  erb = Tmuxinator::Project.render_template(config, binding)
  File.open(path, "w") { |f| f.write(erb) }
  path
end
implode() click to toggle source
# File lib/tmuxinator/cli.rb, line 375
def implode
  if yes?("Are you sure you want to delete all tmuxinator configs?", :red)
    Tmuxinator::Config.directories.each do |directory|
      FileUtils.remove_dir(directory)
    end
    say "Deleted all tmuxinator projects."
  end
end
kill_project(project) click to toggle source
# File lib/tmuxinator/cli.rb, line 221
def kill_project(project)
  Kernel.exec(project.kill)
end
list() click to toggle source
# File lib/tmuxinator/cli.rb, line 394
def list
  say "tmuxinator projects:"
  configs = Tmuxinator::Config.configs(active: options[:active])
  if options[:newline]
    say configs.join("\n")
  else
    print_in_columns configs
  end
end
local() click to toggle source
# File lib/tmuxinator/cli.rb, line 303
def local
  show_version_warning if version_warning?(
    options["suppress-tmux-version-warning"]
  )

  render_project(create_project(attach: options[:attach]))
end
new(name, session = nil) click to toggle source
# File lib/tmuxinator/cli.rb, line 86
def new(name, session = nil)
  if session
    new_project_with_session(name, session)
  else
    new_project(name)
  end
end
new_project(name) click to toggle source
# File lib/tmuxinator/cli.rb, line 95
def new_project(name)
  project_file = find_project_file(name, options[:local])
  Kernel.system("$EDITOR #{project_file}") || doctor
end
new_project_with_session(name, session) click to toggle source
# File lib/tmuxinator/cli.rb, line 100
      def new_project_with_session(name, session)
        if Tmuxinator::Config.version < 1.6
          raise "Creating projects from sessions is unsupported\
            for tmux version 1.5 or lower."
        end

        windows, _, s0 = Open3.capture3(<<-CMD)
          tmux list-windows -t #{session}\
          -F "#W \#{window_layout} \#{window_active} \#{pane_current_path}"
        CMD
        panes, _, s1 = Open3.capture3(<<-CMD)
          tmux list-panes -s -t #{session} -F "#W \#{pane_current_path}"
        CMD
        tmux_options, _, s2 = Open3.capture3(<<-CMD)
          tmux show-options -t #{session}
        CMD
        project_root = tmux_options[/^default-path "(.+)"$/, 1]

        unless [s0, s1, s2].all?(&:success?)
          raise "Session '#{session}' doesn't exist."
        end

        panes = panes.each_line.map(&:split).group_by(&:first)
        windows = windows.each_line.map do |line|
          window_name, layout, active, path = line.split(" ")
          project_root ||= path if active.to_i == 1
          [
            window_name,
            layout,
            Array(panes[window_name]).map do |_, pane_path|
              "cd #{pane_path}"
            end
          ]
        end

        yaml = {
          "name" => name,
          "project_root" => project_root,
          "windows" => windows.map do |window_name, layout, window_panes|
            {
              window_name => {
                "layout" => layout,
                "panes" => window_panes
              }
            }
          end
        }

        path = config_path(name, options[:local])
        File.open(path, "w") do |f|
          f.write(YAML.dump(yaml))
        end
      end
project_create_options(project_options) click to toggle source
# File lib/tmuxinator/cli.rb, line 184
def project_create_options(project_options)
  {
    args: project_options[:args],
    custom_name: project_options[:custom_name],
    force_attach: project_options[:attach] == true,
    force_detach: project_options[:attach] == false,
    name: project_options[:name],
    project_config: project_options[:project_config],
    append: project_options[:append],
    no_pre_window: project_options[:no_pre_window],
  }
end
render_project(project) click to toggle source
# File lib/tmuxinator/cli.rb, line 197
def render_project(project)
  if project.deprecations.any?
    project.deprecations.each { |deprecation| say deprecation, :red }
    show_continuation_prompt
  end

  Kernel.exec(project.render)
end
show_continuation_prompt() click to toggle source
# File lib/tmuxinator/cli.rb, line 215
def show_continuation_prompt
  say
  print "Press ENTER to continue."
  STDIN.getc
end
show_version_warning() click to toggle source
# File lib/tmuxinator/cli.rb, line 210
def show_version_warning
  say Tmuxinator::TmuxVersion::UNSUPPORTED_VERSION_MSG, :red
  show_continuation_prompt
end
start(name = nil, *args) click to toggle source
# File lib/tmuxinator/cli.rb, line 261
def start(name = nil, *args)
  params = start_params(name, *args)

  show_version_warning if version_warning?(
    options["suppress-tmux-version-warning"]
  )

  project = create_project(params)
  render_project(project)
end
start_params(name = nil, *args) click to toggle source
# File lib/tmuxinator/cli.rb, line 225
def start_params(name = nil, *args)
  # project-config takes precedence over a named project in the case that
  # both are provided.
  if options["project-config"]
    args.unshift name if name
    name = nil
  end

  {
    args: args,
    attach: options[:attach],
    custom_name: options[:name],
    name: name,
    project_config: options["project-config"],
    append: options["append"],
    no_pre_window: options["no-pre-window"],
  }
end
stop(name = nil) click to toggle source
# File lib/tmuxinator/cli.rb, line 279
def stop(name = nil)
  # project-config takes precedence over a named project in the case that
  # both are provided.
  if options["project-config"]
    name = nil
  end

  params = {
    name: name,
    project_config: options["project-config"]
  }
  show_version_warning if version_warning?(
    options["suppress-tmux-version-warning"]
  )

  project = create_project(params)
  kill_project(project)
end
version() click to toggle source
# File lib/tmuxinator/cli.rb, line 407
def version
  say "tmuxinator #{Tmuxinator::VERSION}"
end
version_warning?(suppress_flag) click to toggle source
# File lib/tmuxinator/cli.rb, line 206
def version_warning?(suppress_flag)
  !Tmuxinator::TmuxVersion.supported? && !suppress_flag
end