teamocil 0.1.11 → 0.2

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/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .rvmrc
3
3
  .local*
4
4
  .yardoc
5
+ doc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- teamocil (0.1.10)
4
+ teamocil (0.1.11)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/lib/teamocil.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Teamocil
2
- VERSION = "0.1.11"
2
+ VERSION = "0.2"
3
3
  autoload :Layout, "teamocil/layout"
4
4
  autoload :CLI, "teamocil/cli"
5
5
  end
data/lib/teamocil/cli.rb CHANGED
@@ -26,7 +26,8 @@ module Teamocil
26
26
  bail "There is no file \"#{file}\"" unless File.exists?(file)
27
27
  parsed_layout = YAML.load_file(file)
28
28
  layout = Teamocil::Layout.new(parsed_layout, @options)
29
- layout.to_tmux
29
+ layout.compile!
30
+ layout.execute_commands(layout.generate_commands)
30
31
  end
31
32
  end # }}}
32
33
 
@@ -1,7 +1,137 @@
1
1
  module Teamocil
2
- # This class act as a wrapper around a tmux YAML layout file.
2
+
3
+ # This class act as a wrapper around a tmux YAML layout file
3
4
  class Layout
4
5
 
6
+ # This class represents a session within tmux
7
+ class Session
8
+ attr_reader :options, :windows, :name
9
+
10
+ # Initialize a new tmux session
11
+ #
12
+ # @param options [Hash] the options, mostly passed by the CLI
13
+ # @param attrs [Hash] the session data from the layout file
14
+ def initialize(options, attrs={}) # {{{
15
+ @name = attrs["name"]
16
+ @windows = attrs["windows"].each_with_index.map { |window, index| Window.new(self, index, window) }
17
+ @options = options
18
+ end # }}}
19
+
20
+ # Generate commands to send to tmux
21
+ #
22
+ # @return [Array]
23
+ def generate_commands # {{{
24
+ commands = []
25
+ commands << "tmux rename-session \"#{@name}\"" unless @name.nil?
26
+ commands << @windows.map(&:generate_commands)
27
+ commands << "tmux select-pane -t 0"
28
+ commands
29
+ end # }}}
30
+
31
+ end
32
+
33
+ # This class represents a window within tmux
34
+ class Window
35
+ attr_reader :filters, :root, :splits, :options, :index, :name
36
+
37
+ # Initialize a new tmux window
38
+ #
39
+ # @param session [Session] the session where the window is initialized
40
+ # @param index [Fixnnum] the window index
41
+ # @param attrs [Hash] the window data from the layout file
42
+ def initialize(session, index, attrs={}) # {{{
43
+ @name = attrs["name"]
44
+ @root = attrs["root"]
45
+ @options = attrs["options"]
46
+ @filters = attrs["filters"]
47
+ @splits = attrs["splits"].each_with_index.map { |split, index| Split.new(self, index, split) }
48
+ @index = index
49
+ @session = session
50
+
51
+ @options ||= {}
52
+ @filters ||= {}
53
+ @filters["before"] ||= []
54
+ @filters["after"] ||= []
55
+ end # }}}
56
+
57
+ # Generate commands to send to tmux
58
+ #
59
+ # @return [Array]
60
+ def generate_commands # {{{
61
+ commands = []
62
+
63
+ if @session.options.include?(:here) and @index == 0
64
+ commands << "tmux rename-window \"#{@name}\""
65
+ else
66
+ commands << "tmux new-window -n \"#{@name}\""
67
+ end
68
+
69
+ commands << @splits.map(&:generate_commands)
70
+
71
+ @options.each_pair do |option, value|
72
+ value = "on" if value === true
73
+ value = "off" if value === false
74
+ commands << "tmux set-window-option #{option} #{value}"
75
+ end
76
+
77
+ commands
78
+ end # }}}
79
+
80
+ end
81
+
82
+ # This class represents a split within a tmux window
83
+ class Split
84
+ attr_reader :width, :height, :cmd, :index, :target
85
+
86
+ # Initialize a new tmux split
87
+ #
88
+ # @param session [Session] the window where the split is initialized
89
+ # @param index [Fixnnum] the split index
90
+ # @param attrs [Hash] the split data from the layout file
91
+ def initialize(window, index, attrs={}) # {{{
92
+ @height = attrs["height"]
93
+ @width = attrs["width"]
94
+ @cmd = attrs["cmd"]
95
+ @target = attrs["target"]
96
+ @window = window
97
+ @index = index
98
+ end # }}}
99
+
100
+ # Generate commands to send to tmux
101
+ #
102
+ # @return [Array]
103
+ def generate_commands # {{{
104
+ commands = []
105
+
106
+ # Is it a vertical or horizontal split?
107
+ unless @index == 0
108
+ if !@width.nil?
109
+ commands << "tmux split-window -h -p #{@width}"
110
+ elsif !@height.nil?
111
+ commands << "tmux split-window -p #{@height}"
112
+ else
113
+ commands << "tmux split-window"
114
+ end
115
+ commands << " -t #{@target}" unless @target.nil?
116
+ end
117
+
118
+ # Wrap all commands around filters
119
+ @cmd = [@window.filters["before"]] + [@cmd] + [@window.filters["after"]]
120
+
121
+ # If a `root` key exist, start each split in this directory
122
+ @cmd.unshift "cd \"#{@window.root}\"" unless @window.root.nil?
123
+
124
+ # Execute each split command
125
+ @cmd.flatten.compact.each do |command|
126
+ commands << "tmux send-keys -t #{@index} \"#{command}\""
127
+ commands << "tmux send-keys -t #{@index} Enter"
128
+ end
129
+
130
+ commands
131
+ end # }}}
132
+
133
+ end
134
+
5
135
  # Initialize a new layout from a hash
