tmux_launcher 0.1.9
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.
- checksums.yaml +7 -0
- data/app/exit_action.rb +3 -0
- data/app/key.rb +20 -0
- data/app/main.rb +96 -0
- data/app/nil/session.rb +19 -0
- data/app/selections/new_session.rb +18 -0
- data/app/selections/session.rb +25 -0
- data/app/state_machine/existing.rb +23 -0
- data/app/state_machine/manager.rb +0 -0
- data/app/state_machine/new_session_state.rb +34 -0
- data/app/state_machine/quit.rb +20 -0
- data/app/state_machine/state.rb +54 -0
- data/app/tmux/commands.rb +35 -0
- data/bin/tmux_launcher +5 -0
- data/lib/environment.rb +53 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b852b3b0deaff5a895d1a504576f66898f0a5e0d
|
4
|
+
data.tar.gz: dae9dd4bc873eb2f312ac1ab41dfec4edc29c053
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 21ac6400d43af84b7e80f24d2570b22e08505b56898a7d7e3f719882600cbfc237e877c3c271901d8187bcd342e0c839465abaf2570ca10f6ffacb36166f13a4
|
7
|
+
data.tar.gz: 451a176d6e261736976cd99fd24a185c45351afa50ee188cc19f473221e60801c46d3bfb166a99becb0f140078121de3b09aa3a4805536e8d643b0ac97236d6e
|
data/app/exit_action.rb
ADDED
data/app/key.rb
ADDED
data/app/main.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'curses'
|
2
|
+
|
3
|
+
class Main
|
4
|
+
attr_accessor :arg
|
5
|
+
|
6
|
+
def initialize(arg)
|
7
|
+
self.arg = arg
|
8
|
+
|
9
|
+
raise 'Cannot run nested Tmux session' if commander.in_tmux?
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
Curses.crmode
|
14
|
+
|
15
|
+
state = initial_state
|
16
|
+
window = display(state)
|
17
|
+
|
18
|
+
begin
|
19
|
+
loop do
|
20
|
+
state = set_next_screen(window, state)
|
21
|
+
window = display(state)
|
22
|
+
end
|
23
|
+
rescue ExitAction
|
24
|
+
logger.info("Exiting")
|
25
|
+
rescue Interrupt => exception
|
26
|
+
logger.info("Interrupted: exiting application")
|
27
|
+
rescue => exception
|
28
|
+
logger.error(exception)
|
29
|
+
logger.error(exception.backtrace)
|
30
|
+
ensure
|
31
|
+
Curses.close_screen
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def initial_state
|
38
|
+
StateMachine::State.new(selections, 0)
|
39
|
+
end
|
40
|
+
|
41
|
+
def display(state)
|
42
|
+
Curses::Window.new(0, 0, 0, 0).tap do |w|
|
43
|
+
# w.box(?|, ?-)
|
44
|
+
w.attrset(Curses::A_NORMAL)
|
45
|
+
w.setpos(0, 0)
|
46
|
+
w.addstr("TMUX Launcher")
|
47
|
+
|
48
|
+
w.setpos(2, 0)
|
49
|
+
|
50
|
+
i = -1
|
51
|
+
selections.each do |selection|
|
52
|
+
i += 1
|
53
|
+
|
54
|
+
if i == state.selected_index
|
55
|
+
w.attrset(Curses::A_UNDERLINE)
|
56
|
+
w.addstr("> #{selection.to_s}")
|
57
|
+
else
|
58
|
+
w.addstr(selection.to_s)
|
59
|
+
end
|
60
|
+
|
61
|
+
w.addstr("\n") if i < selections.count - 1
|
62
|
+
w.attrset(Curses::A_NORMAL)
|
63
|
+
end
|
64
|
+
|
65
|
+
display_help(w, 2 + selections.count + 3)
|
66
|
+
|
67
|
+
w.setpos(2 + selections.count + 1, 0)
|
68
|
+
w.addstr('Selection: ')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def display_help(window, row)
|
73
|
+
window.setpos(row, 0)
|
74
|
+
|
75
|
+
window.addstr("Help\n")
|
76
|
+
window.addstr("Quit\tq\n")
|
77
|
+
window.addstr("Select\to, ENTER\n")
|
78
|
+
window.addstr("Up\tk, \u2191\n")
|
79
|
+
window.addstr("Down\tj, \u2193")
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_next_screen(window, state)
|
83
|
+
state.action(window)
|
84
|
+
window.close
|
85
|
+
|
86
|
+
state.next_state
|
87
|
+
end
|
88
|
+
|
89
|
+
def selections
|
90
|
+
@selections ||= ([Selections::NewSession.new] + commander.sessions)
|
91
|
+
end
|
92
|
+
|
93
|
+
def commander
|
94
|
+
@commander ||= Tmux::Commands.new
|
95
|
+
end
|
96
|
+
end
|
data/app/nil/session.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Selections
|
2
|
+
class Session
|
3
|
+
attr_reader :id
|
4
|
+
|
5
|
+
def initialize(line)
|
6
|
+
line.match(regex) do |m|
|
7
|
+
@id = m[1]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
@id.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def regex
|
22
|
+
%r{^([^:]+):}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module StateMachine
|
2
|
+
class Existing
|
3
|
+
attr_reader :selected_index
|
4
|
+
|
5
|
+
def initialize(selected_index, session_id)
|
6
|
+
@commander = Tmux::Commands.new
|
7
|
+
@selected_index = selected_index
|
8
|
+
@session_id = session_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
""
|
13
|
+
end
|
14
|
+
|
15
|
+
def next_state
|
16
|
+
end
|
17
|
+
|
18
|
+
def action(window)
|
19
|
+
@commander.attach_to(@session_id)
|
20
|
+
raise ExitAction.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module StateMachine
|
2
|
+
class NewSessionState
|
3
|
+
attr_reader :selected_index
|
4
|
+
|
5
|
+
def initialize(selected_index)
|
6
|
+
@selected_index = selected_index
|
7
|
+
end
|
8
|
+
|
9
|
+
def action(window)
|
10
|
+
name = window.getstr
|
11
|
+
|
12
|
+
name = remove_prohibited_chars(name)
|
13
|
+
|
14
|
+
commander.new_session(name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def next_state
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"Creating new session"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def remove_prohibited_chars(name)
|
27
|
+
name.gsub(%r{[:]}) { |m| '' }
|
28
|
+
end
|
29
|
+
|
30
|
+
def commander
|
31
|
+
@commander ||= Tmux::Commands.new
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module StateMachine
|
2
|
+
class Quit
|
3
|
+
attr_reader :selected_index
|
4
|
+
|
5
|
+
def initialize(selected_index)
|
6
|
+
@selected_index = selected_index
|
7
|
+
end
|
8
|
+
|
9
|
+
def action(window)
|
10
|
+
raise ExitAction.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def next_state
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"Exit"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module StateMachine
|
2
|
+
# TODO: Rename to Select
|
3
|
+
class State
|
4
|
+
attr_reader :selected_index
|
5
|
+
|
6
|
+
def initialize(selections, selected_index)
|
7
|
+
raise 'no selections' if selections.nil? || selections.empty?
|
8
|
+
|
9
|
+
@selections = selections
|
10
|
+
select(selected_index)
|
11
|
+
end
|
12
|
+
|
13
|
+
def action(window)
|
14
|
+
key = Key.new(window.getch)
|
15
|
+
|
16
|
+
begin
|
17
|
+
@next_state =
|
18
|
+
case key.button
|
19
|
+
when :up
|
20
|
+
self.class.new(@selections, selected_index-1)
|
21
|
+
when :down
|
22
|
+
self.class.new(@selections, selected_index+1)
|
23
|
+
when :enter
|
24
|
+
selected_index == 0 ?
|
25
|
+
NewSessionState.new(selected_index) :
|
26
|
+
Existing.new(selected_index, @selections[selected_index])
|
27
|
+
when :quit
|
28
|
+
Quit.new(selected_index)
|
29
|
+
else
|
30
|
+
self
|
31
|
+
end
|
32
|
+
rescue => exception
|
33
|
+
logger.info(exception)
|
34
|
+
@next_state = self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def next_state
|
39
|
+
@next_state
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def select(index)
|
45
|
+
index = index.to_i
|
46
|
+
|
47
|
+
if index < 0 || index > @selections.count - 1
|
48
|
+
raise "index (#{index}) should be between 0 and #{@selections.count}"
|
49
|
+
end
|
50
|
+
|
51
|
+
@selected_index = index.to_i
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Tmux
|
2
|
+
class Commands
|
3
|
+
def initialize(executable=nil)
|
4
|
+
@executable ||= `which tmux`.chomp
|
5
|
+
end
|
6
|
+
|
7
|
+
def sessions
|
8
|
+
strings = `#{@executable} list-sessions`.split("\n")
|
9
|
+
|
10
|
+
if strings.nil? || (strings.count == 1 && empty_session?(strings.first))
|
11
|
+
return []
|
12
|
+
end
|
13
|
+
|
14
|
+
strings.map { |str| Selections::Session.new(str) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def attach_to(id)
|
18
|
+
system("#{@executable} attach -t #{id}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_session(id)
|
22
|
+
system("#{@executable} new-session -s #{id}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def in_tmux?
|
26
|
+
ENV.has_key?('TMUX')
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def empty_session?(line)
|
32
|
+
false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/bin/tmux_launcher
ADDED
data/lib/environment.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_support/logger'
|
2
|
+
|
3
|
+
# App environment boilerplate code
|
4
|
+
class Environment
|
5
|
+
|
6
|
+
APP_ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def app_config
|
10
|
+
@app_config ||= YAML.load_file("#{File.expand_path(APP_ROOT + '/config')}/config.yml")
|
11
|
+
end
|
12
|
+
|
13
|
+
def logger
|
14
|
+
return @logger if @logger
|
15
|
+
l = Logger.new("#{File.expand_path(APP_ROOT + '/log')}/tmux_launcher.log")
|
16
|
+
formatter = proc do |_severity, datetime, _progname, msg|
|
17
|
+
"#{datetime}: #{msg}\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
l.formatter = formatter
|
21
|
+
@logger = l
|
22
|
+
end
|
23
|
+
|
24
|
+
def console_logger
|
25
|
+
return @console_logger if @console_logger
|
26
|
+
l = Logger.new(STDERR)
|
27
|
+
l.formatter = logger.formatter
|
28
|
+
@console_logger = l
|
29
|
+
end
|
30
|
+
|
31
|
+
def report_files_dir
|
32
|
+
"#{Environment::APP_ROOT}/out"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def logger
|
40
|
+
Environment.logger
|
41
|
+
end
|
42
|
+
|
43
|
+
def console_logger
|
44
|
+
Environment.console_logger
|
45
|
+
end
|
46
|
+
|
47
|
+
Dir["#{Environment::APP_ROOT}/config/initializers/**/*.rb"].sort.each { |f| require f }
|
48
|
+
Dir["#{Environment::APP_ROOT}/lib/**/*.rb"].sort.each { |f| require f }
|
49
|
+
Dir["#{Environment::APP_ROOT}/app/**/*.rb"].sort.each { |f| require f }
|
50
|
+
|
51
|
+
# Create log directory
|
52
|
+
log_dir = "#{Environment::APP_ROOT}/log"
|
53
|
+
Dir.mkdir(log_dir) unless Dir.exists?(log_dir)
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tmux_launcher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.9
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Jakob Ofer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A simple hello world gem
|
14
|
+
email: ofer987@gmail.com
|
15
|
+
executables:
|
16
|
+
- tmux_launcher
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- app/exit_action.rb
|
21
|
+
- app/key.rb
|
22
|
+
- app/main.rb
|
23
|
+
- app/nil/session.rb
|
24
|
+
- app/selections/new_session.rb
|
25
|
+
- app/selections/session.rb
|
26
|
+
- app/state_machine/existing.rb
|
27
|
+
- app/state_machine/manager.rb
|
28
|
+
- app/state_machine/new_session_state.rb
|
29
|
+
- app/state_machine/quit.rb
|
30
|
+
- app/state_machine/state.rb
|
31
|
+
- app/tmux/commands.rb
|
32
|
+
- bin/tmux_launcher
|
33
|
+
- lib/environment.rb
|
34
|
+
homepage: http://rubygems.org/gems/tmux_launcher
|
35
|
+
licenses:
|
36
|
+
- Unlicense
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.5.1
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: TMUX Launcher
|
58
|
+
test_files: []
|