class Tmuxinator::Project

Constants

CLIARGS_DEP_MSG
POST_DEP_MSG
PRE_DEP_MSG
RBENVRVM_DEP_MSG
SYNC_DEP_MSG
TABS_DEP_MSG

Attributes

custom_name[R]
force_attach[R]
force_detach[R]
no_pre_window[R]
yaml[R]

Public Class Methods

load(path, options = {}) click to toggle source
# File lib/tmuxinator/project.rb, line 45
def self.load(path, options = {})
  yaml = begin
    args = options[:args] || []
    @settings = parse_settings(args)
    @args = args

    content = render_template(path, binding)
    YAML.safe_load(content, aliases: true)
         rescue SyntaxError, StandardError => error
           raise "Failed to parse config file: #{error.message}"
  end

  new(yaml, options)
end
new(yaml, options = {}) click to toggle source
# File lib/tmuxinator/project.rb, line 81
def initialize(yaml, options = {})
  options[:force_attach] = false if options[:force_attach].nil?
  options[:force_detach] = false if options[:force_detach].nil?

  @yaml = yaml

  set_instance_variables_from_options(options)

  validate_options

  extend Tmuxinator::WemuxSupport if wemux?
end
parse_settings(args) click to toggle source
# File lib/tmuxinator/project.rb, line 60
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
render_template(template, bndg) click to toggle source
# File lib/tmuxinator/project.rb, line 120
def self.render_template(template, bndg)
  content = File.read(template)
  bndg.eval(Erubi::Engine.new(content).src)
end

Public Instance Methods

append?() click to toggle source
# File lib/tmuxinator/project.rb, line 153
def append?
  @append
end
attach?() click to toggle source
# File lib/tmuxinator/project.rb, line 162
def attach?
  yaml_attach = if yaml["attach"].nil?
                  true
                else
                  yaml["attach"]
                end
  attach = force_attach || !force_detach && yaml_attach
  attach
end
base_index() click to toggle source
# File lib/tmuxinator/project.rb, line 248
def base_index
  return last_window_index + 1 if append?

  get_base_index.to_i
end
cli_args?() click to toggle source
# File lib/tmuxinator/project.rb, line 344
def cli_args?
  yaml["cli_args"]
end
current_session_name() click to toggle source
# File lib/tmuxinator/project.rb, line 138
def current_session_name
  `[[ -n "${TMUX+set}" ]] && tmux display-message -p "#S"`.strip
end
deprecation_checks() click to toggle source
# File lib/tmuxinator/project.rb, line 306
def deprecation_checks
  [
    rvm_or_rbenv?,
    tabs?,
    cli_args?,
    legacy_synchronize?,
    pre?,
    post?
  ]
end
deprecation_messages() click to toggle source
# File lib/tmuxinator/project.rb, line 317
def deprecation_messages
  [
    RBENVRVM_DEP_MSG,
    TABS_DEP_MSG,
    CLIARGS_DEP_MSG,
    SYNC_DEP_MSG,
    PRE_DEP_MSG,
    POST_DEP_MSG
  ]
end
deprecations() click to toggle source
# File lib/tmuxinator/project.rb, line 298
def deprecations
  deprecation_checks.zip(deprecation_messages).
    inject([]) do |deps, (chk, msg)|
    deps << msg if chk
    deps
  end
end
enable_pane_titles?() click to toggle source
# File lib/tmuxinator/project.rb, line 381
def enable_pane_titles?
  yaml["enable_pane_titles"]
end
get_base_index() click to toggle source
# File lib/tmuxinator/project.rb, line 360
def get_base_index
  tmux_config["base-index"]
end
get_pane_base_index() click to toggle source
# File lib/tmuxinator/project.rb, line 356
def get_pane_base_index
  tmux_config["pane-base-index"]
end
kill() click to toggle source
# File lib/tmuxinator/project.rb, line 116
def kill
  self.class.render_template(Tmuxinator::Config.stop_template, binding)
end
last_window_index() click to toggle source
# File lib/tmuxinator/project.rb, line 244
def last_window_index
  `tmux list-windows -F '#I'`.split.last.to_i
end
name() click to toggle source
# File lib/tmuxinator/project.rb, line 142
def name
  name =
    if append?
      current_session_name
    else
      custom_name || yaml["project_name"] || yaml["name"]
    end

  blank?(name) ? nil : name.to_s.shellescape
end
name?() click to toggle source
# File lib/tmuxinator/project.rb, line 278
def name?
  !name.nil?
end
pane_base_index() click to toggle source
# File lib/tmuxinator/project.rb, line 254
def pane_base_index
  get_pane_base_index.to_i
end
pane_title_position_not_valid_warning() click to toggle source
# File lib/tmuxinator/project.rb, line 403
def pane_title_position_not_valid_warning
  print_warning(
    "The specified pane title position " +
    "\"#{yaml['pane_title_position']}\" is not valid. " +
    "Please choose one of: top, bottom, or off."
  )
