iTermWindow is now available as a gem
This commit is contained in:
parent
425765fcc7
commit
67a52e5f21
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2009 Chris Powers, The Killswitch Collective
|
||||||
|
http://killswitchcollective.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -14,6 +14,9 @@ the tab name as an ItermWindow method.
|
||||||
|
|
||||||
== EXAMPLE - Open a new iTerm window, cd to a project and open it in TextMate
|
== EXAMPLE - Open a new iTerm window, cd to a project and open it in TextMate
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
require 'chrisjpowers-iterm_window'
|
||||||
|
|
||||||
ItermWindow.open do
|
ItermWindow.open do
|
||||||
open_tab :my_tab do
|
open_tab :my_tab do
|
||||||
write "cd ~/projects/my_project/trunk"
|
write "cd ~/projects/my_project/trunk"
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = 'itermwindow'
|
||||||
|
s.version = '0.3'
|
||||||
|
s.author = 'Chris Powers'
|
||||||
|
s.date = "2009-02-20"
|
||||||
|
s.homepage = 'http://killswitchcollective.com'
|
||||||
|
s.email = 'chris@killswitchcollective.com'
|
||||||
|
s.summary = 'The ItermWindow class models an iTerm terminal window and allows for full control via Ruby commands.'
|
||||||
|
s.files = ['README.rdoc', 'LICENSE', 'lib/iterm_window.rb']
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
s.has_rdoc = true
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = 'itermwindow'
|
||||||
|
s.version = '0.3'
|
||||||
|
s.author = 'Chris Powers'
|
||||||
|
s.date = "2009-02-20"
|
||||||
|
s.homepage = 'http://killswitchcollective.com'
|
||||||
|
s.email = 'chris@killswitchcollective.com'
|
||||||
|
s.summary = 'The ItermWindow class models an iTerm terminal window and allows for full control via Ruby commands.'
|
||||||
|
s.files = ['README.rdoc', 'LICENSE', 'lib/iterm_window.rb']
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
s.has_rdoc = true
|
||||||
|
end
|
|
@ -0,0 +1,231 @@
|
||||||
|
# Developed March 17, 2008 by Chris Powers, Killswitch Collective http://killswitchcollective.com
|
||||||
|
#
|
||||||
|
# The ItermWindow class models an iTerm terminal window and allows for full control via Ruby commands.
|
||||||
|
# Under the hood, this class is a wrapper of iTerm's Applescript scripting API. Methods are used to
|
||||||
|
# generate Applescript code which is run as an <tt>osascript</tt> command when the ItermWindow initialization
|
||||||
|
# block is closed.
|
||||||
|
#
|
||||||
|
# ItermWindow::Tab models a tab (session) in an iTerm terminal window and allows for it to be controlled by Ruby.
|
||||||
|
# These tabs can be created with either the ItermWindow#open_bookmark method or the ItermWindow#open_tab
|
||||||
|
# method. Each tab is given a name (symbol) by which it can be accessed later as a method of ItermWindow.
|
||||||
|
#
|
||||||
|
# EXAMPLE - Open a new iTerm window, cd to a project and open it in TextMate
|
||||||
|
#
|
||||||
|
# ItermWindow.open do
|
||||||
|
# open_tab :my_tab do
|
||||||
|
# write "cd ~/projects/my_project/trunk"
|
||||||
|
# write "mate ./"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# EXAMPLE - Use the current iTerm window, cd to a project and open in TextMate, launch the server and the console and title them
|
||||||
|
#
|
||||||
|
# ItermWindow.current do
|
||||||
|
# open_tab :project_dir do
|
||||||
|
# write "cd ~/projects/my_project/trunk"
|
||||||
|
# write "mate ./"
|
||||||
|
# set_title "MyProject Dir"
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# window.open_tab :server do
|
||||||
|
# write "cd ~/projects/my_project/trunk"
|
||||||
|
# write "script/server -p 3005"
|
||||||
|
# set_title "MyProject Server"
|
||||||
|
# end
|
||||||
|
# window.open_tab :console do
|
||||||
|
# write "cd ~/projects/my_project/trunk"
|
||||||
|
# write "script/console"
|
||||||
|
# set_title "MyProject Console"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# EXAMPLE - Same thing, but use bookmarks that were made for the server and console. Also, switch focus back to project dir.
|
||||||
|
#
|
||||||
|
# ItermWindow.current do
|
||||||
|
# open_tab :project_dir do
|
||||||
|
# write "cd ~/projects/my_project/trunk"
|
||||||
|
# write "mate ./"
|
||||||
|
# end
|
||||||
|
# open_bookmark :server, 'MyProject Server'
|
||||||
|
# open_bookmark :console, 'MyProject Console'
|
||||||
|
# project_dir.select
|
||||||
|
#
|
||||||
|
# EXAMPLE - Arbitrarily open two tabs, switch between them and run methods/blocks with Tab#select method and Tab#write directly
|
||||||
|
#
|
||||||
|
# ItermWindow.open do
|
||||||
|
# open_tab :first_tab
|
||||||
|
# open_tab :second_tab
|
||||||
|
# first_tab.select do
|
||||||
|
# write 'cd ~/projects'
|
||||||
|
# write 'ls'
|
||||||
|
# end
|
||||||
|
# second_tab.write "echo 'hello there!'"
|
||||||
|
# first_tab.select # brings first tab back to focus
|
||||||
|
# end
|
||||||
|
|
||||||
|
|
||||||
|
# The ItermWindow class models an iTerm terminal window and allows for full control via Ruby commands.
|
||||||
|
class ItermWindow
|
||||||
|
|
||||||
|
# While you can directly use ItermWindow.new, using either ItermWindow.open or
|
||||||
|
# ItermWindow.current is the preferred method.
|
||||||
|
def initialize(window_type = :new, &block)
|
||||||
|
@buffer = []
|
||||||
|
@tabs = {}
|
||||||
|
run_commands window_type, &block
|
||||||
|
send_output
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a new terminal window, runs the block on it
|
||||||
|
def self.open(&block)
|
||||||
|
new(:new, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Selects the first terminal window, runs the block on it
|
||||||
|
def self.current(&block)
|
||||||
|
new(:current, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a new tab from a bookmark, runs the block on it
|
||||||
|
def open_bookmark(name, bookmark, &block)
|
||||||
|
create_tab(name, bookmark, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a new tab from 'Default Session', runs the block on it
|
||||||
|
def open_tab(name, &block)
|
||||||
|
create_tab(name, 'Default Session', &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Outputs a single line of Applescript code
|
||||||
|
def output(command)
|
||||||
|
@buffer << command.gsub(/'/, '"')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Outputs @buffer to the command line as an osascript function
|
||||||
|
def send_output
|
||||||
|
buffer_str = @buffer.map {|line| "-e '#{line}'"}.join(' ')
|
||||||
|
`osascript #{buffer_str}`
|
||||||
|
# puts buffer_str
|
||||||
|
end
|
||||||
|
|
||||||
|
# Initializes the terminal window
|
||||||
|
def run_commands(window_type, &block)
|
||||||
|
window_types = {:new => '(make new terminal)', :current => 'first terminal'}
|
||||||
|
raise ArgumentError, "ItermWindow#run_commands should be passed :new or :current." unless window_types.keys.include? window_type
|
||||||
|
output "tell application 'iTerm'"
|
||||||
|
output "activate"
|
||||||
|
output "set myterm to #{window_types[window_type]}"
|
||||||
|
output "tell myterm"
|
||||||
|
self.instance_eval(&block) if block_given?
|
||||||
|
output "end tell"
|
||||||
|
output "end tell"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Creates a new Tab object, either default or from a bookmark
|
||||||
|
def create_tab(name, bookmark=nil, &block)
|
||||||
|
@tabs[name] = Tab.new(self, name, bookmark, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Access the tabs by their names
|
||||||
|
def method_missing(method_name, *args, &block)
|
||||||
|
@tabs[method_name] || super
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The Tab class models a tab (session) in an iTerm terminal window and allows for it to be controlled by Ruby.
|
||||||
|
class Tab
|
||||||
|
|
||||||
|
attr_reader :name
|
||||||
|
attr_reader :bookmark
|
||||||
|
|
||||||
|
def initialize(window, name, bookmark = nil, &block)
|
||||||
|
@name = name
|
||||||
|
@bookmark = bookmark
|
||||||
|
@window = window
|
||||||
|
@currently_executing_block = false
|
||||||
|
output "launch session '#{@bookmark}'"
|
||||||
|
# store tty id for later access
|
||||||
|
output "set #{name}_tty to the tty of the last session"
|
||||||
|
execute_block &block if block_given?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Brings a tab into focus, runs a block on it if passed
|
||||||
|
def select(&block)
|
||||||
|
if block_given?
|
||||||
|
execute_block &block
|
||||||
|
else
|
||||||
|
output "select session id #{name}_tty"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Writes a command into the terminal tab
|
||||||
|
def write(command)
|
||||||
|
if @currently_executing_block
|
||||||
|
output "write text '#{command}'"
|
||||||
|
else
|
||||||
|
execute_block { write command }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the title of the tab (ie the text on the iTerm tab itself)
|
||||||
|
def set_title(str)
|
||||||
|
if @currently_executing_block
|
||||||
|
output "set name to '#{str}'"
|
||||||
|
else
|
||||||
|
execute_block { set_title = str }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# These style methods keep crashing iTerm for some reason...
|
||||||
|
|
||||||
|
# # Sets the tab's font color
|
||||||
|
# def set_font_color(str)
|
||||||
|
# if @currently_executing_block
|
||||||
|
# output "set foreground color to '#{str}'"
|
||||||
|
# else
|
||||||
|
# execute_block { set_font_color = str }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # Sets the tab's background color
|
||||||
|
# def set_background_color(str)
|
||||||
|
# if @currently_executing_block
|
||||||
|
# output "set background color to '#{str}'"
|
||||||
|
# else
|
||||||
|
# execute_block { set_bg_color = str }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# alias_method :set_bg_color, :set_background_color
|
||||||
|
#
|
||||||
|
# # Sets the tab's transparency
|
||||||
|
# def set_transparency(float)
|
||||||
|
# if @currently_executing_block
|
||||||
|
# output "set transparency to '#{float}'"
|
||||||
|
# else
|
||||||
|
# execute_block { set_transparency = float }
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# Runs a block on this tab with proper opening and closing statements
|
||||||
|
def execute_block(&block)
|
||||||
|
@currently_executing_block = true
|
||||||
|
output "tell session id #{name}_tty"
|
||||||
|
self.instance_eval(&block)
|
||||||
|
output "end tell"
|
||||||
|
@currently_executing_block = false
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def output(command)
|
||||||
|
@window.output command
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue