terminitor 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -86,22 +86,24 @@ YAML syntax.
86
86
 
87
87
  #### Ruby DSL Syntax ####
88
88
 
89
- setup 'echo "setup"' # code to run during setup
89
+ ````ruby
90
+ setup 'echo "setup"' # code to run during setup
90
91
 
91
- # open a tab in current window with these commands
92
- tab "echo 'default'", "echo 'default tab'"
92
+ # open a tab in current window with these commands
93
+ tab "echo 'default'", "echo 'default tab'"
93
94
 
94
- window do
95
- before { run 'cd /path' } # run this command before each command.
96
-
97
- run 'padrino start' # run in new window
95
+ window do
96
+ before { run 'cd /path' } # run this command before each command.
97
+
98
+ run 'padrino start' # run in new window
98
99
 
99
- tab "echo 'first tab'", "echo 'of window'" # create a new tab in window and run it.
100
- tab "named tab" do
101
- run "echo 'named tab'"
102
- run "ls"
103
- end
104
- end
100
+ tab "echo 'first tab'", "echo 'of window'" # create a new tab in window and run it.
101
+ tab "named tab" do
102
+ run "echo 'named tab'"
103
+ run "ls"
104
+ end
105
+ end
106
+ ````
105
107
 
106
108
  The newer Ruby DSL syntax allows for more complicated behavior such as window creation as well as setup blocks that can be executed prior loading a project.
107
109
 
@@ -109,51 +111,58 @@ The newer Ruby DSL syntax allows for more complicated behavior such as window cr
109
111
 
110
112
  to create tabs, we can simply invoke the tab command with either the command arguments like:
111
113
 
112
- tab "echo 'hi'", "gitx"
113
-
114
+ ````ruby
115
+ tab "echo 'hi'", "gitx"
116
+ ````
117
+
114
118
  or even pass it a block:
115
119
 
116
- tab do
117
- run "echo 'hi'"
118
- run "mate ."
119
- end
120
+ ````ruby
121
+ tab do
122
+ run "echo 'hi'"
123
+ run "mate ."
124
+ end
125
+ ````
120
126
 
121
127
  ##### Windows #####
122
128
 
123
129
  to create windows, we can simply invoke the window command with a block containing additional commands like:
124
130
 
125
- window do
131
+ ````ruby
132
+ window do
126
133
 
127
- run "whoami" # Runs the command in the current window.
128
-
129
- tab "echo 'hi'" # Creates another tab
130
- tab "mate ." # And another
131
- tab do # Last hoorah
132
- run "open http://www.google.com"
133
- end
134
- end
134
+ run "whoami" # Runs the command in the current window.
135
135
 
136
+ tab "echo 'hi'" # Creates another tab
137
+ tab "mate ." # And another
138
+ tab do # Last hoorah
139
+ run "open http://www.google.com"
140
+ end
141
+ end
142
+ ````
136
143
 
137
144
  ##### Before #####
138
145
 
139
146
  Sometimes you'll want to create a few commands that you want to run in each tab instance. You can do that with 'before':
140
147
 
141
- before { run "cd /path" } # execute this command before other commands in the default window
142
- run "whoami"
143
- tab 'uptime'
148
+ ````ruby
149
+ before { run "cd /path" } # execute this command before other commands in the default window
150
+ run "whoami"
151
+ tab 'uptime'
144
152
 
145
- # In this instance, "cd /path" wil be executed in the default window before 'whoami'
146
- # and also in the tab before 'uptime'.
147
- # You can also use this inside a specific window context:
153
+ # In this instance, "cd /path" wil be executed in the default window before 'whoami'
154
+ # and also in the tab before 'uptime'.
155
+ # You can also use this inside a specific window context:
148
156
 
149
- window do
150
- before 'cd /tmp'
151
- run 'watchr test.watchr' # "cd /tmp" first than run watchr
157
+ window do
158
+ before 'cd /tmp'
159
+ run 'watchr test.watchr' # "cd /tmp" first than run watchr
152
160
 
