termup 1.3.1 → 2.0.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.
- data/README.md +15 -13
- data/lib/templates/iterm_advanced.yml +25 -0
- data/lib/templates/iterm_basic.yml +15 -0
- data/lib/templates/template.yml +8 -14
- data/lib/termup.rb +3 -2
- data/lib/termup/base.rb +62 -51
- data/lib/termup/cli.rb +10 -2
- data/lib/termup/handler.rb +111 -0
- data/lib/termup/version.rb +1 -1
- metadata +14 -11
data/README.md
CHANGED
@@ -5,10 +5,12 @@ Automate opening up terminal tabs (or split panes) with a set of routine command
|
|
5
5
|
|
6
6
|
It's the easiest way to get started for your projects every day.
|
7
7
|
|
8
|
-
Compatible with Terminal.app
|
8
|
+
Compatible with Terminal.app and iTerm 2 on Mac OS X 10.6 - 10.8 and Ruby 1.8.7 - 1.9.3.
|
9
9
|
|
10
10
|

|
11
11
|
|
12
|
+
**iTerm 1 users** the current version is not compatible with iTerms 1. Use v1.3.1 - `gem install termup -v=1.3.1`
|
13
|
+
|
12
14
|
Installation
|
13
15
|
------------
|
14
16
|
|
@@ -26,38 +28,38 @@ Usage
|
|
26
28
|
Call the following command:
|
27
29
|
|
28
30
|
```sh
|
29
|
-
$ termup create
|
31
|
+
$ termup create myproject
|
30
32
|
```
|
31
33
|
|
32
|
-
This will create a new project at `~/.config/termup/
|
34
|
+
This will create a new project at `~/.config/termup/myproject.yml`. Edit the file:
|
33
35
|
|
34
36
|
```sh
|
35
|
-
$ termup edit
|
37
|
+
$ termup edit myproject
|
36
38
|
```
|
37
39
|
|
38
40
|
And now you're good to go:
|
39
41
|
|
40
42
|
```sh
|
41
|
-
$ termup start
|
43
|
+
$ termup start myproject
|
42
44
|
```
|
43
45
|
|
44
46
|
### YAML Syntax ###
|
45
47
|
|
46
48
|
```yaml
|
47
|
-
# ~/.config/termup/
|
49
|
+
# ~/.config/termup/myproject.yml
|
48
50
|
---
|
49
51
|
tabs:
|
50
|
-
|
52
|
+
tab1:
|
51
53
|
- cd ~/projects/foo
|
52
54
|
- git status
|
53
|
-
-
|
54
|
-
|
55
|
+
- subl .
|
56
|
+
tab2:
|
55
57
|
- mysql -u root
|
56
58
|
- show databases;
|
57
|
-
|
59
|
+
tab3:
|
58
60
|
- cd ~/projects/foo
|
59
61
|
- tail -f log/development.log
|
60
|
-
|
62
|
+
tab4:
|
61
63
|
- cd ~/projects/foo
|
62
64
|
- autotest
|
63
65
|
options:
|
@@ -73,10 +75,10 @@ Tabs can contain a single command, or YAML arrays to execute multiple commands.
|
|
73
75
|
Commands have a shortcut for even fewer keystrokes.
|
74
76
|
|
75
77
|
```sh
|
76
|
-
$ termup s
|
78
|
+
$ termup s myproject
|
77
79
|
```
|
78
80
|
|
79
|
-
That's equivalent to `termup start
|
81
|
+
That's equivalent to `termup start myproject`.
|
80
82
|
|
81
83
|
### iTerm 2 Split Pane Support ###
|
82
84
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# COMMENT OF SCRIPT HERE
|
2
|
+
---
|
3
|
+
tabs:
|
4
|
+
pane1:
|
5
|
+
commands:
|
6
|
+
- echo tab1
|
7
|
+
layout:
|
8
|
+
- split_vertically
|
9
|
+
pane2:
|
10
|
+
commands:
|
11
|
+
- echo tab2
|
12
|
+
layout:
|
13
|
+
- split_horizontally
|
14
|
+
pane3:
|
15
|
+
commands:
|
16
|
+
- echo tab3
|
17
|
+
layout:
|
18
|
+
- split_horizontally
|
19
|
+
pane4:
|
20
|
+
properties:
|
21
|
+
foreground_color: yellow
|
22
|
+
background_color: blue
|
23
|
+
transparency: 0.1
|
24
|
+
commands:
|
25
|
+
- echo tab4
|
data/lib/templates/template.yml
CHANGED
@@ -1,17 +1,11 @@
|
|
1
1
|
# COMMENT OF SCRIPT HERE
|
2
2
|
---
|
3
3
|
tabs:
|
4
|
-
|
5
|
-
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
-
|
10
|
-
|
11
|
-
|
12
|
-
- cd ~/foo/project
|
13
|
-
- autotest
|
14
|
-
options:
|
15
|
-
iterm:
|
16
|
-
width: 2
|
17
|
-
height: 2
|
4
|
+
tab1:
|
5
|
+
- echo tab1
|
6
|
+
tab2:
|
7
|
+
- echo tab2
|
8
|
+
tab3:
|
9
|
+
- echo tab3
|
10
|
+
tab4:
|
11
|
+
- echo tab4
|
data/lib/termup.rb
CHANGED
data/lib/termup/base.rb
CHANGED
@@ -1,79 +1,90 @@
|
|
1
|
-
require 'appscript'
|
2
1
|
require 'yaml'
|
3
2
|
|
4
3
|
module Termup
|
5
4
|
class Base
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(project)
|
6
|
+
@handler = Termup::Handler.new
|
8
7
|
|
9
|
-
|
8
|
+
config = YAML.load(File.read("#{TERMUP_DIR}/#{project}.yml"))
|
9
|
+
@tabs = config['tabs']
|
10
10
|
|
11
|
-
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
@terminal = app(@frontmost)
|
11
|
+
# Config file compatibility checking
|
12
|
+
if @tabs.is_a?(Array) and @tabs.first.is_a?(Hash)
|
13
|
+
abort 'YAML syntax for config has been changed. See https://github.com/kenn/termup for details.'
|
14
|
+
end
|
16
15
|
|
17
|
-
@
|
16
|
+
@options = config['options'] || {}
|
17
|
+
@iterm_options = @options['iterm']
|
18
18
|
|
19
19
|
# Split panes for iTerm 2
|
20
|
-
split_panes if
|
20
|
+
split_panes if @handler.iterm? and @iterm_options
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
@terminal.current_terminal.current_session.write(:text => "#{cmd}")
|
32
|
-
end
|
22
|
+
# Setting up tabs / panes
|
23
|
+
@tabs.each_with_index do |(tabname, values), index|
|
24
|
+
# Set tab title
|
25
|
+
@handler.set_property(:name, tabname)
|
26
|
+
|
27
|
+
# Run commands
|
28
|
+
(advanced_iterm? ? values['commands'] : values).each do |command|
|
29
|
+
@handler.run command
|
33
30
|
end
|
34
|
-
end
|
35
|
-
end
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
# Layout
|
33
|
+
if advanced_iterm?
|
34
|
+
values['properties'].each do |key, value|
|
35
|
+
@handler.set_property(key, value)
|
36
|
+
end if values['properties']
|
37
|
+
|
38
|
+
values['layout'].each do |command|
|
39
|
+
layout command
|
40
|
+
end if values['layout']
|
41
41
|
else
|
42
|
-
|
42
|
+
# Move to next
|
43
|
+
if @iterm_options
|
44
|
+
layout :goto_next_pane
|
45
|
+
else
|
46
|
+
if index < @tabs.size - 1
|
47
|
+
layout :new_tab
|
48
|
+
sleep 0.01 # Allow some time to complete opening a new tab
|
49
|
+
else
|
50
|
+
layout :goto_next_tab # Back home
|
51
|
+
end
|
52
|
+
end
|
43
53
|
end
|
44
54
|
end
|
45
|
-
@got_first_tab_already = true
|
46
|
-
sleep 0.01 # Allow some time to complete opening a new tab
|
47
|
-
@terminal.windows[1].tabs.last.get if terminal?
|
48
55
|
end
|
49
56
|
|
50
57
|
def split_panes
|
51
|
-
|
52
|
-
|
53
|
-
|
58
|
+
width, height = @iterm_options['width'], @iterm_options['height']
|
59
|
+
return unless width and height
|
60
|
+
|
61
|
+
(width - 1).times do
|
62
|
+
layout :split_vertically
|
54
63
|
end
|
55
|
-
# Back
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
(@project['options']['iterm']['height'] - 1).times do |i|
|
60
|
-
@apps[@frontmost].keystroke('d', :using => [ :command_down, :shift_down ])
|
64
|
+
layout :goto_next_pane # Back home
|
65
|
+
width.times do
|
66
|
+
(height - 1).times do
|
67
|
+
layout :split_horizontally
|
61
68
|
end
|
62
|
-
# Move to
|
63
|
-
@apps[@frontmost].keystroke(']', :using => :command_down)
|
69
|
+
layout :goto_next_pane # Move to next, or back home
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
67
|
-
def
|
68
|
-
@
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
+
def advanced_iterm?
|
74
|
+
unless defined?(@advanced_iterm)
|
75
|
+
@advanced_iterm = case @tabs.values.first
|
76
|
+
when Hash then true
|
77
|
+
when Array then false
|
78
|
+
else
|
79
|
+
abort 'invalid YAML format'
|
80
|
+
end
|
81
|
+
abort 'advanced config only supported for iTerm' if @advanced_iterm and !@handler.iterm?
|
82
|
+
end
|
83
|
+
@advanced_iterm
|
73
84
|
end
|
74
85
|
|
75
|
-
def
|
76
|
-
@
|
86
|
+
def layout(command)
|
87
|
+
@handler.layout(command)
|
77
88
|
end
|
78
89
|
end
|
79
90
|
end
|
data/lib/termup/cli.rb
CHANGED
@@ -17,7 +17,9 @@ module Termup
|
|
17
17
|
map 'l' => :list
|
18
18
|
map 's' => :start
|
19
19
|
|
20
|
-
desc 'create PROJECT', 'Create termup project (Shortcut: c)'
|
20
|
+
desc 'create PROJECT', 'Create termup project (Shortcut: c, Options: --iterm_basic / --iterm_advanced)'
|
21
|
+
method_option :iterm_basic, :type => :boolean, :required => false
|
22
|
+
method_option :iterm_advanced, :type => :boolean, :required => false
|
21
23
|
def create(project)
|
22
24
|
edit(project)
|
23
25
|
end
|
@@ -26,7 +28,13 @@ module Termup
|
|
26
28
|
def edit(project)
|
27
29
|
unless File.exists?(path(project))
|
28
30
|
empty_directory TERMUP_DIR
|
29
|
-
|
31
|
+
if options['iterm_advanced']
|
32
|
+
template 'templates/iterm_advanced.yml', path(project)
|
33
|
+
elsif options['iterm_basic']
|
34
|
+
template 'templates/iterm_basic.yml', path(project)
|
35
|
+
else
|
36
|
+
template 'templates/template.yml', path(project)
|
37
|
+
end
|
30
38
|
end
|
31
39
|
say 'please set $EDITOR in ~/.bash_profile' and return unless editor = ENV['EDITOR']
|
32
40
|
system("#{editor} #{path(project)}")
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'appscript'
|
2
|
+
|
3
|
+
module Termup
|
4
|
+
class Handler
|
5
|
+
def app(*args)
|
6
|
+
Appscript.app(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(command)
|
10
|
+
if terminal?
|
11
|
+
app_process.do_script(command, :in => app_process.windows[1].tabs.last.get)
|
12
|
+
else
|
13
|
+
app_process.current_terminal.current_session.write(:text => command)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_property(key, value)
|
18
|
+
if iterm?
|
19
|
+
app_process.current_terminal.current_session.send(key).set(value)
|
20
|
+
else
|
21
|
+
# No-op for terminal for now
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def activate
|
26
|
+
app_process.activate
|
27
|
+
end
|
28
|
+
|
29
|
+
def hit(key, *using)
|
30
|
+
activate
|
31
|
+
case key
|
32
|
+
when Integer
|
33
|
+
app('System Events').key_code key, using && { :using => using }
|
34
|
+
when String
|
35
|
+
app('System Events').keystroke key, using && { :using => using }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def terminal?
|
40
|
+
app_name == 'Terminal'
|
41
|
+
end
|
42
|
+
|
43
|
+
def iterm?
|
44
|
+
app_name == 'iTerm'
|
45
|
+
end
|
46
|
+
|
47
|
+
def app_name
|
48
|
+
@app_name ||= app_process.name.get
|
49
|
+
end
|
50
|
+
|
51
|
+
def app_process
|
52
|
+
@app_process ||= app.by_pid(term_pid)
|
53
|
+
end
|
54
|
+
|
55
|
+
def term_pid
|
56
|
+
return @term_pid if @term_pid
|
57
|
+
|
58
|
+
pid = Process.ppid
|
59
|
+
|
60
|
+
# Go up the process tree to find term-like process
|
61
|
+
100.times do
|
62
|
+
ppid = `ps -p #{pid} -o ppid=`.strip.to_i
|
63
|
+
|
64
|
+
abort 'terminal pid not found!' if ppid == 1
|
65
|
+
|
66
|
+
if term_like_pids.include?(ppid)
|
67
|
+
@term_pid = ppid
|
68
|
+
break
|
69
|
+
end
|
70
|
+
|
71
|
+
pid = ppid
|
72
|
+
end
|
73
|
+
|
74
|
+
@term_pid
|
75
|
+
end
|
76
|
+
|
77
|
+
def term_like_pids
|
78
|
+
@term_like_pids ||= `ps x | grep Term`.split("\n").reject{|i| i =~ /grep/ }.map{|i| i.match(/^\d+/).to_s.to_i }
|
79
|
+
end
|
80
|
+
|
81
|
+
def layout(command)
|
82
|
+
if iterm?
|
83
|
+
case command.to_sym
|
84
|
+
when :new_tab then hit 't', :command_down
|
85
|
+
when :close_tab then hit 'w', :command_down
|
86
|
+
when :goto_previous_tab then hit '[', :command_down, :shift_down
|
87
|
+
when :goto_next_tab then hit ']', :command_down, :shift_down
|
88
|
+
when :goto_previous_pane then hit '[', :command_down
|
89
|
+
when :goto_next_pane then hit ']', :command_down
|
90
|
+
when :split_vertically then hit 'd', :command_down
|
91
|
+
when :split_horizontally then hit 'd', :command_down, :shift_down
|
92
|
+
when :go_left then hit 123, :command_down, :option_down
|
93
|
+
when :go_right then hit 124, :command_down, :option_down
|
94
|
+
when :go_down then hit 125, :command_down, :option_down
|
95
|
+
when :go_up then hit 126, :command_down, :option_down
|
96
|
+
else
|
97
|
+
abort "Unknown iTerm2.app command: #{command}"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
case command.to_sym
|
101
|
+
when :new_tab then hit 't', :command_down
|
102
|
+
when :close_tab then hit 'w', :command_down
|
103
|
+
when :goto_previous_tab then hit '[', :command_down, :shift_down
|
104
|
+
when :goto_next_tab then hit ']', :command_down, :shift_down
|
105
|
+
else
|
106
|
+
abort "Unknown Terminal.app command: #{command}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/termup/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: termup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,40 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rb-appscript
|
16
|
+
prerelease: false
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 0.6.1
|
22
|
+
none: false
|
22
23
|
type: :runtime
|
23
|
-
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
25
|
requirements:
|
27
26
|
- - ~>
|
28
27
|
- !ruby/object:Gem::Version
|
29
28
|
version: 0.6.1
|
29
|
+
none: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: thor
|
32
|
+
prerelease: false
|
32
33
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: 0.16.0
|
38
|
+
none: false
|
38
39
|
type: :runtime
|
39
|
-
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
41
|
requirements:
|
43
42
|
- - ~>
|
44
43
|
- !ruby/object:Gem::Version
|
45
44
|
version: 0.16.0
|
45
|
+
none: false
|
46
46
|
description: Setup terminal tabs with preset commands for your projects
|
47
47
|
email:
|
48
48
|
- kenn.ejima@gmail.com
|
@@ -53,15 +53,17 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- .gitignore
|
55
55
|
- Gemfile
|
56
|
-
- Gemfile.lock
|
57
56
|
- LICENSE
|
58
57
|
- README.md
|
59
58
|
- Rakefile
|
60
59
|
- bin/termup
|
60
|
+
- lib/templates/iterm_advanced.yml
|
61
|
+
- lib/templates/iterm_basic.yml
|
61
62
|
- lib/templates/template.yml
|
62
63
|
- lib/termup.rb
|
63
64
|
- lib/termup/base.rb
|
64
65
|
- lib/termup/cli.rb
|
66
|
+
- lib/termup/handler.rb
|
65
67
|
- lib/termup/version.rb
|
66
68
|
- termup.gemspec
|
67
69
|
homepage: https://github.com/kenn/termup
|
@@ -71,17 +73,17 @@ rdoc_options: []
|
|
71
73
|
require_paths:
|
72
74
|
- lib
|
73
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
76
|
requirements:
|
76
77
|
- - ! '>='
|
77
78
|
- !ruby/object:Gem::Version
|
78
79
|
version: '0'
|
79
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
80
|
none: false
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
82
|
requirements:
|
82
83
|
- - ! '>='
|
83
84
|
- !ruby/object:Gem::Version
|
84
85
|
version: '0'
|
86
|
+
none: false
|
85
87
|
requirements: []
|
86
88
|
rubyforge_project:
|
87
89
|
rubygems_version: 1.8.24
|
@@ -89,3 +91,4 @@ signing_key:
|
|
89
91
|
specification_version: 3
|
90
92
|
summary: Setup terminal tabs with preset commands for your projects
|
91
93
|
test_files: []
|
94
|
+
has_rdoc:
|