teamocil 0.3.7 → 0.3.8

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 CHANGED
@@ -51,6 +51,7 @@ If you are not using a top-level `session` key, then the first key of your layou
51
51
  * `name` (the name that will appear in `tmux` statusbar)
52
52
  * `root` (the directory in which every split will be created)
53
53
  * `filters` (a hash of `before` and `after` commands to run for each split)
54
+ * `clear` (whether or not to prepend a `clear` command before the `before` filters list)
54
55
  * `splits` (an array of split items)
55
56
  * `options` (a hash of tmux options, see `man tmux` for a list)
56
57
 
@@ -59,6 +60,7 @@ If you are not using a top-level `session` key, then the first key of your layou
59
60
  ```yaml
60
61
  windows:
61
62
  - name: "my-first-window"
63
+ clear: true
62
64
  options:
63
65
  synchronize-panes: true
64
66
  root: "~/Projects/foo-www"
@@ -87,7 +89,8 @@ Every window must define an array of splits that will be created within it. A ve
87
89
  * `cmd` (the commands to initially execute in the split)
88
90
  * `width` (the split width, in percentage)
89
91
  * `height` (the split width, in percentage)
90
- * `target` (the split to set focus on, before creating the current one)
92
+ * `target` (the split to set focus on before creating the current one)
93
+ * `focus` (the split to set focus on after initializing all the splits for a window)
91
94
 
92
95
  #### Example
93
96
 
@@ -101,6 +104,7 @@ windows:
101
104
  splits:
102
105
  - cmd: "git status"
103
106
  - cmd: "bundle exec rails server --port 4000"
107
+ focus: true
104
108
  width: 50
105
109
  - cmd:
106
110
  - "sudo service memcached start"
@@ -185,9 +189,9 @@ To get autocompletion when typing `teamocil <Tab>` in a zsh session, add this li
185
189
  compctl -g '~/.teamocil/*(:t:r)' teamocil
186
190
  ```
187
191
 
188
- ### ERB Support
192
+ ### ERB support
189
193
 
190
- You can use ERB in your config files. For example, you can use an environment variable in your config like so:
194
+ You can use ERB in your layouts. For example, you can use an environment variable in a layout like so:
191
195
 
