terminitor 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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