153
- tab do
154
- run 'padrino start' # "cd /tmp" is ran beforehand and then padrino start is executed
155
- end
156
- end
161
+ tab do
162
+ run 'padrino start' # "cd /tmp" is ran beforehand and then padrino start is executed
163
+ end
164
+ end
165
+ ````
157
166
 
158
167
 
159
168
 
@@ -163,15 +172,19 @@ The setup block allows you to store commands that can be ran specifically before
163
172
 
164
173
  the command arguments:
165
174
 
166
- setup "bundle install", "gitx"
175
+ ````ruby
176
+ setup "bundle install", "gitx"
177
+ ````
167
178
 
168
179
  or with a block:
169
180
 
170
- setup do
171
- run "echo 'hi'"
172
- run "bundle install"
173
- run 'git remote add upstream git://github.com/achiu/terminitor.git'
174
- end
181
+ ````ruby
182
+ setup do
183
+ run "echo 'hi'"
184
+ run "bundle install"
185
+ run 'git remote add upstream git://github.com/achiu/terminitor.git'
186
+ end
187
+ ````
175
188
 
176
189
 
177
190
  Once defined, you can invoke your projects setup with:
@@ -185,19 +198,23 @@ You can also set settings on each of your tabs and windows. for example, this is
185
198
 
186
199
  Open a tab with terminal settings "Grass"
187
200
 
188
- tab :name => "named tab", :settings => "Grass" do
189
- run "echo 'named tab'"
190
- run "ls"
191
- end
201
+ ````ruby
202
+ tab :name => "named tab", :settings => "Grass" do
203
+ run "echo 'named tab'"
204
+ run "ls"
205
+ end
206
+ ````
192
207
 
193
208
  This will create a tab with a title of 'named tab' using Terminals 'Grass' setting.
194
209
 
195
210
 
196
211
  How about a window with a specific size:
197
212
 
198
- window :bounds => [10,20,300,200] do
213
+ ````ruby
214
+ window :bounds => [10,20,300,200] do
199
215
 
200
- end
216
+ end
217
+ ````
201
218
 
202
219
  Currently, the following options are available:
203
220
 
@@ -322,9 +339,39 @@ focus during execution of these commands. Obviously the long term goal is to sol
322
339
 
323
340
  #### ITermCore ####
324
341
 
325
- Currently the iTerm Core only provides basic functionality such as opening tabs, windows, and executing commands within them. The capture
342
+ Currently the iTerm Core only provides basic functionality such as opening tabs, windows, and executing commands within them. It is also possible to split tabs into panes. The capture
326
343
  and settings functionality will be integrated soon.
327
344
 
345
+ Splitting tabs into panes works as follows:
346
+
347
+ tab do
348
+ pane "gitx" # first pane
349
+ pane do # second pane level => horizontal split
350
+ run "irb"
351
+ end
352
+ pane 'ls' # first pane level => vertical split
353
+ end
354
+
355
+ should result into something like this:
356
+
357
+ # ###########################
358
+ # # # #
359
+ # # # #
360
+ # # 'gitx' # #
361
+ # # # #
362
+ # # # #
363
+ # ############## 'ls' #
364
+ # # # #
365
+ # # # #
366
+ # # 'irb' # #
367
+ # # # #
368
+ # # # #
369
+ # ###########################
370
+
371
+ It is not possible to split the second level panes (the horizontal
372
+ ones). Nevertheless you should be able to split tabs into any kind of pane pattern you wish
373
+ with this syntax.
374
+
328
375
 
329
376
  #### Fetching ####
330
377
 