192
196
  ```yaml
193
197
  windows:
@@ -208,6 +212,7 @@ Feel free to contribute and submit issues/pull requests [on GitHub](https://gith
208
212
 
209
213
  * Samuel Garneau ([garno](https://github.com/garno))
210
214
  * Jimmy Bourassa ([jbourassa](https://github.com/jbourassa))
215
+ * Brandon Dimcheff ([bdimcheff](https://github.com/bdimcheff))
211
216
 
212
217
  Take a look at the `spec` folder before you do, and make sure `bundle exec rake spec` passes after your modifications :)
213
218
 
@@ -4,6 +4,7 @@ windows:
4
4
  - cmd: "echo 'first split'"
5
5
  - cmd: "echo 'second split'"
6
6
  width: 50
7
+ focus: true
7
8
  - cmd: "echo 'fourth split'"
8
9
  height: 50
9
10
  target: bottom-right
data/lib/teamocil.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Teamocil
2
- VERSION = "0.3.7"
2
+ VERSION = "0.3.8"
3
3
  autoload :Layout, "teamocil/layout"
4
4
  autoload :CLI, "teamocil/cli"
5
+ autoload :Error, "teamocil/error"
5
6
  end
data/lib/teamocil/cli.rb CHANGED
@@ -36,7 +36,12 @@ module Teamocil
36
36
  yaml = ERB.new(File.read(file)).result
37
37
 
38
38
  @layout = Teamocil::Layout.new(YAML.load(yaml), @options)
39
- @layout.compile!
39
+
40
+ begin
41
+ @layout.compile!
42
+ rescue Teamocil::Error::LayoutError => e
43
+ bail e.message
44
+ end
40
45
  @layout.execute_commands(@layout.generate_commands)
41
46
  end
42
47
  end # }}}
@@ -0,0 +1,6 @@
1
+ module Teamocil
2
+ module Error
3
+ class StandardError < ::StandardError; end
4
+ class LayoutError < StandardError; end
5
+ end
6
+ end
@@ -10,7 +10,8 @@ module Teamocil
10
10
  # @param options [Hash] the options, mostly passed by the CLI
11
11
  # @param attrs [Hash] the session data from the layout file
12
12
  def initialize(options, attrs={}) # {{{
13
- @name = attrs["name"]
13
+ raise Teamocil::Error::LayoutError.new("You must specify a `windows` or `session` key for your layout.") unless attrs["windows"]
14
+ @name = attrs["name"] || "teamocil-session"
14
15
  @windows = attrs["windows"].each_with_index.map { |window, window_index| Window.new(self, window_index, window) }
15
16
  @options = options
16
17
  end # }}}
@@ -22,8 +23,6 @@ module Teamocil
22
23
  commands = []
23
24
  commands << "tmux rename-session \"#{@name}\"" unless @name.nil?
24
25
  commands << @windows.map(&:generate_commands)
25
- commands << "tmux select-pane -t 0"
26
- commands
27
26
  end # }}}
28
27
 
29
28
  end
@@ -3,7 +3,7 @@ module Teamocil
3
3
 
4
4
  # This class represents a split within a tmux window
5
5
  class Split
6
- attr_reader :width, :height, :cmd, :index, :target
6
+ attr_reader :width, :height, :cmd, :index, :target, :focus
7
7
 
8
8
  # Initialize a new tmux split
9
9
  #
@@ -11,10 +11,12 @@ module Teamocil
11
11
  # @param index [Fixnnum] the split index
12
12
  # @param attrs [Hash] the split data from the layout file
13
13
  def initialize(window, index, attrs={}) # {{{
14
+ raise Teamocil::Error::LayoutError.new("You cannot have empty splits") if attrs.nil?
14
15
  @height = attrs["height"]
15
16
  @width = attrs["width"]
16
17
  @cmd = attrs["cmd"]
17
18
  @target = attrs["target"]
19
+ @focus = attrs["focus"] || false
18
20
 
19
21
  @window = window
20
22
  @index = index
@@ -41,7 +43,7 @@ module Teamocil
41
43
  end
42
44
 
43
45
  # Wrap all commands around filters
44
- @cmd = [@window.filters["before"]] + [@cmd] + [@window.filters["after"]]
46
+ @cmd = [@window.filters["before"]] + [@window.clear] + [@cmd] + [@window.filters["after"]]
45
47
 
46
48
  # If a `root` key exist, start each split in this directory
47
49
  @cmd.unshift "cd \"#{@window.root}\"" unless @window.root.nil?
@@ -3,7 +3,7 @@ module Teamocil
3
3
 
4
4
  # This class represents a window within tmux
5
5
  class Window
6
- attr_reader :filters, :root, :splits, :options, :index, :name
6
+ attr_reader :filters, :root, :splits, :options, :index, :name, :clear
7
7
 
8
8
  # Initialize a new tmux window
9
9
  #
@@ -11,11 +11,13 @@ module Teamocil
11
11
  # @param index [Fixnnum] the window index
12
12
  # @param attrs [Hash] the window data from the layout file
13
13
  def initialize(session, index, attrs={}) # {{{
14
- @name = attrs["name"]
15
- @root = attrs["root"]
14
+ @name = attrs["name"] || "teamocil-window-#{index+1}"
15
+ @root = attrs["root"] || "."
16
+ @clear = attrs["clear"] == true ? "clear" : nil
16
17
  @options = attrs["options"] || {}
17
18
 
18
19
  @splits = attrs["splits"] || []
20
+ raise Teamocil::Error::LayoutError.new("You must specify a `splits` key for every window.") if @splits.empty?
19
21
  @splits = @splits.each_with_index.map { |split, split_index| Split.new(self, split_index, split) }
20
22
 
21
23
  @filters = attrs["filters"] || {}
@@ -46,6 +48,8 @@ module Teamocil
46
48
  commands << "tmux set-window-option #{option} #{value}"
47
49
  end
48
50
 
51
+ commands << "tmux select-pane -t #{@splits.map(&:focus).index(true) || 0}"
52
+
49
53
  commands
50
54
  end # }}}
51
55
 
@@ -2,6 +2,7 @@
2
2
  two-windows:
3
3
  windows:
4
4
  - name: "foo"
5
+ clear: true
5
6
  root: "/foo"
6
7
  splits:
7
8
  - cmd: "echo 'foo'"
@@ -15,6 +16,7 @@ two-windows:
15
16
  - "echo 'bar in an array'"
16
17
  target: bottom-right
17
18
  - cmd: "echo 'bar again'"
19
+ focus: true
18
20
  width: 50
19
21
 
20
22
  # Simple two windows layout with filters
@@ -39,5 +41,11 @@ three-windows-within-a-session:
39
41
  name: "my awesome session"
40
42
  windows:
41
43
  - name: "first window"
44
+ splits:
45
+ - cmd: "echo 'foo'"
42
46
  - name: "second window"
47
+ splits:
48
+ - cmd: "echo 'foo'"
43
49
  - name: "third window"
50
+ splits:
51
+ - cmd: "echo 'foo'"
data/spec/layout_spec.rb CHANGED
@@ -8,6 +8,23 @@ describe Teamocil::Layout do
8
8
  @layout = Teamocil::Layout.new(layouts["two-windows"], {})
9
9
  end # }}}
10
10
 
11
+ describe "handles bad layouts" do # {{{
12
+ it "does not compile without windows" do # {{{
13
+ @layout = Teamocil::Layout.new({ "name" => "foo" }, {})
14
+ lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
15
+ end # }}}
16
+
17
+ it "does not compile without splits" do # {{{
18
+ @layout = Teamocil::Layout.new({ "windows" => [{ "name" => "foo" }] }, {})
19
+ lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
20
+ end # }}}
21
+
22
+ it "does not compile with empty splits" do # {{{
23
+ @layout = Teamocil::Layout.new({ "windows" => [{ "name" => "foo", "splits" => [nil, nil] }] }, {})
24
+ lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
25
+ end # }}}
26
+ end # }}}
27
+
11
28
  describe "windows" do # {{{
12
29
  it "creates windows" do # {{{
13
30
  session = @layout.compile!
@@ -27,6 +44,12 @@ describe Teamocil::Layout do
27
44
  session.windows[0].root.should == "/foo"
28
45
  session.windows[1].root.should == "/bar"
29
46
  end # }}}
47
+
48
+ it "creates windows with clear option" do # {{{
49
+ session = @layout.compile!
50
+ session.windows[0].clear.should == "clear"
51
+ session.windows[1].clear.should be_nil
52
+ end # }}}
30
53
  end # }}}
31
54
 
32
55
  describe "splits" do # {{{
@@ -54,6 +77,12 @@ describe Teamocil::Layout do
54
77
  session.windows.last.splits[0].cmd.first.should == "echo 'bar'"
55
78
  session.windows.last.splits[0].cmd.last.should == "echo 'bar in an array'"
56
79
  end # }}}
80
+
81
+ it "handles focused splits" do # {{{
82
+ session = @layout.compile!
83
+ session.windows.last.splits[1].focus.should be_true
84
+ session.windows.last.splits[0].focus.should be_false
85
+ end # }}}
57
86
  end # }}}
58
87
 
59
88
  describe "filters" do # {{{
@@ -109,12 +138,25 @@ describe Teamocil::Layout do
109
138
  @layout = Teamocil::Layout.new(layouts["two-windows"], {})
110
139
  end # }}}
111
140
 
112
- it "should generate commands" do #{{{
141
+ it "should generate split commands" do #{{{
113
142
  session = @layout.compile!
114
143
  commands = session.windows.last.splits[0].generate_commands
115
144
  commands.length.should == 2
116
145
  commands.first.should == "tmux send-keys -t 0 \"export TEAMOCIL=1 && cd \"/bar\" && echo 'bar' && echo 'bar in an array'\""
117
146
  commands.last.should == "tmux send-keys -t 0 Enter"
147
+
148
+ session = @layout.compile!
149
+ commands = session.windows.first.splits[0].generate_commands
150
+ commands.length.should == 2
151
+ commands.first.should == "tmux send-keys -t 0 \"export TEAMOCIL=1 && cd \"/foo\" && clear && echo 'foo'\""
152
+ commands.last.should == "tmux send-keys -t 0 Enter"
153
+ end # }}}
154
+
155
+ it "should generate window commands" do #{{{
156
+ session = @layout.compile!
157
+ commands = session.windows.last.generate_commands
158
+ commands.first.should == "tmux new-window -n \"bar\""
159
+ commands.last.should == "tmux select-pane -t 1"
118
160
  end # }}}
119
161
  end
120
162
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teamocil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.7
4
+ version: 0.3.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-29 00:00:00.000000000Z
12
+ date: 2012-08-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -97,6 +97,7 @@ files:
97
97
  - examples/simple-two-vertical-splits.yml
98
98
  - lib/teamocil.rb
99
99
  - lib/teamocil/cli.rb
100
+ - lib/teamocil/error.rb
100
101
  - lib/teamocil/layout.rb
101
102
  - lib/teamocil/layout/session.rb
102
103
  - lib/teamocil/layout/split.rb
@@ -126,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  version: '0'
127
128
  segments:
128
129
  - 0
129
- hash: 2721488511741570961
130
+ hash: -4311130867002785670
130
131
  required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  none: false
132
133
  requirements:
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  version: '0'
136
137
  segments:
137
138
  - 0
138
- hash: 2721488511741570961
139
+ hash: -4311130867002785670
139
140
  requirements: []
140
141
  rubyforge_project:
141
142
  rubygems_version: 1.8.18