6
136
  #
7
137
  # @param layout [Hash] the parsed layout
@@ -11,79 +141,22 @@ module Teamocil
11
141
  @options = options
12
142
  end # }}}
13
143
 
14
- # Generate commands and sends them to tmux
15
- def to_tmux # {{{
16
- commands = generate_commands
17
- execute_commands(commands)
18
- end # }}}
19
-
20
144
  # Generate tmux commands based on the data found in the layout file
21
145
  #
22
146
  # @return [Array] an array of shell commands to send
23
147
  def generate_commands # {{{
24
- output = []
148
+ @session.generate_commands
149
+ end # }}}
25
150
 
26
- # Support renaming of current session
151
+ # Compile the layout into objects
152
+ #
153
+ # @return [Session]
154
+ def compile! # {{{
27
155
  if @layout["session"].nil?
28
- windows = @layout["windows"]
156
+ @session = Session.new @options, "windows" => @layout["windows"]
29
157
  else
30
- output << "tmux rename-session #{@layout["session"]["name"]}" if @layout["session"]["name"]
31
- windows = @layout["session"]["windows"]
32
- end
33
-
34
- windows.each_with_index do |window, window_index|
35
-
36
- # Create a new window unless we used the `--here` option
37
- if @options.include?(:here) and window_index == 0
38
- output << "tmux rename-window \"#{window["name"]}\""
39
- else
40
- output << "tmux new-window -n \"#{window["name"]}\""
41
- end
42
-
43
- # Make sure we have all the keys we need
44
- window["options"] ||= {}
45
- window["filters"] ||= {}
46
- window["filters"]["before"] ||= []
47
- window["filters"]["after"] ||= []
48
-
49
- # Create splits
50
- window["splits"].each_with_index do |split, split_index|
51
- unless split_index == 0
52
- if split.include?("width")
53
- cmd = "tmux split-window -h -p #{split["width"]}"
54
- elsif split.include?("height")
55
- cmd = "tmux split-window -p #{split["height"]}"
56
- else
57
- cmd = "tmux split-window"
58
- end
59
- cmd << " -t #{split["target"]}" if split.include?("target")
60
- output << cmd
61
- end
62
-
63
- # Wrap all commands around filters
64
- split["cmd"] = [window["filters"]["before"]] + [split["cmd"]] + [window["filters"]["after"]]
65
-
66
- # If a `root` key exist, start each split in this directory
67
- split["cmd"].unshift "cd \"#{window["root"]}\"" if window.include?("root")
68
-
69
- # Execute each split command
70
- split["cmd"].flatten.compact.each do |command|
71
- output << "tmux send-keys -t #{split_index} \"#{command}\""
72
- output << "tmux send-keys -t #{split_index} Enter"
73
- end
74
- end
75
-
76
- # Set tmux options
77
- window["options"].each_pair do |option, value|
78
- value = "on" if value === true
79
- value = "off" if value === false
80
- output << "tmux set-window-option #{option} #{value}"
81
- end
82
-
158
+ @session = Session.new @options, @layout["session"]
83
159
  end
84
-
85
- # Set the focus in the first split
86
- output << "tmux select-pane -t 0"
87
160
  end # }}}
