terminitor 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- terminitor (0.4.0)
4
+ terminitor (0.4.1)
5
5
  github (~> 0.6.0)
6
6
  rb-appscript
7
7
  text-format (= 1.0.0)
@@ -25,11 +25,9 @@ GEM
25
25
  rake (>= 0.8.1)
26
26
  rake (0.8.7)
27
27
  rb-appscript (0.6.0)
28
- riot (0.12.1)
28
+ riot (0.12.2)
29
29
  rr
30
- term-ansicolor
31
30
  rr (1.0.2)
32
- term-ansicolor (1.0.5)
33
31
  text-format (1.0.0)
34
32
  text-hyphen (~> 1.0.0)
35
33
  text-hyphen (1.0.0)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Arthur Chiu
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,7 +1,16 @@
1
1
  Terminitor
2
2
  ===========
3
3
 
4
- Terminitor automates your development workflow setup. Less time setting up, more time getting things done.
4
+ Terminitor automates your development workflow setup. Less time setting up, more time getting things done.
5
+
6
+ Upgrading Terminitor from 0.4.1 and under
7
+ ------------------------------------------
8
+
9
+ For those upgrading from Terminitor 0.4.1, please run:
10
+
11
+ $ terminitor update
12
+
13
+ This will move your terminitor files to the new directory located at .config/terminitor
5
14
 
6
15
  Installation
7
16
  ------------
