tmuxinator 0.5.0 → 0.6.0

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +5 -0
  5. data/CHANGELOG.md +36 -0
  6. data/CONTRIBUTING.md +29 -0
  7. data/Gemfile +4 -7
  8. data/{LICENSE.txt → LICENSE} +1 -1
  9. data/README.md +128 -118
  10. data/Rakefile +1 -72
  11. data/bin/mux +8 -3
  12. data/bin/tmuxinator +8 -3
  13. data/completion/tmuxinator.bash +18 -0
  14. data/completion/tmuxinator.zsh +20 -0
  15. data/lib/tmuxinator.rb +13 -7
  16. data/lib/tmuxinator/assets/sample.yml +24 -11
  17. data/lib/tmuxinator/assets/template.erb +47 -0
  18. data/lib/tmuxinator/cli.rb +121 -145
  19. data/lib/tmuxinator/config.rb +92 -0
  20. data/lib/tmuxinator/deprecations.rb +19 -0
  21. data/lib/tmuxinator/pane.rb +36 -0
  22. data/lib/tmuxinator/project.rb +142 -0
  23. data/lib/tmuxinator/util.rb +14 -0
  24. data/lib/tmuxinator/version.rb +3 -0
  25. data/lib/tmuxinator/window.rb +76 -0
  26. data/spec/factories/projects.rb +17 -0
  27. data/spec/fixtures/sample.deprecations.yml +35 -0
  28. data/spec/fixtures/sample.yml +35 -0
  29. data/spec/lib/tmuxinator/cli_spec.rb +230 -0
  30. data/spec/lib/tmuxinator/config_spec.rb +121 -0
  31. data/spec/lib/tmuxinator/pane_spec.rb +7 -0
  32. data/spec/lib/tmuxinator/project_spec.rb +209 -0
  33. data/spec/lib/tmuxinator/util_spec.rb +4 -0
  34. data/spec/lib/tmuxinator/window_spec.rb +62 -0
  35. data/spec/spec_helper.rb +28 -8
  36. data/tmuxinator.gemspec +47 -65
  37. metadata +186 -62
  38. data/.document +0 -5
  39. data/Gemfile.lock +0 -28
  40. data/TODO +0 -4
  41. data/VERSION +0 -1
  42. data/bin/tmuxinator_completion +0 -29
  43. data/lib/tmuxinator/assets/tmux_config.tmux +0 -37
  44. data/lib/tmuxinator/config_writer.rb +0 -104
  45. data/lib/tmuxinator/helper.rb +0 -19
  46. data/spec/tmuxinator_spec.rb +0 -54
data/bin/mux CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
- $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
2
+ $: << File.expand_path("../../lib/", __FILE__)
3
3
 
4
- require 'tmuxinator'
4
+ require "thor"
5
+ require "tmuxinator"
5
6
 
6
- Tmuxinator::Cli.run(*ARGV)
7
+ if ARGV.length == 1 && (ARGV & Tmuxinator::Cli.new.command_list).empty?
8
+ Tmuxinator::Cli.new.start(ARGV[0])
9
+ else
10
+ Tmuxinator::Cli.start
11
+ end
data/bin/tmuxinator CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
- $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
2
+ $: << File.expand_path("../../lib/", __FILE__)
3
3
 
4
- require 'tmuxinator'
4
+ require "thor"
5
+ require "tmuxinator"
5
6
 
