Class: Appear::Revealers::Tmux

Inherits:
BaseRevealer show all
Defined in:
lib/appear/revealers.rb

Overview

support for the cross-platform Tmux multiplexer. Also reveals a connected tmux client, if possible.

Instance Method Summary collapse

Methods inherited from BaseRevealer

#call, register!

Methods inherited from BaseService

delegate, #initialize, require_service, required_services

Constructor Details

This class inherits a constructor from Appear::BaseService

Instance Method Details

#reveal_tree(tree) ⇒ Object

Implementation.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/appear/revealers.rb', line 119

def reveal_tree(tree)
  relevent_panes = Util::Join.join(:pid, tree, services.tmux.panes)
  relevent_panes.each do |pane|
    log("#{self.class.name}: revealing pane #{pane}")
    services.tmux.reveal_pane(pane)
  end

  # we should also appear the tmux client for this tree in the gui
  pid = tmux_client_for_tree(tree)
  if pid
    services.revealer.call(pid)
  end

  return relevent_panes.length > 0
end

#supports_tree?(target, rest) ⇒ Boolean

Implementation

Returns:

  • (Boolean)

See Also:



113
114
115
# File 'lib/appear/revealers.rb', line 113

def supports_tree?(target, rest)
  rest.any? { |p| p.name == 'tmux' }
end

#tmux_client_for_tree(tree) ⇒ Number?

tmux does not tell us the PIDs of any of these clients. The only way to find the PID of a tmux client is to lsof() the TTY that the client is connected to, and then deduce the client PID, which will be a tmux process PID that is not the server PID.

Parameters:

Returns:

  • (Number, nil)

    pid of a tmux client, if one was found. Otherwise nil.



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/appear/revealers.rb', line 143

def tmux_client_for_tree(tree)
  tmux_server = tree.find {|p| p.name == 'tmux'}

  # join processes on tmux panes by PID.
  proc_and_panes = Util::Join.join(:pid, services.tmux.panes, tree)

  # Join the list of tmux clients with process_and_pid on :session.
  # In tmux, every pane is addressed by session_name:window_index:pane_index.
  # This gives us back a list of all the clients that have a pane that
  # contains a process in our given process tree.
  proc_and_clients = Util::Join.join(:session, services.tmux.clients, proc_and_panes)

  # there *should* be only one of these, unless there are two clients
  # connected to the same tmux session. In that case we just choose one
  # of the clients.
  client = proc_and_clients.last

  # at this point it's possible that none of our tree's processes are
  # alive inside tmux.
  return nil unless client

  tty_of_client = client[:tty]
  connections_to_tty = services.lsof.lsofs(
    [tty_of_client],
    :pids => services.processes.pgrep('tmux')
  )[tty_of_client]

  client_connection = connections_to_tty.find do |conn|
    (conn.command_name =~ /^tmux/) && (conn.pid != tmux_server.pid)
  end

  if client_connection
    log("tmux_client_for_tree: found client pid=#{client_connection.pid} for tree pid=#{tree.first.pid}")
    return client_connection.pid
  end
end