automux 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,322 @@
1
+ Automux is a highly configurable Tmux automator inspired from similar projects like [Teamocil](https://github.com/remiprev/teamocil) & [Tmuxinator](https://github.com/aziz/tmuxinator).
2
+ It provides more advanced configuration options like **getopts integration**, **custom indexes** and **recipes** while keeping a strong focus on well designed, easily extendable code base.
3
+
4
+ ## Setup
5
+
6
+ > Run these commands to get Automux started. Its easier to look at the different options later.
7
+
8
+ ```sh
9
+ $ gem install automux
10
+ $ automux setup
11
+ $ automux
12
+ ```
13
+ This should open 3 windows with 3 panes in the first window.
14
+
15
+ ## Blueprints & Recipes
16
+
17
+ > The yaml configuration files are called **blueprints** while a logic to translate it into a shell script is called a **recipe**. Automux can be used with different combinations of blueprints and recipes.
18
+
19
+ ## Session, Windows and Panes
20
+
21
+ > Automux stays true to tmux conventions for session, windows and panes. The first blueprint indentation level is for the `session`. Session can have many Windows all listed under the key `windows`.
22
+
23
+ `windows` is an array of hashes. Just as in Tmux convention a window has atleast one pane, each hash should atleast have a blank `panes` key defined.
24
+
25
+ ```yaml
26
+ name: test
27
+ windows:
28
+ - name: blank
29
+ - panes:
30
+ ```
31
+ The above blueprint will ask *automux* to create two shell windows with the first one named as blank.
32
+
33
+ ## Session Options
34
+
35
+ __name__: helps to identify your session when `tmux ls` is run. Its the only field thats compulsory.
36
+
37
+ __root__: automux will `cd` to this path before starting tmux.
38
+
39
+ __windows__: an array of windows. A tmux session can be started with no windows defined.
40
+
41
+ __flags__: session specific flags as given in the tmux man page.
42
+
43
+ __options__: translates each key-value pair into `set-option`. See `man tmux` for the list of available options.
44
+
45
+ __hooks__: is an hash with `pre` and `post` keys. The specified commands are run before starting and attaching session respectively.
46
+
47
+ ## Window Options
48
+
49
+ __name__: optional name field.
50
+
51
+ __layout__: layout can be one of the preset layouts(even-horizontal, even-vertical, main-horizontal, main-vertical, or tiled) or a custom defined value.
52
+
53
+ __root__: automux will `cd` to this path before running the adding the pane.
54
+
55
+ __panes__: is an array of commands for each pane in this window.
56
+
57
+ __options__: translates each key-value pair into `set-window-option`. See `man tmux` for the list of available options.
58
+
59
+ __hooks__: is an hash with `pre` and `post` keys. The specified commands are run before and after adding the panes respectively.
60
+
61
+ __index__: index for the window.
62
+
63
+ __opt__: makes the window optional. The window will not be created if the flag is not passed.
64
+
65
+ ## Default Blueprint
66
+
67
+ > By default, `automux` uses the blueprint located at `$HOME/.automux/blueprints/default.yml`, which was copied during `automux setup`.
68
+
69
+ ```yaml
70
+ name: test
71
+ root: ~/
72
+ flags: -u2
73
+ options:
74
+ status-left: '#S>'
75
+ hooks:
76
+ pre: echo 'Starting session'
77
+ windows:
78
+ - name: panes
79
+ layout: tiled
80
+ panes:
81
+ - irb
82
+ - top
83
+ - ls
84
+ - name: vim
85
+ hooks:
86
+ pre:
87
+ - echo 'Starting vim'
88
+ panes: vim
89
+ - name: custom-indexed-window
90
+ index: 1
91
+ hooks:
92
+ post:
93
+ - echo 'Running <%= name %>'
94
+ - name: optional-window
95
+ opt: '-r'
96
+ panes:
97
+ - echo 'Created optional window'
98
+ options:
99
+ automatic-rename: off
100
+ window-status-bg: black
101
+ ```
102
+
103
+ When an argument is passed, Automux will look for a blueprint with the specified name. For e.g., the following command will look for `custom.yml` under `$HOME/.automux/blueprints`
104
+ ```sh
105
+ $ automux custom
106
+ ```
107
+ The default blueprint can be changed to suit your needs. To get the original default blueprint back, run `automux setup` again.
108
+
109
+ ## Managing Blueprints
110
+
111
+ > If __$EDITOR__ is undefined, `vi` will be used to open the blueprint.
112
+
113
+ ##### Create
114
+ ```sh
115
+ $ automux blueprint create custom
116
+ ```
117
+ This will clone the `default.yml` as `custom.yml` and open it in an editor.
118
+
119
+ ##### Edit
120
+ ```sh
121
+ $ automux blueprint edit custom
122
+ ```
123
+
124
+ ##### Delete
125
+ ```sh
126
+ $ automux blueprint delete custom
127
+ ```
128
+ *aliased to __rm__*
129
+
130
+ ##### Copy
131
+ ```sh
132
+ $ automux blueprint copy default custom
133
+ ```
134
+ *aliased to __cp__*
135
+
136
+ ##### List
137
+ ```sh
138
+ $ automux blueprint list
139
+ ```
140
+ *aliased to __index__*
141
+
142
+ ## Command-line options
143
+
144
+ > Automux can understand command-line options to make windows optional or provide input at runtime. Lets look at some examples.
145
+
146
+ ```yaml
147
+ name: test
148
+ root: '-r:'
149
+ windows:
150
+ - name: top
151
+ opt: "-t"
152
+ panes: top
153
+ ```
154
+
155
+ `automux test` will start Tmux with a window containing *shell*.
156
+
157
+ `automux test -t` will start Tmux with a window containing *top*.
158
+
159
+ `automux test -tr projects` will `cd` into the *projects* folder and then launch *top*.
160
+
161
+ > The option can also be specified inside another command. This can be useful in cases like providing a branch name for a `git pull` at runtime:
162
+
163
+ ```yaml
164
+ name: test
165
+ windows:
166
+ - name: git
167
+ panes: git pull '-r:' master
168
+ ```
169
+
170
+ * Note: The option needs to be surounded by quotes. It makes Automux's job easier.
171
+
172
+ ## Custom defined window indexes
173
+
174
+ > Windows can have custom indexes which will be assigned to them at runtime. Lets look at an example.
175
+
176
+ ```yaml
177
+ name: test
178
+ windows:
179
+ - name: third
180
+ panes: ls
181
+ - name: fourth
182
+ panes: htop
183
+ - name: second
184
+ index: 1
185
+ panes: pwd
186
+ - name: first
187
+ index: 0
188
+ panes: [pwd, echo Hello]
189
+ ```
190
+
191
+ Here the windows will be arranged in the order indicated by their names.
192
+
193
+ #### Base Index
194
+
195
+ As Automux tries to assign window indexes beforehand, it will overwrite any global **base-index** setting. To use a **base-index**, one would need to let Automux know about it like so:
196
+
197
+ ```yaml
198
+ name: test
199
+ options:
200
+ base-index: 2
201
+ windows:
202
+ - panes: pwd
203
+ - panes: ls
204
+ index: 9
205
+ ```
206
+ Here the indexing will start from 2 onwards.
207
+
208
+ ## The Automux Way
209
+
210
+ > What would Tmux do?
211
+
212
+ Automux is built on top of an ruby API for Tmux. Instead of providing a custom key for every possible Tmux option, its approach is to provide direct access to the session/window objects. This gives way for higher levels of customizations like allowing end users to add their own session/window methods and using them in the blueprints to letting them define their own recipes for logic. The following sections will look at some these approaches.
213
+
214
+ ### Hooks with ERB
215
+
216
+ > Automux provides context specific ERB support for hooks.
217
+
218
+ ```yaml
219
+ name: projects
220
+ hooks:
221
+ pre: cd ~/<%= name %>
222
+ windows:
223
+ - name: automux
224
+ hooks:
225
+ pre:
226
+ - cd <%= name %>
227
+ - pwd
228
+ panes: vim
229
+ - panes: pwd
230
+ ```
231
+
232
+ This will execute the following steps
233
+
234
+ * cd ~/projects
235
+ * ... tmux startup stuff
236
+ * ... create first window
237
+ * cd automux
238
+ * pwd => ~/projects/automux
239
+ * vim
240
+ * ... create second window
241
+ * pwd => ~/projects
242
+
243
+ The session/window hooks have access to session and window objects respectively.
244
+
245
+ ### Select/Focus Window
246
+
247
+ To select a specific window when session is attached, Tmux provides the method `select-window`. Staying true to Tmux conventions, Automux's session object provides `select_window`.
248
+ ```yaml
249
+ name: hooked
250
+ hooks:
251
+ post:
252
+ - <%= select_window 'one' %>
253
+ windows:
254
+ - name: one
255
+ - name: two
256
+ ```
257
+ This selects the window named 'one' after all windows have been setup. Index number is also an acceptable parameter.
258
+
259
+ ### Link Window
260
+
261
+ Tmux exposes the `link-window` method to link an existing window with current session.
262
+
263
+ ```yaml
264
+ name: test
265
+ hooks:
266
+ post:
267
+ - <%= link_window('primary', 'irb', 3)%>
268
+ windows:
269
+ - panes: vim
270
+ ```
271
+
272
+ This will link a window named *irb* from an existing session named *primary* as 3rd window in current session. The third parameter is optional just like Tmux would do.
273
+
274
+ ## Writing your own Recipe
275
+
276
+ * `automux setup` copies a sample of the default recipe to `$HOME/recipes/default.sh.erb`. It looks like the following script:
277
+
278
+ ```
279
+ cd <%= root %>
280
+
281
+ = start_server
282
+ = new_session
283
+
284
+ - windows.each do |window|
285
+ = new_window(window)
286
+ = rename_window(window) if window.name
287
+
288
+ - if window.has_panes?
289
+ - window.panes.each do |pane|
290
+ = create_pane if pane.index > 0
291
+ = send_keys(window, pane.command)
292
+ - end
293
+ - end
294
+ - end
295
+
296
+ = attach_session
297
+ ```
298
+
299
+ Its a simpler form of ERB much like [HAML](https://github.com/haml/haml) without indentation. The ERB is evaluated with session's context. Hence all methods defined for session are available here. The default recipe comes from the gem and cannot be overwritten. Custom recipes can be run like so:
300
+
301
+ ```sh
302
+ $ automux default custom_recipe
303
+ ```
304
+ _Here default is the default blueprint name._
305
+
306
+ ## Bash Autocompletion
307
+
308
+ Currently blueprint names can be autocompleted. A dedicated autocompletion shell script is in the pipeline. For now add the following to your `~/.bashrc` to get autocompletion for blueprint names.
309
+
310
+ ```sh
311
+ complete -W "$(automux blueprint list)" automux
312
+ ```
313
+
314
+ ## Coming Up
315
+
316
+ * Bash Autocompletion for blueprint commands and recipe names.
317
+ * Make Session and Window extendable on the client end.
318
+ * Blueprint inheritance.
319
+
320
+ ## License
321
+
322
+ MIT License. See LICENSE.txt for more details.
data/automux.gemspec CHANGED
@@ -1,6 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
3
  require 'automux/version'
4
+ require 'automux/installation'
4
5
 
5
6
  Gem::Specification.new do |gem|
6
7
  gem.name = 'automux'
@@ -10,9 +11,11 @@ Gem::Specification.new do |gem|
10
11
  gem.description = %[Highly configurable Tmux Automator]
11
12
  gem.summary = %[Automate tmux sessions stored in yaml files using custom recipes]
12
13
  gem.homepage = %[https://github.com/notalex/automux]
14
+ gem.license = %[MIT License]
13
15
 
14
16
  gem.files = %x[git ls-files].split($/)
15
17
  gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
16
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
19
  gem.require_paths = %w(lib)
20
+ gem.post_install_message = Automux::Installation::MESSAGE
18
21
  end
data/bin/automux CHANGED
@@ -12,7 +12,7 @@ when 'setup'
12
12
  Automux::Controller::Setup.new.clone_defaults
13
13
  when 'blueprint'
14
14
  params = { blueprint_name: args[2], clone_name: args[3] }
15
- Automux::Controller::Blueprints.new(params).send(args[1])
15
+ Automux::Controller::Blueprints.new(params).public_send(args[1])
16
16
  else
17
17
  params = {
18
18
  blueprint_name: args[0] || 'default',
@@ -2,10 +2,12 @@ name: test
2
2
  root: ~/
3
3
  flags: -u2
4
4
  options:
5
- status: off
5
+ status-left: '#S>'
6
+ hooks:
7
+ pre: echo 'Starting session'
6
8
  windows:
7
9
  - name: panes
8
- layout: main-vertical
10
+ layout: tiled
9
11
  panes:
10
12
  - irb
11
13
  - top
@@ -24,3 +26,6 @@ windows:
24
26
  opt: '-r'
25
27
  panes:
26
28
  - echo 'Created optional window'
29
+ options:
30
+ automatic-rename: off
31
+ window-status-bg: black
@@ -39,8 +39,8 @@ cd <%= root %>
39
39
  - end
40
40
  - end
41
41
 
42
- = attach_session
43
-
44
42
  - post_hooks.each do |hook|
45
43
  = hook.command
46
44
  - end
45
+
46
+ = attach_session
@@ -8,7 +8,11 @@ Feature: Using pre and post hooks for session
8
8
  pre:
9
9
  - "echo Hello"
10
10
  - "rvm use automux"
11
- post: "echo 'I will be back'"
11
+ post:
12
+ - <%= select_window 'one' %>
13
+ windows:
14
+ - name: one
15
+ - name: two
12
16
  """
13
17
  When I invoke Automux with the blueprint "test_sample"
14
18
  Then the rendered sequence of shell commands should be
@@ -21,9 +25,17 @@ Feature: Using pre and post hooks for session
21
25
  tmux start-server
22
26
  tmux new-session -d -s hooked
23
27
 
24
- tmux attach-session -t hooked
28
+ tmux new-window -t hooked:0 2> /dev/null
29
+ tmux rename-window -t hooked:0 one
30
+ tmux send-keys -t hooked:0 "" C-m
25
31
 
26
- echo 'I will be back'
32
+ tmux new-window -t hooked:1 2> /dev/null
33
+ tmux rename-window -t hooked:1 two
34
+ tmux send-keys -t hooked:1 "" C-m
35
+
36
+ tmux select-window -t hooked:0
37
+
38
+ tmux attach-session -t hooked
27
39
  """
28
40
 
29
41
  Scenario: Using window hooks
@@ -13,6 +13,6 @@ Then(/^the window with the name "(.+)" should have the following$/) do |name, ta
13
13
  window = @session.windows.find { |window| window.name == name }
14
14
  params = common_transformations(table.hashes).first
15
15
  params.each do |field, value|
16
- window.send(field).must_equal value
16
+ window.public_send(field).must_equal value
17
17
  end
18
18
  end
@@ -33,7 +33,7 @@ end
33
33
 
34
34
  def expected_array_for(string)
35
35
  expected_string = string.gsub(/\$HOME/, ENV['HOME'])
36
- expected_array = expected_string.split("\n").reject { |text| text.split.empty? }
36
+ expected_array = expected_string.squeeze("\n").split("\n")
37
37
  expected_array.map { |text| text.strip }
38
38
  end
39
39
 
@@ -36,6 +36,11 @@ module Automux
36
36
  end
37
37
  alias_method :rm, :delete
38
38
 
39
+ def index
40
+ render 'index'
41
+ end
42
+ alias_method :list, :index
43
+
39
44
  private ###
40
45
 
41
46
  def load_blueprint
@@ -41,7 +41,7 @@ module Automux
41
41
 
42
42
  # The recipe files can have empty lines for clarity. Remove them here.
43
43
  def remove_empty_lines(string)
44
- string.split("\n").reject { |text| text.strip.empty? }.join("\n")
44
+ string.gsub(/\n\s+\n/, "\n")
45
45
  end
46
46
 
47
47
  # Remove all parent namespacing.
@@ -47,6 +47,19 @@ module Automux
47
47
  %[tmux send-keys -t #{ name }:#{ window.index } "#{ command }" C-m]
48
48
  end
49
49
 
50
+ def select_window(identifier)
51
+ window = get_window(identifier)
52
+ %[tmux select-window -t #{ name }:#{ window.index }]
53
+ end
54
+
55
+ # Links window from source session to current session. Window name or index must be provided.
56
+ #
57
+ # E.g.: link_window(primary, finch, 3)
58
+ # This links a window named *finch* from an existing session named *primary* as 3rd window in current session.
59
+ def link_window(source_session_name, source_window_identifier, index = nil)
60
+ %[tmux link-window -s #{ source_session_name }:#{ source_window_identifier } -t #{ name }:#{ index }]
61
+ end
62
+
50
63
  def attach_session
51
64
  %[#{ tmux_with_flags } attach-session -t #{ name }]
52
65
  end
@@ -1 +1 @@
1
- ENV['EDITOR'] ||= 'vim'
1
+ ENV['EDITOR'] ||= 'vi'
@@ -0,0 +1,10 @@
1
+ module Automux
2
+ module Installation
3
+ MESSAGE = <<-END
4
+ ********************************************************************************
5
+ Please run the following the following command to setup default Automux folders:
6
+ $ automux setup
7
+ ********************************************************************************
8
+ END
9
+ end
10
+ end
@@ -1,5 +1,5 @@
1
1
  module Automux
2
2
  module Version
3
- STRING = '0.1.0'
3
+ STRING = '0.2.0'
4
4
  end
5
5
  end
@@ -0,0 +1,2 @@
1
+ rm <%= path %>
2
+ echo <%= File.basename(path) %> deleted
@@ -0,0 +1,4 @@
1
+ for filename in $(ls <%= Automux::Paths::blueprints_container %>)
2
+ do
3
+ echo ${filename%.yml}
4
+ done
data/lib/automux.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'automux/version'
2
+ require 'automux/installation'
2
3
  require 'automux/paths'
3
4
  require 'automux/library'
4
5
  require 'automux/core'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automux
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-01 00:00:00.000000000 Z
12
+ date: 2013-04-02 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Highly configurable Tmux Automator
15
15
  email:
@@ -23,6 +23,7 @@ files:
23
23
  - Gemfile
24
24
  - Gemfile.lock
25
25
  - LICENSE.txt
26
+ - README.md
26
27
  - automux.gemspec
27
28
  - bin/automux
28
29
  - data/automux/blueprints/default.yml
@@ -74,6 +75,7 @@ files:
74
75
  - lib/automux/initializers/custom_hooks.rb
75
76
  - lib/automux/initializers/setup_caches.rb
76
77
  - lib/automux/initializers/setup_editor.rb
78
+ - lib/automux/installation.rb
77
79
  - lib/automux/library.rb
78
80
  - lib/automux/library/mini_erb.rb
79
81
  - lib/automux/library/yaml_parser.rb
@@ -81,7 +83,9 @@ files:
81
83
  - lib/automux/version.rb
82
84
  - lib/automux/views/blueprints/copy.sh.erb
83
85
  - lib/automux/views/blueprints/create.sh.erb
86
+ - lib/automux/views/blueprints/delete.sh.erb
84
87
  - lib/automux/views/blueprints/edit.sh.erb
88
+ - lib/automux/views/blueprints/index.sh.erb
85
89
  - lib/automux/views/messages/error.sh.erb
86
90
  - lib/automux/views/setup/clone_defaults.sh.erb
87
91
  - test/session_test.rb
@@ -90,8 +94,17 @@ files:
90
94
  - test/support/hash_factory.rb
91
95
  - test/support/test_helper.rb
92
96
  homepage: https://github.com/notalex/automux
93
- licenses: []
94
- post_install_message:
97
+ licenses:
98
+ - MIT License
99
+ post_install_message: ! '********************************************************************************
100
+
101
+ Please run the following the following command to setup default Automux folders:
102
+
103
+ $ automux setup
104
+
105
+ ********************************************************************************
106
+
107
+ '
95
108
  rdoc_options: []
96
109
  require_paths:
97
110
  - lib