6
- Tmuxinator::Cli.run(*ARGV)
7
+ if ARGV.length == 1 && (ARGV & Tmuxinator::Cli.new.command_list).empty?
8
+ Tmuxinator::Cli.new.start(ARGV[0])
9
+ else
10
+ Tmuxinator::Cli.start
11
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+
3
+ _tmuxinator() {
4
+ COMPREPLY=()
5
+ local word="${COMP_WORDS[COMP_CWORD]}"
6
+
7
+ if [ "$COMP_CWORD" -eq 1 ]; then
8
+ COMPREPLY=( $(compgen -W "$(tmuxinator commands)" -- "$word") )
9
+ else
10
+ local words=("${COMP_WORDS[@]}")
11
+ unset words[0]
12
+ unset words[$COMP_CWORD]
13
+ local completions=$(tmuxinator completions "${words[@]}")
14
+ COMPREPLY=( $(compgen -W "$completions" -- "$word") )
15
+ fi
16
+ }
17
+
18
+ complete -F _tmuxinator -o tmuxinator mux
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env zsh
2
+
3
+ if [[ ! -o interactive ]]; then
4
+ return
5
+ fi
6
+
7
+ compctl -K _tmuxinator tmuxinator mux
8
+
9
+ _tmuxinator() {
10
+ local words completions
11
+ read -cA words
12
+
13
+ if [ "${#words}" -eq 2 ]; then
14
+ completions="$(tmuxinator commands)"
15
+ else
16
+ completions="$(tmuxinator completions ${words[2,-2]})"
17
+ fi
18
+
19
+ reply=("${(ps:\n:)completions}")
20
+ }
data/lib/tmuxinator.rb CHANGED
@@ -1,11 +1,17 @@
1
- require 'yaml'
2
- require 'ostruct'
3
- require 'erb'
4
- require 'tmuxinator/helper'
5
- require 'tmuxinator/cli'
6
- require 'tmuxinator/config_writer'
1
+ require "yaml"
2
+ require "erubis"
3
+ require "shellwords"
4
+ require "thor"
5
+ require "active_support/all"
7
6
 
8
- TMUX_TEMPLATE = "#{File.dirname(__FILE__)}/tmuxinator/assets/tmux_config.tmux"
7
+ require "tmuxinator/util"
8
+ require "tmuxinator/deprecations"
9
+ require "tmuxinator/cli"
10
+ require "tmuxinator/config"
11
+ require "tmuxinator/pane"
12
+ require "tmuxinator/project"
13
+ require "tmuxinator/window"
14
+ require "tmuxinator/version"
9
15
 
10
16
  module Tmuxinator
11
17
  end
@@ -1,22 +1,35 @@
1
1
  # ~/.tmuxinator/<%= @name %>.yml
2
2
  # you can make as many tabs as you wish...
3
3
 
4
- project_name: Tmuxinator
5
- project_root: ~/code/rails_project
6
- socket_name: foo # Not needed. Remove to use default socket
7
- rvm: 1.9.2@rails_project
8
- pre: sudo /etc/rc.d/mysqld start
9
- tabs:
4
+ name: sample
5
+ root: ~/test
6
+ socket_name: foo # Remove to use default socket
7
+ pre: sudo /etc/rc.d/mysqld start # Runs before everything
8
+ pre_window: rbenv shell 2.0.0-p247 # Runs in each tab and pane
9
+ tmux_options: -v -2 # Pass arguments to tmux
10
+ windows:
10
11
  - editor:
12
+ pre:
13
+ - echo "I get run in each pane, before each pane command!"
14
+ -
11
15
  layout: main-vertical
12
16
  panes:
13
17
  - vim
14
18
  - #empty, will just run plain bash
15
19
  - top
16
20
  - shell: git pull
17
- - database: rails db
18
- - server: rails s
19
- - logs: tail -f logs/development.log
20
- - console: rails c
21
+ - guard:
22
+ layout: tiled
23
+ pre:
24
+ - echo "I get run in each pane."
25
+ - echo "Before each pane command!"
26
+ panes:
27
+ -
28
+ - #empty, will just run plain bash
29
+ -
30
+ - database: bundle exec rails db
31
+ - server: bundle exec rails s
32
+ - logs: tail -f log/development.log
33
+ - console: bundle exec rails c
21
34
  - capistrano:
