teamocil 0.3.9 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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