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 tostart
(rather than to ::start). In order to prevent this, theTHOR_COMMANDS
andRESERVED_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 inCOMMANDS
, above.
Public Class Methods
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
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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/tmuxinator/cli.rb, line 221 def kill_project(project) Kernel.exec(project.kill) end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/tmuxinator/cli.rb, line 215 def show_continuation_prompt say print "Press ENTER to continue." STDIN.getc end
# File lib/tmuxinator/cli.rb, line 210 def show_version_warning say Tmuxinator::TmuxVersion::UNSUPPORTED_VERSION_MSG, :red show_continuation_prompt end
# 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
# 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
# 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
# File lib/tmuxinator/cli.rb, line 407 def version say "tmuxinator #{Tmuxinator::VERSION}" end
# File lib/tmuxinator/cli.rb, line 206 def version_warning?(suppress_flag) !Tmuxinator::TmuxVersion.supported? && !suppress_flag end