22
- - server: ssh me@myhost
35
+ - server: ssh user@example.com
@@ -0,0 +1,47 @@
1
+ #!<%= ENV["SHELL"] || "/bin/bash" %>
2
+ <%= tmux %> start-server\; has-session -t <%= name %> 2>/dev/null
3
+
4
+ if [ "$?" -eq 1 ]; then
5
+ cd <%= root || "." %>
6
+
7
+ # Run pre command.
8
+ <%= pre %>
9
+
10
+ # Create the session and the first window.
11
+ <%= tmux %> new-session -d -s <%= name %> -n <%= windows.first.name %>
12
+
13
+ # Set the default path.
14
+ <%= tmux %> set-option -t <%= name %> default-path <%= root -%> 1>/dev/null
15
+
16
+ # Create other windows.
17
+ <%- windows.drop(1).each do |window| -%>
18
+ <%= window.tmux_new_window_command %>
19
+ <%- end -%>
20
+
21
+ <%- windows.each do |window| -%>
22
+
23
+ # Window "<%= window.name %>"
24
+ <%- unless window.panes? -%>
25
+ <%= window.tmux_pre_window_command %>
26
+ <%= window.tmux_main_command %>
27
+ <%- else -%>
28
+ <%- window.panes.each do |pane| -%>
29
+ <%= pane.tmux_pre_window_command %>
30
+ <%= pane.tmux_pre_command %>
31
+ <%= pane.tmux_main_command %>
32
+
33
+ <%- unless pane.last? -%>
34
+ <%= pane.tmux_split_command %>
35
+ <%- end -%>
36
+ <%- end -%>
37
+
38
+
39
+ <%= window.tmux_layout_command %>
40
+ <%= window.tmux_select_first_pane %>
41
+ <%- end -%>
42
+ <%- end -%>
43
+
44
+ <%= tmux %> select-window -t <%= base_index %>
45
+ fi
46
+
47
+ <%= tmux %> -u attach-session -t <%= name %>
@@ -1,175 +1,151 @@
1
- require 'fileutils'
2
-
3
1
  module Tmuxinator
4
- class Cli
2
+ class Cli < Thor
3
+ include Tmuxinator::Util
5
4
 
6
- class << self
7
- include Tmuxinator::Helper
5
+ attr_reader :command_list
8
6
 
9
- def run *args
10
- if args.empty?
11
- self.usage
12
- else
13
- self.send(args.shift, *args)
14
- end
15
- end
7
+ def initialize(*args)
8
+ super
9
+ @command_list = %w(commands copy debug delete doctor help implode list start version)
10
+ end
11
+
12
+ package_name "tmuxinator"
13
+
14
+ desc "commands", "Lists commands available in tmuxinator"
16
15
 
17
- # print the usage string, this is a fall through method.
18
- def usage
19
- puts %{
20
- Usage: tmuxinator ACTION [Arg]
21
- or
22
- tmuxinator [project_name]
23
-
24
- ACTIONS:
25
- start [project_name]
26
- start a tmux session using project's tmuxinator config
27
- open [project_name]
28
- create a new project file and open it in your editor
29
- copy [source_project] [new_project]
30
- copy source_project project file to a new project called new_project
31
- delete [project_name]
32
- deletes the project called project_name
33
- implode
34
- deletes all existing projects!
35
- list [-v]
36
- list all existing projects
37
- doctor
38
- look for problems in your configuration
39
- help
40
- shows this help document
41
- version
42
- shows tmuxinator version number
43
- }
16
+ def commands
17
+ puts command_list.join("\n")
18
+ end
19
+
20
+ desc "completions [arg1 arg2]", "Used for shell completion"
21
+
22
+ def completions(arg)
23
+ if %w(start open copy delete).include?(arg)
24
+ configs = Tmuxinator::Config.configs
25
+ puts configs
44
26
  end
45
- alias :help :usage
46
- alias :h :usage
47
-
48
- # Open a config file, it's created if it doesn't exist already.
49
- def open *args
50
- exit!("You must specify a name for the new project") unless args.size > 0
51
- puts "warning: passing multiple arguments to open will be ignored" if args.size > 1
52
- @name = args.shift
53
- config_path = "#{root_dir}#{@name}.yml"
54
- unless File.exists?(config_path)
55
- template = File.exists?(user_config) ? user_config : sample_config
56
- erb = ERB.new(File.read(template)).result(binding)
57
- tmp = File.open(config_path, 'w') {|f| f.write(erb) }
58
- end
59
- system("$EDITOR #{config_path}")
27
+ end
28
+
29
+ desc "new [PROJECT]", "Create a new project file and open it in your editor"
30
+ map "open" => :new
31
+ map "o" => :new
32
+ map "n" => :new
33
+
34
+ def new(name)
35
+ config = Tmuxinator::Config.project(name)
36
+
37
+ unless Tmuxinator::Config.exists?(name)
38
+ template = Tmuxinator::Config.default? ? Tmuxinator::Config.default : Tmuxinator::Config.sample
39
+ erb = ERB.new(File.read(template)).result(binding)
40
+ File.open(config, "w") { |f| f.write(erb) }
60
41
  end