@@ -365,14 +412,15 @@ Thanks to the following people for their contributions so far:
365
412
  * Flavio Castelli ([flavio](https://github.com/flavio)) for contributing Konsole(KDE) core.
366
413
  * Alexey Kuleshov ([kulesa](https://github.com/kulesa)) for contributing the terminal settings and terminal settings capture functionality
367
414
  * Arthur Gunn ([gunn](https://github.com/gunn)) for contributing a path to support tab syntax and load path.
368
- * Elliot Winkler ([mcmire](https://github.com/mcmire)) for adding 1.8.6 compatiblity and ensuring tabs open in order.
415
+ * Elliot Winkler ([mcmire](https://github.com/mcmire)) for adding 1.8.6 compatiblity and ensuring tabs open in order and fixing named tabs
369
416
  * Justin Hilemen ([bobthecow](https://github.com/bobthecow)) for fixing the list command to remove the term extensions.
370
417
  * Dave Perrett ([recurser](https://github.com/recurser)) for adding basic iTerm support.
371
418
  * Ilkka Laukkanen ([ilkka](https://github.com/achiu/terminitor/commits/master?author=ilkka)) for Terminator core and other fixes
372
419
  * Elia Schito ([elia](https://github.com/achiu/terminitor/commits/master?author=elia)) for patch to allow usage of "&" for background operations
373
420
  * Dotan J. Nahum ([jondot](https://github.com/jondot)) for adding windows(cmd.exe) support
374
- * Kyriacos Souroullas ([kyriacos](https://github.com/kyriacos) For removing params to support generic commands
375
- * Jerry Cheung ([jch](https://github.com/jch)) For adding ignore for emac backups
421
+ * Kyriacos Souroullas ([kyriacos](https://github.com/kyriacos) for removing params to support generic commands
422
+ * Jerry Cheung ([jch](https://github.com/jch)) for adding ignore for emac backups
423
+ * Michael Klein ([LevelbossMike](https://github.com/LevelbossMike)) for adding iTerm Pane support
376
424
 
377
425
  Acknowledgements
378
426
  -----------------
@@ -53,7 +53,7 @@ module Terminitor
53
53
  # clean up prompt
54
54
  tab_content[:commands].insert(0, 'clear') if tab_name || !@working_dir.to_s.empty?
55
55
  # add title to tab
56
- tab_content[:commands].insert(0, "PS1=$PS1\"\\e]2;#{tab_name}\\a\"") if tab_name
56
+ tab_content[:commands].insert(0, "PS1=\"$PS1\\e]2;#{tab_name}\\a\"") if tab_name
57
57
  tab_content[:commands].insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
58
58
  tab_content[:commands].each { |cmd| execute_command(cmd, :in => tab) }
59
59
  end
@@ -3,12 +3,12 @@ module Terminitor
3
3
  # This Core manages all the interaction with Appscript and the Terminal
4
4
  class ItermCore < AbstractCore
5
5
  include Appscript
6
-
6
+
7
7
  ALLOWED_OPTIONS = {
8
8
  :window => [:bounds, :visible, :miniaturized],
9
9
  :tab => [:settings, :selected]
10
10
  }
11
-
11
+
12
12
  # Initialize @terminal with Terminal.app, Load the Windows, store the Termfile
13
13
  # Terminitor::MacCore.new('/path')
14
14
  def initialize(path)
@@ -17,10 +17,10 @@ module Terminitor
17
17
  @windows = @terminal.terminals
18
18
  @delayed_options = []
19
19
  end
20
-
20
+
21
21
  # executes the given command via appscript
22
22
  # execute_command 'cd /path/to', :in => #<tab>
23
- def execute_command(cmd, options = {})
23
+ def execute_command(cmd, options = {})
24
24
  if options[:in]
25
25
  options[:in].write(:text => "#{cmd}")
26
26
  else
@@ -28,48 +28,33 @@ module Terminitor
28
28
  end
29
29
  end
30
30
 
31
- # Opens a new tab and returns itself.
31
+ # Opens a new tab, iterm sets focus on new tab
32
32
  # TODO : handle options (?)
33
33
  def open_tab(options = nil)
34
- session = current_terminal.sessions.end.make( :new => :session )
35
- session.exec(:command => ENV['SHELL'])
36
- session
34
+ current_terminal.launch_ :session => 'New session'
37
35
  end
38
-
39
- # Opens A New Window, applies settings to the first tab and returns the tab object.
36
+
37
+ # Open new window, applies settings to the first tab. iterm sets focus on
38
+ # new tab
40
39
  # TODO : handle options (?)
41
40
  def open_window(options = nil)
42
41
  window = terminal.make( :new => :terminal )
43
- session = window.sessions.end.make( :new => :session )
44
- session.exec(:command => ENV['SHELL'])
45
- session
46
- end
47
-
48
- # Returns the Terminal Process
49
- # We need this method to workaround appscript so that we can instantiate new tabs and windows.
50
- # otherwise it would have looked something like window.make(:new => :tab) but that doesn't work.
51
- def terminal_process
52
- app("System Events").application_processes["iTerm.app"]
53
- end
54
-
55
- # Returns the last instantiated tab from active window
56
- def return_last_tab
57
- current_terminal.sessions.last.get rescue false
42
+ window.launch_ :session => 'New session'
58
43
  end
59
44
 
60
- # returns the active windows
45
+ # Returns the active window i.e. the active terminal session in iTerm
61
46
  def active_window
62
- current_terminal.current_session.get
47
+ current_terminal.current_session
63
48
  end
64
-
65
- # Returns the current terminal
49
+
50
+ # Returns the current terminal i.e. the active iTerm window
66
51
  def current_terminal
67
52
  @terminal.current_terminal
68
53
  end
69
54
 
70
55
  # Sets options of the given object
71
56
  def set_options(object, options = {})
72
- options.each_pair do |option, value|
57
+ options.each_pair do |option, value|
73
58
  case option
74
59
  when :settings # works for windows and tabs, for example :settings => "Grass"
75
60
  begin
@@ -97,7 +82,7 @@ module Terminitor
97
82
  end
98
83
  end
99
84
  end
100
-
85
+
101
86
  # Apply delayed options and remove them from the queue
102
87
  def set_delayed_options
103
88
  @delayed_options.length.times do
@@ -106,12 +91,134 @@ module Terminitor
106
91
  end
107
92
  end
108
93
 
94
+ # this command will run commands in the designated window
95
+ # run_in_window 'window1', {:tab1 => ['ls','ok']}
96
+ # @param [String] name of window
97
+ # @param [Hash] Hash of window's content extracted from Termfile
98
+ # @param [Hash] Hash of options
99
+ def run_in_window(window_name, window_content, options = {})
100
+ window_options = window_content[:options]
101
+ first_tab = true
102
+ window_content[:tabs].keys.sort.each do |tab_key|
103
+ tab_content = window_content[:tabs][tab_key]
104
+ # Open window on first 'tab' statement
105
+ # first tab is already opened in the new window, so first tab should be
106
+ # opened as a new tab in default window only
107
+ tab_options = tab_content[:options]
108
+ tab_name = tab_options[:name] if tab_options
109
+ if first_tab && !options[:default]
110
+ first_tab = false
111
+ combined_options = (window_options.to_a + tab_options.to_a).inject([]) {|arr, pair| arr += pair }
112
+ window_options = Hash[*combined_options] # safe merge
113
+ tab = window_options.empty? ? open_window(nil) : open_window(window_options)
114
+ else
115
+ # give us the current window if its default, else open a tab.
116
+ tab = ( tab_key == 'default' ? active_window : open_tab(tab_options) )
117
+ end
118
+ # append our before block commands.
119
+ tab_content[:commands].insert(0, window_content[:before]).flatten! if window_content[:before]
120
+ # clean up prompt
121
+ tab_content[:commands].insert(0, 'clear') if tab_name || !@working_dir.to_s.empty?
122
+ # add title to tab
123
+ tab_content[:commands].insert(0, "PS1=$PS1\"\\e]2;#{tab_name}\\a\"") if tab_name
124
+ tab_content[:commands].insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
125
+ # if tab_content hash has a key :panes we know this tab should be split
126
+ # we can execute tab commands if there is no key :panes
127
+ if tab_content.key?(:panes)
128
+ handle_panes(tab_content)
129
+ else
130
+ tab_content[:commands].each { |cmd| execute_command(cmd, :in => tab) }
131
+ end
132
+ end
133
+ set_delayed_options
134
+ end
135
+
136
+ def handle_panes(tab_content)
137
+ panes = tab_content[:panes]
138
+ tab_commands = tab_content[:commands]
139
+ first_pane_level_split(panes, tab_commands)
140
+ second_pane_level_split(panes, tab_commands)
141
+ end
142
+
143
+ def first_pane_level_split(panes, tab_commands)
144
+ first_pane = true
145
+ split_v_counter = 0
146
+ panes.keys.sort.each do |pane_key|
147
+ pane_content = panes[pane_key]
148
+ unless first_pane
149
+ split_v
150
+ split_v_counter += 1
151
+ end
152
+ first_pane = false if first_pane
153
+ pane_commands = pane_content[:commands]
154
+ execute_pane_commands(pane_commands, tab_commands)
155
+ end
156
+ split_v_counter.times { select_pane 'Left' }
157
+ end
158
+
159
+ def second_pane_level_split(panes, tab_commands)
160
+ panes.keys.sort.each do |pane_key|
161
+ pane_content = panes[pane_key]
162
+ handle_subpanes(pane_content[:panes], tab_commands) if pane_content.has_key? :panes
163
+ # select next vertical pane
164
+ select_pane 'Right'
165
+ end
166
+ end
167
+
168
+ def handle_subpanes(subpanes, tab_commands)
169
+ subpanes.keys.sort.each do |subpane_key|
170
+ subpane_commands = subpanes[subpane_key][:commands]
171
+ split_h
172
+ execute_pane_commands(subpane_commands, tab_commands)
173
+ end
174
+ end
175
+
176
+ def execute_pane_commands(pane_commands, tab_commands)
177
+ pane_commands = tab_commands + pane_commands
178
+ pane_commands.each { |cmd| execute_command cmd}
179
+ end
180
+
181
+
182
+ # Methods for splitting panes (GUI_scripting)
183
+ #
184
+ def iterm_menu
185
+ terminal_process = Appscript.app("System Events").processes["iTerm"]
186
+ terminal_process.menu_bars.first
187
+ end
188
+
189
+ def call_ui_action(menu, submenu = nil, action)
190
+ menu = iterm_menu.menu_bar_items[menu].menus[menu]
191
+ if submenu
192
+ menu = menu.menu_items[submenu].menus[submenu]
193
+ end
194
+ menu.menu_items[action].click
195
+ end
196
+
197
+ def split_v
198
+ call_ui_action("Shell", nil, "Split vertically")
199
+ end
200
+
201
+ def split_h
202
+ call_ui_action("Shell", nil, "Split horizontally")
203
+ end
204
+
205
+ # to select panes; iTerm's Appscript select method does not work
206
+ # as expected, we have to select via menu instead
207
+ def select_pane(direction)
208
+ valid_directions = %w[Above Below Left Right]
209
+ if valid_directions.include?(direction)
210
+ call_ui_action("Window", "Select Split Pane", "Select Pane #{direction}")
211
+ else
212
+ puts "Error: #{direction} is not a valid direction to select a pane; Only Above/Below/Left/Right are valid directions"
213
+ end
214
+ end
215
+
109
216
  private
110
-
217
+
111
218
  # These methods are here for reference so I can ponder later
112
219
  # how I could possibly use them.
113
220
  # And Currently aren't tested. =(
114
-
221
+
115
222
  # returns a window by the id
116
223
  def window_by_id(id)
117
224
  @windows.ID(id)
@@ -127,12 +234,12 @@ module Terminitor
127
234
  def set_window_title(window, title)
128
235
  window.custom_title.set(title)
129
236
  end
130
-
237
+
131
238
  # selects options allowed for window or tab
132
239
  def allowed_options(object_type, options)
133
240
  Hash[ options.select {|option, value| ALLOWED_OPTIONS[object_type].include?(option) }]
134
241
  end
135
-
242
+
136
243
  # Add option to the list of delayed options
137
244
  def delayed_option(option, value, object)
138
245
  @delayed_options << {
@@ -28,7 +28,7 @@ module Terminitor
28
28
 
29
29
  # sets command context to be run inside a specific window
30
30
  # @param [Hash] options hash.
31
- # @param [Proc]
31
+ # @param [Proc]
32
32
  # @example
33
33
  # window(:name => 'new window', :size => [80,30], :position => [9, 100]) { tab('ls','gitx') }
34
34
  # window { tab('ls', 'gitx') }
@@ -47,6 +47,8 @@ module Terminitor
47
47
  # if we are in a window context, append commands to default tab.
48
48
  if @_context.is_a?(Hash) && @_context[:tabs]
49
49
  current = @_context[:tabs]['default'][:commands]
50
+ elsif @_context.is_a?(Hash)
51
+ current = @_context[:commands]
50
52
  else
51
53
  current = @_context
52
54
  end
@@ -82,19 +84,50 @@ module Terminitor
82
84
  tab_name = "tab#{tabs.keys.size}"
83
85
  if block_given?
84
86
  tab_contents = tabs[tab_name] = {:commands => []}
85
-
87
+
86
88
  options = {}
87
89
  options = args.pop if args.last.is_a? Hash
88
90
  options[:name] = args.first if args.first.is_a?(String) || args.first.is_a?(Symbol)
89
-
91
+
90
92
  tab_contents[:options] = options unless options.empty?
91
-
92
- in_context tab_contents[:commands], &block
93
+
94
+ in_context tab_contents, &block
95
+ clean_up_context
93
96
  else
94
97
  tabs[tab_name] = { :commands => args}
95
98
  end
96
99
  end
97
100
 
101
+ # Generates a pane in the terminal. These can be nested to
102
+ # create horizontal panes. Vertical panes are created with each top
103
+ # level nest.
104
+ # @param [Array<String>] Array of comamnds
105
+ # @param [Proc]
106
+ # @example
107
+ # pane "top"
108
+ # pane { pane "uptime" }
109
+ def pane(*args, &block)
110
+ @_context[:panes] = {} unless @_context.has_key? :panes
111
+ panes = @_context[:panes]
112
+ pane_name = "pane#{panes.keys.size}"
113
+ if block_given?
114
+ pane_contents = panes[pane_name] = {:commands => []}
115
+ if @_context.has_key? :is_first_lvl_pane
116
+ # after in_context we should be able to access
117
+ # @_context and @_old_context as before
118
+ context = @_context
119
+ old_context = @_old_context
120
+ in_context pane_contents[:commands], &block
121
+ clean_up_context(context, old_context)
122
+ else
123
+ pane_contents[:is_first_lvl_pane] = true
124
+ in_context pane_contents, &block
125
+ end
126
+ else
127
+ panes[pane_name] = { :commands => args }
128
+ end
129
+ end
130
+
98
131
  # Returns yaml file as Terminitor formmatted hash
99
132
  # @return [Hash] Return hash format of Termfile
100
133
  def to_hash
@@ -111,6 +144,13 @@ module Terminitor
111
144
  @_context = @_old_context
112
145
  end
113
146
 
147
+ def clean_up_context(context = last_open_window, old_context = nil)
148
+ @_context = context
149
+ @_old_context = old_context
150
+ end
114
151
 
152
+ def last_open_window
153
+ @windows[@windows.keys.last]
154
+ end
115
155
  end
116
156
  end
@@ -1,3 +1,3 @@
1
1
  module Terminitor
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -123,11 +123,11 @@ context "AbstractCore" do
123
123
  mock(core).open_window(:bounds => [10,10], :settings => 'cool', :name => "first tab") { "first" }
124
124
  mock(core).open_tab(:settings => 'grass', :name => 'second tab') { "second" }
125
125
  mock(core).set_delayed_options { true }
126
- mock(core).execute_command('PS1=$PS1"\e]2;first tab\a"', :in => 'first')
126
+ mock(core).execute_command('PS1="$PS1\e]2;first tab\a"', :in => 'first')
127
127
  mock(core).execute_command('clear', :in => 'first')
128
128
  mock(core).execute_command('ls', :in => "first")
129
129
  mock(core).execute_command('ok', :in => "first")
130
- mock(core).execute_command('PS1=$PS1"\e]2;second tab\a"', :in => 'second')
130
+ mock(core).execute_command('PS1="$PS1\e]2;second tab\a"', :in => 'second')
131
131
  mock(core).execute_command('clear', :in => 'second')
132
132
  mock(core).execute_command('ps', :in => "second")
133
133
  core.process!
@@ -11,54 +11,30 @@ on_platform "darwin" do
11
11
  @iterm_core = Terminitor::ItermCore.new('/path/to')
12
12
  end
13
13
 
14
- asserts "#terminal_process calls System Events" do
15
- core = topic.dup
16
- mock(core).app('System Events') { mock!.application_processes.returns("iTerm.app" => true) }
17
- core.terminal_process
18
- end
19
-
20
- context "#open_tab" do
21
14
 
22
- should "return the current tab" do
23
- core = topic.dup
24
- mock(core).current_terminal.stub!.sessions.stub!.end.
25
- stub!.make(:new => :session).stub!.
26
- exec(:command => ENV['SHELL'])
27
- core.open_tab
28
- end
15
+ asserts "#open_tab launches a new sessions" do
16
+ core = topic.dup
17
+ mock(core).current_terminal.stub!.launch_(:session => 'New session')
18
+ core.open_tab
19
+ end.nil
29
20
 
30
- end
21
+ asserts "#open_window creates a new session" do
22
+ core = topic.dup
23
+ mock(core).terminal.stub!.make(:new => :terminal).stub!.launch_(:session => 'New session')
24
+ core.open_window
25
+ end.nil
31
26
 
32
- context "#open_window" do
33
-
34
- should "return the last tab" do
35
- core = topic.dup
36
- mock(core).terminal.stub!.make(:new=>:terminal).
37
- stub!.sessions.stub!.end.stub!.make(:new=>:session).
38
- stub!.exec(:command => ENV['SHELL'])
39
- core.open_window
40
- end
41
- end
42
-
43
- asserts "#return_last_tab returns the last tab" do
44
- core = topic.dup
45
- mock(core).current_terminal.stub!.sessions.stub!.
46
- last.stub!.get.returns(true)
47
- core.return_last_tab
48
- end
49
-
50
27
  asserts "#execute_command executes" do
51
28
  core = topic.dup
52
29
  mock(core).active_window.stub!.write(:text => "hasta").returns(true)
53
30
  core.execute_command('hasta')
54
31
  end
55
-
32
+
56
33
  asserts "#active_window gives window" do
57
34
  core = topic.dup
58
35
  mock(core).current_terminal.stub!.current_session.stub!.get.returns(true)
59
36
  core.active_window
60
37
  end
61
-
62
38
  end
63
39
  end
64
40
 
@@ -20,7 +20,7 @@ context "Dsl" do
20
20
 
21
21
  context "with :tabs" do
22
22
  setup { topic[:tabs] }
23
-
23
+
24
24
  asserts(:[], 'tab2').equivalent_to({
25
25
  :commands=>["echo 'named tab'", "ls"],
26
26
  :options => {
@@ -87,3 +87,58 @@ context "Dsl" do
87
87
  end
88
88
  end
89
89
  end
90
+
91
+ context "with panes" do
92
+ setup { Terminitor::Dsl.new File.expand_path('../fixtures/iterm_panes.term', __FILE__) }
93
+ asserts_topic.assigns :setup
94
+ asserts_topic.assigns :windows
95
+ asserts_topic.assigns :_context
96
+
97
+ context "creates correct hash" do
98
+ setup { topic.to_hash }
99
+
100
+ context "in windows" do
101
+ setup { topic[:windows] }
102
+
103
+ context "with default window" do
104
+ setup { topic['default'] }
105
+
106
+ context "tabs with panes " do
107
+ setup { topic[:tabs] }
108
+
109
+ context "tabs can hold panes" do
110
+ asserts(:[], 'tab1').equivalent_to({
111
+ :commands=>["ls"],
112
+ :panes => {
113
+ 'pane0' => {
114
+ :commands => ["echo 'first level pane'"],
115
+ :is_first_lvl_pane => true,
116
+ :panes => {
117
+ 'pane0' => {
118
+ :commands => ["echo 'first second level pane'"]
119
+ }
120
+ }
121
+ },
122
+ 'pane1' => {
123
+ :commands => ["gitx"],
124
+ :is_first_lvl_pane => true,
125
+ :panes => {
126
+ 'pane0' => {
127
+ :commands => ["ls"]
128
+ },
129
+ 'pane1' => {
130
+ :commands => ["echo 'wohoo'", "echo '2nd cmd'"]
131
+ }
132
+ }
133
+ }
134
+ }
135
+ })
136
+ asserts(:[], 'tab2').equivalent_to({
137
+ :commands => ["echo 'second tab'"]
138
+ })
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,20 @@
1
+ tab do
2
+ run 'ls'
3
+ pane do
4
+ run "echo 'first level pane'"
5
+ pane do
6
+ run "echo 'first second level pane'"
7
+ end
8
+ end
9
+ pane do
10
+ run "gitx"
11
+ pane 'ls'
12
+ pane do
13
+ run "echo 'wohoo'"
14
+ run "echo '2nd cmd'"
15
+ end
16
+ end
17
+ end
18
+ tab do
19
+ run "echo 'second tab'"
20
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminitor
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 5
9
- - 2
10
- version: 0.5.2
7
+ - 6
8
+ - 0
9
+ version: 0.6.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Arthur Chiu
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2011-04-22 00:00:00 -07:00
18
+ date: 2011-05-15 00:00:00 -07:00
20
19
  default_executable:
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -27,7 +26,6 @@ dependencies:
27
26
  requirements:
28
27
  - - ~>
29
28
  - !ruby/object:Gem::Version
30
- hash: 5
31
29
  segments:
32
30
  - 0
33
31
  - 6
@@ -43,7 +41,6 @@ dependencies:
43
41
  requirements:
44
42
  - - ~>
45
43
  - !ruby/object:Gem::Version
46
- hash: 39
47
44
  segments:
48
45
  - 0
49
46
  - 14
@@ -59,7 +56,6 @@ dependencies:
59
56
  requirements:
60
57
  - - ~>
61
58
  - !ruby/object:Gem::Version
62
- hash: 3
63
59
  segments:
64
60
  - 0
65
61
  - 6
@@ -75,7 +71,6 @@ dependencies:
75
71
  requirements:
76
72
  - - ~>
77
73
  - !ruby/object:Gem::Version
78
- hash: 23
79
74
  segments:
80
75
  - 1
81
76
  - 0
@@ -91,7 +86,6 @@ dependencies:
91
86
  requirements:
92
87
  - - ~>
93
88
  - !ruby/object:Gem::Version
94
- hash: 41
95
89
  segments:
96
90
  - 0
97
91
  - 12
@@ -107,7 +101,6 @@ dependencies:
107
101
  requirements:
108
102
  - - ~>
109
103
  - !ruby/object:Gem::Version
110
- hash: 23
111
104
  segments:
112
105
  - 1
113
106
  - 0
@@ -123,7 +116,6 @@ dependencies:
123
116
  requirements:
124
117
  - - ">="
125
118
  - !ruby/object:Gem::Version
126
- hash: 3
127
119
  segments:
128
120
  - 0
129
121
  version: "0"
@@ -185,6 +177,7 @@ files:
185
177
  - test/fixtures/bar.term
186
178
  - test/fixtures/foo.term
187
179
  - test/fixtures/foo.yml
180
+ - test/fixtures/iterm_panes.term
188
181
  - test/runner_test.rb
189
182
  - test/teststrap.rb
190
183
  - test/yaml_test.rb
@@ -203,7 +196,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
196
  requirements:
204
197
  - - ">="
205
198
  - !ruby/object:Gem::Version
206
- hash: 3
207
199
  segments:
208
200
  - 0
209
201
  version: "0"
@@ -212,7 +204,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
204
  requirements:
213
205
  - - ">="
214
206
  - !ruby/object:Gem::Version
215
- hash: 23
216
207
  segments:
217
208
  - 1
218
209
  - 3
@@ -221,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
212
  requirements: []
222
213
 
223
214
  rubyforge_project: terminitor
224
- rubygems_version: 1.6.1
215
+ rubygems_version: 1.3.7
225
216
  signing_key:
226
217
  specification_version: 3
227
218
  summary: Automate your development workflow