88
161
 
89
162
  # Execute each command in the shell
@@ -2,12 +2,33 @@
2
2
  two-windows:
3
3
  windows:
4
4
  - name: "foo"
5
+ root: "/foo"
5
6
  splits:
6
7
  - cmd: "echo 'foo'"
7
8
  - cmd: "echo 'foo again'"
8
9
  width: 50
9
10
  - name: "bar"
11
+ root: "/bar"
10
12
  splits:
11
- - cmd: "echo 'bar'"
13
+ - cmd:
14
+ - "echo 'bar'"
15
+ - "echo 'bar in an array'"
12
16
  - cmd: "echo 'bar again'"
13
17
  width: 50
18
+
19
+ # Simple two windows layout with filters
20
+ two-windows-with-filters:
21
+ windows:
22
+ - name: "foo"
23
+ root: "/foo"
24
+ filters:
25
+ before:
26
+ - "echo first before filter"
27
+ - "echo second before filter"
28
+ after:
29
+ - "echo first after filter"
30
+ - "echo second after filter"
31
+ splits:
32
+ - cmd: "echo 'foo'"
33
+ - cmd: "echo 'foo again'"
34
+ width: 50
data/spec/layout_spec.rb CHANGED
@@ -1,12 +1,60 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper.rb")
2
2
 
3
3
  describe Teamocil::Layout do
4
+
4
5
  context "initializing" do
6
+ end
7
+
8
+ context "compiling" do
9
+
10
+ before :each do # {{{
11
+ @layout = Teamocil::Layout.new(layouts["two-windows"], {})
12
+ end # }}}
13
+
14
+ it "creates windows with names" do # {{{
15
+ session = @layout.compile!
16
+ session.windows[0].name.should == "foo"
17
+ session.windows[1].name.should == "bar"
18
+ end # }}}
19
+
20
+ it "creates windows with root paths" do # {{{
21
+ session = @layout.compile!
22
+ session.windows[0].root.should == "/foo"
23
+ session.windows[1].root.should == "/bar"
24
+ end # }}}
25
+
26
+ it "creates splits with dimensions" do # {{{
27
+ session = @layout.compile!
28
+ session.windows.first.splits[0].width.should == nil
29
+ session.windows.first.splits[1].width.should == 50
30
+ end # }}}
31
+
32
+ it "creates splits with commands specified in strings" do # {{{
33
+ session = @layout.compile!
34
+ session.windows.first.splits[0].cmd.should == "echo 'foo'"
35
+ end # }}}
36
+
37
+ it "creates splits with commands specified in an array" do # {{{
38
+ session = @layout.compile!
39
+ session.windows.last.splits[0].cmd.length.should == 2
40
+ session.windows.last.splits[0].cmd.first.should == "echo 'bar'"
41
+ session.windows.last.splits[0].cmd.last.should == "echo 'bar in an array'"
42
+ end # }}}
43
+
44
+ it "creates windows with before filters" do # {{{
45
+ layout = Teamocil::Layout.new(layouts["two-windows-with-filters"], {})
46
+ session = layout.compile!
47
+ session.windows.first.filters["before"].length.should == 2
48
+ session.windows.first.filters["before"].first.should == "echo first before filter"
49
+ session.windows.first.filters["before"].last.should == "echo second before filter"
50
+ end # }}}
5
51
 
6
- it "create two windows" do # {{{
7
- layout = Teamocil::Layout.new(layouts["two-windows"], {})
8
- commands = layout.generate_commands
9
- commands.grep(/new-window/).length.should be 2
52
+ it "creates windows with after filters" do # {{{
53
+ layout = Teamocil::Layout.new(layouts["two-windows-with-filters"], {})
54
+ session = layout.compile!
55
+ session.windows.first.filters["after"].length.should == 2
56
+ session.windows.first.filters["after"].first.should == "echo first after filter"
57
+ session.windows.first.filters["after"].last.should == "echo second after filter"
10
58
  end # }}}
11
59
 
12
60
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teamocil
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 11
10
- version: 0.1.11
8
+ - 2
9
+ version: "0.2"
11
10
  platform: ruby
12
11
  authors:
13
12
  - "R\xC3\xA9mi Pr\xC3\xA9vost"
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-10-20 00:00:00 Z
17
+ date: 2011-10-23 00:00:00 Z
19
18
  dependencies:
20
19
  - !ruby/object:Gem::Dependency
21
20
  name: rake