tlux 0.0.1
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 +17 -0
- data/.rspec +2 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +46 -0
- data/Rakefile +7 -0
- data/bin/tlux +32 -0
- data/lib/tlux/commandable.rb +16 -0
- data/lib/tlux/commands/base.rb +17 -0
- data/lib/tlux/commands/list_command.rb +13 -0
- data/lib/tlux/commands/new_command.rb +40 -0
- data/lib/tlux/commands/run_command.rb +40 -0
- data/lib/tlux/commands/start.rb +13 -0
- data/lib/tlux/commands/start_command.rb +13 -0
- data/lib/tlux/commands.rb +13 -0
- data/lib/tlux/config/generator.rb +28 -0
- data/lib/tlux/config/parser.rb +23 -0
- data/lib/tlux/config.rb +8 -0
- data/lib/tlux/pane.rb +26 -0
- data/lib/tlux/session.rb +21 -0
- data/lib/tlux/splitable.rb +13 -0
- data/lib/tlux/templates/config.erb +27 -0
- data/lib/tlux/templates/new.erb +14 -0
- data/lib/tlux/version.rb +3 -0
- data/lib/tlux/window.rb +12 -0
- data/lib/tlux.rb +18 -0
- data/spec/commands/base_spec.rb +62 -0
- data/spec/commands/list_command_spec.rb +62 -0
- data/spec/commands/new_command_spec.rb +31 -0
- data/spec/commands/run_command_spec.rb +45 -0
- data/spec/config/generator_spec.rb +24 -0
- data/spec/config/parser_spec.rb +48 -0
- data/spec/fixtures/sample_config.rb +21 -0
- data/spec/pane_spec.rb +63 -0
- data/spec/session_spec.rb +39 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/commandable.rb +18 -0
- data/spec/support/splitable.rb +28 -0
- data/spec/window_spec.rb +19 -0
- data/tlux.gemspec +20 -0
- metadata +110 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Oliver Nightingale
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#Tlux
|
2
|
+
|
3
|
+
Luxurious tmux configuration with Ruby.
|
4
|
+
|
5
|
+
##About
|
6
|
+
|
7
|
+
Specify your tmux environments using an intuitive DSL instead of having to remember tmux commands.
|
8
|
+
|
9
|
+
Set up different environemnts that can be shared between projects, have an environment for your Rails projects and specify it once, rather than once per project.
|
10
|
+
|
11
|
+
##Usage
|
12
|
+
|
13
|
+
Tlux is available as a ruby gem, it has dependencies on tmux. Once you have tmux installed install the tlux gem:
|
14
|
+
|
15
|
+
gem install tlux
|
16
|
+
|
17
|
+
To get usage details just run the tlux command without any args
|
18
|
+
|
19
|
+
tlux
|
20
|
+
|
21
|
+
##Config
|
22
|
+
|
23
|
+
An example config showing some of the commands available
|
24
|
+
|
25
|
+
window :editor do
|
26
|
+
command "vim ."
|
27
|
+
|
28
|
+
split :vertical, percentage: 30 do
|
29
|
+
split :horizontal, lines: 20
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
window :console do
|
34
|
+
command "tail -f log/development.log"
|
35
|
+
|
36
|
+
split :vertical do
|
37
|
+
command "rails c"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
window :server do
|
42
|
+
command "rails s"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
data/Rakefile
ADDED
data/bin/tlux
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'tlux'
|
7
|
+
|
8
|
+
if ARGV.any?
|
9
|
+
begin
|
10
|
+
|
11
|
+
puts Tlux::Commands.run(ARGV.shift, ARGV)
|
12
|
+
|
13
|
+
rescue Tlux::EditorNotDefinedError
|
14
|
+
puts "You must define an editor in either $TMUX_EDITOR or $EDITOR to use this command"
|
15
|
+
exit 1
|
16
|
+
|
17
|
+
rescue Tlux::Config::FileNotFound
|
18
|
+
puts "Tlux config file not found #{ARGV[0]}"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
else
|
22
|
+
|
23
|
+
puts <<-EOF
|
24
|
+
Tlux version: #{Tlux::VERSION}
|
25
|
+
|
26
|
+
Usage:
|
27
|
+
tlux new <config_name> : creates a new a config file and opens it in your editor
|
28
|
+
tlux list : lists the currently available configs
|
29
|
+
tlux run <config_name> : attach a tmux session with the given config name
|
30
|
+
EOF
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Commands
|
3
|
+
class Base
|
4
|
+
def setup
|
5
|
+
FileUtils.mkdir_p(File.join(Dir.home, '.tlux', 'generated'))
|
6
|
+
end
|
7
|
+
|
8
|
+
def config_path
|
9
|
+
File.join(Dir.home, '.tlux')
|
10
|
+
end
|
11
|
+
|
12
|
+
def generated_path
|
13
|
+
File.join(Dir.home, '.tlux', 'generated')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Commands
|
3
|
+
class NewCommand < Tlux::Commands::Base
|
4
|
+
attr_reader :config_name
|
5
|
+
|
6
|
+
def initialize(config_name)
|
7
|
+
@config_name = config_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(open_editor = true)
|
11
|
+
setup
|
12
|
+
create_config unless File.exists?(config_file_path)
|
13
|
+
raise Tlux::EditorNotDefinedError unless editor
|
14
|
+
exec "#{editor} #{config_file_path}" if open_editor
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def editor
|
20
|
+
[ENV['TLUX_EDITOR'], ENV['VISUAL'], ENV['EDITOR']].find{|e| !e.nil? && !e.empty? }
|
21
|
+
end
|
22
|
+
|
23
|
+
def config_file_path
|
24
|
+
File.join(config_path, config_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_config
|
28
|
+
File.open(config_file_path, 'w+') do |f|
|
29
|
+
f.write template.result(binding)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def template
|
34
|
+
File.open(File.join(Tlux::TEMPLATES_PATH, 'new.erb'), 'r') do |f|
|
35
|
+
ERB.new(f.read)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Commands
|
3
|
+
class RunCommand < Tlux::Commands::Base
|
4
|
+
|
5
|
+
attr_reader :config_name
|
6
|
+
|
7
|
+
def initialize(config_name)
|
8
|
+
@config_name = config_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
parser = Tlux::Config::Parser.from_file(config_file_path)
|
13
|
+
parser.parse!
|
14
|
+
parser.session.name = config_name
|
15
|
+
|
16
|
+
write_output Tlux::Config::Generator.new(parser.session).generate!
|
17
|
+
|
18
|
+
exec "tmux -f #{output_path} attach"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def config_file_path
|
24
|
+
File.join(config_path, config_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def output_path
|
28
|
+
File.join(generated_path, config_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_output(output)
|
32
|
+
File.delete(output_path) if File.exists?(output_path)
|
33
|
+
|
34
|
+
file = File.open(output_path, 'w')
|
35
|
+
file.write output
|
36
|
+
file.close
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Commands
|
3
|
+
def self.run(command_name, args = [])
|
4
|
+
command = self.const_get("#{command_name.capitalize}Command").new(*args)
|
5
|
+
command.run
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'tlux/commands/base'
|
11
|
+
require 'tlux/commands/list_command'
|
12
|
+
require 'tlux/commands/run_command'
|
13
|
+
require 'tlux/commands/new_command'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Config
|
3
|
+
class Generator
|
4
|
+
|
5
|
+
attr_reader :session, :template
|
6
|
+
|
7
|
+
def initialize(session)
|
8
|
+
@session = session
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate!
|
12
|
+
name = session.name
|
13
|
+
windows = session.windows
|
14
|
+
dir = Dir.pwd
|
15
|
+
|
16
|
+
template.result(binding)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def template
|
22
|
+
File.open(File.join(Tlux::TEMPLATES_PATH, 'config.erb'), 'r') do |f|
|
23
|
+
ERB.new(f.read)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tlux
|
2
|
+
module Config
|
3
|
+
class Parser
|
4
|
+
def self.from_file(path)
|
5
|
+
raise Tlux::Config::FileNotFound.new(path) unless File.exists?(path) && File.file?(path)
|
6
|
+
File.open(path, 'r') do |config|
|
7
|
+
self.new(config.read)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :config, :session
|
12
|
+
|
13
|
+
def initialize(config)
|
14
|
+
@config = config
|
15
|
+
@session = Tlux::Session.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse!
|
19
|
+
session.instance_eval(config)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/tlux/config.rb
ADDED
data/lib/tlux/pane.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Tlux
|
2
|
+
class Pane
|
3
|
+
include Tlux::Splitable
|
4
|
+
include Tlux::Commandable
|
5
|
+
|
6
|
+
attr_reader :lines, :percentage
|
7
|
+
|
8
|
+
def initialize(orientation = :vertical, opts = {})
|
9
|
+
@orientation = orientation
|
10
|
+
@lines = opts[:lines]
|
11
|
+
@percentage = opts[:percentage]
|
12
|
+
end
|
13
|
+
|
14
|
+
def orientation
|
15
|
+
"-#{@orientation.to_s.chars.first}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def size
|
19
|
+
if lines
|
20
|
+
"-l #{lines}"
|
21
|
+
elsif percentage
|
22
|
+
"-p #{percentage}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/tlux/session.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tlux
|
2
|
+
class Session
|
3
|
+
attr_accessor :name
|
4
|
+
attr_reader :windows
|
5
|
+
|
6
|
+
def initialize(name = "")
|
7
|
+
@name = name
|
8
|
+
@windows = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def window(name, opts = {}, &block)
|
12
|
+
window = Tlux::Window.new(name, opts)
|
13
|
+
@windows << window
|
14
|
+
window.instance_eval(&block) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_binding
|
18
|
+
binding
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# This file is automatically generated by tlux and should not be manually edited
|
2
|
+
# To make changes to your config edit the file at ~/.tlux/<%= name %>
|
3
|
+
|
4
|
+
source-file ~/.tmux.conf
|
5
|
+
|
6
|
+
new-session -s <%= name %> -n <%= windows.first.name %> -d
|
7
|
+
send-keys -t <%= name %> 'cd <%= dir %>' C-m
|
8
|
+
|
9
|
+
<% windows.each_with_index do |window, window_idx| %>
|
10
|
+
<% if window_idx > 0 %>
|
11
|
+
new-window -n <%= window.name %> -t <%= name %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
send-keys -t <%= name %> 'cd <%= dir %>' C-m
|
15
|
+
|
16
|
+
<% window.commands.each do |command| %>
|
17
|
+
send-keys -t <%= name %> '<%= command %>' C-m
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% window.panes.each_with_index do |pane, pane_idx| %>
|
21
|
+
split-window <%= pane.orientation %> <%= pane.size %> -t <%= name %>
|
22
|
+
send-keys -t <%= name %>:<%= window_idx + 1 %>.<%= pane_idx + 1 %> 'cd <%= dir %>' C-m
|
23
|
+
<% pane.commands.each do |command| %>
|
24
|
+
send-keys -t <%= name %>:<%= window_idx + 1 %>.<%= pane_idx + 1 %> '<%= command %>' C-m
|
25
|
+
<% end %>
|
26
|
+
<% end %>
|
27
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Declare you configuration in this file, below is a quick sample of what
|
2
|
+
# is possible.
|
3
|
+
#
|
4
|
+
# window :editor do
|
5
|
+
# split :vertical, lines: 50
|
6
|
+
#
|
7
|
+
# split :vertical, percentage: 10 do
|
8
|
+
# command "vim ."
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# window :logs do
|
13
|
+
# command "tail -f log/development.log"
|
14
|
+
# end
|
data/lib/tlux/version.rb
ADDED
data/lib/tlux/window.rb
ADDED
data/lib/tlux.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "tlux/version"
|
2
|
+
require "erb"
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module Tlux
|
6
|
+
TEMPLATES_PATH = File.join(File.dirname(__FILE__), 'tlux', 'templates')
|
7
|
+
class EditorNotDefinedError < StandardError ; end
|
8
|
+
end
|
9
|
+
|
10
|
+
require "tlux/splitable"
|
11
|
+
require "tlux/commandable"
|
12
|
+
|
13
|
+
require "tlux/session"
|
14
|
+
require "tlux/window"
|
15
|
+
require "tlux/pane"
|
16
|
+
|
17
|
+
require "tlux/config"
|
18
|
+
require "tlux/commands"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Commands::Base do
|
4
|
+
describe "#setup" do
|
5
|
+
before :each do
|
6
|
+
FakeFS.activate!
|
7
|
+
end
|
8
|
+
|
9
|
+
after :each do
|
10
|
+
FakeFS.deactivate!
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { Tlux::Commands::Base.new }
|
14
|
+
|
15
|
+
context "tlux directory not present" do
|
16
|
+
it "should create the tlux directory structure" do
|
17
|
+
subject.setup
|
18
|
+
|
19
|
+
Dir.exists?(File.join(Dir.home, '.tlux')).should be_true
|
20
|
+
Dir.exists?(File.join(Dir.home, '.tlux', 'generated')).should be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "tlux directory already present" do
|
25
|
+
before :each do
|
26
|
+
FileUtils.mkdir_p(File.join(Dir.home, '.tlux', 'generated'))
|
27
|
+
FileUtils.touch(File.join(Dir.home, '.tlux', 'test'))
|
28
|
+
FileUtils.touch(File.join(Dir.home, '.tlux', 'generated', 'test'))
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not re-create the directory structure" do
|
32
|
+
subject.setup
|
33
|
+
|
34
|
+
Dir.exists?(File.join(Dir.home, '.tlux')).should be_true
|
35
|
+
Dir.exists?(File.join(Dir.home, '.tlux', 'generated')).should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not loose the existing files" do
|
39
|
+
subject.setup
|
40
|
+
|
41
|
+
File.exists?(File.join(Dir.home, '.tlux', 'test')).should be_true
|
42
|
+
File.exists?(File.join(Dir.home, '.tlux', 'generated', 'test')).should be_true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "config_path" do
|
48
|
+
subject { Tlux::Commands::Base.new }
|
49
|
+
|
50
|
+
it "should return the path to the config files" do
|
51
|
+
subject.config_path.should == File.join(Dir.home, '.tlux')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "generated_path" do
|
56
|
+
subject { Tlux::Commands::Base.new }
|
57
|
+
|
58
|
+
it "should return the path to the generated files" do
|
59
|
+
subject.generated_path.should == File.join(Dir.home, '.tlux', 'generated')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Commands::ListCommand do
|
4
|
+
describe "#run" do
|
5
|
+
before :each do
|
6
|
+
FakeFS.activate!
|
7
|
+
FakeFS::FileSystem.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
after :each do
|
11
|
+
FakeFS.deactivate!
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { Tlux::Commands::ListCommand.new }
|
15
|
+
|
16
|
+
context "tlux dir not set up" do
|
17
|
+
it "should set up the tlux dir" do
|
18
|
+
subject.run
|
19
|
+
Dir.exists?(File.join(Dir.home, '.tlux')).should be_true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "no configs available" do
|
24
|
+
let(:list) { subject.run }
|
25
|
+
|
26
|
+
it "should return an empty array" do
|
27
|
+
list.should be_kind_of Array
|
28
|
+
list.should be_empty
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "one config available" do
|
33
|
+
let(:list) { subject.run }
|
34
|
+
let(:config_name) { 'foo' }
|
35
|
+
|
36
|
+
before :each do
|
37
|
+
FileUtils.mkdir_p(File.join(Dir.home, '.tlux', config_name))
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return an array with the name of the config" do
|
41
|
+
list.include?(config_name).should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "more than one config available" do
|
46
|
+
let(:list) { subject.run }
|
47
|
+
let(:config_names) { %w{foo bar baz} }
|
48
|
+
|
49
|
+
before :each do
|
50
|
+
config_names.each do |config_name|
|
51
|
+
FileUtils.mkdir_p(File.join(Dir.home, '.tlux', config_name))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return an array with all the names of the config" do
|
56
|
+
config_names.each do |config_name|
|
57
|
+
list.include?(config_name).should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Commands::NewCommand do
|
4
|
+
describe "#run" do
|
5
|
+
let(:config_name) { 'foo' }
|
6
|
+
subject { Tlux::Commands::NewCommand.new(config_name) }
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
FakeFS.activate!
|
10
|
+
FileUtils.mkdir_p(Tlux::TEMPLATES_PATH)
|
11
|
+
FileUtils.touch(File.join(Tlux::TEMPLATES_PATH, 'new.erb'))
|
12
|
+
end
|
13
|
+
|
14
|
+
after :each do
|
15
|
+
FakeFS::FileSystem.clear
|
16
|
+
FakeFS.deactivate!
|
17
|
+
end
|
18
|
+
|
19
|
+
context "tlux dir doesn't exist" do
|
20
|
+
it "should create the tlux dir" do
|
21
|
+
subject.run(false)
|
22
|
+
Dir.exists?(File.join(Dir.home, '.tlux')).should be_true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should create the config file" do
|
27
|
+
subject.run(false)
|
28
|
+
File.exists?(File.join(Dir.home, '.tlux', config_name))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#require 'spec_helper'
|
2
|
+
#
|
3
|
+
#describe Tlux::Commands::RunCommand do
|
4
|
+
# describe "#run" do
|
5
|
+
# before :each do
|
6
|
+
# FakeFS.activate!
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# after :each do
|
10
|
+
# FakeFS.deactivate!
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# let(:config_path) { File.join(Dir.home, '.tlux', 'test') }
|
14
|
+
# let(:current_dir) { Dir.pwd }
|
15
|
+
# let(:command) { Tlux::Commands::RunCommand.new(config_path, current_dir) }
|
16
|
+
#
|
17
|
+
# context "config file does not exist" do
|
18
|
+
# it "should raise a Tlux::Config::FileNotFoundError" do
|
19
|
+
# expect {
|
20
|
+
# command.run
|
21
|
+
# }.to raise_error(Tlux::Config::FileNotFoundError)
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# context "config file does exist" do
|
26
|
+
# before :each do
|
27
|
+
# Tlux::Config::Parser.stub!(:new).with
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# describe "parsing the config file" do
|
31
|
+
# it "should parse the config file" do
|
32
|
+
# parser.should_receive(:parse!)
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# it "should generate the tmux config for the tlux config file" do
|
37
|
+
#
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# it "should write the file out to tlux directory" do
|
41
|
+
#
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Config::Generator do
|
4
|
+
describe "#initialize" do
|
5
|
+
let(:session) { Tlux::Session.new }
|
6
|
+
subject { Tlux::Config::Generator.new(session) }
|
7
|
+
|
8
|
+
it "should have a session" do
|
9
|
+
subject.session.should == session
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# describe "generate!" do
|
14
|
+
# let(:session) { Tlux::Session.new }
|
15
|
+
# let(:template) { :template }
|
16
|
+
# subject { Tlux::Config::Generator.new(session) }
|
17
|
+
#
|
18
|
+
# it "should render the config template using the session" do
|
19
|
+
# ERB.should_receive(:new).and_return(template)
|
20
|
+
# template.should_receive(:run).with(session.get_binding)
|
21
|
+
# subject.generate!
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Config::Parser do
|
4
|
+
describe ".from_file" do
|
5
|
+
context "config file doesn't exist" do
|
6
|
+
it "should raise a Tlux::Config::FileNotFound" do
|
7
|
+
expect {
|
8
|
+
Tlux::Config::Parser.from_file(File.join('no', 'such', 'file'))
|
9
|
+
}.to raise_error(Tlux::Config::FileNotFound)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "config file does exist" do
|
14
|
+
it "should return a new instance of Tlux::Config::Parser" do
|
15
|
+
parser = Tlux::Config::Parser.from_file(File.join('spec', 'fixtures', 'sample_config.rb'))
|
16
|
+
parser.should be_kind_of(Tlux::Config::Parser)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#initialize" do
|
22
|
+
let(:config) { 'dummy config' }
|
23
|
+
subject { Tlux::Config::Parser.new config }
|
24
|
+
|
25
|
+
it "should have a config string" do
|
26
|
+
subject.config.should == config
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a new session object" do
|
30
|
+
subject.session.should be_kind_of Tlux::Session
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#parse!" do
|
35
|
+
let!(:session) { Tlux::Session.new }
|
36
|
+
let(:config) { 'dummy config' }
|
37
|
+
subject { Tlux::Config::Parser.new config }
|
38
|
+
|
39
|
+
before :each do
|
40
|
+
Tlux::Session.stub!(:new).and_return(session)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should instance eval the config with the new session" do
|
44
|
+
session.should_receive(:instance_eval).with(config)
|
45
|
+
subject.parse!
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
window "editor", selected: true do
|
2
|
+
command "vim ."
|
3
|
+
|
4
|
+
split :horizontal, height: 20
|
5
|
+
|
6
|
+
split :vertical do
|
7
|
+
command "vim ."
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
window "console" do
|
12
|
+
command "bundle exec rails c"
|
13
|
+
|
14
|
+
split :vertical do
|
15
|
+
command "tail -f log/development.log"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
window "server" do
|
20
|
+
command "bundle exec rails s"
|
21
|
+
end
|
data/spec/pane_spec.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Pane do
|
4
|
+
it_behaves_like Tlux::Splitable do
|
5
|
+
let(:splitable) { Tlux::Pane.new(:vertical) }
|
6
|
+
end
|
7
|
+
|
8
|
+
it_behaves_like Tlux::Commandable do
|
9
|
+
let(:commandable) { Tlux::Pane.new(:vertical) }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#orientation" do
|
13
|
+
context "vertical" do
|
14
|
+
subject { Tlux::Pane.new(:vertical) }
|
15
|
+
|
16
|
+
it "should be v" do
|
17
|
+
subject.orientation.should == '-v'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "horizontal" do
|
22
|
+
subject { Tlux::Pane.new(:horizontal) }
|
23
|
+
|
24
|
+
it "should be h" do
|
25
|
+
subject.orientation.should == '-h'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "default" do
|
30
|
+
subject { Tlux::Pane.new }
|
31
|
+
|
32
|
+
it "should be v" do
|
33
|
+
subject.orientation.should == '-v'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "size" do
|
39
|
+
context "no size specified" do
|
40
|
+
subject { Tlux::Pane.new }
|
41
|
+
|
42
|
+
it "should be nil" do
|
43
|
+
subject.size.should be_nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with lines specified" do
|
48
|
+
subject { Tlux::Pane.new(:vertical, lines: 20) }
|
49
|
+
|
50
|
+
it "should be -l 20" do
|
51
|
+
subject.size.should == "-l 20"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with a percentage specified" do
|
56
|
+
subject { Tlux::Pane.new(:vertical, percentage: 20) }
|
57
|
+
|
58
|
+
it "should be -p 20" do
|
59
|
+
subject.size.should == "-p 20"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Session do
|
4
|
+
let(:session) { Tlux::Session.new }
|
5
|
+
|
6
|
+
describe "#name" do
|
7
|
+
it "should have a name" do
|
8
|
+
session.name = "foo"
|
9
|
+
session.name.should == "foo"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#window" do
|
14
|
+
let(:name) { "bar" }
|
15
|
+
let(:opts) { {:baz => true} }
|
16
|
+
|
17
|
+
it "should create a new window" do
|
18
|
+
Tlux::Window.should_receive(:new).with(name, opts)
|
19
|
+
session.window name, opts
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should add a window to the list of windows" do
|
23
|
+
expect {
|
24
|
+
session.window name, opts
|
25
|
+
}.to change(session.windows, :size).by(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should yield the new window in the passed block" do
|
29
|
+
window = nil
|
30
|
+
|
31
|
+
session.window "foo" do
|
32
|
+
window = self
|
33
|
+
end
|
34
|
+
|
35
|
+
window.should be_kind_of(Tlux::Window)
|
36
|
+
window.name.should == "foo"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'rubygems'
|
8
|
+
require 'bundler/setup'
|
9
|
+
|
10
|
+
require 'fakefs/safe'
|
11
|
+
|
12
|
+
require 'tlux'
|
13
|
+
|
14
|
+
Dir[File.expand_path('../support/**/*.rb', __FILE__)].each do |file|
|
15
|
+
require(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.configure do |config|
|
19
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
20
|
+
config.run_all_when_everything_filtered = true
|
21
|
+
config.filter_run :focus
|
22
|
+
|
23
|
+
# Run specs in random order to surface order dependencies. If you find an
|
24
|
+
# order dependency and want to debug it, you can fix the order by providing
|
25
|
+
# the seed, which is printed after each run.
|
26
|
+
# --seed 1234
|
27
|
+
config.order = 'random'
|
28
|
+
end
|
29
|
+
|
30
|
+
def empty_tlux_dir!
|
31
|
+
FakeFS do
|
32
|
+
path = File.join(Dir.home, '.tlux')
|
33
|
+
return unless Dir.exists?(path)
|
34
|
+
Dir.foreach(path) { |filename| File.delete(File.join(path, filename)) if File.exists?(File.join(path, filename)) }
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
shared_examples_for Tlux::Commandable do
|
2
|
+
describe "#command" do
|
3
|
+
it "should have add a command to a list of commands" do
|
4
|
+
expect {
|
5
|
+
commandable.command "vim ."
|
6
|
+
}.to change(commandable.commands, :size).by(1)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#directory" do
|
11
|
+
let(:dir) { "~/code/tlux" }
|
12
|
+
|
13
|
+
it "should set the directory" do
|
14
|
+
commandable.directory dir
|
15
|
+
commandable.directory.should == dir
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
shared_examples_for Tlux::Splitable do
|
2
|
+
describe "#split" do
|
3
|
+
let(:orientation) { :vertical }
|
4
|
+
let(:opts) { {:height => 20} }
|
5
|
+
|
6
|
+
it "should create a new pane" do
|
7
|
+
splitable.split(orientation, opts)
|
8
|
+
splitable.panes.first.should be_kind_of Tlux::Pane
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should add the new pane to the list of panes" do
|
12
|
+
expect {
|
13
|
+
splitable.split orientation, opts
|
14
|
+
}.to change(splitable.panes, :size).by(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should call the passed block with the context of the new pane" do
|
18
|
+
pane = nil
|
19
|
+
|
20
|
+
splitable.split :vertical do
|
21
|
+
pane = self
|
22
|
+
end
|
23
|
+
|
24
|
+
pane.should be_kind_of(Tlux::Pane)
|
25
|
+
pane.orientation.should_not be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/window_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Tlux::Window do
|
4
|
+
it_behaves_like Tlux::Splitable do
|
5
|
+
let(:splitable) { Tlux::Window.new("foo") }
|
6
|
+
end
|
7
|
+
|
8
|
+
it_behaves_like Tlux::Commandable do
|
9
|
+
let(:commandable) { Tlux::Window.new("foo") }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".new" do
|
13
|
+
subject { Tlux::Window.new("foo") }
|
14
|
+
|
15
|
+
it "should have a name" do
|
16
|
+
subject.name.should == "foo"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/tlux.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tlux/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Oliver Nightingale"]
|
6
|
+
gem.email = ["oliver.nightingale1@gmail.com"]
|
7
|
+
gem.description = %q{Luxurious tmux configuration}
|
8
|
+
gem.summary = %q{Luxurious tmux configuration}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "tlux"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Tlux::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency('rspec')
|
19
|
+
#gem.add_development_dependency('fakefs')
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tlux
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Oliver Nightingale
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-31 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70260310518360 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70260310518360
|
25
|
+
description: Luxurious tmux configuration
|
26
|
+
email:
|
27
|
+
- oliver.nightingale1@gmail.com
|
28
|
+
executables:
|
29
|
+
- tlux
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- .rspec
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- bin/tlux
|
40
|
+
- lib/tlux.rb
|
41
|
+
- lib/tlux/commandable.rb
|
42
|
+
- lib/tlux/commands.rb
|
43
|
+
- lib/tlux/commands/base.rb
|
44
|
+
- lib/tlux/commands/list_command.rb
|
45
|
+
- lib/tlux/commands/new_command.rb
|
46
|
+
- lib/tlux/commands/run_command.rb
|
47
|
+
- lib/tlux/commands/start.rb
|
48
|
+
- lib/tlux/commands/start_command.rb
|
49
|
+
- lib/tlux/config.rb
|
50
|
+
- lib/tlux/config/generator.rb
|
51
|
+
- lib/tlux/config/parser.rb
|
52
|
+
- lib/tlux/pane.rb
|
53
|
+
- lib/tlux/session.rb
|
54
|
+
- lib/tlux/splitable.rb
|
55
|
+
- lib/tlux/templates/config.erb
|
56
|
+
- lib/tlux/templates/new.erb
|
57
|
+
- lib/tlux/version.rb
|
58
|
+
- lib/tlux/window.rb
|
59
|
+
- spec/commands/base_spec.rb
|
60
|
+
- spec/commands/list_command_spec.rb
|
61
|
+
- spec/commands/new_command_spec.rb
|
62
|
+
- spec/commands/run_command_spec.rb
|
63
|
+
- spec/config/generator_spec.rb
|
64
|
+
- spec/config/parser_spec.rb
|
65
|
+
- spec/fixtures/sample_config.rb
|
66
|
+
- spec/pane_spec.rb
|
67
|
+
- spec/session_spec.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
- spec/support/commandable.rb
|
70
|
+
- spec/support/splitable.rb
|
71
|
+
- spec/window_spec.rb
|
72
|
+
- tlux.gemspec
|
73
|
+
homepage: ''
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.8.11
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Luxurious tmux configuration
|
97
|
+
test_files:
|
98
|
+
- spec/commands/base_spec.rb
|
99
|
+
- spec/commands/list_command_spec.rb
|
100
|
+
- spec/commands/new_command_spec.rb
|
101
|
+
- spec/commands/run_command_spec.rb
|
102
|
+
- spec/config/generator_spec.rb
|
103
|
+
- spec/config/parser_spec.rb
|
104
|
+
- spec/fixtures/sample_config.rb
|
105
|
+
- spec/pane_spec.rb
|
106
|
+
- spec/session_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/support/commandable.rb
|
109
|
+
- spec/support/splitable.rb
|
110
|
+
- spec/window_spec.rb
|