class Consular::GnomeTerminal

Consular core for interacting with Gnome Terminal.

Since we don’t have any real API to work with and just send keypresses via XTEST, we don’t have tab references either. Instead we just count tabs and return tab indexes.

Adapted from github.com/ikka/consular-terminator

Constants

VERSION

Public Class Methods

new(path) click to toggle source

Initialize

@param [String] path

path to Termfile.

@api public

Calls superclass method
# File lib/consular/gnome-terminal.rb, line 40
def initialize(path)
  super
  @tabidx = nil
end
valid_system?() click to toggle source

Check to see if current system is valid for this core

@api public

# File lib/consular/gnome-terminal.rb, line 20
def valid_system?
  if (RbConfig::CONFIG['host_os'] =~ /linux/) != nil
    if !(xdotool = `which xdotool`.chomp).empty?
      begin
        return File::Stat.new(xdotool).executable?
      rescue
        return false
      end
    end
  end
  return false
end

Public Instance Methods

execute_command(cmd, options = {}) click to toggle source

Execute the given command in the context of the active window.

@param [String] cmd

The command to execute.

@param [Hash] options

Additional options to pass into appscript for the context.

@example

@osx.execute_command 'ps aux', :in => @tab_object

@api public

# File lib/consular/gnome-terminal.rb, line 156
def execute_command(cmd, options = {})
  run_in_active_gnome_terminal cmd, options
end
execute_window(content, options = {}) click to toggle source

Executes the commands for each designated window. .run_windows will iterate through each of the tabs in sorted order to execute the tabs in the order they were set. The logic follows this:

If the content is for the 'default' window,
then use the current active window and generate the commands.

If the content is for a new window,
then generate a new window and activate the windows.

Otherwise, open a new tab and execute the commands.

@param [Hash] content

The hash contents of the window from the Termfile.

@param [Hash] options

Addional options to pass. You can use:
  :default - Whether this is being run as the default window.

@example

@core.execute_window contents, :default => true
@core.execute_window contents, :default => true

@api public

# File lib/consular/gnome-terminal.rb, line 86
def execute_window(content, options = {})
  window_options = content[:options]
  _contents      = content[:tabs]
  _first_run     = true

  _contents.keys.sort.each do |key|
    _content = _contents[key]
    _options = content[:options]
    _name    = options[:name]

    _tab =
    if _first_run && !options[:default]
      open_window options.merge(window_options)
    else
      key == 'default' ? nil : open_tab(_options)
    end

    _first_run = false
    commands = prepend_befores _content[:commands], _contents[:befores]
    commands = set_title _name, commands
    commands.each { |cmd| execute_command cmd, :in => _tab }
  end

end
open_tab(options = nil) click to toggle source

Opens a new tab and return the last instantiated tab(itself).

@param [Hash] options

Options to further customize the window. You can use:
  :settings -
  :selected -

@return

Returns a refernce to the last instantiated tab of the
window.

@api public

# File lib/consular/gnome-terminal.rb, line 172
def open_tab(options = nil)
  send_keypress(active_gnome_terminal_window, "ctrl+shift+t")
  # FIXME: horribly hacky but can't come up with any way
  # to truly make sure tab has opened.
  sleep 1
end
open_window(options = nil) click to toggle source

Opens a new window and returns its last instantiated tab.(The first ‘tab’ in the window).

@param [Hash] options

Options to further customize the window. You can use:
  :bound        - Set the bounds of the windows
  :visible      - Set whether or not the current window is visible
  :miniaturized - Set whether or not the window is minimized

@return

Returns a refernce to the last instantiated tab of the
window.

@api public

# File lib/consular/gnome-terminal.rb, line 193
def open_window(options = nil)
  windowid_before = active_gnome_terminal_window
  send_keypress(active_gnome_terminal_window, "ctrl+shift+n")
  # wait for the active window to change -> new window opened
  while active_gnome_terminal_window == windowid_before
    sleep 1
  end
  return (@tabidx = 0)
end
prepend_befores(commands, befores = nil) click to toggle source

Prepends the :before commands to the current context’s commands if it exists.

@param [Array<String>] commands

The current tab commands

@param [Array<String>] befores

The current window's :befores

@return [Array<String>]

The current context commands with the :before commands prepended

@api public

# File lib/consular/gnome-terminal.rb, line 136
def prepend_befores(commands, befores = nil)
  unless befores.nil? || befores.empty?
    commands.insert(0, befores).flatten! 
  else
    commands
  end
end
process!() click to toggle source

Method called by runner to execute Termfile.

@api public

# File lib/consular/gnome-terminal.rb, line 55
def process!
  windows = @termfile[:windows]
  default = windows.delete('default')
  execute_window(default, :default => true) unless default[:tabs].empty?
  windows.each_pair { |_, cont| execute_window(cont) }
end
set_title(title, commands) click to toggle source

Prepend a title setting command prior to the other commands.

@param [String] title

The title to set for the context of the commands.

@param [Array<String>] commands

The context of commands to preprend to.

@api public

# File lib/consular/gnome-terminal.rb, line 119
def set_title(title, commands)
  cmd = "PS1=\"$PS1\\[\\e]2;#{title}\\a\\]\""
  title ? commands.insert(0, cmd) : commands
end
setup!() click to toggle source

Method called by runner to Execute Termfile setup.

@api public

# File lib/consular/gnome-terminal.rb, line 48
def setup!
  @termfile[:setup].each { |cmd| execute_command(cmd, :in => active_window) }
end

Private Instance Methods

active_gnome_terminal_window() click to toggle source

Get active gnome-terminal window winid. Gets the active window and returns it if it is a GnomeTerminal window. If it is not a gnome-terminal window, the method gets all gnome-terminal windows and returns the first one. If no gnome-terminal windows exist, aborts.

@api private

# File lib/consular/gnome-terminal.rb, line 227
def active_gnome_terminal_window
  active = xdotool("getactivewindow").chomp
  if not all_gnome_terminal_windows.include? active
    active = all_gnome_terminal_windows.first
  end
  if not active
    abort("No Gnome Terminal windows found")
  end
  return active
end
all_gnome_terminal_windows() click to toggle source

Get window IDs of all gnome-terminal windows.

@api private

# File lib/consular/gnome-terminal.rb, line 241
def all_gnome_terminal_windows
  xdotool("search --onlyvisible --class gnome-terminal").split("\n")
end
run_in_active_gnome_terminal(cmd, options = {}) click to toggle source

Run command with active gnome-terminal

@api private

# File lib/consular/gnome-terminal.rb, line 216
def run_in_active_gnome_terminal(cmd, options = {})
  type_in_window(active_gnome_terminal_window, "#{cmd}\n")
end
send_keypress(winid, keys) click to toggle source

Send keypresses to window winid

@api private

# File lib/consular/gnome-terminal.rb, line 208
def send_keypress(winid, keys)
  xdotool("windowfocus #{winid}")
  xdotool("key #{keys}")
end
type_in_window(winid, text) click to toggle source

Type text in window winid.

@api private

# File lib/consular/gnome-terminal.rb, line 248
def type_in_window(winid, text)
  xdotool("windowfocus #{winid}")
  xdotool("type \"#{text}\"")
end
xdotool(cmd) click to toggle source

Execute xdotool with the given args and return output

@api private

# File lib/consular/gnome-terminal.rb, line 256
def xdotool(cmd)
  IO.popen("xdotool #{cmd}").read
end