module Runbook::Helpers::TmuxHelper

Constants

FILE_PERMISSIONS

Public Instance Methods

_all_panes_exist?(stored_layout) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 49
def _all_panes_exist?(stored_layout)
  (stored_layout.values - _session_panes).empty?
end
_initialize_panes(panes_to_init, layout_panes) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 141
def _initialize_panes(panes_to_init, layout_panes)
  panes_to_init.each do |pane|
    target = layout_panes[pane[:name]]
    _set_directory(pane[:directory], target) if pane[:directory]
    send_keys(pane[:command], target) if pane[:command]
  end
end
_kill_pane(pane_id) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 37
def _kill_pane(pane_id)
  `tmux kill-pane -t #{pane_id}`
end
_layout_file(runbook_title) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 41
def _layout_file(runbook_title)
  `tmux display-message -p -t $TMUX_PANE "#{Dir.tmpdir}/runbook_layout_\#{pid}_\#{session_name}_\#{pane_pid}_\#{pane_id}_#{runbook_title}.yml"`.strip
end
_new_window(name) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 157
def _new_window(name)
  `tmux new-window -n "#{name}" -P -F '#D' -d`.strip
end
_pager_escape_sequence() click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 33
def _pager_escape_sequence
  "q C-u"
end
_remove_stale_layouts() click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 53
def _remove_stale_layouts
  session_panes = _session_panes
  session_layout_files = _session_layout_files
  session_layout_files.each do |file|
    File.delete(file) unless session_panes.any? { |pane| /_#{pane}_/ =~ file }
  end
end
_rename_window(name) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 153
def _rename_window(name)
  `tmux rename-window "#{name}"`
end
_runbook_pane() click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 149
def _runbook_pane
  @runbook_pane ||= `tmux display-message -p '#D'`.strip
end
_session_layout_files() click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 65
def _session_layout_files
  session_layout_glob = `tmux display-message -p "#{Dir.tmpdir}/runbook_layout_\#{pid}_\#{session_name}_*.yml"`.strip
  Dir[session_layout_glob]
end
_session_panes() click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 61
def _session_panes
  `tmux list-panes -s -F '#D'`.split("\n")
end
_set_directory(directory, target) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 172
def _set_directory(directory, target)
  send_keys("cd #{directory}; clear", target)
end
_setup_layout(structure) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 70
def _setup_layout(structure)
  current_pane = _runbook_pane
  panes_to_init = []
  {}.tap do |layout_panes|
    if structure.is_a?(Hash)
      first_window = true
      structure.each do |name, window|
        if first_window
          _rename_window(name)
          first_window = false
        else
          current_pane = _new_window(name)
        end
        _setup_panes(layout_panes, panes_to_init, current_pane, window)
      end
    else
      _setup_panes(layout_panes, panes_to_init, current_pane, structure)
    end
    _swap_runbook_pane(panes_to_init, layout_panes)
    _initialize_panes(panes_to_init, layout_panes)
  end
end
_setup_panes(layout_panes, panes_to_init, current_pane, structure, depth=0) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 93
def _setup_panes(layout_panes, panes_to_init, current_pane, structure, depth=0)
  return if structure.empty?
  case structure
  when Array
    case structure.size
    when 1
      _setup_panes(layout_panes, panes_to_init, current_pane, structure.shift, depth+1)
    else
      size = 100 - 100 / structure.size
      new_pane = _split(current_pane, depth, size)
      _setup_panes(layout_panes, panes_to_init, current_pane, structure.shift, depth+1)
      _setup_panes(layout_panes, panes_to_init, new_pane, structure, depth)
    end
  when Hash
    if structure.values.all? { |v| v.is_a?(Numeric) }
      total_size = structure.values.reduce(:+)
      case structure.size
      when 1
        _setup_panes(layout_panes, panes_to_init, current_pane, structure.keys[0], depth+1)
      else
        size = (total_size - structure.values[0]) * 100 / total_size
        new_pane = _split(current_pane, depth, size)
        first_struct = structure.keys[0]
        structure.delete(first_struct)
        _setup_panes(layout_panes, panes_to_init, current_pane, first_struct, depth+1)
        _setup_panes(layout_panes, panes_to_init, new_pane, structure, depth)
      end
    else
      layout_panes[structure[:name]] = current_pane
      panes_to_init << structure
    end
  when Symbol
    layout_panes[structure] = current_pane
  end
end
_slug(title) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 45
def _slug(title)
  title.titleize.gsub(/[\/\s]+/, "").underscore.dasherize
end
_split(current_pane, depth, size) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 161
def _split(current_pane, depth, size)
  direction = depth.even? ? "h" : "v"
  command = "tmux split-window"
  args = "-#{direction} -t #{current_pane} -p #{size} -P -F '#D' -d"
  `#{command} #{args}`.strip
end
_swap_panes(target_pane, source_pane) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 168
def _swap_panes(target_pane, source_pane)
  `tmux swap-pane -d -t #{target_pane} -s #{source_pane}`
end
_swap_runbook_pane(panes_to_init, layout_panes) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 129
def _swap_runbook_pane(panes_to_init, layout_panes)
  if (runbook_pane = panes_to_init.find { |pane| pane[:runbook_pane] })
    current_runbook_pane_name = layout_panes.keys.find do |k|
      layout_panes[k] == _runbook_pane
    end
    target_pane_id = layout_panes[runbook_pane[:name]]
    layout_panes[runbook_pane[:name]] = _runbook_pane
    layout_panes[current_runbook_pane_name] = target_pane_id
    _swap_panes(target_pane_id, _runbook_pane)
  end
end
kill_all_panes(layout_panes) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 26
def kill_all_panes(layout_panes)
  runbook_pane = _runbook_pane
  layout_panes.values.each do |pane_id|
    _kill_pane(pane_id) unless pane_id == runbook_pane
  end
end
send_keys(command, target) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 22
def send_keys(command, target)
  `tmux send-keys -t #{target} #{_pager_escape_sequence} #{Shellwords.escape(command)} C-m`
end
setup_layout(structure, runbook_title:) click to toggle source
# File lib/runbook/helpers/tmux_helper.rb, line 5
def setup_layout(structure, runbook_title:)
  _remove_stale_layouts
  layout_file = _layout_file(_slug(runbook_title))
  if File.exist?(layout_file)
    stored_layout = ::YAML::load_file(layout_file)
    if _all_panes_exist?(stored_layout)
      return stored_layout
    end
  end

  _setup_layout(structure).tap do |layout_panes|
    File.open(layout_file, 'w', FILE_PERMISSIONS) do |f|
      f.write(layout_panes.to_yaml)
    end
  end
end