terminitor 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -106,6 +106,39 @@ or with a block:
106
106
  end
107
107
 
108
108
 
109
+ ##### Settings #####
110
+
111
+ You can also set settings on each of your tabs and windows. for example, this is possible:
112
+
113
+ Open a tab with terminal settings "Grass"
114
+
115
+ tab "named tab", :settings => "Grass" do
116
+ run "echo 'named tab'"
117
+ run "ls"
118
+ end
119
+
120
+ How about a window with a specific size:
121
+
122
+ window :bounds => [10,20,300,200] do
123
+
124
+ end
125
+
126
+ Currently, the following options are available:
127
+
128
+ __tabs__
129
+
130
+ * :settings - [String] Set the tab to terminal settings
131
+ * :selected - [Boolean] Sets whether the tab is active
132
+ * :miniaturized - [Boolean] Sets whether its miniaturized
133
+ * :visible - [Boolean] Sets whether its visible
134
+
135
+
136
+ __windows__
137
+
138
+ * :bounds - [Array] Sets the bounds
139
+ * :miniaturized - [Boolean] Sets whether its miniaturized
140
+ * :visible - [Boolean] Sets whether its visible
141
+
109
142
  ### Running Terminitor Projects ###
110
143
 
111
144
  Once the project file has been declared to your satisfaction, simply execute any project defined in the `~/.terminitor` directory with:
@@ -167,6 +200,14 @@ In addition, you are in the project folder and you wish to remove the Termfile,
167
200
 
168
201
  This will clear the `Termfile` for the particular project.
169
202
 
203
+ ### Capturing Terminal Settings with Terminitor ###
204
+
205
+ Terminitor has the ability to also capture your terminal setup and settings simply with:
206
+
207
+ $ terminitor edit my_project --capture
208
+
209
+ this will open up a new terminitor project with the captured settings for you to continuing modifying as you see fit.
210
+
170
211
 
171
212
  ### Fetching Github Projects with Terminitor ###
172
213
 
@@ -198,12 +239,17 @@ Limitations
198
239
  #### MacCore ####
199
240
 
200
241
  Right now the Mac OS X Terminal tabs are created by invoking keystrokes which means there are limitations with the terminal being in
201
- focus during execution of these commands. Obviously the long term goal is to solve this issue as well but in all honesty,
202
- this solution works well enough most of the time.
242
+ focus during execution of these commands. Obviously the long term goal is to solve this issue as well but in all honesty, this solution works well enough most of the time.
203
243
 
204
244
  #### Fetching ####
205
245
 
206
- The fetch task only pulls off Github repositories at the moment(which is cool). Later on, this functionality will be extended to non github repository(probably later this week.)
246
+ The fetch task only pulls off Github repositories at the moment. Later on, this functionality will be extended to non github repository.
247
+
248
+
249
+ #### Settings and Captures ####
250
+
251
+ This feature is currently only available in Mac OS X at the moment.
252
+
207
253
 
208
254
  Authors
209
255
  -------
@@ -218,6 +264,7 @@ Thanks to the following people for their contributions so far:
218
264
 