61
- alias :o :open
62
- alias :new :open
63
- alias :n :open
64
42
 
65
- def copy *args
66
- @copy = args.shift
67
- @name = args.shift
68
- @config_to_copy = "#{root_dir}#{@copy}.yml"
43
+ Kernel.system("$EDITOR #{config}")
44
+ end
69
45
 
70
- exit!("Project #{@copy} doesn't exist!") unless File.exists?(@config_to_copy)
71
- exit!("You must specify a name for the new project") unless @name
46
+ desc "start [PROJECT]", "Start a tmux session using a project's tmuxinator config"
47
+ map "s" => :start
72
48
 
73
- file_path = "#{root_dir}#{@name}.yml"
49
+ def start(name)
50
+ project = Tmuxinator::Config.validate(name)
74
51
 
75
- if File.exists?(file_path)
76
- confirm!("#{@name} already exists, would you like to overwrite it? (type yes or no):") do
77
- FileUtils.rm(file_path)
78
- puts "Overwriting #{@name}"
79
- end
80
- end
81
- open @name
82
- end
83
- alias :c :copy
84
-
85
- def delete *args
86
- puts "warning: passing multiple arguments to delete will be ignored" if args.size > 1
87
- filename = args.shift
88
- file_path = "#{root_dir}#{filename}.yml"
89
-
90
- if File.exists?(file_path)
91
- confirm!("Are you sure you want to delete #{filename}? (type yes or no):") do
92
- FileUtils.rm(file_path)
93
- puts "Deleted #{filename}"
94
- end
95
- else
96
- exit! "That file doesn't exist."
97
- end
52
+ if project.deprecations.any?
53
+ project.deprecations.each { |deprecation| say deprecation, :red }
54
+ puts
55
+ print "Press any key to continue."
56
+ STDIN.getc
98
57
  end
99
- alias :d :delete
100
58
 
101
- def implode *args
102
- exit!("delete_all doesn't accapt any arguments!") unless args.empty?
103
- confirm!("Are you sure you want to delete all tmuxinator configs? (type yes or no):") do
104
- FileUtils.remove_dir(root_dir)
105
- puts "Deleted #{root_dir}"
59
+ Kernel.exec(project.render)
60
+ end
61
+
62
+ desc "debug [PROJECT]", "Output the shell commands that are generated by tmuxinator"
63
+
64
+ def debug(name)
65
+ project = Tmuxinator::Config.validate(name)
66
+ puts project.render
67
+ end
68
+
69
+ desc "copy [EXISTING] [NEW]", "Copy an existing project to a new project and open it in your editor"
70
+ map "c" => :copy
71
+ map "cp" => :copy
72
+
73
+ def copy(existing, new)
74
+ existing_config_path = Tmuxinator::Config.project(existing)
75
+ new_config_path = Tmuxinator::Config.project(new)
76
+
77
+ exit!("Project #{existing} doesn't exist!") unless Tmuxinator::Config.exists?(existing)
78
+
79
+ if Tmuxinator::Config.exists?(new)
80
+ if yes?("#{new} already exists, would you like to overwrite it?", :red)
81
+ FileUtils.rm(new_config_path)
82
+ say "Overwriting #{new}"
106
83
  end
107
84
  end
