teamocil 0.3.9 → 0.4

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjUwMTBkNTkxZjQyMjMzOTU5ZTAxYmZlN2EyZDdlMDNjZmFmOWRlZQ==
5
+ data.tar.gz: !binary |-
6
+ NTY4Nzc1ZjAzMjQzZTYyOTA4NzhhNWRiNjI4NGE0NzFiNWZhYzMzOQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZmVhMDQ3ZWUyOGZkOGYwZWE4NzdlNTcwZjkxNTZmYmEyZjYwMDg1MzBjYjEz
10
+ MjU5MGEwZmQ5YWM0ZjI0MzJmMDFjYzM3Y2M1ZjVhMGJmMTQxNjk1ZWE5N2Q3
11
+ ZjZhZjExNDEyZDlhOWQ2MmRjMmQxMDJlYWQ3M2UyYWE4MWMxNjY=
12
+ data.tar.gz: !binary |-
13
+ NTZjOWZmMTFmMDNkNGFkNGFhZjkxNTdlZjY2MDhiNWYyNWI0ZGYwOTExMTgx
14
+ MzY4NjYyYWVhOWZlNGViMmQ3ZGJjMWZiY2QyZTliMjExOTdhMjQxNDcxMGM2
15
+ ZDgwY2EzOTcwNzE5NzdlZDgxNWQ4Yjg0YjU2M2IyNzNiY2IyZWE=
data/README.md CHANGED
@@ -51,9 +51,25 @@ If you are not using a top-level `session` key, then the first key of your layou
51
51
  * `root` (the directory in which every split will be created)
52
52
  * `filters` (a hash of `before` and `after` commands to run for each split)
53
53
  * `clear` (whether or not to prepend a `clear` command before the `before` filters list)
54
- * `layout` (a layout name or serialized string supported by `tmux`’s `select-layout` command)
54
+ * `layout` (a layout name or serialized string supported by the `tmux select-layout` command)
55
55
  * `splits` (an array of split items)
56
- * `options` (a hash of tmux options, see `man tmux` for a list)
56
+ * `options` (a hash of `tmux` options, see `man tmux` for a list)
57
+
58
+ #### Notes
59
+
60
+ If you want to use a custom value for the `layout` key, running this command will give you the layout of the current window:
61
+
62
+ ```bash
63
+ $ tmux list-windows -F "#{window_active} #{window_layout}" | grep "^1" | cut -d " " -f 2
64
+ ```
65
+
66
+ You can then use the value as a string, like so:
67
+
68
+ ```yaml
69
+ - name: "a-window-with-weird-layout"
70
+ layout: "4d71,204x51,0,0{101x51,0,0,114,102x51,102,0[102x10,102,0,118,102x40,102,11,115]}"
71
+ splits: …
72
+ ```
57
73
 
58
74
  #### Example
59
75
 
@@ -66,15 +82,17 @@ windows:
66
82
  root: "~/Projects/foo-www"
67
83
  filters:
68
84
  before:
69
- - "echo 'Let’s use ruby-1.9.2 for each split in this window.'"
70
- - "rvm use 1.9.2"
85
+ - "echo 'Let’s use ruby-1.9.3 for each split in this window.'"
86
+ - "rbenv local 1.9.3-p374"
71
87
  splits:
72
88
  [splits list]
73
89
  - name: "my-second-window"
90
+ layout: tiled
74
91
  root: "~/Projects/foo-api"
75
92
  splits:
76
93
  [splits list]
77
94
  - name: "my-third-window"
95
+ layout: main-vertical
78
96
  root: "~/Projects/foo-daemons"
79
97
  splits:
80
98
  [splits list]
@@ -82,7 +100,7 @@ windows:
82
100
 
83
101
  ### Splits
84
102
 
85
- Every window must define an array of splits that will be created within it. A vertical or horizontal split will be created, depending on whether the `width` or `height` parameter is used.
103
+ Every window must define an array of splits that will be created within it. A vertical or horizontal split will be created, depending on whether the `width` or `height` parameter is used. If a `layout` option is used for the window, the `width` and `height` attributes won’t have any effect.
86
104
 
87
105
  #### Item keys
88
106
 
@@ -98,18 +116,17 @@ Every window must define an array of splits that will be created within it. A ve
98
116
  windows:
99
117
  - name: "my-first-window"
100
118
  root: "~/Projects/foo-www"
119
+ layout: even-vertical
101
120
  filters:
102
- before: "rvm use 1.9.2"
121
+ before: "rbenv local 2.0.0-p0"
103
122
  after: "echo 'I am done initializing this split.'"
104
123
  splits:
105
124
  - cmd: "git status"
106
125
  - cmd: "bundle exec rails server --port 4000"
107
126
  focus: true
108
- width: 50
109
127
  - cmd:
110
128
  - "sudo service memcached start"
111
129
  - "sudo service mongodb start"
112
- height: 50
113
130
  ```
114
131
 
115
132
  ## Layout examples
@@ -124,10 +141,10 @@ See more example files in the `examples` directory.
124
141
  windows:
125
142
  - name: "sample-two-splits"
126
143
  root: "~/Code/sample/www"
144
+ layout: even-horizontal
127
145
  splits:
128
146
  - cmd: ["pwd", "ls -la"]
129
147
  - cmd: "rails server --port 3000"
130
- width: 50
131
148
  ```