219
265
  * Pat George ([pcg79](http://github.com/pcg79)) for contributing a patch for when a project is not found.
220
266
  * Flavio Castelli ([flavio](http://github.com/flavio)) for contributing Konsole(KDE) core.
267
+ * Alexey Kuleshov ([kulesa](http://github.com/kulesa)) for contributing the terminal settings and terminal settings capture functionality
221
268
 
222
269
  Acknowledgements
223
270
  -----------------
@@ -7,11 +7,15 @@ setup 'echo "setup"'
7
7
  tab "echo 'default'", "echo 'default tab'"
8
8
 
9
9
  window do
10
+
10
11
  tab "echo 'first tab'", "echo 'of window'"
11
12
 
12
- tab "named tab" do
13
+ tab "named tab", :settings => "Ocean" do
13
14
  run "echo 'named tab'"
14
15
  run "ls"
15
16
  end
16
17
  end
17
18
 
19
+ window "autotest" do
20
+ tab "echo 'window and tab without options'"
21
+ end
data/lib/terminitor.rb CHANGED
@@ -1,18 +1,20 @@
1
- require 'rubygems'
2
- require File.expand_path('../terminitor/yaml', __FILE__)
3
- require File.expand_path('../terminitor/dsl', __FILE__)
4
- require File.expand_path('../terminitor/runner', __FILE__)
5
- require File.expand_path('../terminitor/abstract_core', __FILE__)
6
- require File.expand_path('../terminitor/cli', __FILE__)
1
+ require 'terminitor/yaml'
2
+ require 'terminitor/dsl'
3
+ require 'terminitor/runner'
4
+ require 'terminitor/abstract_core'
5
+ require 'terminitor/cli'
6
+ require 'terminitor/abstract_capture'
7
7
 
8
8
  module Terminitor
9
- autoload :Version, File.expand_path('../terminitor/version', __FILE__)
9
+ autoload :Version, 'terminitor/version'
10
10
  case RUBY_PLATFORM.downcase
11
11
  when %r{darwin}
12
12
  require 'appscript'
13
- autoload :MacCore, File.expand_path('../terminitor/cores/mac_core', __FILE__)
13
+ autoload :MacCore, 'terminitor/cores/mac_core'
14
+ autoload :MacCapture, 'terminitor/capture/mac_capture'
14
15
  when %r{linux}
15
16
  require 'dbus'
16
- autoload :KonsoleCore, File.expand_path('../terminitor/cores/konsole_core', __FILE__)
17
+ autoload :KonsoleCore, 'terminitor/cores/konsole_core'
18
+ autoload :KonsoleCapture, 'terminitor/capture/konsole_capture'
17
19
  end
18
20
  end
@@ -0,0 +1,36 @@
1
+ module Terminitor
2
+ # This AbstractCapture defines the basic methods that the Capture class should inherit
3
+ class AbstractCapture
4
+ # Generates .term file from settings of currently opened terminal windows and tabs
5
+ def capture_settings
6
+ capture_windows.inject("") do |config, w|
7
+ config << generate_object_dsl('window', w) do |dsl|
8
+ w[:tabs].each do |t|
9
+ dsl << generate_object_dsl('tab', t, 4)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ # Returns array of settings of currently opened windows,
16
+ # [{:options => {:window_option1 => ... }, :tabs => [{:options => {:tab_option1 => ... }}]}]
17
+ # Needs to be defined for specific platform
18
+ def capture_windows
19
+ end
20
+
21
+ private
22
+
23
+ # Helper method to generate the .term file
24
+ def generate_object_dsl(name, object, ident = 0, &block)
25
+ dsl, margin = "", " "*ident
26
+
27
+ params = object[:options].inject([]) do |params, option|
28
+ params << ":#{option[0]} => #{option[1].inspect}"
29
+ end.join(", ")
30
+
31
+ dsl << margin + "#{name} #{params} do\n"
32
+ yield(dsl) if block_given?
33
+ dsl << margin + "end\n\n"
34
+ end
35
+ end
36
+ end
@@ -18,22 +18,34 @@ module Terminitor
18
18
  # Executes the Termfile
19
19
  def process!
20
20
  term_windows = @termfile[:windows]
21
- run_in_window(term_windows['default'], :default => true) unless term_windows['default'].to_s.empty?
21
+ run_in_window('default', term_windows['default'], :default => true) unless term_windows['default'].to_s.empty?
22
22
  term_windows.delete('default')
23
- term_windows.each_pair { |window_name, tabs| run_in_window(tabs) }
23
+ term_windows.each_pair { |window_name, window_content| run_in_window(window_name, window_content) }
24
24
  end
25
25
 
26
26
  # this command will run commands in the designated window
27
- # run_in_window {:tab1 => ['ls','ok']}
28
- def run_in_window(tabs, options = {})
29
- open_window unless options[:default]
30
- tabs.each_pair do |tab_name,commands|
31
- tab = open_tab
32
- commands.insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
33
- commands.each do |cmd|
27
+ # run_in_window 'window1', {:tab1 => ['ls','ok']}
28
+ def run_in_window(window_name, window_content, options = {})
29
+ window_options = window_content[:options]
30
+ first_tab = true
31
+ window_content[:tabs].each_pair do |tab_name, tab_content|
32
+ # Open window on first 'tab' statement
33
+ # first tab is already opened in the new window, so first tab should be
34
+ # opened as a new tab in default window only
35
+ tab_options = tab_content[:options]
36
+ if first_tab && !options[:default]
37
+ first_tab = false
38
+ window_options = Hash[window_options.to_a + tab_options.to_a] # safe merge
39
+ tab = window_options.empty? ? open_window(nil) : open_window(window_options)
40
+ else
41
+ tab = open_tab(tab_options)
42
+ end
43
+ tab_content[:commands].insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
44
+ tab_content[:commands].each do |cmd|
34
45
  execute_command(cmd, :in => tab)
35
46
  end
36
47
  end
48
+ set_delayed_options
37
49
  end
38
50
 
39
51
  # Loads commands via the termfile and returns them as a hash
@@ -52,7 +64,7 @@ module Terminitor
52
64
  end
53
65
 
54
66
  # Opens a new tab and returns itself.
55
- def open_tab
67
+ def open_tab(options = nil)
56
68
  @working_dir = Dir.pwd # pass in current directory.
57
69
  end
58
70
 
@@ -61,7 +73,13 @@ module Terminitor
61
73
  end
62
74
 
63
75
  # Opens a new window and returns the tab object.
64
- def open_window
76
+ def open_window(options = nil)
77
+ @working_dir = Dir.pwd # pass in current directory.
78
+ end
79
+
80
+ # For options which should be set after all tabs have been opened
81
+ def set_delayed_options
82
+ @working_dir = Dir.pwd # not nil
65
83
  end
66
84
 
67
85
  end
@@ -0,0 +1,8 @@
1
+ module Terminitor
2
+ # Captures terminal windows and tabs for Linux
3
+ class KonsoleCapture < AbstractCapture
4
+ def initialize
5
+ super
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ module Terminitor
2
+ # Captures terminal windows and tabs for Mac OS X
3
+ class MacCapture < AbstractCapture
4
+ include Appscript
5
+
6
+ # Defines what options of window or tab to capture and how
7
+ # just in case we'll need to get other properties
8
+ OPTIONS_MASK = {
9
+ :window => {
10
+ :bounds => "bounds"
11
+ },
12
+ :tab => {
13
+ :settings => "current_settings.name"
14
+ }
15
+ }
16
+
17
+ # Initialize @terminal with Terminal.app, Load the Windows, store the Termfile
18
+ # Terminitor::MacCore.new('/path')
19
+ def initialize
20
+ @terminal = app('Terminal.app')
21
+ end
22
+
23
+ # Returns settings of currently opened windows and tabs.
24
+ def capture_windows
25
+ windows = []
26
+ # for some reason terminal.windows[] contain duplicated elements
27
+ @terminal.windows.get.uniq.each do |window|
28
+ if window.visible.get
29
+ tabs = window.tabs.get.inject([]) do |tabs, tab|
30
+ tabs << {:options => object_options(tab)}
31
+ end
32
+ windows << {:options => object_options(window), :tabs => tabs}
33
+ end
34
+ end
35
+ windows
36
+ end
37
+
38
+ # Returns hash of options of window or tab
39
+ def object_options(object)
40
+ options = {}
41
+ class_ = object.class_.get
42
+ if class_ && OPTIONS_MASK[class_]
43
+ OPTIONS_MASK[class_].each_pair do |option, getter|
44
+ value = object.instance_eval(getter).get
45
+ options[option] = value
46
+ end
47
+ end
48
+ options
49
+ end
50
+ end
51
+ end
@@ -23,7 +23,7 @@ module Terminitor
23
23
  method_option :root, :type => :string, :default => '.', :aliases => '-r'
24
24
  method_option :setup, :type => :boolean, :default => true
25
25
  def fetch(username, project)
26
- fetch_repo username, project, options
26
+ github_repo username, project, options
27
27
  end
28
28
 
29
29
  desc "list", "lists all terminitor scripts"
@@ -43,10 +43,28 @@ module Terminitor
43
43
  method_option :root, :type => :string, :default => '.', :aliases => '-r'
44
44
  method_option :editor, :type => :string, :default => nil, :aliases => '-c'
45
45
  method_option :syntax, :type => :string, :default => 'term', :aliases => '-s'
46
+ method_option :capture, :type => :boolean, :default => false, :aliases => '-g'
46
47
  def edit(project="")
47
48
  syntax = project.empty? ? 'term' : options[:syntax] # force Termfile to use term syntax
48
49
  path = config_path(project, syntax.to_sym)
49
- template "templates/example.#{syntax}.tt", path, :skip => true
50
+ if options[:capture] && !File.exists?(path)
51
+ # capture settings of currently opened windows and tabs
52
+ if syntax == 'term'
53
+ if core = capture_core(RUBY_PLATFORM)
54
+ term = core.new().capture_settings
55
+ (f = File.new(path, "w") << term).close
56
+ else
57
+ say("No suitable core found!")
58
+ return
59
+ end
60
+ else
61
+ say "Terminal settings can be captured only to DSL format."
62
+ return
63
+ end
64
+ else
65
+ # use standard template
66
+ template "templates/example.#{syntax}.tt", path, :skip => true
67
+ end
50
68
  open_in_editor(path,options[:editor])
51
69
  end
52
70
 
@@ -18,7 +18,7 @@ module Terminitor
18
18
  end
19
19
 
20
20
  # Opens a new tab and returns itself.
21
- def open_tab
21
+ def open_tab(options = nil)
22
22
  session_number = @konsole.newSession
23
23
  session_object = @konsole_service.object("/Sessions/#{session_number}")
24
24
  session_object.introspect
@@ -26,7 +26,7 @@ module Terminitor
26
26
  end
27
27
 
28
28
  # Opens a new window and returns the tab object.
29
- def open_window
29
+ def open_window(options = nil)
30
30
  session_number = @konsole.currentSession
31
31
  session_object = @konsole_service.object("/Sessions/#{session_number}")
32
32
  session_object.introspect
@@ -4,12 +4,18 @@ module Terminitor
4
4
  class MacCore < AbstractCore
5
5
  include Appscript
6
6
 
7
+ ALLOWED_OPTIONS = {
8
+ :window => [:bounds, :visible, :miniaturized],
9
+ :tab => [:settings, :selected, :miniaturized, :visible]
10
+ }
11
+
7
12
  # Initialize @terminal with Terminal.app, Load the Windows, store the Termfile
8
13
  # Terminitor::MacCore.new('/path')
9
14
  def initialize(path)
10
15
  super
11
16
  @terminal = app('Terminal')
12
17
  @windows = @terminal.windows
18
+ @delayed_options = []
13
19
  end
14
20
 
15
21
  # executes the given command via appscript
@@ -19,15 +25,21 @@ module Terminitor
19
25
  end
20
26
 
21
27
  # Opens a new tab and returns itself.
22
- def open_tab
23
- super
28
+ def open_tab(options = nil)
24
29
  terminal_process.keystroke("t", :using => :command_down)
30
+ set_options(return_last_tab, options) if options
25
31
  return_last_tab
26
32
  end
27
-
28
- # Opens A New Window and returns the tab object.
29
- def open_window
33
+
34
+ # Opens A New Window, applies settings to the first tab and returns the tab object.
35
+ def open_window(options = nil)
30
36
  terminal_process.keystroke("n", :using => :command_down)
37
+ # Options of the first tab must be set before window options,
38
+ # because change of the first tab options causes change of window size
39
+ if options
40
+ set_options(return_last_tab, allowed_options(:tab, options))
41
+ set_options(active_window, allowed_options(:window, options))
42
+ end
31
43
  return_last_tab
32
44
  end
33
45
 
@@ -52,6 +64,42 @@ module Terminitor
52
64
  window.properties_.get[:frontmost] rescue false
53
65
  end
54
66
  end
67
+
68
+ # Sets options of the given object
69
+ def set_options(object, options = {})
70
+ options.each_pair do |option, value|
71
+ case option
72
+ when :settings # works for windows and tabs, for example :settings => "Grass"
73
+ begin
74
+ object.current_settings.set(@terminal.settings_sets[value])
75
+ rescue Appscript::CommandError => e
76
+ puts "Error: invalid settings set '#{value}'"
77
+ end
78
+ when :bounds # works only for windows, for example :bounds => [10,20,300,200]
79
+ # the only working sequence to restore window size and position!
80
+ object.bounds.set(value)
81
+ object.frame.set(value)
82
+ object.position.set(value)
83
+ when :selected # works for tabs, for example tab :active => true
84
+ delayed_option(option, value, object)
85
+ else # trying to apply any other option
86
+ begin
87
+ object.instance_eval(option.to_s).set(value)
88
+ rescue Appscript::CommandError => e
89
+ puts "Error setting '#{option} = #{value}' on #{object.inspect}"
90
+ puts e.message
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Apply delayed options and remove them from the queue
97
+ def set_delayed_options
98
+ @delayed_options.length.times do
99
+ option = @delayed_options.shift
100
+ option[:object].instance_eval(option[:option]).set(option[:value])
101
+ end
102
+ end
55
103
 
56
104
  private
57
105
 
@@ -75,5 +123,18 @@ module Terminitor
75
123
  window.custom_title.set(title)
76
124
  end
77
125
 
126
+ # selects options allowed for window or tab
127
+ def allowed_options(object_type, options)
128
+ Hash[ options.select {|option, value| ALLOWED_OPTIONS[object_type].include?(option) }]
129
+ end
130
+
131
+ # Add option to the list of delayed options
132
+ def delayed_option(option, value, object)
133
+ @delayed_options << {
134
+ :option => option.to_s,
135
+ :value => value,
136
+ :object => object
137
+ }
138
+ end
78
139
  end
79
140
  end
@@ -26,10 +26,15 @@ module Terminitor
26
26
  end
27
27
 
28
28
  # sets command context to be run inside a specific window
29
- # window('new window') { tab('ls','gitx') }
30
- def window(name = nil, &block)
31
- window_tabs = @windows[name || "window#{@windows.keys.size}"] = {}
32
- @_context, @_old_context = window_tabs, @_context
29
+ # window(:name => 'new window', :size => [80,30], :position => [9, 100]) { tab('ls','gitx') }
30
+ # window { tab('ls', 'gitx') }
31
+ def window(name =nil, options = nil, &block)
32
+ options ||= {}
33
+ options, name = name, nil if name.is_a?(Hash)
34
+ window_name = name || "window#{@windows.keys.size}"
35
+ window_contents = @windows[window_name] = {:tabs => {}}
36
+ window_contents[:options] = options unless options.empty?
37
+ @_context, @_old_context = window_contents[:tabs], @_context
33
38
  instance_eval(&block)
34
39
  @_context = @_old_context
35
40
  end
@@ -41,17 +46,20 @@ module Terminitor
41
46
  end
42
47
 
43
48
  # sets command context to be run inside specific tab
44
- # tab('new tab') { run 'mate .' }
49
+ # tab(:name => 'new tab', :settings => 'Grass') { run 'mate .' }
45
50
  # tab 'ls', 'gitx'
46
- def tab(name= nil, *commands, &block)
51
+ def tab(name = nil, options = nil, *commands, &block)
52
+ options ||= {}
47
53
  if block_given?
48
- tab_tasks = @_context[name || "tab#{@_context.keys.size}"] = []
49
- @_context, @_old_context = tab_tasks, @_context
54
+ options, name = name, nil if name.is_a?(Hash)
55
+ tab_name = name || "tab#{@_context.keys.size}"
56
+ tab_contents = @_context[tab_name] = {:commands => []}
57
+ tab_contents[:options] = options unless options.empty?
58
+ @_context, @_old_context = tab_contents[:commands], @_context
50
59
  instance_eval(&block)
51
60
  @_context = @_old_context
52
61
  else
53
- tab_tasks = @_context["tab#{@_context.keys.size}"] = []
54
- tab_tasks.concat([name] + commands)
62
+ tab_tasks = @_context["tab#{@_context.keys.size}"] = { :commands => [name] + [options] +commands}
55
63
  end
56
64
  end
57
65
 
@@ -60,7 +68,6 @@ module Terminitor
60
68
  { :setup => @setup, :windows => @windows }
61
69
  end
62
70
 
63
-
64
71
  private
65
72
 
66
73
  #
@@ -11,6 +11,15 @@ module Terminitor
11
11
  else nil
12
12
  end
13
13
  end
14
+
15
+ # Defines how to capture terminal settings on the specified platform
16
+ def capture_core(platform)
17
+ core = case platform.downcase
18
+ when %r{darwin} then Terminitor::MacCapture
19
+ when %r{linux} then Terminitor::KonsoleCapture # TODO check for gnome and others
20
+ else nil
21
+ end
22
+ end
14
23
 
15
24
  # Execute the core with the given method.
16
25
  # execute_core :process!, 'project'
@@ -80,7 +89,7 @@ module Terminitor
80
89
  # This will clone a repo in the current directory.
81
90
  # It will first try to clone via ssh(read/write),
82
91
  # if not fall back to git-read only, else, fail.
83
- def clone_repo(username, project)
92
+ def github_clone(username, project)
84
93
  github = `which github`
85
94
  return false if github.empty?
86
95
  command = "github clone #{username} #{project}"
@@ -89,8 +98,8 @@ module Terminitor
89
98
 
90
99
  # Fetch the git repo and run the setup block
91
100
  # fetch_repo 'achiu', 'terminitor', :setup => true
92
- def fetch_repo(username, project, options ={})
93
- if clone_repo(username, project)
101
+ def github_repo(username, project, options ={})
102
+ if github_clone(username, project)
94
103
  path = File.join(Dir.pwd, project)
95
104
  FileUtils.cd(path)
96
105
  invoke(:setup, []) if options[:setup]
@@ -1,3 +1,3 @@
1
1
  module Terminitor
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../teststrap', __FILE__)
2
+
3
+ context "AbstractCapture" do
4
+ context "capture_settings" do
5
+ setup do
6
+ @capture = Terminitor::AbstractCapture.new()
7
+ any_instance_of(Terminitor::AbstractCapture) do |core|
8
+ stub(core).capture_windows { [
9
+ {:options => {:size => [10,20], :name => "main window"},
10
+ :tabs => [
11
+ {:options => {:settings => "Grass"}}
12
+ ]},
13
+ {:options => {:size => [14,30], :name => "another window"},
14
+ :tabs => [{:options => {:settings => "Yello"}}]}
15
+ ] }
16
+ end
17
+ end
18
+
19
+ setup { @capture.capture_settings() }
20
+ asserts_topic.equivalent_to <<-OUTPUT
21
+ window :size => [10, 20], :name => "main window" do
22
+ tab :settings => "Grass" do
23
+ end
24
+
25
+ end
26
+
27
+ window :size => [14, 30], :name => "another window" do
28
+ tab :settings => "Yello" do
29
+ end
30
+
31
+ end
32
+
33
+ OUTPUT
34
+
35
+ end
36
+ end
@@ -20,57 +20,90 @@ context "AbstractCore" do
20
20
  context "without default" do
21
21
  setup do
22
22
  any_instance_of(Terminitor::AbstractCore) do |core|
23
- stub(core).load_termfile('/path/to') { {:windows => {'tab1' => ['ls', 'ok'], 'default' => [] } } }
23
+ stub(core).load_termfile('/path/to') do
24
+ {:windows => {'window1' => {:tabs => {'tab1' => ['ls', 'ok']}}, 'default' => [] }}
25
+ end
24
26
  end
25
27
  end
26
28
  setup { @core = Terminitor::AbstractCore.new('/path/to') }
27
- setup { mock(@core).run_in_window(['ls', 'ok']) }
29
+ setup { mock(@core).run_in_window('window1', {:tabs => {'tab1' => ['ls', 'ok']}}) }
28
30
  asserts("ok") { @core.process! }
29
31
  end
30
32
 
31
33
  context "with default" do
32
34
  setup do
33
35
  any_instance_of(Terminitor::AbstractCore) do |core|
34
- stub(core).load_termfile('/path/to') { {:windows => {'tab1' => ['ls', 'ok'], 'default' => ['echo'] } } }
36
+ stub(core).load_termfile('/path/to') do
37
+ {:windows => {'window1' => {:tabs => {'tab1' => ['ls', 'ok']} },
38
+ 'default' => {:tabs => {'tab0' => ['echo']} }
39
+ }
40
+ }
41
+ end
35
42
  end
36
43
  end
37
44
  setup { @core = Terminitor::AbstractCore.new('/path/to') }
38
- setup { mock(@core).run_in_window(['echo'], :default => true) }
39
- setup { mock(@core).run_in_window(['ls', 'ok']) }
45
+ setup { mock(@core).run_in_window('default',{:tabs => {'tab0'=>['echo']}}, :default => true) }
46
+ setup { mock(@core).run_in_window('window1', {:tabs => {'tab1' => ['ls', 'ok']}}) }
40
47
  asserts("ok") { @core.process! }
41
48
  end
42
49
 
43
50
  end
44
51
 
45
52
  context "run_in_window" do
46
- setup do
47
- any_instance_of(Terminitor::AbstractCore) do |core|
48
- stub(core).load_termfile('/path/to') { true }
53
+ context "without options" do
54
+ setup do
55
+ any_instance_of(Terminitor::AbstractCore) do |core|
56
+ stub(core).load_termfile('/path/to') { {:windows => {'window1' => {:tabs => {'tab1' => {:commands => ['ls', 'ok']}, 'tab2' => {:commands => ['ps']}}}}} }
57
+ end
58
+ @core = Terminitor::AbstractCore.new('/path/to')
49
59
  end
50
- @core = Terminitor::AbstractCore.new('/path/to')
51
- end
52
60
 
53
- context "with default" do
54
- setup { mock(@core).open_window { true } }
55
- setup { mock(@core).open_tab { true } }
56
- setup { mock(@core).execute_command('ls', :in => true) }
57
- setup { mock(@core).execute_command('ok', :in => true) }
58
- asserts("ok") { @core.run_in_window('tab' => ['ls','ok']) }
59
- end
60
-
61
- context "without default" do
62
- setup { mock(@core).open_tab { true } }
63
- setup { mock(@core).execute_command('ls', :in => true) }
64
- setup { mock(@core).execute_command('ok', :in => true) }
65
- asserts("ok") { @core.run_in_window({'tab' => ['ls','ok']}, :default => true) }
66
- end
61
+ context "without default" do
62
+ setup { mock(@core).open_window(nil) { "first" } }
63
+ setup { mock(@core).open_tab(nil) { "second" } }
64
+ setup { mock(@core).set_delayed_options { true } }
65
+ setup { mock(@core).execute_command('ls', :in => "first") }
66
+ setup { mock(@core).execute_command('ok', :in => "first") }
67
+ setup { mock(@core).execute_command('ps', :in => "second") }
68
+ asserts("ok") { @core.process! }
69
+ end
67
70
 
71
+ context "with default" do
72
+ setup { mock(@core).open_tab(nil) { true } }
73
+ setup { mock(@core).execute_command('echo', :in => true) }
74
+ asserts("ok") { @core.run_in_window('default',{:tabs => {'tab0'=>{:commands => ['echo']}}}, :default => true)}
75
+ end
68
76
 
69
- context "with working_dir" do
70
- setup { stub(Dir).pwd { '/tmp/path' } }
71
- setup { mock(@core).execute_command("cd \"/tmp/path\"", :in => '/tmp/path') }
72
- setup { mock(@core).execute_command('ls', :in => '/tmp/path') }
73
- asserts("ok") { @core.run_in_window({'tab' => ['ls']}) }
77
+ context "with working_dir" do
78
+ setup { stub(Dir).pwd { '/tmp/path' } }
79
+ setup { mock(@core).execute_command("cd \"/tmp/path\"", :in => '/tmp/path') }
80
+ setup { mock(@core).execute_command('ls', :in => '/tmp/path') }
81
+ asserts("ok") { @core.run_in_window('window1', {:tabs => {'tab1' => {:commands => ['ls']}}}) }
82
+ end
83
+ end
84
+
85
+ context "with options" do
86
+ setup do
87
+ any_instance_of(Terminitor::AbstractCore) do |core|
88
+ stub(core).load_termfile('/path/to') do
89
+ {:windows => {'window1' => {:tabs => {'tab1' => {:commands => ['ls', 'ok'], :options => {:settings => 'cool', :name => 'first tab'}},
90
+ 'tab2' => {:commands => ['ps'], :options => {:settings => 'grass', :name => 'second tab'}},
91
+ },
92
+ :options => {:bounds => [10,10]}}}
93
+ }
94
+ end
95
+ end
96
+ @core = Terminitor::AbstractCore.new('/path/to')
97
+ end
98
+
99
+ setup { mock(@core).open_window(:bounds => [10,10], :settings => 'cool', :name => "first tab") { "first" } }
100
+ setup { mock(@core).open_tab(:settings => 'grass', :name => 'second tab') { "second" } }
101
+ setup { mock(@core).set_delayed_options { true } }
102
+ setup { mock(@core).execute_command('ls', :in => "first") }
103
+ setup { mock(@core).execute_command('ok', :in => "first") }
104
+ setup { mock(@core).execute_command('ps', :in => "second") }
105
+
106
+ asserts("ok") { @core.process! }
74
107
  end
75
108
  end
76
109
 
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../teststrap',__FILE__)
2
+
3
+ if platform?("darwin") # Only run test if it's darwin
4
+ context "MacCapture" do
5
+ # Stub out the initialization
6
+ setup do
7
+ @terminal = Object.new
8
+ any_instance_of(Terminitor::MacCapture) do |core|
9
+ stub(core).app('Terminal.app') { @terminal }
10
+ end
11
+ end
12
+ setup { @mac_capture = Terminitor::MacCapture.new() }
13
+
14
+ context "capture_windows" do
15
+ setup do
16
+ window, tab = Object.new, Object.new
17
+ stub(@terminal).windows.stub!.get { [window]}
18
+ stub(window).tabs.stub!.get {[tab]}
19
+ stub(window).visible.stub!.get { true }
20
+ mock(@mac_capture).object_options(window) { {:window_option => true} }
21
+ mock(@mac_capture).object_options(tab) { {:tab_option => true} }
22
+ # any_instance_of(Terminitor::MacCapture) {|core| stub(core).object_options(anything) { {} }}
23
+ end
24
+ setup { @mac_capture.capture_windows}
25
+ asserts_topic.equals [{:tabs=>[{:options=>{:tab_option=>true}}], :options=>{:window_option=>true}}]
26
+ end
27
+
28
+ context "object_options" do
29
+ setup do
30
+ @object = Object.new
31
+ stub(@object).class_.stub!.get { :window }
32
+ stub(@object).bounds.stub!.get { [10,20,30,40]}
33
+ end
34
+ setup { @mac_capture.object_options(@object) }
35
+ asserts_topic.equals { {:bounds => [10,20,30,40]} }
36
+ end
37
+ end
38
+ else
39
+ context "MacCore" do
40
+ puts "Nothing to do, you are not on OSX"
41
+ end
42
+ end
data/test/cli_test.rb CHANGED
@@ -67,6 +67,32 @@ context "Terminitor" do
67
67
  setup { mock.instance_of(Terminitor::Cli).open_in_editor('/tmp/sample_project/Termfile','nano') { true }.once }
68
68
  asserts("runs nano") { capture(:stdout) { Terminitor::Cli.start(['edit','-r=/tmp/sample_project','-c=nano']) } }
69
69
  end
70
+
71
+ context "for capture flag" do
72
+ context "for yaml" do
73
+ setup { capture(:stdout) { Terminitor::Cli.start(['edit','foobar', '-s=yml', '--capture']) } }
74
+ asserts_topic.matches %r{Terminal settings can be captured only to DSL format.}
75
+ end
76
+
77
+ context "for term" do
78
+ context "with no core returned" do
79
+ setup { mock.instance_of(Terminitor::Cli).capture_core(anything) { nil } }
80
+ setup { FileUtils.touch("#{ENV['HOME']}/.terminitor/delete_this.term") }
81
+ setup { capture(:stdout) { Terminitor::Cli.start(['edit', 'test_foo_bar2', '--capture']) } }
82
+ asserts_topic.matches %r{No suitable core found!}
83
+ end
84
+
85
+ context "for known core" do
86
+ setup do
87
+ core = Object.new
88
+ mock.instance_of(Terminitor::Cli).capture_core(anything) { core }
89
+ stub(core).new.stub!.capture_settings { "settings"}
90
+ mock.instance_of(Terminitor::Cli).open_in_editor("#{ENV['HOME']}/.terminitor/test_foo_bar2.term",nil) { true }
91
+ end
92
+ asserts("ok") { Terminitor::Cli.start(['edit','test_foo_bar2', '--capture']) }
93
+ end
94
+ end
95
+ end
70
96
 
71
97
  end
72
98
 
@@ -115,7 +141,7 @@ context "Terminitor" do
115
141
  end
116
142
 
117
143
  context "fetch" do
118
- setup { mock.instance_of(Terminitor::Cli).fetch_repo('achiu','terminitor', 'root' => '.', 'setup' => true) { true } }
144
+ setup { mock.instance_of(Terminitor::Cli).github_repo('achiu','terminitor', 'root' => '.', 'setup' => true) { true } }
119
145
  asserts("run setup in project dir") { capture(:stdout) { Terminitor::Cli.start(['fetch','achiu','terminitor'])} }
120
146
  end
121
147
  end
@@ -9,7 +9,7 @@ if platform?("darwin") # Only run test if it's darwin
9
9
  any_instance_of(Terminitor::MacCore) do |core|
10
10
  stub(core).app('Terminal') { terminal }
11
11
  stub(core).load_termfile('/path/to') { true }
12
- end
12
+ end
13
13
  end
14
14
  setup { @mac_core = Terminitor::MacCore.new('/path/to') }
15
15
 
@@ -31,6 +31,17 @@ if platform?("darwin") # Only run test if it's darwin
31
31
  end
32
32
  asserts("returns last tab") { @mac_core.open_tab }
33
33
  end
34
+
35
+ context "open_tab with options" do
36
+ setup do
37
+ process = Object.new
38
+ mock(process).keystroke('t', :using => :command_down)
39
+ mock(@mac_core).set_options(true, :option1 => '1', :option2 => '2')
40
+ mock(@mac_core).return_last_tab.times(2) { true }
41
+ mock(@mac_core).terminal_process { process }
42
+ end
43
+ asserts("returns last tab") { @mac_core.open_tab(:option1 => '1', :option2 => '2') }
44
+ end
34
45
 
35
46
  context "open_window" do
36
47
  setup do
@@ -42,6 +53,21 @@ if platform?("darwin") # Only run test if it's darwin
42
53
  asserts("returns last tab") { @mac_core.open_window }
43
54
  end
44
55
 
56
+ context "open_window with options" do
57
+ setup do
58
+ process = Object.new
59
+ window = Object.new
60
+ tab = Object.new
61
+ mock(process).keystroke('n', :using => :command_down)
62
+ mock(@mac_core).set_options(window, :bounds => '1')
63
+ mock(@mac_core).set_options(tab, :settings => "2")
64
+ mock(@mac_core).active_window { window }
65
+ mock(@mac_core).return_last_tab { tab }.times(2)
66
+ mock(@mac_core).terminal_process { process }
67
+ end
68
+ asserts("opens window with options") { @mac_core.open_window(:bounds => '1', :settings => '2')}
69
+ end
70
+
45
71
  context "return_last_tab" do
46
72
  setup do
47
73
  window = Object.new
@@ -76,6 +102,61 @@ if platform?("darwin") # Only run test if it's darwin
76
102
  end
77
103
  asserts("gives me window") { Terminitor::MacCore.new('/path/to').active_window }
78
104
  end
105
+
106
+ context "set_options" do
107
+ setup do
108
+ @object, @terminal, @windows= 3.times.collect { Object.new }
109
+ any_instance_of(Terminitor::MacCore) do |core|
110
+ stub(core).app('Terminal') { @terminal }
111
+ stub(core).load_termfile('/path/to') { true }
112
+ end
113
+ stub(@terminal).windows { @windows }
114
+ end
115
+
116
+ context "valid settings set" do
117
+ setup do
118
+ stub(@terminal).settings_sets {{:valid_settings => true}}
119
+ stub(@object).current_settings.stub!.set(anything) { true }
120
+ end
121
+ asserts("applies known settings set") { Terminitor::MacCore.new('/path/to').set_options(@object, :settings => :valid_settings)}
122
+ end
123
+
124
+ context "invalid settings set" do
125
+ setup do
126
+ stub(@terminal).settings_sets {{:invalid_settings => true}}
127
+ stub(Object).raise
128
+ stub(@object).current_settings.stub!.set(anything) { raise Appscript::CommandError.new("code","error","object","reference", "command") }
129
+ end
130
+ setup { capture(:stdout) {Terminitor::MacCore.new('/path/to').set_options(@object, :settings => :invalid_settings)}}
131
+ asserts_topic.matches %r{invalid settings set}
132
+ end
133
+
134
+ context "bounds" do
135
+ setup do
136
+ setup { stub(@object).bounds.stub!.set(true) }
137
+ setup { stub(@object).frame.stub!.set(true) }
138
+ setup { stub(@object).position.stub!.set(true) }
139
+ end
140
+ asserts("sets bounds") { Terminitor::MacCore.new('/path/to').set_options(@object, :bounds => true)}
141
+ end
142
+
143
+ context "unknown option" do
144
+ setup do
145
+ stub(Object).raise
146
+ stub(@object).unknown_option.stub!.set(anything) { raise Appscript::CommandError.new("code","error","object","reference", "command") }
147
+ end
148
+ setup { capture(:stdout) { Terminitor::MacCore.new('/path/to').set_options(@object, :unknown_option => true)}}
149
+ asserts_topic.matches %r{Error}
150
+ end
151
+
152
+ context "delayed option" do
153
+ setup do
154
+ setup { Terminitor::MacCore.new('/path/to').set_options(@object, :selected => true) }
155
+ stub(@object).selected.stub!.set(true)
156
+ end
157
+ asserts("sets delayed options") { @mac_core.set_delayed_options }
158
+ end
159
+ end
79
160
  end
80
161
  else
81
162
  context "MacCore" do
data/test/dsl_test.rb CHANGED
@@ -6,10 +6,14 @@ context "Dsl" do
6
6
  asserts_topic.assigns :setup
7
7
  asserts_topic.assigns :windows
8
8
  asserts_topic.assigns :_context
9
-
9
+
10
10
  context "to_hash" do
11
11
  setup { @yaml.to_hash }
12
- asserts_topic.equivalent_to(:setup=>["echo \"setup\""], :windows=>{"window1"=>{"named tab"=>["echo 'named tab'", "ls"], "tab0"=>["echo 'first tab'", "echo 'of window'"]}, "default"=>{"tab0"=>["echo 'default'", "echo 'default tab'"]}})
12
+ asserts_topic.equivalent_to :setup=>["echo \"setup\""],
13
+ :windows=>{
14
+ "window1"=>{:tabs=>{"named tab"=>{:commands=>["echo 'named tab'", "ls"], :options => {:settings=>"Grass"}},
15
+ "tab0"=>{:commands=>["echo 'first tab'", "echo 'of window'", "echo 'than now'"]}}, :options => {:size=>[70,30]}},
16
+ "default"=>{"tab0"=>{:commands=>["echo 'default'", "echo 'default tab'", "ok", "for real"]}}}
13
17
  end
14
18
 
15
19
  end
@@ -3,14 +3,15 @@
3
3
 
4
4
  setup 'echo "setup"'
5
5
 
6
- tab "echo 'default'", "echo 'default tab'"
6
+ tab "echo 'default'", "echo 'default tab'", "ok", "for real"
7
7
 
8
- window do
9
- tab "echo 'first tab'", "echo 'of window'"
8
+ window :size => [70,30] do
9
+ tab "echo 'first tab'", "echo 'of window'", "echo 'than now'"
10
10
 
11
- tab "named tab" do
11
+ tab "named tab", :settings => "Grass" do
12
12
  run "echo 'named tab'"
13
13
  run "ls"
14
14
  end
15
15
  end
16
16
 
17
+
data/test/runner_test.rb CHANGED
@@ -38,6 +38,13 @@ context "Runner" do
38
38
  end
39
39
  end
40
40
  end
41
+
42
+ context "capture_core" do
43
+ context "for Darwin" do
44
+ setup { @test_runner.capture_core('darwin') }
45
+ asserts_topic.equals Terminitor::MacCapture
46
+ end
47
+ end
41
48
 
42
49
  context "open_in_editor" do
43
50
  context "using $EDITOR" do
@@ -192,40 +199,40 @@ context "Runner" do
192
199
  end
193
200
  end
194
201
 
195
- context "clone_repo" do
202
+ context "github_clone" do
196
203
  context "with github" do
197
204
  setup { stub(@test_runner).__double_definition_create__.call(:`,'which github') { "github" } }
198
205
  context "with read/write priv" do
199
206
  setup { mock(@test_runner).system("github clone achiu terminitor --ssh") { true } }
200
- asserts("invokes ssh") { @test_runner.clone_repo('achiu','terminitor') }
207
+ asserts("invokes ssh") { @test_runner.github_clone('achiu','terminitor') }
201
208
  end
202
209
 
203
210
  context "with read only" do
204
211
  setup { mock(@test_runner).system("github clone achiu terminitor --ssh") { false } }
205
212
  setup { mock(@test_runner).system("github clone achiu terminitor") { true } }
206
- asserts("invokes git://") { @test_runner.clone_repo('achiu', 'terminitor') }
213
+ asserts("invokes git://") { @test_runner.github_clone('achiu', 'terminitor') }
207
214
  end
208
215
  end
209
216
  end
210
217
 
211
- context "fetch_repo" do
218
+ context "github_repo" do
212
219
  context "with setup" do
213
- setup { mock(@test_runner).clone_repo('achiu','terminitor') { true } }
220
+ setup { mock(@test_runner).github_clone('achiu','terminitor') { true } }
214
221
  setup { mock(FileUtils).cd(File.join(Dir.pwd,'terminitor')) { true } }
215
222
  setup { mock(@test_runner).invoke(:setup, []) { true } }
216
- asserts("invokes setup") { @test_runner.fetch_repo('achiu','terminitor', :setup => true) }
223
+ asserts("invokes setup") { @test_runner.github_repo('achiu','terminitor', :setup => true) }
217
224
  end
218
225
 
219
226
  context "without setup" do
220
- setup { mock(@test_runner).clone_repo('achiu','terminitor') { true } }
227
+ setup { mock(@test_runner).github_clone('achiu','terminitor') { true } }
221
228
  setup { mock(FileUtils).cd(File.join(Dir.pwd,'terminitor')) { true } }
222
- asserts("invokes setup") { @test_runner.fetch_repo('achiu','terminitor') }.nil
229
+ asserts("invokes setup") { @test_runner.github_repo('achiu','terminitor') }.nil
223
230
  end
224
231
 
225
232
  context "failed on repo" do
226
- setup { mock(@test_runner).clone_repo('achiu','terminitor') { false } }
233
+ setup { mock(@test_runner).github_clone('achiu','terminitor') { false } }
227
234
  setup { mock(@test_runner).say("could not fetch repo!") { true } }
228
- asserts("invokes say") { @test_runner.fetch_repo('achiu', 'terminitor') }
235
+ asserts("invokes say") { @test_runner.github_repo('achiu', 'terminitor') }
229
236
  end
230
237
 
231
238
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminitor
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Arthur Chiu
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-09-30 00:00:00 -07:00
19
+ date: 2010-11-05 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -144,7 +144,10 @@ files:
144
144
  - lib/templates/example.term.tt
145
145
  - lib/templates/example.yml.tt
146
146
  - lib/terminitor.rb
147
+ - lib/terminitor/abstract_capture.rb
147
148
  - lib/terminitor/abstract_core.rb
149
+ - lib/terminitor/capture/konsole_capture.rb
150
+ - lib/terminitor/capture/mac_capture.rb
148
151
  - lib/terminitor/cli.rb
149
152
  - lib/terminitor/cores/konsole_core.rb
150
153
  - lib/terminitor/cores/mac_core.rb
@@ -155,7 +158,9 @@ files:
155
158
  - templates/example.yml.tt
156
159
  - terminitor.gemspec
157
160
  - test.watchr
161
+ - test/abstract_capture_test.rb
158
162
  - test/abstract_core_test.rb
163
+ - test/capture/mac_capture_test.rb
159
164
  - test/cli_test.rb
160
165
  - test/cores/konsole_core_test.rb
161
166
  - test/cores/mac_core_test.rb