color tab support
This commit is contained in:
parent
f206847274
commit
81a8462103
|
@ -11,4 +11,6 @@ Gem::Specification.new do |s|
|
|||
s.has_rdoc = true
|
||||
|
||||
s.add_development_dependency 'rspec', '~> 2.6.0'
|
||||
s.add_development_dependency 'fakefs'
|
||||
s.add_development_dependency 'mocha'
|
||||
end
|
||||
|
|
|
@ -67,15 +67,18 @@
|
|||
# first_tab.select # brings first tab back to focus
|
||||
# end
|
||||
|
||||
require 'tempfile'
|
||||
|
||||
# The ItermWindow class models an iTerm terminal window and allows for full control via Ruby commands.
|
||||
class ItermWindow
|
||||
attr_reader :tab_color_files
|
||||
|
||||
# While you can directly use ItermWindow.new, using either ItermWindow.open or
|
||||
# ItermWindow.current is the preferred method.
|
||||
def initialize
|
||||
@buffer = []
|
||||
@tabs = {}
|
||||
@tab_color_files = []
|
||||
end
|
||||
|
||||
# Creates a new terminal window, runs the block on it
|
||||
|
@ -105,16 +108,18 @@ class ItermWindow
|
|||
|
||||
# Outputs a single line of Applescript code
|
||||
def output(command)
|
||||
@buffer << command.gsub(/'/, '"')
|
||||
@buffer << command.gsub("'", '"').gsub('\\', '\\\\\\')
|
||||
end
|
||||
|
||||
def concatenated_buffer
|
||||
@buffer.join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Outputs @buffer to the command line as an osascript function
|
||||
def send_output
|
||||
buffer_str = @buffer.map {|line| "-e '#{line}'"}.join(' ')
|
||||
shell_out "osascript #{buffer_str}"
|
||||
shell_out
|
||||
end
|
||||
|
||||
# Initializes the terminal window
|
||||
|
@ -137,16 +142,18 @@ class ItermWindow
|
|||
create_tab_convenience_method(name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_tab_convenience_method(name)
|
||||
(class << self; self; end).send(:define_method, name) do
|
||||
@tabs[name]
|
||||
end
|
||||
end
|
||||
|
||||
def shell_out(str)
|
||||
%x{str}
|
||||
def shell_out
|
||||
Tempfile.open('iterm') do |f|
|
||||
f.print concatenated_buffer
|
||||
f.close
|
||||
system %{osascript #{f.path}}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -194,6 +201,15 @@ class ItermWindow
|
|||
end
|
||||
end
|
||||
|
||||
# Sets the title of the tab (ie the text on the iTerm tab itself)
|
||||
def tab_color(color)
|
||||
if @currently_executing_block
|
||||
output "write text 'cat #{file = create_tab_color_file(color)} && rm #{file}'"
|
||||
else
|
||||
execute_block { tab_color(color) }
|
||||
end
|
||||
end
|
||||
|
||||
# Runs a block on this tab with proper opening and closing statements
|
||||
def execute_block(&block)
|
||||
@currently_executing_block = true
|
||||
|
@ -203,13 +219,34 @@ class ItermWindow
|
|||
@currently_executing_block = false
|
||||
end
|
||||
|
||||
def self.create_tab_color(color)
|
||||
raise ArgumentError.new("bad hex color: #{color}") if color.downcase[%r{[^a-f0-9]}] || !([ 3, 6 ].include?(color.length))
|
||||
%w{red green blue}.zip(color.scan(
|
||||
(case color.length
|
||||
when 3
|
||||
/./
|
||||
when 6
|
||||
/../
|
||||
end)
|
||||
).collect { |part|
|
||||
part += part if part.length == 1
|
||||
part.hex
|
||||
}).collect do |color, brightness|
|
||||
"\033]6;1;bg;#{color};brightness;#{brightness}\a"
|
||||
end.join
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def output(command)
|
||||
@window.output command
|
||||
end
|
||||
|
||||
|
||||
def create_tab_color_file(color)
|
||||
file = Tempfile.open('iterm').path + '.tc'
|
||||
File.open(file, 'wb') { |f| f.puts self.class.create_tab_color(color) }
|
||||
@window.tab_color_files << file
|
||||
file
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,12 +4,13 @@ require 'iterm_window'
|
|||
describe ItermWindow do
|
||||
before(:each) do
|
||||
@window = ItermWindow.new
|
||||
Kernel.stubs(:system)
|
||||
end
|
||||
|
||||
describe ".current" do
|
||||
it "should instantiate the current window and run the block" do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
@window.should_receive(:run).with(:current)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
@window.expects(:run).with(:current)
|
||||
ItermWindow.current do
|
||||
|
||||
end
|
||||
|
@ -18,8 +19,8 @@ describe ItermWindow do
|
|||
|
||||
describe ".open" do
|
||||
it "should instantiate a new window and run the block" do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
@window.should_receive(:run).with(:new)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
@window.expects(:run).with(:new)
|
||||
ItermWindow.open do
|
||||
|
||||
end
|
||||
|
@ -28,12 +29,25 @@ describe ItermWindow do
|
|||
|
||||
describe "opening a tab (example 1)" do
|
||||
before(:each) do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
end
|
||||
|
||||
it "should generate and run the right Applescript" do
|
||||
desired = "osascript -e 'tell application \"iTerm\"' -e 'activate' -e 'set myterm to (make new terminal)' -e 'tell myterm' -e 'launch session \"Default Session\"' -e 'set my_tab_tty to the tty of the last session' -e 'tell session id my_tab_tty' -e 'write text \"cd ~/projects/my_project/trunk\"' -e 'write text \"mate ./\"' -e 'end tell' -e 'end tell' -e 'end tell'"
|
||||
@window.should_receive(:shell_out).with(desired)
|
||||
desired = (<<-CMD).strip
|
||||
tell application "iTerm"
|
||||
activate
|
||||
set myterm to (make new terminal)
|
||||
tell myterm
|
||||
launch session "Default Session"
|
||||
set my_tab_tty to the tty of the last session
|
||||
tell session id my_tab_tty
|
||||
write text \"cd ~/projects/my_project/trunk\"
|
||||
write text \"mate ./\"
|
||||
end tell
|
||||
end tell
|
||||
end tell
|
||||
CMD
|
||||
@window.expects(:shell_out)
|
||||
|
||||
ItermWindow.open do
|
||||
open_tab :my_tab do
|
||||
|
@ -41,17 +55,47 @@ describe ItermWindow do
|
|||
write "mate ./"
|
||||
end
|
||||
end
|
||||
|
||||
@window.concatenated_buffer.should == desired
|
||||
end
|
||||
end
|
||||
|
||||
describe "open multiple tabs (example 2)" do
|
||||
before(:each) do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
end
|
||||
|
||||
it "should generate and run the right Applescript" do
|
||||
desired = "osascript -e 'tell application \"iTerm\"' -e 'activate' -e 'set myterm to first terminal' -e 'tell myterm' -e 'launch session \"Default Session\"' -e 'set project_dir_tty to the tty of the last session' -e 'tell session id project_dir_tty' -e 'write text \"cd ~/projects/my_project/trunk\"' -e 'write text \"mate ./\"' -e 'set name to \"MyProject Dir\"' -e 'end tell' -e 'launch session \"Default Session\"' -e 'set server_tty to the tty of the last session' -e 'tell session id server_tty' -e 'write text \"cd ~/projects/my_project/trunk\"' -e 'write text \"script/server -p 3005\"' -e 'set name to \"MyProject Server\"' -e 'end tell' -e 'launch session \"Default Session\"' -e 'set console_tty to the tty of the last session' -e 'tell session id console_tty' -e 'write text \"cd ~/projects/my_project/trunk\"' -e 'write text \"script/console\"' -e 'set name to \"MyProject Console\"' -e 'end tell' -e 'end tell' -e 'end tell'"
|
||||
@window.should_receive(:shell_out).with(desired)
|
||||
desired = (<<-CMD).strip
|
||||
tell application "iTerm"
|
||||
activate
|
||||
set myterm to first terminal
|
||||
tell myterm
|
||||
launch session "Default Session"
|
||||
set project_dir_tty to the tty of the last session
|
||||
tell session id project_dir_tty
|
||||
write text "cd ~/projects/my_project/trunk"
|
||||
write text "mate ./"
|
||||
set name to "MyProject Dir"
|
||||
end tell
|
||||
launch session "Default Session"
|
||||
set server_tty to the tty of the last session
|
||||
tell session id server_tty
|
||||
write text "cd ~/projects/my_project/trunk"
|
||||
write text "script/server -p 3005"
|
||||
set name to "MyProject Server"
|
||||
end tell
|
||||
launch session "Default Session"
|
||||
set console_tty to the tty of the last session
|
||||
tell session id console_tty
|
||||
write text "cd ~/projects/my_project/trunk"
|
||||
write text "script/console"
|
||||
set name to "MyProject Console"
|
||||
end tell
|
||||
end tell
|
||||
end tell
|
||||
CMD
|
||||
@window.expects(:shell_out)
|
||||
|
||||
ItermWindow.current do
|
||||
open_tab :project_dir do
|
||||
|
@ -72,17 +116,37 @@ describe ItermWindow do
|
|||
set_title "MyProject Console"
|
||||
end
|
||||
end
|
||||
|
||||
@window.concatenated_buffer.should == desired
|
||||
end
|
||||
end
|
||||
|
||||
describe "open tabs using bookmarks (example 3)" do
|
||||
before(:each) do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
end
|
||||
|
||||
it "should generate and run the correct Applescript" do
|
||||
desired = "osascript -e 'tell application \"iTerm\"' -e 'activate' -e 'set myterm to first terminal' -e 'tell myterm' -e 'launch session \"Default Session\"' -e 'set project_dir_tty to the tty of the last session' -e 'tell session id project_dir_tty' -e 'write text \"cd ~/projects/my_project/trunk\"' -e 'write text \"mate ./\"' -e 'end tell' -e 'launch session \"MyProject Server\"' -e 'set server_tty to the tty of the last session' -e 'launch session \"MyProject Console\"' -e 'set console_tty to the tty of the last session' -e 'select session id project_dir_tty' -e 'end tell' -e 'end tell'"
|
||||
@window.should_receive(:shell_out).with(desired)
|
||||
desired = (<<-CMD).strip
|
||||
tell application "iTerm"
|
||||
activate
|
||||
set myterm to first terminal
|
||||
tell myterm
|
||||
launch session "Default Session"
|
||||
set project_dir_tty to the tty of the last session
|
||||
tell session id project_dir_tty
|
||||
write text "cd ~/projects/my_project/trunk"
|
||||
write text "mate ./"
|
||||
end tell
|
||||
launch session "MyProject Server"
|
||||
set server_tty to the tty of the last session
|
||||
launch session "MyProject Console"
|
||||
set console_tty to the tty of the last session
|
||||
select session id project_dir_tty
|
||||
end tell
|
||||
end tell
|
||||
CMD
|
||||
@window.stubs(:shell_out)
|
||||
|
||||
ItermWindow.current do
|
||||
open_tab :project_dir do
|
||||
|
@ -95,17 +159,38 @@ describe ItermWindow do
|
|||
|
||||
project_dir.select
|
||||
end
|
||||
|
||||
@window.concatenated_buffer.should == desired
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "switching between tabs (example 4)" do
|
||||
before(:each) do
|
||||
ItermWindow.should_receive(:new).and_return(@window)
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
end
|
||||
|
||||
it "should generate and run the correct Applescript" do
|
||||
desired = "osascript -e 'tell application \"iTerm\"' -e 'activate' -e 'set myterm to (make new terminal)' -e 'tell myterm' -e 'launch session \"Default Session\"' -e 'set first_tab_tty to the tty of the last session' -e 'launch session \"Default Session\"' -e 'set second_tab_tty to the tty of the last session' -e 'tell session id first_tab_tty' -e 'write text \"cd ~/projects\"' -e 'write text \"ls\"' -e 'end tell' -e 'tell session id second_tab_tty' -e 'write text \"echo \"hello there!\"\"' -e 'end tell' -e 'select session id first_tab_tty' -e 'end tell' -e 'end tell'"
|
||||
@window.should_receive(:shell_out).with(desired)
|
||||
desired = (<<-CMD).strip
|
||||
tell application "iTerm"
|
||||
activate
|
||||
set myterm to (make new terminal)
|
||||
tell myterm
|
||||
launch session "Default Session"
|
||||
set first_tab_tty to the tty of the last session
|
||||
launch session "Default Session"
|
||||
set second_tab_tty to the tty of the last session
|
||||
tell session id first_tab_tty
|
||||
write text "cd ~/projects"
|
||||
write text "ls"
|
||||
end tell
|
||||
tell session id second_tab_tty
|
||||
write text "echo "hello there!""
|
||||
end tell
|
||||
select session id first_tab_tty
|
||||
end tell
|
||||
end tell
|
||||
CMD
|
||||
@window.expects(:shell_out)
|
||||
|
||||
ItermWindow.open do
|
||||
open_tab :first_tab
|
||||
|
@ -117,6 +202,61 @@ describe ItermWindow do
|
|||
second_tab.write "echo 'hello there!'"
|
||||
first_tab.select
|
||||
end
|
||||
|
||||
@window.concatenated_buffer.should == desired
|
||||
end
|
||||
end
|
||||
|
||||
describe 'tab color' do
|
||||
before(:each) do
|
||||
ItermWindow.expects(:new).returns(@window)
|
||||
end
|
||||
|
||||
it "should generate and run the correct Applescript" do
|
||||
@window.expects(:shell_out)
|
||||
ItermWindow::Tab.any_instance.expects(:create_tab_color_file).with("FF00AA")
|
||||
|
||||
ItermWindow.open do
|
||||
open_tab :first_tab do
|
||||
tab_color "FF00AA"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".create_tab_color" do
|
||||
subject { ItermWindow::Tab.create_tab_color(color) }
|
||||
|
||||
context 'bad hex color' do
|
||||
[ "whatever", "F00F" ].each do |bad|
|
||||
context bad do
|
||||
let(:color) { bad }
|
||||
|
||||
it 'should raise an exception on bad hex color' do
|
||||
expect { subject }.to raise_error(ArgumentError, /bad hex color/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'long hex color' do
|
||||
let(:color) { "FF00AA" }
|
||||
|
||||
it 'should create an escape sequence to execute to change a tab color' do
|
||||
subject.should match(/red;brightness;255/)
|
||||
subject.should match(/green;brightness;0/)
|
||||
subject.should match(/blue;brightness;170/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'short hex color' do
|
||||
let(:color) { "F0A" }
|
||||
|
||||
it 'should create an escape sequence to execute to change a tab color' do
|
||||
subject.should match(/red;brightness;255/)
|
||||
subject.should match(/green;brightness;0/)
|
||||
subject.should match(/blue;brightness;170/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
RSpec.configure do |c|
|
||||
c.mock_with :mocha
|
||||
end
|
||||
|
Loading…
Reference in New Issue