@@ -45,7 +54,7 @@ This will open your default editor (set through the $TERM_EDITOR or $EDITOR vari
45
54
 
46
55
  #### YAML Syntax ( Legacy ) ####
47
56
 
48
- # ~/.terminitor/foo.yml
57
+ # ~/.config/terminitor/foo.yml
49
58
  # you can make as many tabs as you wish...
50
59
  # tab names are actually arbitrary at this point too.
51
60
  ---
@@ -208,7 +217,7 @@ __windows__
208
217
 
209
218
  ### Running Terminitor Projects ###
210
219
 
211
- Once the project file has been declared to your satisfaction, simply execute any project defined in the `~/.terminitor` directory with:
220
+ Once the project file has been declared to your satisfaction, simply execute any project defined in the `~/.config/terminitor` directory with:
212
221
 
213
222
  $ terminitor start foo
214
223
 
@@ -296,6 +305,7 @@ Cores allow Terminitor to operate on a variety of platforms. They abstract the g
296
305
 
297
306
  * MacCore - Mac OS X Terminal
298
307
  * KonsoleCore - KDE Konsole
308
+ * TerminatorCore - [Terminator](http://www.tenshu.net/terminator/)
299
309
  * ITermCore - Mac OS X iTerm
300
310
 
301
311
  Feel free to contribute more cores so that Terminitor can support your terminal of choice :)
@@ -326,6 +336,19 @@ The fetch task only pulls off Github repositories at the moment. Later on, this
326
336
  This feature is currently only available in Mac OS X at the moment.
327
337
 
328
338
 
339
+ #### Terminator support ####
340
+
341
+ This feature currently requires the "xdotool" utility to be installed and in
342
+ the search path. The xdotool homepage is
343
+ http://www.semicomplete.com/blog/projects/xdotool/.
344
+
345
+
346
+ #### Windows suppport ####
347
+
348
+ Windows support is currently limited to plain cmd.exe. It is also
349
+ limited to only creating new windows, as cmd.exe does not support tabs.
350
+
351
+
329
352
  Authors
330
353
  -------
331
354
 
@@ -338,12 +361,16 @@ Contributors
338
361
  Thanks to the following people for their contributions so far:
339
362
 
340
363
  * Pat George ([pcg79](https://github.com/pcg79)) for contributing a patch for when a project is not found.
364
+ * Tim Gossett ([[MrGossett](https://github.com/MrGossett)) for a patch to fix comment reading
341
365
  * Flavio Castelli ([flavio](https://github.com/flavio)) for contributing Konsole(KDE) core.
342
366
  * Alexey Kuleshov ([kulesa](https://github.com/kulesa)) for contributing the terminal settings and terminal settings capture functionality
343
367
  * Arthur Gunn ([gunn](https://github.com/gunn)) for contributing a path to support tab syntax and load path.
344
368
  * Elliot Winkler ([mcmire](https://github.com/mcmire)) for adding 1.8.6 compatiblity and ensuring tabs open in order.
345
369
  * Justin Hilemen ([bobthecow](https://github.com/bobthecow)) for fixing the list command to remove the term extensions.
346
- * recurser ([recurser](https://github.com/recurser)) for adding basic iTerm support.
370
+ * Dave Perrett ([recurser](https://github.com/recurser)) for adding basic iTerm support.
371
+ * Ilkka Laukkanen ([ilkka](https://github.com/achiu/terminitor/commits/master?author=ilkka)) for Terminator core and other fixes
372
+ * Elia Schito ([elia](https://github.com/achiu/terminitor/commits/master?author=elia)) for patch to allow usage of "&" for background operations
373
+ * Dotan J. Nahum ([[jondot](https://github.com/jondot)) for adding windows(cmd.exe) support
347
374
 
348
375
  Acknowledgements
349
376
  -----------------
@@ -20,6 +20,17 @@ module Terminitor
20
20
  when %r{linux}
21
21
  require 'dbus'
22
22
  autoload :KonsoleCore, 'terminitor/cores/konsole_core'
23
- autoload :KonsoleCapture, 'terminitor/capture/konsole_capture'
23
+ autoload :KonsoleCapture, 'terminitor/capture/konsole_capture'
24
+ autoload :TerminatorCore, 'terminitor/cores/terminator_core'
25
+ autoload :TerminatorCapture, 'terminitor/capture/terminator_capture'
26
+ when %r{mswin|mingw}
27
+ require 'windows/process'
28
+ require 'windows/handle'
29
+ require 'win32/process'
30
+ require 'windows/window'
31
+
32
+ require 'terminitor/cores/cmd_core/input'
33
+ require 'terminitor/cores/cmd_core/windows_console'
34
+ autoload :CmdCore, 'terminitor/cores/cmd_core/cmd_core'
24
35
  end
25
36
  end
@@ -4,6 +4,7 @@ module Terminitor
4
4
  attr_accessor :terminal, :windows, :working_dir, :termfile
5
5
 
6
6
  # set the terminal object, windows, and load the Termfile.
7
+ # @param [String] path to termfile
7
8
  def initialize(path)
8
9
  @termfile = load_termfile(path)
9
10
  end
@@ -26,6 +27,9 @@ module Terminitor
26
27
 
27
28
  # this command will run commands in the designated window
28
29
  # run_in_window 'window1', {:tab1 => ['ls','ok']}
30
+ # @param [String] name of window
31
+ # @param [Hash] Hash of window's content extracted from Termfile
32
+ # @param [Hash] Hash of options
29
33
  def run_in_window(window_name, window_content, options = {})
30
34
  window_options = window_content[:options]
31
35
  first_tab = true
@@ -44,19 +48,22 @@ module Terminitor
44
48
  else
45
49
  tab = ( tab_key == 'default' ? active_window : open_tab(tab_options) ) # give us the current window if its default, else open a tab.
46
50
  end
47
- tab_content[:commands].insert(0, window_content[:before]).flatten! if window_content[:before] # append our before block commands.
48
- tab_content[:commands].insert(0, 'clear') if tab_name || !@working_dir.to_s.empty? # clean up prompt
49
- tab_content[:commands].insert(0, "PS1=$PS1\"\\e]2;#{tab_name}\\a\"") if tab_name # add title to tab
51
+ # append our before block commands.
52
+ tab_content[:commands].insert(0, window_content[:before]).flatten! if window_content[:before]
53
+ # clean up prompt
54
+ tab_content[:commands].insert(0, 'clear') if tab_name || !@working_dir.to_s.empty?
55
+ # add title to tab
56
+ tab_content[:commands].insert(0, "PS1=$PS1\"\\e]2;#{tab_name}\\a\"") if tab_name
50
57
  tab_content[:commands].insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
51
- tab_content[:commands].each do |cmd|
52
- execute_command(cmd, :in => tab)
53
- end
58
+ tab_content[:commands].each { |cmd| execute_command(cmd, :in => tab) }
54
59
  end
55
60
  set_delayed_options
56
61
  end
57
62
 
58
63
  # Loads commands via the termfile and returns them as a hash
59
64
  # if it matches legacy yaml, parse as yaml, else use new dsl
65
+ # @param [String] path to termfile
66
+ # @return [Hash] returns a hash containing termfile details
60
67
  def load_termfile(path)
61
68
  File.extname(path) == '.yml' ? Terminitor::Yaml.new(path).to_hash : Terminitor::Dsl.new(path).to_hash
62
69
  end
@@ -67,11 +74,14 @@ module Terminitor
67
74
 
68
75
  # Executes the Command
69
76
  # should use the :in key to interact with terminal object.
77
+ # @param [String] command to be ran.
78
+ # @param [Hash] options hash
70
79
  # execute_command 'cd /path/to', {:in => #<TerminalObject>}
71
80
  def execute_command(cmd, options = {})
72
81
  end
73
82
 
74
83
  # Opens a new tab and returns itself.
84
+ # @param [Hash] options hash.
75
85
  def open_tab(options = nil)
76
86
  @working_dir = Dir.pwd # pass in current directory.
77
87
  end
@@ -81,6 +91,7 @@ module Terminitor
81
91
  end
82
92
 
83
93
  # Opens a new window and returns the tab object.
94
+ # @param [Hahs] options hash.
84
95
  def open_window(options = nil)
85
96
  @working_dir = Dir.pwd # pass in current directory.
86
97
  end
@@ -0,0 +1,7 @@
1
+ module Terminitor
2
+ class CmdCapture < AbstractCapture
3
+ def initialize
4
+ super
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Terminitor
2
+ # Captures terminal windows and tabs for Terminator
3
+ class TerminatorCapture < AbstractCapture
4
+ def initialize
5
+ super
6
+ end
7
+ end
8
+ end
9
+
@@ -29,14 +29,14 @@ module Terminitor
29
29
  desc "list", "lists all terminitor scripts"
30
30
  def list
31
31
  say "Global scripts: \n"
32
- Dir.glob("#{ENV['HOME']}/.terminitor/*").each do |file|
32
+ Dir.glob("#{TERM_PATH}/*").each do |file|
33
33
  say " * #{File.basename(file, '.term')} #{grab_comment_for_file(file)}"
34
34
  end
35
35
  end
36
36
 
37
37
  desc "init", "create initial root terminitor folder"
38
38
  def init
39
- empty_directory "#{ENV['HOME']}/.terminitor"
39
+ empty_directory TERM_PATH
40
40
  end
41
41
 
42
42
  desc "edit PROJECT_NAME", "open termitor script"
@@ -91,5 +91,16 @@ module Terminitor
91
91
  remove_file path
92
92
  end
93
93
 
94
+ desc "update", "update Terminitor to new global path(.config/.terminitor)"
95
+ def update
96
+ if File.exists?(old_path = File.join(ENV['HOME'],'.terminitor/'))
97
+ FileUtils.cp_r "#{old_path}/.", TERM_PATH
98
+ FileUtils.rm_r old_path
99
+ say "Terminitor has updated your global folder to ~/.config/terminitor/ !"
100
+ else
101
+ say "Old .terminitor/ global path doesn't exist. cool."
102
+ end
103
+ end
104
+
94
105
  end
95
106
  end
@@ -0,0 +1,35 @@
1
+ module Terminitor
2
+ class CmdCore < AbstractCore
3
+ attr_reader :current_window
4
+
5
+ CMD_XLT = {
6
+ 'clear' => 'cls'
7
+ }
8
+
9
+ def initialize(path)
10
+ @current_window = CurrentWindowsConsole.new
11
+ super
12
+ end
13
+
14
+ def execute_command(cmd, options = {})
15
+ cmd = CMD_XLT[cmd] || cmd
16
+ cmd += "\n" if (cmd =~ /\n\Z/).nil?
17
+ (options[:in] || current_window).send_command(cmd)
18
+ end
19
+
20
+ def open_tab(options = nil)
21
+ create_window
22
+ end
23
+
24
+ def open_window(options = nil)
25
+ create_window
26
+ end
27
+
28
+ def create_window
29
+ WindowsConsole.new :name=>'cmd'
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+
@@ -0,0 +1,273 @@
1
+ module Terminitor
2
+ #
3
+ # Thanks win32/autogui!
4
+ #
5
+ module Input
6
+
7
+ # MSDN virtual key codes
8
+ VK_LBUTTON = 0x01
9
+ VK_RBUTTON = 0x02
10
+
11
+ VK_CANCEL = 0x03
12
+ VK_BACK = 0x08
13
+ VK_TAB = 0x09
14
+ VK_CLEAR = 0x0c
15
+ VK_RETURN = 0x0d
16
+ VK_SHIFT = 0x10
17
+ VK_CONTROL = 0x11
18
+ VK_MENU = 0x12
19
+ VK_PAUSE = 0x13
20
+ VK_ESCAPE = 0x1b
21
+ VK_SPACE = 0x20
22
+ VK_PRIOR = 0x21
23
+ VK_NEXT = 0x22
24
+ VK_END = 0x23
25
+ VK_HOME = 0x24
26
+ VK_LEFT = 0x25
27
+ VK_UP = 0x26
28
+ VK_RIGHT = 0x27
29
+ VK_DOWN = 0x28
30
+ VK_SELECT = 0x29
31
+ VK_EXECUTE = 0x2b
32
+ VK_SNAPSHOT = 0x2c
33
+ VK_INSERT = 0x2d
34
+ VK_DELETE = 0x2e
35
+ VK_HELP = 0x2f
36
+
37
+ VK_0 = 0x30
38
+ VK_1 = 0x31
39
+ VK_2 = 0x32
40
+ VK_3 = 0x33
41
+ VK_4 = 0x34
42
+ VK_5 = 0x35
43
+ VK_6 = 0x36
44
+ VK_7 = 0x37
45
+ VK_8 = 0x38
46
+ VK_9 = 0x39
47
+ VK_A = 0x41
48
+ VK_B = 0x42
49
+ VK_C = 0x43
50
+ VK_D = 0x44
51
+ VK_E = 0x45
52
+ VK_F = 0x46
53
+ VK_G = 0x47
54
+ VK_H = 0x48
55
+ VK_I = 0x49
56
+ VK_J = 0x4a
57
+ VK_K = 0x4b
58
+ VK_L = 0x4c
59
+ VK_M = 0x4d
60
+ VK_N = 0x4e
61
+ VK_O = 0x4f
62
+ VK_P = 0x50
63
+ VK_Q = 0x51
64
+ VK_R = 0x52
65
+ VK_S = 0x53
66
+ VK_T = 0x54
67
+ VK_U = 0x55
68
+ VK_V = 0x56
69
+ VK_W = 0x57
70
+ VK_X = 0x58
71
+ VK_Y = 0x59
72
+ VK_Z = 0x5a
73
+
74
+ VK_LWIN = 0x5b
75
+ VK_RWIN = 0x5c
76
+ VK_APPS = 0x5d
77
+
78
+ VK_NUMPAD0 = 0x60
79
+ VK_NUMPAD1 = 0x61
80
+ VK_NUMPAD2 = 0x62
81
+ VK_NUMPAD3 = 0x63
82
+ VK_NUMPAD4 = 0x64
83
+ VK_NUMPAD5 = 0x65
84
+ VK_NUMPAD6 = 0x66
85
+ VK_NUMPAD7 = 0x67
86
+ VK_NUMPAD8 = 0x68
87
+ VK_NUMPAD9 = 0x69
88
+ VK_MULTIPLY = 0x6a
89
+ VK_ADD = 0x6b
90
+ VK_SEPARATOR = 0x6c
91
+ VK_SUBTRACT = 0x6d
92
+ VK_DECIMAL = 0x6e
93
+ VK_DIVIDE = 0x6f
94
+
95
+ VK_F1 = 0x70
96
+ VK_F2 = 0x71
97
+ VK_F3 = 0x72
98
+ VK_F4 = 0x73
99
+ VK_F5 = 0x74
100
+ VK_F6 = 0x75
101
+ VK_F7 = 0x76
102
+ VK_F8 = 0x77
103
+ VK_F9 = 0x78
104
+ VK_F10 = 0x79
105
+ VK_F11 = 0x7a
106
+ VK_F12 = 0x7b
107
+
108
+ VK_NUMLOCK = 0x90
109
+ VK_SCROLL = 0x91
110
+ VK_OEM_EQU = 0x92
111
+ VK_LSHIFT = 0xa0
112
+ VK_RSHIFT = 0xa1
113
+ VK_LCONTROL = 0xa2
114
+ VK_RCONTROL = 0xa3
115
+ VK_LMENU = 0xa4
116
+ VK_RMENU = 0xa5
117
+
118
+ VK_OEM_1 = 0xba # US ";:"
119
+ VK_OEM_PLUS = 0xbb
120
+ VK_OEM_COMMA = 0xbc
121
+ VK_OEM_MINUS = 0xbd
122
+ VK_OEM_PERIOD = 0xbe
123
+ VK_OEM_2 = 0xbf # US "/?"
124
+ VK_OEM_3 = 0xc0 # US '`~'
125
+ VK_OEM_4 = 0xdb # US "[{"
126
+ VK_OEM_5 = 0xdc # US '\|'
127
+ VK_OEM_6 = 0xdd # US ']}'
128
+ VK_OEM_7 = 0xde # US quotes
129
+ VK_OEM_8 = 0xdf # none
130
+
131
+ # delay in seconds between keystrokes
132
+ KEYBD_KEYDELAY = 0
133
+
134
+ # keybd_event
135
+ KEYBD_EVENT_KEYUP = 2
136
+ KEYBD_EVENT_KEYDOWN = 0
137
+
138
+ Windows::API.auto_namespace = 'Terminitor::Input'
139
+ Windows::API.auto_constant = true
140
+ Windows::API.auto_method = true
141
+ Windows::API.auto_unicode = false
142
+
143
+ Windows::API.new('keybd_event', 'IILL', 'V', 'user32')
144
+ Windows::API.new('mouse_event', 'LLLLL', 'V', 'user32')
145
+
146
+ # Send keystroke to the focused window, keystrokes are virtual keycodes
147
+ #
148
+ # @example send 2+2<CR>
149
+ #
150
+ # keystroke(VK_2, VK_ADD, VK_2, VK_RETURN)
151
+ #
152
+ def keystroke(*keys)
153
+ return if keys.empty?
154
+
155
+ keybd_event keys.first, 0, KEYBD_EVENT_KEYDOWN, 0
156
+ sleep KEYBD_KEYDELAY
157
+ keystroke *keys[1..-1]
158
+ sleep KEYBD_KEYDELAY
159
+ keybd_event keys.first, 0, KEYBD_EVENT_KEYUP, 0
160
+ end
161
+
162
+ # String together keystrokes, simulates the user typing.
163
+ #
164
+ # Note: This method can be slow for large strings. Consider using
165
+ # the clipboard instead.
166
+ #
167
+ # @see Clipboard
168
+ #
169
+ # @example send 2+2<CR>
170
+ #
171
+ # type_in("2+2\n")
172
+ #
173
+ # @param [String] string of characters to simulate typing
174
+ def type_in(string)
175
+ string.each_char do |char|
176
+ keystroke(*char_to_virtual_keycode(char))
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ # convert a single character to a virtual keycode
183
+ #
184
+ # @param [Char] char is the character to convert
185
+ #
186
+ # @return [Array] of virtual keycodes
187
+ def char_to_virtual_keycode(char)
188
+
189
+ unless char.size == 1
190
+ raise "virtual keycode conversion is for single characters only"
191
+ end
192
+
193
+ code = char.unpack('U')[0]
194
+
195
+ case char
196
+ when '0'..'9'
197
+ [code - ?0 + 0x30]
198
+ when 'A'..'Z'
199
+ [VK_SHIFT, code]
200
+ when 'a'..'z'
201
+ [code - ?a + ?A]
202
+ when ' '
203
+ [code]
204
+ when '+'
205
+ [VK_ADD]
206
+ when '='
207
+ [VK_OEM_PLUS]
208
+ when ','
209
+ [VK_OEM_COMMA]
210
+ when '.'
211
+ [VK_OEM_PERIOD]
212
+ when '-'
213
+ [VK_OEM_MINUS]
214
+ when '_'
215
+ [VK_SHIFT, VK_OEM_MINUS]
216
+
217
+ when ';'
218
+ [VK_OEM_1]
219
+ when ':'
220
+ [VK_SHIFT, VK_OEM_1]
221
+ when '/'
222
+ [VK_OEM_2]
223
+ when '?'
224
+ [VK_SHIFT, VK_OEM_2]
225
+ when '`'
226
+ [VK_OEM_3]
227
+ when '~'
228
+ [VK_SHIFT, VK_OEM_3]
229
+ when '['
230
+ [VK_OEM_4]
231
+ when '{'
232
+ [VK_SHIFT, VK_OEM_4]
233
+ when '\\'
234
+ [VK_OEM_5]
235
+ when '|'
236
+ [VK_SHIFT, VK_OEM_5]
237
+ when ']'
238
+ [VK_OEM_6]
239
+ when '}'
240
+ [VK_SHIFT, VK_OEM_6]
241
+ when "'"
242
+ [VK_OEM_7]
243
+ when '"'
244
+ [VK_SHIFT, VK_OEM_7]
245
+
246
+ when '!'
247
+ [VK_SHIFT, VK_1]
248
+ when '@'
249
+ [VK_SHIFT, VK_2]
250
+ when '#'
251
+ [VK_SHIFT, VK_3]
252
+ when '$'
253
+ [VK_SHIFT, VK_4]
254
+ when '%'
255
+ [VK_SHIFT, VK_5]
256
+ when '^'
257
+ [VK_SHIFT, VK_6]
258
+ when '&'
259
+ [VK_SHIFT, VK_7]
260
+ when '*'
261
+ [VK_SHIFT, VK_8]
262
+ when '('
263
+ [VK_SHIFT, VK_9]
264
+ when ')'
265
+ [VK_SHIFT, VK_0]
266
+ when "\n"
267
+ [VK_RETURN]
268
+ else
269
+ raise "No conversion exists for character #{char}"
270
+ end
271
+ end
272
+ end
273
+ end