108
- alias :i :implode
109
-
110
- def list *args
111
- verbose = args.include?("-v")
112
- puts "tmuxinator configs:"
113
- Dir["#{root_dir}**"].each do |path|
114
- next unless verbose || File.extname(path) == ".yml"
115
- path = path.gsub(root_dir, '').gsub('.yml','') unless verbose
116
- puts " #{path}"
85
+
86
+ FileUtils.copy_file(existing_config_path, new_config_path)
87
+ Kernel.system("$EDITOR #{new_config_path}")
88
+ end
89
+
90
+ desc "delete [PROJECT]", "Deletes given project"
91
+ map "d" => :delete
92
+ map "rm" => :delete
93
+
94
+ def delete(project)
95
+ config = "#{Tmuxinator::Config.root}#{project}.yml"
96
+
97
+ if Tmuxinator::Config.exists?(config)
98
+ if yes?("Are you sure you want to delete #{project}?", :red)
99
+ FileUtils.rm(config)
100
+ say "Deleted #{project}"
117
101
  end
102
+ else
103
+ exit! "That file doesn't exist."
118
104
  end
119
- alias :l :list
120
- alias :ls :list
105
+ end
121
106
 
122
- def version
123
- system("cat #{File.dirname(__FILE__) + '/../../VERSION'}")
124
- puts
125
- end
126
- alias :v :version
127
-
128
- def doctor
129
- print " checking if tmux is installed ==> "
130
- puts system("which tmux > /dev/null") ? "Yes" : "No"
131
- print " checking if $EDITOR is set ==> "
132
- puts ENV['EDITOR'] ? "Yes" : "No"
133
- print " checking if $SHELL is set ==> "
134
- puts ENV['SHELL'] ? "Yes" : "No"
135
- end
107
+ desc "implode", "Delets all tmuxinator projects"
108
+ map "i" => :implode
136
109
 
137
- # build script and run it
138
- def start *args
139
- exit!("You must specify a name for the new project") unless args.size > 0
140
- puts "warning: passing multiple arguments to open will be ignored" if args.size > 1
141
- project_name = args.shift
142
- config_path = "#{root_dir}#{project_name}.yml"
143
- config = Tmuxinator::ConfigWriter.new(config_path).render
144
- # replace current proccess by running compiled tmux config
145
- exec(config)
110
+ def implode
111
+ if yes?("Are you sure you want to delete all tmuxinator configs?", :red)
112
+ FileUtils.remove_dir(Tmuxinator::Config.root)
113
+ say "Deleted all tmuxinator projects."
146
114
  end
147
- alias :s :start
115
+ end
148
116
 
149
- def method_missing method, *args, &block
150
- start method if File.exists?("#{root_dir}#{method}.yml")
151
- puts "There's no command or project '#{method}' in tmuxinator"
152
- usage
153
- end
117
+ desc "list", "Lists all tmuxinator projects"
118
+ map "l" => :list
119
+ map "ls" => :list
154
120
 
155
- private #==============================
121
+ def list
122
+ say "tmuxinator projects:"
156
123
 
157
- def root_dir
158
- # create ~/.tmuxinator directory if it doesn't exist
159
- Dir.mkdir("#{ENV["HOME"]}/.tmuxinator/") unless File.directory?(File.expand_path("~/.tmuxinator"))
160
- "#{ENV["HOME"]}/.tmuxinator/"
124
+ configs = Dir["#{Tmuxinator::Config.root}/*.yml"].sort.map do |path|
125
+ path.gsub("#{Tmuxinator::Config.root}/", "").gsub(".yml", "")
161
126
  end
162
127
 
163
- def sample_config
164
- "#{File.dirname(__FILE__)}/assets/sample.yml"
165
- end
128
+ print_in_columns configs
129
+ end
166
130
 
167
- def user_config
168
- @config_to_copy || "#{ENV["HOME"]}/.tmuxinator/default.yml"
169
- end
131
+ desc "version", "Display installed tmuxinator version"
132
+ map "-v" => :version
170
133
 
134
+ def version
135
+ say "tmuxinator #{Tmuxinator::VERSION}"
171
136
  end
172
137
 
138
+ desc "doctor", "Look for problems in your configuration"
139
+
140
+ def doctor
141
+ say "Checking if tmux is installed ==> "
142
+ yes_no Tmuxinator::Config.installed?
143
+
144
+ say "Checking if $EDITOR is set ==> "
145
+ yes_no Tmuxinator::Config.editor?
146
+
147
+ say "Checking if $SHELL is set ==> "
148
+ yes_no Tmuxinator::Config.shell?
149
+ end
173
150
  end
174
151
  end
175
-