132
149
 
133
150
 
@@ -153,16 +170,12 @@ windows:
153
170
  windows:
154
171
  - name: "sample-four-splits"
155
172
  root: "~/Code/sample/www"
173
+ layout: tiled
156
174
  splits:
157
175
  - cmd: "pwd"
158
176
  - cmd: "pwd"
159
- width: 50
160
177
  - cmd: "pwd"
161
- height: 50
162
- target: "bottom-right"
163
178
  - cmd: "pwd"
164
- height: 50
165
- target: "bottom-left"
166
179
  ```
167
180
 
168
181
  #### Result of `$ teamocil sample-2`
@@ -226,4 +239,4 @@ Take a look at the `spec` folder before you do, and make sure `bundle exec rake
226
239
 
227
240
  ## License
228
241
 
229
- Teamocil is © 2011-2012 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [MIT license](https://github.com/remiprev/teamocil/blob/master/LICENSE). See the `LICENSE` file.
242
+ Teamocil is © 2011-2013 [Rémi Prévost](http://exomel.com) and may be freely distributed under the [MIT license](https://github.com/remiprev/teamocil/blob/master/LICENSE). See the `LICENSE` file.
data/Rakefile CHANGED
@@ -7,13 +7,13 @@ require "rspec/core/rake_task"
7
7
  task :default => :spec
8
8
 
9
9
  desc "Run all specs"
10
- RSpec::Core::RakeTask.new(:spec) do |task| # {{{
10
+ RSpec::Core::RakeTask.new(:spec) do |task|
11
11
  task.pattern = "spec/**/*_spec.rb"
12
12
  task.rspec_opts = "--colour --format=documentation"
13
- end # }}}
13
+ end
14
14
 
15
15
  desc "Generate YARD Documentation"
16
- YARD::Rake::YardocTask.new do |task| # {{{
16
+ YARD::Rake::YardocTask.new do |task|
17
17
  task.options = [
18
18
  "-o", File.expand_path("../doc", __FILE__),
19
19
  "--readme=README.md",
@@ -25,4 +25,4 @@ YARD::Rake::YardocTask.new do |task| # {{{
25
25
  "--title=Teamocil",
26
26
  ]
27
27
  task.files = ["lib/**/*.rb"]
28
- end # }}}
28
+ end
@@ -0,0 +1,8 @@
1
+ windows:
2
+ - name: simple-four-splits
3
+ layout: tiled
4
+ splits:
5
+ - cmd: echo 'first split'
6
+ - cmd: echo 'second split'
7
+ - cmd: echo 'fourth split'
8
+ - cmd: echo 'third split'
@@ -0,0 +1,8 @@
1
+ windows:
2
+ - name: simple-one-and-three-splits
3
+ layout: main-vertical
4
+ splits:
5
+ - cmd: echo 'first split'
6
+ - cmd: echo 'second split'
7
+ - cmd: echo 'third split'
8
+ - cmd: echo 'fourth split'
@@ -0,0 +1,10 @@
1
+ windows:
2
+ - name: simple-six-splits
3
+ layout: tiled
4
+ splits:
5
+ - cmd: echo 'first split'
6
+ - cmd: echo 'second split'
7
+ - cmd: echo 'fourth split'
8
+ - cmd: echo 'third split'
9
+ - cmd: echo 'sixth split'
10
+ - cmd: echo 'fifth split'
@@ -0,0 +1,6 @@
1
+ windows:
2
+ - name: simple-two-vertical-splits
3
+ layout: even-horizontal
4
+ splits:
5
+ - cmd: echo 'first split'
6
+ - cmd: echo 'second split'
@@ -0,0 +1,6 @@
1
+ windows:
2
+ - name: simple-two-horizontal-splits
3
+ layout: even-vertical
4
+ splits:
5
+ - cmd: echo 'first split'
6
+ - cmd: echo 'second split'
data/lib/teamocil.rb CHANGED
@@ -1,6 +1,7 @@
1
+ require "teamocil/layout"
2
+ require "teamocil/cli"
3
+ require "teamocil/error"
4
+
1
5
  module Teamocil
2
- VERSION = "0.3.9"
3
- autoload :Layout, "teamocil/layout"
4
- autoload :CLI, "teamocil/cli"
5
- autoload :Error, "teamocil/error"
6
+ VERSION = "0.4"
6
7
  end
data/lib/teamocil/cli.rb CHANGED
@@ -5,14 +5,13 @@ require 'erb'
5
5
  module Teamocil
6
6
  # This class handles interaction with the `tmux` utility.
7
7
  class CLI
8
-
9
8
  attr_accessor :layout, :layouts
10
9
 
11
10
  # Initialize a new run of `tmux`
12
11
  #
13
12
  # @param argv [Hash] the command line parameters hash (usually `ARGV`).
14
13
  # @param env [Hash] the environment variables hash (usually `ENV`).
15
- def initialize(argv, env) # {{{
14
+ def initialize(argv, env)
16
15
  parse_options! argv
17
16
  layout_path = env["TEAMOCIL_PATH"] || File.join("#{env["HOME"]}", ".teamocil")
18
17
 
@@ -44,10 +43,10 @@ module Teamocil
44
43
  end
45
44
  @layout.execute_commands(@layout.generate_commands)
46
45
  end
47
- end # }}}
46
+ end
48
47
 
49
48
  # Parse the command line options
50
- def parse_options!(args) # {{{
49
+ def parse_options!(args)
51
50
  @options = {}
52
51
  opts = ::OptionParser.new do |opts|
53
52
  opts.banner = "Usage: teamocil [options] <layout>
@@ -76,28 +75,27 @@ module Teamocil
76
75
 
77
76
  end
78
77
  opts.parse! args
79
- end # }}}
78
+ end
80
79
 
81
80
  # Return an array of available layouts
82
81
  #
83
82
  # @param path [String] the path used to look for layouts
84
- def get_layouts(path) # {{{
83
+ def get_layouts(path)
85
84
  Dir.glob(File.join(path, "*.yml")).map { |file| File.basename(file).gsub(/\..+$/, "") }.sort
86
- end # }}}
85
+ end
87
86
 
88
87
  # Print each layout on a single line
89
- def print_layouts # {{{
88
+ def print_layouts
90
89
  STDOUT.puts @layouts.join("\n")
91
90
  exit 0
92
- end # }}}
91
+ end
93
92
 
94
93
  # Print an error message and exit the utility
95
94
  #
96
95
  # @param msg [Mixed] something to print before exiting.
97
- def bail(msg) # {{{
96
+ def bail(msg)
98
97
  STDERR.puts "[teamocil] #{msg}"
99
98
  exit 1
100
- end # }}}
101
-
99
+ end
102
100
  end
103
101
  end
@@ -1,46 +1,44 @@
1
- module Teamocil
1
+ require "teamocil/layout/session"
2
+ require "teamocil/layout/window"
3
+ require "teamocil/layout/split"
2
4
 
5
+ module Teamocil
3
6
  # This class act as a wrapper around a tmux YAML layout file
4
7
  class Layout
5
- autoload :Session, "teamocil/layout/session"
6
- autoload :Window, "teamocil/layout/window"
7
- autoload :Split, "teamocil/layout/split"
8
-
9
8
  attr_reader :session
10
9
 
11
10
  # Initialize a new layout from a hash
12
11
  #
13
12
  # @param layout [Hash] the parsed layout
14
13
  # @param options [Hash] some options
15
- def initialize(layout, options={}) # {{{
14
+ def initialize(layout, options={})
16
15
  @layout = layout
17
16
  @options = options
18
- end # }}}
17
+ end
19
18
 
20
19
  # Generate tmux commands based on the data found in the layout file
21
20
  #
22
21
  # @return [Array] an array of shell commands to send
23
- def generate_commands # {{{
22
+ def generate_commands
24
23
  @session.generate_commands
25
- end # }}}
24
+ end
26
25
 
27
26
  # Compile the layout into objects
28
27
  #
29
28
  # @return [Session]
30
- def compile! # {{{
29
+ def compile!
31
30
  if @layout["session"].nil?
32
31
  @session = Session.new @options, "windows" => @layout["windows"]
33
32
  else
34
33
  @session = Session.new @options, @layout["session"]
35
34
  end
36
- end # }}}
35
+ end
37
36
 
38
37
  # Execute each command in the shell
39
38
  #
40
39
  # @param commands [Array] an array of complete commands to send to the shell
41
- def execute_commands(commands) # {{{
40
+ def execute_commands(commands)
42
41
  `#{commands.join("; ")}`
43
- end # }}}
44
-
42
+ end
45
43
  end
46
44
  end
@@ -1,6 +1,5 @@
1
1
  module Teamocil
2
2
  class Layout
3
-
4
3
  # This class represents a session within tmux
5
4
  class Session
6
5
  attr_reader :options, :windows, :name
@@ -9,22 +8,21 @@ module Teamocil
9
8
  #
10
9
  # @param options [Hash] the options, mostly passed by the CLI
11
10
  # @param attrs [Hash] the session data from the layout file
12
- def initialize(options, attrs={}) # {{{
11
+ def initialize(options, attrs={})
13
12
  raise Teamocil::Error::LayoutError.new("You must specify a `windows` or `session` key for your layout.") unless attrs["windows"]
14
13
  @name = attrs["name"] || "teamocil-session"
15
14
  @windows = attrs["windows"].each_with_index.map { |window, window_index| Window.new(self, window_index, window) }
16
15
  @options = options
17
- end # }}}
16
+ end
18
17
 
19
18
  # Generate commands to send to tmux
20
19
  #
21
20
  # @return [Array]
22
- def generate_commands # {{{
21
+ def generate_commands
23
22
  commands = []
24
23
  commands << "tmux rename-session \"#{@name}\"" unless @name.nil?
25
24
  commands << @windows.map(&:generate_commands)
26
- end # }}}
27
-
25
+ end
28
26
  end
29
27
  end
30
28
  end
@@ -1,6 +1,5 @@
1
1
  module Teamocil
2
2
  class Layout
3
-
4
3
  # This class represents a split within a tmux window
5
4
  class Split
6
5
  attr_reader :width, :height, :cmd, :index, :target, :focus
@@ -10,7 +9,7 @@ module Teamocil
10
9
  # @param session [Session] the window where the split is initialized
11
10
  # @param index [Fixnnum] the split index
12
11
  # @param attrs [Hash] the split data from the layout file
13
- def initialize(window, index, attrs={}) # {{{
12
+ def initialize(window, index, attrs={})
14
13
  raise Teamocil::Error::LayoutError.new("You cannot have empty splits") if attrs.nil?
15
14
  @height = attrs["height"]
16
15
  @width = attrs["width"]
@@ -20,17 +19,17 @@ module Teamocil
20
19
 
21
20
  @window = window
22
21
  @index = index
23
- end # }}}
22
+ end
24
23
 
25
24
  # Generate commands to send to tmux
26
25
  #
27
26
  # @return [Array]
28
- def generate_commands # {{{
27
+ def generate_commands
29
28
  commands = []
30
29
 
31
30
  # Is it a vertical or horizontal split?
32
31
  init_command = ""
33
- unless @index == 0
32
+ unless @index == @window.pane_base_index
34
33
  if !@width.nil?
35
34
  init_command = "tmux split-window -h -p #{@width}"
36
35
  elsif !@height.nil?
@@ -56,9 +55,7 @@ module Teamocil
56
55
  commands << "tmux send-keys -t #{@index} Enter"
57
56
 
58
57
  commands
59
- end # }}}
60
-
58
+ end
61
59
  end
62
-
63
60
  end
64
61
  end
@@ -1,6 +1,5 @@
1
1
  module Teamocil
2
2
  class Layout
3
-
4
3
  # This class represents a window within tmux
5
4
  class Window
6
5
  attr_reader :filters, :root, :splits, :options, :index, :name, :clear, :layout
@@ -10,7 +9,7 @@ module Teamocil
10
9
  # @param session [Session] the session where the window is initialized
11
10
  # @param index [Fixnnum] the window index
12
11
  # @param attrs [Hash] the window data from the layout file
13
- def initialize(session, index, attrs={}) # {{{
12
+ def initialize(session, index, attrs={})
14
13
  @name = attrs["name"] || "teamocil-window-#{index+1}"
15
14
  @root = attrs["root"] || "."
16
15
  @clear = attrs["clear"] == true ? "clear" : nil
@@ -19,7 +18,7 @@ module Teamocil
19
18
 
20
19
  @splits = attrs["splits"] || []
21
20
  raise Teamocil::Error::LayoutError.new("You must specify a `splits` key for every window.") if @splits.empty?
22
- @splits = @splits.each_with_index.map { |split, split_index| Split.new(self, split_index, split) }
21
+ @splits = @splits.each_with_index.map { |split, split_index| Split.new(self, split_index + pane_base_index, split) }
23
22
 
24
23
  @filters = attrs["filters"] || {}
25
24
  @filters["before"] ||= []
@@ -27,12 +26,12 @@ module Teamocil
27
26
 
28
27
  @index = index
29
28
  @session = session
30
- end # }}}
29
+ end
31
30
 
32
31
  # Generate commands to send to tmux
33
32
  #
34
33
  # @return [Array]
35
- def generate_commands # {{{
34
+ def generate_commands
36
35
  commands = []
37
36
 
38
37
  if @session.options.include?(:here) and @index == 0
@@ -53,9 +52,18 @@ module Teamocil
53
52
  commands << "tmux select-pane -t #{@splits.map(&:focus).index(true) || 0}"
54
53
 
55
54
  commands
56
- end # }}}
55
+ end
57
56
 
57
+ # Return the `pane-base-index` option for the current window
58
+ #
59
+ # @return [Fixnum]
60
+ def pane_base_index
61
+ @pane_base_index ||= begin
62
+ global_setting = `tmux show-window-option -g pane-base-index`.split(/\s/).last
63
+ local_setting = `tmux show-window-option pane-base-index`.split(/\s/).last
64
+ (local_setting || global_setting || "0").to_i
65
+ end
66
+ end
58
67
  end
59
-
60
68
  end
61
69
  end
data/spec/cli_spec.rb CHANGED
@@ -2,77 +2,70 @@
2
2
  require File.join(File.dirname(__FILE__), "spec_helper.rb")
3
3
 
4
4
  describe Teamocil::CLI do
5
-
6
5
  context "executing" do
7
-
8
- before do # {{{
9
- @fake_env = { "TMUX" => 1, "HOME" => File.join(File.dirname(__FILE__), "fixtures") }
10
- end # }}}
6
+ before do
7
+ @fake_env = { "TMUX" => 1, "HOME" => File.join(File.dirname(__FILE__), "fixtures") }
8
+ end
11
9
 
12
10
  context "not in tmux" do
13
-
14
- it "should allow editing" do # {{{
11
+ it "should allow editing" do
15
12
  FileUtils.stub(:touch)
16
13
  Kernel.should_receive(:system).with("$EDITOR #{File.join(@fake_env["HOME"], ".teamocil", "my-layout.yml").inspect}")
17
14
  Teamocil::CLI.new(["--edit", "my-layout"], @fake_env)
18
- end # }}}
19
-
15
+ end
20
16
  end
21
17
 
22
18
  context "in tmux" do
23
-
24
- before :each do # {{{
19
+ before :each do
25
20
  Teamocil::CLI.messages = []
26
- end # }}}
21
+ end
27
22
 
28
- it "creates a layout from a name" do # {{{
23
+ it "creates a layout from a name" do
29
24
  @cli = Teamocil::CLI.new(["sample"], @fake_env)
30
25
  @cli.layout.session.name.should == "sample"
31
26
  @cli.layout.session.windows.length.should == 2
32
27
  @cli.layout.session.windows.first.name.should == "foo"
33
28
  @cli.layout.session.windows.last.name.should == "bar"
34
- end # }}}
29
+ end
35
30
 
36
- it "fails to create a layout from a layout that doesn’t exist" do # {{{
37
- lambda { @cli = Teamocil::CLI.new(["i-do-not-exist"], @fake_env) }.should raise_error SystemExit
31
+ it "fails to create a layout from a layout that doesn’t exist" do
32
+ expect { @cli = Teamocil::CLI.new(["i-do-not-exist"], @fake_env) }.to raise_error SystemExit
38
33
  Teamocil::CLI.messages.should include("There is no file \"#{File.join(File.dirname(__FILE__), "fixtures", ".teamocil", "i-do-not-exist.yml")}\"")
39
- end # }}}
34
+ end
40
35
 
41
- it "creates a layout from a specific file" do # {{{
36
+ it "creates a layout from a specific file" do
42
37
  @cli = Teamocil::CLI.new(["--layout", "./spec/fixtures/.teamocil/sample.yml"], @fake_env)
43
38
  @cli.layout.session.name.should == "sample"
44
39
  @cli.layout.session.windows.length.should == 2
45
40
  @cli.layout.session.windows.first.name.should == "foo"
46
41
  @cli.layout.session.windows.last.name.should == "bar"
47
- end # }}}
42
+ end
48
43
 
49
- it "fails to create a layout from a file that doesn’t exist" do # {{{
50
- lambda { @cli = Teamocil::CLI.new(["--layout", "./spec/fixtures/.teamocil/i-do-not-exist.yml"], @fake_env) }.should raise_error SystemExit
44
+ it "fails to create a layout from a file that doesn’t exist" do
45
+ expect { @cli = Teamocil::CLI.new(["--layout", "./spec/fixtures/.teamocil/i-do-not-exist.yml"], @fake_env) }.to raise_error SystemExit
51
46
  Teamocil::CLI.messages.should include("There is no file \"./spec/fixtures/.teamocil/i-do-not-exist.yml\"")
52
- end # }}}
47
+ end
53
48
 
54
- it "lists available layouts" do # {{{
49
+ it "lists available layouts" do
55
50
  @cli = Teamocil::CLI.new(["--list"], @fake_env)
56
51
  @cli.layouts.should == ["sample", "sample-2"]
57
- end # }}}
52
+ end
58
53
 
59
- it "should show the content" do # {{{
54
+ it "should show the content" do
60
55
  FileUtils.stub(:touch)
61
56
  Kernel.should_receive(:system).with("cat #{File.join(@fake_env["HOME"], ".teamocil", "sample.yml").inspect}")
62
57
  Teamocil::CLI.new(["--show", "sample"], @fake_env)
63
- end # }}}
58
+ end
64
59
 
65
- it "looks only in the $TEAMOCIL_PATH environment variable for layouts" do # {{{
60
+ it "looks only in the $TEAMOCIL_PATH environment variable for layouts" do
66
61
  @fake_env = { "TMUX" => 1, "HOME" => File.join(File.dirname(__FILE__), "fixtures"), "TEAMOCIL_PATH" => File.join(File.dirname(__FILE__), "fixtures/.my-fancy-layouts-directory") }
67
62
 
68
63
  @cli = Teamocil::CLI.new(["sample-3"], @fake_env)
69
64
  @cli.layout.session.name.should == "sample-3"
70
65
 
71
- lambda { @cli = Teamocil::CLI.new(["sample"], @fake_env) }.should raise_error SystemExit
66
+ expect { @cli = Teamocil::CLI.new(["sample"], @fake_env) }.to raise_error SystemExit
72
67
  Teamocil::CLI.messages.should include("There is no file \"#{@fake_env["TEAMOCIL_PATH"]}/sample.yml\"")
73
- end # }}}
74
-
68
+ end
75
69
  end
76
-
77
70
  end
78
71
  end
data/spec/layout_spec.rb CHANGED
@@ -2,149 +2,149 @@
2
2
  require File.join(File.dirname(__FILE__), "spec_helper.rb")
3
3
 
4
4
  describe Teamocil::Layout do
5
+ let(:window_pane_base_index) { 0 }
6
+ before { Teamocil::Layout::Window.any_instance.stub(:pane_base_index).and_return(window_pane_base_index) }
5
7
 
6
8
  context "compiling" do
7
- before do # {{{
9
+ before do
8
10
  @layout = Teamocil::Layout.new(layouts["two-windows"], {})
9
- end # }}}
11
+ end
10
12
 
11
- describe "handles bad layouts" do # {{{
12
- it "does not compile without windows" do # {{{
13
+ describe "handles bad layouts" do
14
+ it "does not compile without windows" do
13
15
  @layout = Teamocil::Layout.new({ "name" => "foo" }, {})
14
- lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
15
- end # }}}
16
+ expect { @layout.compile! }.to raise_error Teamocil::Error::LayoutError
17
+ end
16
18
 
17
- it "does not compile without splits" do # {{{
19
+ it "does not compile without splits" do
18
20
  @layout = Teamocil::Layout.new({ "windows" => [{ "name" => "foo" }] }, {})
19
- lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
20
- end # }}}
21
+ expect { @layout.compile! }.to raise_error Teamocil::Error::LayoutError
22
+ end
21
23
 
22
- it "does not compile with empty splits" do # {{{
24
+ it "does not compile with empty splits" do
23
25
  @layout = Teamocil::Layout.new({ "windows" => [{ "name" => "foo", "splits" => [nil, nil] }] }, {})
24
- lambda { @layout.compile! }.should raise_error Teamocil::Error::LayoutError
25
- end # }}}
26
- end # }}}
26
+ expect { @layout.compile! }.to raise_error Teamocil::Error::LayoutError
27
+ end
28
+ end
27
29
 
28
- describe "windows" do # {{{
29
- it "creates windows" do # {{{
30
+ describe "windows" do
31
+ it "creates windows" do
30
32
  session = @layout.compile!
31
33
  session.windows.each do |window|
32
34
  window.should be_an_instance_of Teamocil::Layout::Window
33
35
  end
34
- end # }}}
36
+ end
35
37
 
36
- it "creates windows with names" do # {{{
38
+ it "creates windows with names" do
37
39
  session = @layout.compile!
38
40
  session.windows[0].name.should == "foo"
39
41
  session.windows[1].name.should == "bar"
40
- end # }}}
42
+ end
41
43
 
42
- it "creates windows with root paths" do # {{{
44
+ it "creates windows with root paths" do
43
45
  session = @layout.compile!
44
46
  session.windows[0].root.should == "/foo"
45
47
  session.windows[1].root.should == "/bar"
46
- end # }}}
48
+ end
47
49
 
48
- it "creates windows with clear option" do # {{{
50
+ it "creates windows with clear option" do
49
51
  session = @layout.compile!
50
52
  session.windows[0].clear.should == "clear"
51
53
  session.windows[1].clear.should be_nil
52
- end # }}}
54
+ end
53
55
 
54
- it "creates windows with layout option" do # {{{
56
+ it "creates windows with layout option" do
55
57
  session = @layout.compile!
56
58
  session.windows[0].layout.should == "tiled"
57
59
  session.windows[1].layout.should be_nil
58
- end # }}}
59
- end # }}}
60
+ end
61
+ end
60
62
 
61
- describe "splits" do # {{{
62
- it "creates splits" do # {{{
63
+ describe "splits" do
64
+ it "creates splits" do
63
65
  session = @layout.compile!
64
66
  session.windows.first.splits.each do |split|
65
67
  split.should be_an_instance_of Teamocil::Layout::Split
66
68
  end
67
- end # }}}
69
+ end
68
70
 
69
- it "creates splits with dimensions" do # {{{
71
+ it "creates splits with dimensions" do
70
72
  session = @layout.compile!
71
73
  session.windows.first.splits[0].width.should == nil
72
74
  session.windows.first.splits[1].width.should == 50
73
- end # }}}
75
+ end
74
76
 
75
- it "creates splits with commands specified in strings" do # {{{
77
+ it "creates splits with commands specified in strings" do
76
78
  session = @layout.compile!
77
79
  session.windows.first.splits[0].cmd.should == "echo 'foo'"
78
- end # }}}
80
+ end
79
81
 
80
- it "creates splits with commands specified in an array" do # {{{
82
+ it "creates splits with commands specified in an array" do
81
83
  session = @layout.compile!
82
84
  session.windows.last.splits[0].cmd.length.should == 2
83
85
  session.windows.last.splits[0].cmd.first.should == "echo 'bar'"
84
86
  session.windows.last.splits[0].cmd.last.should == "echo 'bar in an array'"
85
- end # }}}
87
+ end
86
88
 
87
- it "handles focused splits" do # {{{
89
+ it "handles focused splits" do
88
90
  session = @layout.compile!
89
91
  session.windows.last.splits[1].focus.should be_true
90
92
  session.windows.last.splits[0].focus.should be_false
91
- end # }}}
92
- end # }}}
93
+ end
94
+ end
93
95
 
94
- describe "filters" do # {{{
95
- it "creates windows with before filters" do # {{{
96
+ describe "filters" do
97
+ it "creates windows with before filters" do
96
98
  layout = Teamocil::Layout.new(layouts["two-windows-with-filters"], {})
97
99
  session = layout.compile!
98
100
  session.windows.first.filters["before"].length.should == 2
99
101
  session.windows.first.filters["before"].first.should == "echo first before filter"
100
102
  session.windows.first.filters["before"].last.should == "echo second before filter"
101
- end # }}}
103
+ end
102
104
 
103
- it "creates windows with after filters" do # {{{
105
+ it "creates windows with after filters" do
104
106
  layout = Teamocil::Layout.new(layouts["two-windows-with-filters"], {})
105
107
  session = layout.compile!
106
108
  session.windows.first.filters["after"].length.should == 2
107
109
  session.windows.first.filters["after"].first.should == "echo first after filter"
108
110
  session.windows.first.filters["after"].last.should == "echo second after filter"
109
- end # }}}
111
+ end
110
112
 
111
- it "should handle blank filters" do # {{{
113
+ it "should handle blank filters" do
112
114
  session = @layout.compile!
113
115
  session.windows.first.filters.should have_key "after"
114
116
  session.windows.first.filters.should have_key "before"
115
117
  session.windows.first.filters["after"].should be_empty
116
118
  session.windows.first.filters["before"].should be_empty
117
- end # }}}
118
- end # }}}
119
+ end
120
+ end
119
121
 
120
- describe "targets" do # {{{
121
- it "should handle splits without a target" do # {{{
122
+ describe "targets" do
123
+ it "should handle splits without a target" do
122
124
  session = @layout.compile!
123
125
  session.windows.last.splits.last.target.should == nil
124
- end # }}}
126
+ end
125
127
 
126
- it "should handle splits with a target" do # {{{
128
+ it "should handle splits with a target" do
127
129
  session = @layout.compile!
128
130
  session.windows.last.splits.first.target.should == "bottom-right"
129
- end # }}}
130
- end # }}}
131
+ end
132
+ end
131
133
 
132
- describe "sessions" do # {{{
133
- it "should handle windows within a session" do # {{{
134
+ describe "sessions" do
135
+ it "should handle windows within a session" do
134
136
  layout = Teamocil::Layout.new(layouts["three-windows-within-a-session"], {})
135
137
  session = layout.compile!
136
138
  session.windows.length.should == 3
137
139
  session.name.should == "my awesome session"
138
- end # }}}
139
- end # }}}
140
+ end
141
+ end
140
142
  end
141
143
 
142
144
  context "generating commands" do
143
- before do # {{{
144
- @layout = Teamocil::Layout.new(layouts["two-windows"], {})
145
- end # }}}
145
+ before { @layout = Teamocil::Layout.new(layouts["two-windows"], {}) }
146
146
 
147
- it "should generate split commands" do #{{{
147
+ it "should generate split commands" do
148
148
  session = @layout.compile!
149
149
  commands = session.windows.last.splits[0].generate_commands
150
150
  commands.length.should == 2
@@ -156,14 +156,25 @@ describe Teamocil::Layout do
156
156
  commands.length.should == 2
157
157
  commands.first.should == "tmux send-keys -t 0 \"export TEAMOCIL=1 && cd \"/foo\" && clear && echo 'foo'\""
158
158
  commands.last.should == "tmux send-keys -t 0 Enter"
159
- end # }}}
159
+ end
160
160
 
161
- it "should generate window commands" do #{{{
161
+ it "should generate window commands" do
162
162
  session = @layout.compile!
163
163
  commands = session.windows.last.generate_commands
164
164
  commands.first.should == "tmux new-window -n \"bar\""
165
165
  commands.last.should == "tmux select-pane -t 1"
166
- end # }}}
167
- end
166
+ end
167
+
168
+ context "with custom pane-base-index option" do
169
+ let(:window_pane_base_index) { 2 }
168
170
 
171
+ it "should generate split commands" do
172
+ session = @layout.compile!
173
+ commands = session.windows.last.splits[0].generate_commands
174
+ commands.length.should == 2
175
+ commands.first.should == "tmux send-keys -t 2 \"export TEAMOCIL=1 && cd \"/bar\" && echo 'bar' && echo 'bar in an array'\""
176
+ commands.last.should == "tmux send-keys -t 2 Enter"
177
+ end
178
+ end
179
+ end
169
180
  end
data/spec/mock/cli.rb CHANGED
@@ -1,36 +1,33 @@
1
1
  module Teamocil
2
2
  module Mock
3
3
  module CLI
4
-
5
- def self.included(base) # {{{
4
+ def self.included(base)
6
5
  base.class_eval do
7
6
 
8
7
  # Return all messages
9
- def self.messages # {{{
8
+ def self.messages
10
9
  @@messages
11
- end # }}}
10
+ end
12
11
 
13
12
  # Change messages
14
- def self.messages=(messages) # {{{
13
+ def self.messages=(messages)
15
14
  @@messages = messages
16
- end # }}}
15
+ end
17
16
 
18
17
  # Do not print anything
19
- def print_layouts # {{{
18
+ def print_layouts
20
19
  # Nothing
21
- end # }}}
20
+ end
22
21
 
23
22
  # Print an error message and exit the utility
24
23
  #
25
24
  # @param msg [Mixed] something to print before exiting.
26
- def bail(msg) # {{{
25
+ def bail(msg)
27
26
  Teamocil::CLI.messages << msg
28
27
  exit 1
29
- end # }}}
30
-
28
+ end
31
29
  end
32
- end # }}}
33
-
30
+ end
34
31
  end
35
32
  end
36
33
  end
data/spec/mock/layout.rb CHANGED
@@ -1,18 +1,14 @@
1
1
  module Teamocil
2
2
  module Mock
3
3
  module Layout
4
-
5
- def self.included(base) # {{{
4
+ def self.included(base)
6
5
  base.class_eval do
7
-
8
6
  # Do not execute anything
9
7
  def execute_commands(commands)
10
8
  # Nothing
11
9
  end
12
-
13
10
  end
14
- end # }}}
15
-
11
+ end
16
12
  end
17
13
  end
18
14
  end
data/spec/spec_helper.rb CHANGED
@@ -6,12 +6,10 @@ require File.join(File.dirname(__FILE__), "./mock/layout.rb")
6
6
  require File.join(File.dirname(__FILE__), "./mock/cli.rb")
7
7
 
8
8
  module Helpers
9
-
10
- def layouts # {{{
9
+ def layouts
11
10
  return @@examples if defined?(@@examples)
12
11
  @@examples = YAML.load_file(File.join(File.dirname(__FILE__), "fixtures/layouts.yml"))
13
- end # }}}
14
-
12
+ end
15
13
  end
16
14
 
17
15
  RSpec.configure do |c|
data/teamocil.gemspec CHANGED
@@ -23,7 +23,7 @@ spec = Gem::Specification.new do |s|
23
23
 
24
24
  # Dependencies
25
25
  s.add_development_dependency "rake"
26
- s.add_development_dependency "rspec"
26
+ s.add_development_dependency "rspec", '~> 2.13'
27
27
  s.add_development_dependency "yard"
28
28
  s.add_development_dependency "maruku"
29
29
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teamocil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
5
- prerelease:
4
+ version: '0.4'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rémi Prévost
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-17 00:00:00.000000000Z
11
+ date: 2013-03-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,23 +27,20 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rspec
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ~>
36
32
  - !ruby/object:Gem::Version
37
- version: '0'
33
+ version: '2.13'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: '0'
40
+ version: '2.13'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: yard
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: maruku
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -90,11 +81,11 @@ files:
90
81
  - README.md
91
82
  - Rakefile
92
83
  - bin/teamocil
93
- - examples/simple-four-splits.yml
94
- - examples/simple-one-and-three-splits.yml
95
- - examples/simple-six-splits.yml
96
- - examples/simple-two-horitonzal-splits.yml
97
- - examples/simple-two-vertical-splits.yml
84
+ - examples/four-splits.yml
85
+ - examples/one-and-three-splits.yml
86
+ - examples/six-splits.yml
87
+ - examples/two-horizontal-splits.yml
88
+ - examples/two-vertical-splits.yml
98
89
  - lib/teamocil.rb
99
90
  - lib/teamocil/cli.rb
100
91
  - lib/teamocil/error.rb
@@ -115,33 +106,26 @@ files:
115
106
  homepage: http://remiprev.github.com/teamocil
116
107
  licenses:
117
108
  - MIT
109
+ metadata: {}
118
110
  post_install_message:
119
111
  rdoc_options: []
120
112
  require_paths:
121
113
  - lib
122
114
  required_ruby_version: !ruby/object:Gem::Requirement
123
- none: false
124
115
  requirements:
125
116
  - - ! '>='
126
117
  - !ruby/object:Gem::Version
127
118
  version: '0'
128
- segments:
129
- - 0
130
- hash: -2208554246657691212
131
119
  required_rubygems_version: !ruby/object:Gem::Requirement
132
- none: false
133
120
  requirements:
134
121
  - - ! '>='
135
122
  - !ruby/object:Gem::Version
136
123
  version: '0'
137
- segments:
138
- - 0
139
- hash: -2208554246657691212
140
124
  requirements: []
141
125
  rubyforge_project:
142
- rubygems_version: 1.8.18
126
+ rubygems_version: 2.0.0
143
127
  signing_key:
144
- specification_version: 3
128
+ specification_version: 4
145
129
  summary: Easy window and split layouts for tmux
146
130
  test_files:
147
131
  - spec/cli_spec.rb
@@ -1,13 +0,0 @@
1
- windows:
2
- - name: simple-four-splits
3
- splits:
4
- - cmd: "echo 'first split'"
5
- - cmd: "echo 'second split'"
6
- width: 50
7
- focus: true
8
- - cmd: "echo 'fourth split'"
9
- height: 50
10
- target: bottom-right
11
- - cmd: "echo 'third split'"
12
- height: 50
13
- target: bottom-left
@@ -1,12 +0,0 @@
1
- windows:
2
- - name: simple-one-and-three-splits
3
- splits:
4
- - cmd: "echo 'first split'"
5
- - cmd: "echo 'second split'"
6
- width: 50
7
- - cmd: "echo 'third split'"
8
- height: 66
9
- target: bottom-right
10
- - cmd: "echo 'fourth split'"
11
- height: 50
12
- target: bottom-right
@@ -1,18 +0,0 @@
1
- windows:
2
- - name: simple-six-splits
3
- splits:
4
- - cmd: "echo 'first split'"
5
- - cmd: "echo 'second split'"
6
- width: 50
7
- - cmd: "echo 'fourth split'"
8
- height: 66
9
- target: bottom-right
10
- - cmd: "echo 'third split'"
11
- height: 66
12
- target: bottom-left
13
- - cmd: "echo 'sixth split'"
14
- height: 50
15
- target: bottom-right
16
- - cmd: "echo 'fifth split'"
17
- height: 50
18
- target: bottom-left
@@ -1,6 +0,0 @@
1
- windows:
2
- - name: simple-two-horizontal-splits
3
- splits:
4
- - cmd: "echo 'first split'"
5
- - cmd: "echo 'second split'"
6
- height: 50
@@ -1,6 +0,0 @@
1
- windows:
2
- - name: simple-two-vertical-splits
3
- splits:
4
- - cmd: "echo 'first split'"
5
- - cmd: "echo 'second split'"
6
- width: 50