end
pane_titles_not_supported_warning() click to toggle source
# File lib/tmuxinator/project.rb, line 411
def pane_titles_not_supported_warning
  print_warning(
    "You have enabled pane titles in your configuration, " +
    "but the feature is not supported by your version of tmux.\n" +
    "Please consider upgrading to a version that supports it (tmux >=2.6)."
  )
end
post() click to toggle source
# File lib/tmuxinator/project.rb, line 187
def post
  post_config = yaml["post"]
  parsed_parameters(post_config)
end
post?() click to toggle source
# File lib/tmuxinator/project.rb, line 352
def post?
  yaml["post"]
end
pre() click to toggle source
# File lib/tmuxinator/project.rb, line 157
def pre
  pre_config = yaml["pre"]
  parsed_parameters(pre_config)
end
pre?() click to toggle source
# File lib/tmuxinator/project.rb, line 348
def pre?
  yaml["pre"]
end
pre_window() click to toggle source
# File lib/tmuxinator/project.rb, line 172
def pre_window
  return if no_pre_window

  params = if rbenv?
             "rbenv shell #{yaml['rbenv']}"
           elsif rvm?
             "rvm use #{yaml['rvm']}"
           elsif pre_tab?
             yaml["pre_tab"]
           else
             yaml["pre_window"]
           end
  parsed_parameters(params)
end
rbenv?() click to toggle source
# File lib/tmuxinator/project.rb, line 328
def rbenv?
  yaml["rbenv"]
end
render() click to toggle source
# File lib/tmuxinator/project.rb, line 112
def render
  self.class.render_template(Tmuxinator::Config.template, binding)
end
root() click to toggle source
# File lib/tmuxinator/project.rb, line 133
def root
  root = yaml["project_root"] || yaml["root"]
  blank?(root) ? nil : File.expand_path(root).shellescape
end
root?() click to toggle source
# File lib/tmuxinator/project.rb, line 274
def root?
  !root.nil?
end
rvm?() click to toggle source
# File lib/tmuxinator/project.rb, line 332
def rvm?
  yaml["rvm"]
end
rvm_or_rbenv?() click to toggle source
# File lib/tmuxinator/project.rb, line 336
def rvm_or_rbenv?
  rvm? || rbenv?
end
send_keys(cmd, window_index) click to toggle source
# File lib/tmuxinator/project.rb, line 290
def send_keys(cmd, window_index)
  if cmd.empty?
    ""
  else
    "#{tmux} send-keys -t #{window(window_index)} #{cmd.shellescape} C-m"
  end
end
send_pane_command(cmd, window_index, _pane_index) click to toggle source
# File lib/tmuxinator/project.rb, line 286
def send_pane_command(cmd, window_index, _pane_index)
  send_keys(cmd, window_index)
end
set_instance_variables_from_options(options) click to toggle source
# File lib/tmuxinator/project.rb, line 94
def set_instance_variables_from_options(options)
  @custom_name = options[:custom_name]
  @force_attach = options[:force_attach]
  @force_detach = options[:force_detach]
  @append = options[:append]
  @no_pre_window = options[:no_pre_window]
end
show_tmux_options() click to toggle source
# File lib/tmuxinator/project.rb, line 364
def show_tmux_options
  "#{tmux} start-server\\; " \
    "show-option -g base-index\\; " \
    "show-window-option -g pane-base-index\\;"
end
socket() click to toggle source
# File lib/tmuxinator/project.rb, line 218
def socket
  if socket_path
    " -S #{socket_path}"
  elsif socket_name
    " -L #{socket_name}"
  end
end
socket_name() click to toggle source
# File lib/tmuxinator/project.rb, line 226
def socket_name
  yaml["socket_name"]
end
socket_path() click to toggle source
# File lib/tmuxinator/project.rb, line 230
def socket_path
  yaml["socket_path"]
end
startup_pane() click to toggle source
# File lib/tmuxinator/project.rb, line 262
def startup_pane
  "#{startup_window}.#{yaml['startup_pane'] || pane_base_index}"
end
startup_window() click to toggle source
# File lib/tmuxinator/project.rb, line 258
def startup_window
  "#{name}:#{yaml['startup_window'] || base_index}"
end
tabs?() click to toggle source
# File lib/tmuxinator/project.rb, line 340
def tabs?
  yaml["tabs"]
end
tmux() click to toggle source
# File lib/tmuxinator/project.rb, line 192
def tmux
  "#{tmux_command}#{tmux_options}#{socket}"
end
tmux_command() click to toggle source
# File lib/tmuxinator/project.rb, line 196
def tmux_command
  yaml["tmux_command"] || "tmux"
