teamocil 0.1.11 → 0.2

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