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_COMMANDSandRESERVED_COMMANDSconstants 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
startand hence a different
signature
# File lib/tmuxinator/cli.rb, line 423 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.exists?(name: name) Tmuxinator::Cli.new.start(name, *args.drop(1)) 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 7 def self.exit_on_failure? true end
Public Instance Methods
# File lib/tmuxinator/cli.rb, line 53 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 67 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 161 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 331 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?(name: existing) new_exists = Tmuxinator::Config.exists?(name: new) question = "#{new} already exists, would you like to overwrite it?" if !new_exists || yes?(question, :red) say "Overwriting #{new}" if Tmuxinator::Config.exists?(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 = {}) # Strings provided to --attach are coerced into booleans by Thor. # "f" and "false" will result in `:attach` being `false` and any other # string or the empty flag will result in `:attach` being `true`. # If the flag is not present, `:attach` will be `nil`. attach = detach = false attach = true if project_options[:attach] == true detach = true if project_options[:attach] == false options = { args: project_options[:args], custom_name: project_options[:custom_name], force_attach: attach, force_detach: detach, name: project_options[:name], project_config: project_options[:project_config] } begin Tmuxinator::Config.validate(options) rescue => e exit! e.message end end
# File lib/tmuxinator/cli.rb, line 307 def debug(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 params = { args: args, attach: options[:attach], custom_name: options[:name], name: name, project_config: options["project-config"] } project = create_project(params) say project.render end
# File lib/tmuxinator/cli.rb, line 352 def delete(*projects) projects.each do |project| if Tmuxinator::Config.exists?(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 404 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 152 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 169 def generate_project_file(name, path) template = Tmuxinator::Config.default? ? :default : :sample content = File.read(Tmuxinator::Config.send(template.to_sym)) erubi_content = Erubi::Engine.new(content).src erb = binding.instance_eval(erubi_content) File.open(path, "w") { |f| f.write(erb) } path end
# File lib/tmuxinator/cli.rb, line 370 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 227 def kill_project(project) Kernel.exec(project.kill) end
# File lib/tmuxinator/cli.rb, line 386 def list say "tmuxinator projects:" if options[:newline] say Tmuxinator::Config.configs.join("\n") else print_in_columns Tmuxinator::Config.configs end end
# File lib/tmuxinator/cli.rb, line 290 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 84 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 93 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 98 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 203 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 221 def show_continuation_prompt say print "Press ENTER to continue." STDIN.getc end
# File lib/tmuxinator/cli.rb, line 216 def show_version_warning say Tmuxinator::TmuxVersion::UNSUPPORTED_VERSION_MSG, :red show_continuation_prompt end
# File lib/tmuxinator/cli.rb, line 244 def start(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 params = { args: args, attach: options[:attach], custom_name: options[:name], name: name, project_config: options["project-config"] } 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 273 def stop(name) params = { name: name } 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 398 def version say "tmuxinator #{Tmuxinator::VERSION}" end
# File lib/tmuxinator/cli.rb, line 212 def version_warning?(suppress_flag) !Tmuxinator::TmuxVersion.supported? && !suppress_flag end