end
tmux_has_session?(name) click to toggle source
# File lib/tmuxinator/project.rb, line 200
def tmux_has_session?(name)
  return false unless name

  # Redirect stderr to /dev/null in order to prevent "failed to connect
  # to server: Connection refused" error message and non-zero exit status
  # if no tmux sessions exist.
  # Please see issues #402 and #414.
  sessions = `#{tmux} ls 2> /dev/null`

  # Remove any escape sequences added by `shellescape` in Project#name.
  # Escapes can result in: "ArgumentError: invalid multibyte character"
  # when attempting to match `name` against `sessions`.
  # Please see issue #564.
  unescaped_name = name.shellsplit.join("")

  !(sessions !~ /^#{unescaped_name}:/)
end
tmux_kill_session_command() click to toggle source
# File lib/tmuxinator/project.rb, line 377
def tmux_kill_session_command
  "#{tmux} kill-session -t #{name}"
end
tmux_new_session_command() click to toggle source
# File lib/tmuxinator/project.rb, line 370
def tmux_new_session_command
  return if append?

  window = windows.first.tmux_window_name_option
  "#{tmux} new-session -d -s #{name} #{window}"
end
tmux_options() click to toggle source
# File lib/tmuxinator/project.rb, line 234
def tmux_options
  if cli_args?
    " #{yaml['cli_args'].to_s.strip}"
  elsif tmux_options?
    " #{yaml['tmux_options'].to_s.strip}"
  else
    ""
  end
end
tmux_options?() click to toggle source
# File lib/tmuxinator/project.rb, line 266
def tmux_options?
  yaml["tmux_options"]
end
tmux_set_pane_title_format(tmux_window_target) click to toggle source
# File lib/tmuxinator/project.rb, line 394
def tmux_set_pane_title_format(tmux_window_target)
  command = set_window_option(tmux_window_target)
  if pane_title_format?
    "#{command} pane-border-format \"#{yaml['pane_title_format']}\""
  else
    "#{command} pane-border-format \"\#{pane_index}: \#{pane_title}\""
  end
end
tmux_set_pane_title_position(tmux_window_target) click to toggle source
# File lib/tmuxinator/project.rb, line 385
def tmux_set_pane_title_position(tmux_window_target)
  command = set_window_option(tmux_window_target)
  if pane_title_position? && pane_title_position_valid?
    "#{command} pane-border-status #{yaml['pane_title_position']}"
  else
    "#{command} pane-border-status top"
  end
end
validate!() click to toggle source
# File lib/tmuxinator/project.rb, line 72
def validate!
  raise "Your project file should include some windows." \
    unless windows?
  raise "Your project file didn't specify a 'project_name'" \
    unless name?

  self
end
validate_options() click to toggle source
# File lib/tmuxinator/project.rb, line 102
def validate_options
  if @force_attach && @force_detach
    raise "Cannot force_attach and force_detach at the same time"
  end

  if append? && !tmux_has_session?(name)
    raise "Cannot append to a session that does not exist"
  end
end
window(index) click to toggle source
# File lib/tmuxinator/project.rb, line 282
def window(index)
  append? ? ":#{index}" : "#{name}:#{index}"
end
windows() click to toggle source
# File lib/tmuxinator/project.rb, line 125
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
windows?() click to toggle source
# File lib/tmuxinator/project.rb, line 270
def windows?
  windows.any?
end

Private Instance Methods

blank?(object) click to toggle source
# File lib/tmuxinator/project.rb, line 421
def blank?(object)
  (object.respond_to?(:empty?) && object.empty?) || !object
end
extract_tmux_config() click to toggle source
# File lib/tmuxinator/project.rb, line 429
def extract_tmux_config
  options_hash = {}

  `#{show_tmux_options}`.
    encode("UTF-8", invalid: :replace).
    split("\n").
    map do |entry|
    key, value = entry.split("\s")
    options_hash[key] = value
    options_hash
  end

  options_hash
end
legacy_synchronize?() click to toggle source
# File lib/tmuxinator/project.rb, line 444
def legacy_synchronize?
  (synchronize_options & [true, "before"]).any?
end
pane_title_format?() click to toggle source
# File lib/tmuxinator/project.rb, line 474
def pane_title_format?
  yaml["pane_title_format"]
end
pane_title_position?() click to toggle source
# File lib/tmuxinator/project.rb, line 466
def pane_title_position?
  yaml["pane_title_position"]
end
pane_title_position_valid?() click to toggle source
# File lib/tmuxinator/project.rb, line 470
def pane_title_position_valid?
  ["top", "bottom", "off"].include? yaml["pane_title_position"]
end
parsed_parameters(parameters) click to toggle source
# File lib/tmuxinator/project.rb, line 458
def parsed_parameters(parameters)
  parameters.is_a?(Array) ? parameters.join("; ") : parameters
end
print_warning(message) click to toggle source
set_window_option(tmux_window_target) click to toggle source
# File lib/tmuxinator/project.rb, line 485
def set_window_option(tmux_window_target)
  "#{tmux} set-window-option -t #{tmux_window_target}"
end
synchronize_options() click to toggle source
# File lib/tmuxinator/project.rb, line 448
def synchronize_options
  window_options.map do |option|
    option["synchronize"] if option.is_a?(Hash)
  end
end
tmux_config() click to toggle source
# File lib/tmuxinator/project.rb, line 425
def tmux_config
  @tmux_config ||= extract_tmux_config
end
wemux?() click to toggle source
# File lib/tmuxinator/project.rb, line 462
def wemux?
  yaml["tmux_command"] == "wemux"
end
window_options() click to toggle source
# File lib/tmuxinator/project.rb, line 454
def window_options
  yaml["windows"].map(&:values).flatten
end