tmux-ruby 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/LICENSE +22 -0
- data/README.md +23 -0
- data/lib/tmux.rb +56 -0
- data/lib/tmux/buffer.rb +131 -0
- data/lib/tmux/client.rb +193 -0
- data/lib/tmux/exception.rb +5 -0
- data/lib/tmux/exception/basic_exception.rb +6 -0
- data/lib/tmux/exception/in_tmux.rb +9 -0
- data/lib/tmux/exception/index_in_use.rb +9 -0
- data/lib/tmux/exception/unknown_command.rb +9 -0
- data/lib/tmux/exception/unsupported_version.rb +15 -0
- data/lib/tmux/filterable_hash.rb +15 -0
- data/lib/tmux/options.rb +109 -0
- data/lib/tmux/options/attr_option.rb +10 -0
- data/lib/tmux/options/bell_action_option.rb +19 -0
- data/lib/tmux/options/boolean_option.rb +26 -0
- data/lib/tmux/options/char_array_option.rb +26 -0
- data/lib/tmux/options/clock_mode_style_option.rb +27 -0
- data/lib/tmux/options/color_option.rb +23 -0
- data/lib/tmux/options/justification_option.rb +19 -0
- data/lib/tmux/options/keymap_option.rb +19 -0
- data/lib/tmux/options/number_option.rb +26 -0
- data/lib/tmux/options/option.rb +38 -0
- data/lib/tmux/options/string_option.rb +26 -0
- data/lib/tmux/options/symbol_option.rb +26 -0
- data/lib/tmux/options/word_array_option.rb +26 -0
- data/lib/tmux/options_list.rb +150 -0
- data/lib/tmux/pane.rb +496 -0
- data/lib/tmux/server.rb +217 -0
- data/lib/tmux/session.rb +312 -0
- data/lib/tmux/status_bar.rb +134 -0
- data/lib/tmux/status_bar/field.rb +129 -0
- data/lib/tmux/version.rb +4 -0
- data/lib/tmux/widget.rb +35 -0
- data/lib/tmux/widgets/progress_bar.rb +107 -0
- data/lib/tmux/window.rb +697 -0
- data/lib/tmux/window/status.rb +21 -0
- data/lib/tmux/window/status/state.rb +87 -0
- metadata +96 -0
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--tag "tmux:tmux command" --tag "tmuxver:Required tmux version" --hide-void-return -m markdown --private --protected --default-return Undefined
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2010 Dominik Honnef <dominikh@fork-bomb.org>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Widgets
|
2
|
+
|
3
|
+
- Progress bar ({Tmux::Widgets::ProgressBar ProgressBar})
|
4
|
+
|
5
|
+
# Semantic Versioning
|
6
|
+
|
7
|
+
tmux-ruby uses [Semantic Versioning](http://semver.org/)
|
8
|
+
|
9
|
+
|
10
|
+
# Documentation
|
11
|
+
|
12
|
+
tmux-ruby uses [YARD](http://github.com/lsegal/yard) for documenting
|
13
|
+
its codebase.
|
14
|
+
|
15
|
+
|
16
|
+
# Contributing
|
17
|
+
|
18
|
+
* Fork the project.
|
19
|
+
* Make your feature addition or bug fix.
|
20
|
+
* Commit, do not mess with rakefile, version, or history. (if you want
|
21
|
+
to have your own version, that is fine but bump version in a commit
|
22
|
+
by itself I can ignore when I pull)
|
23
|
+
* Send me a pull request. Bonus points for topic branches.
|
data/lib/tmux.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require "date"
|
2
|
+
require "tmux/filterable_hash"
|
3
|
+
require "tmux/exception"
|
4
|
+
require "tmux/server"
|
5
|
+
require "tmux/session"
|
6
|
+
require "tmux/client"
|
7
|
+
require "tmux/window"
|
8
|
+
require "tmux/pane"
|
9
|
+
require "tmux/buffer"
|
10
|
+
require "tmux/status_bar"
|
11
|
+
require "tmux/options_list"
|
12
|
+
require "tmux/options"
|
13
|
+
require "tmux/widget"
|
14
|
+
require "tmux/version"
|
15
|
+
|
16
|
+
# @todo Support querying and modifying keymaps
|
17
|
+
module Tmux
|
18
|
+
# The newest version of tmux we officially support
|
19
|
+
TMUX_VERSION = "1.3".freeze
|
20
|
+
|
21
|
+
@binary = `which tmux`.chomp
|
22
|
+
@verbose = false
|
23
|
+
|
24
|
+
class << self
|
25
|
+
# Path of the tmux binary.
|
26
|
+
# @return [String]
|
27
|
+
attr_accessor :binary
|
28
|
+
|
29
|
+
# Print verbose information on $stderr?
|
30
|
+
# @return [Boolean]
|
31
|
+
attr_accessor :verbose
|
32
|
+
alias_method :verbose?, :verbose
|
33
|
+
|
34
|
+
# Invokes a tmux command and returns all output.
|
35
|
+
#
|
36
|
+
# @param [String] command Command to invoke
|
37
|
+
# @param [Boolean] unset_tmux If true, unsets $TMUX before calling
|
38
|
+
# tmux, to allow nesting
|
39
|
+
# @return [String] all output
|
40
|
+
# @raise [Exception::UnknownCommand]
|
41
|
+
# @api private
|
42
|
+
def invoke_command(cmd, unset_tmux = false)
|
43
|
+
command = ""
|
44
|
+
command << "TMUX='' " if unset_tmux
|
45
|
+
command << "#{@binary} #{cmd}"
|
46
|
+
|
47
|
+
$stderr.puts(command) if verbose?
|
48
|
+
ret = `#{command} 2>&1`
|
49
|
+
if ret.start_with?("unknown command:")
|
50
|
+
raise Exception::UnknownCommand, ret.split(":", 2).last.strip
|
51
|
+
else
|
52
|
+
return ret
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/tmux/buffer.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require "filesize"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
module Tmux
|
5
|
+
class Buffer
|
6
|
+
# @return [Number]
|
7
|
+
attr_reader :number
|
8
|
+
# @return [Session]
|
9
|
+
attr_reader :session
|
10
|
+
# @return [Filesize]
|
11
|
+
def initialize(number, session)
|
12
|
+
@number, @session, @size = number, session
|
13
|
+
unless server.version >= "1.3"
|
14
|
+
# we do not need a temporary file for tmux versions that can
|
15
|
+
# directly load/save from/to stdin/stdout
|
16
|
+
@file = Tempfile.new("buffer")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param [Boolean] force_reload Ignore frozen state if true
|
21
|
+
# @return [Filesize]
|
22
|
+
attr_reader :size
|
23
|
+
undef_method "size"
|
24
|
+
def size(force_reload = false)
|
25
|
+
if @size && !force_reload
|
26
|
+
@size
|
27
|
+
else
|
28
|
+
Filesize.new(@session.buffers_information[number][:size].to_i)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param [Boolean] force_reload Ignore frozen state if true
|
33
|
+
# @return [String]
|
34
|
+
attr_accessor :data
|
35
|
+
undef_method "data"
|
36
|
+
undef_method "data="
|
37
|
+
def data(force_reload = false)
|
38
|
+
# note: we cannot use show-buffer because that would escape tabstops
|
39
|
+
if @data && !force_reload
|
40
|
+
@data
|
41
|
+
else
|
42
|
+
if server.version >= "1.3"
|
43
|
+
return server.invoke_command "save-buffer -b #@number -t #{@session.identifier} -"
|
44
|
+
else
|
45
|
+
server.invoke_command "save-buffer -b #@number -t #{@session.identifier} #{@file.path}"
|
46
|
+
return @file.read
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def data=(new_data)
|
52
|
+
# FIXME maybe some more escaping?
|
53
|
+
server.invoke_command "set-buffer -b #@number -t #{@session.identifier} \"#{new_data}\""
|
54
|
+
@data = data(true) if @frozen
|
55
|
+
@size = size(true)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Saves the contents of a buffer.
|
59
|
+
#
|
60
|
+
# @param [String] file The file to write to
|
61
|
+
# @param [Boolean] append Append to instead of overwriting the file
|
62
|
+
# @tmux save-buffer
|
63
|
+
# @return [void]
|
64
|
+
def save(file, append = false)
|
65
|
+
flag = append ? "-a" : ""
|
66
|
+
server.invoke_command "save-buffer #{flag} -b #@number -t #{@session.identifier} #{file}"
|
67
|
+
end
|
68
|
+
alias_method :write, :save
|
69
|
+
|
70
|
+
# By default, Buffer will not cache its data but instead query it each time.
|
71
|
+
# By calling this method, the data will be cached and not updated anymore.
|
72
|
+
#
|
73
|
+
# @return [void]
|
74
|
+
def freeze!
|
75
|
+
@frozen = true
|
76
|
+
@data = data
|
77
|
+
@size = size
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Server]
|
81
|
+
attr_reader :server
|
82
|
+
undef_method "server"
|
83
|
+
def server
|
84
|
+
@session.server
|
85
|
+
end
|
86
|
+
|
87
|
+
# Deletes a buffer.
|
88
|
+
#
|
89
|
+
# @tmux delete-buffer
|
90
|
+
# @return [void]
|
91
|
+
def delete
|
92
|
+
freeze! # so we can still access its old value
|
93
|
+
server.invoke_command "delete-buffer -b #@number -t #{@session.identifier}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [String] The content of a buffer
|
97
|
+
def to_s
|
98
|
+
text
|
99
|
+
end
|
100
|
+
|
101
|
+
# Pastes the content of a buffer into a {Window window} or {Pane pane}.
|
102
|
+
#
|
103
|
+
# @param [Window] target The {Pane pane} or {Window window} to
|
104
|
+
# paste the buffer into. Note: {Pane Panes} as as target are only
|
105
|
+
# supported since tmux version 1.3.
|
106
|
+
# @param [Boolean] pop If true, delete the buffer from the stack
|
107
|
+
# @param [Boolean] translate If true, any linefeed (LF) characters
|
108
|
+
# in the paste buffer are replaced with carriage returns (CR)
|
109
|
+
# @param [String] separator Replace any linefeed (LF) in the
|
110
|
+
# buffer with this separator. +translate+ must be false.
|
111
|
+
#
|
112
|
+
# @tmux paste-buffer
|
113
|
+
# @tmuxver >=1.3 for pasting to {Pane panes}
|
114
|
+
# @return [void]
|
115
|
+
# @see Window#paste
|
116
|
+
# @see Pane#paste
|
117
|
+
def paste(target = nil, pop = false, translate = true, separator = nil)
|
118
|
+
if server.version < "1.3"
|
119
|
+
if separator || target.is_a?(Pane)
|
120
|
+
raise Exception::UnsupportedVersion, "1.3"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
flag_pop = pop ? "-d" : ""
|
125
|
+
flag_translate = translate ? "" : "-r"
|
126
|
+
flag_separator = separator ? "" : "-s \"#{separator}\"" # FIXME escape
|
127
|
+
window_param = target ? "-t #{target.identifier}" : ""
|
128
|
+
server.invoke_command "paste-buffer #{flag_pop} #{flag_translate} #{flag_separator} #{window_param}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
data/lib/tmux/client.rb
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
module Tmux
|
2
|
+
class Client
|
3
|
+
# @return [Server]
|
4
|
+
attr_reader :server
|
5
|
+
# @return [String]
|
6
|
+
attr_reader :device
|
7
|
+
def initialize(server, device)
|
8
|
+
@server, @device = server, device
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String]
|
12
|
+
attr_reader :identifier
|
13
|
+
undef_method "identifier"
|
14
|
+
def identifier
|
15
|
+
@device
|
16
|
+
end
|
17
|
+
|
18
|
+
# Setting this will make a client switch to another {Session session}.
|
19
|
+
#
|
20
|
+
# @tmux switch-client
|
21
|
+
# @return [Session]
|
22
|
+
attr_accessor :session
|
23
|
+
undef_method "session"
|
24
|
+
undef_method "session="
|
25
|
+
def session
|
26
|
+
@server.clients_information[@device][:session]
|
27
|
+
end
|
28
|
+
|
29
|
+
def session=(new_session)
|
30
|
+
@server.invoke_command "switch-client -c #@device -t #{new_session.number}"
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Integer]
|
34
|
+
attr_reader :width
|
35
|
+
undef_method "width"
|
36
|
+
def width
|
37
|
+
@server.clients_information[@device][:width]
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Integer]
|
41
|
+
attr_reader :height
|
42
|
+
undef_method "height"
|
43
|
+
def height
|
44
|
+
@server.clients_information[@device][:height]
|
45
|
+
end
|
46
|
+
|
47
|
+
# $TERM of a client.
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
attr_reader :term
|
51
|
+
undef_method "term"
|
52
|
+
def term
|
53
|
+
@server.clients_information[@device][:term]
|
54
|
+
end
|
55
|
+
|
56
|
+
# True if the terminal is using UTF-8.
|
57
|
+
#
|
58
|
+
# @return [Boolean]
|
59
|
+
attr_reader :utf8
|
60
|
+
undef_method "utf8"
|
61
|
+
def utf8
|
62
|
+
@server.clients_information[@device][:utf8]
|
63
|
+
end
|
64
|
+
alias_method :utf8?, :utf8
|
65
|
+
|
66
|
+
# Detaches a client from tmux.
|
67
|
+
#
|
68
|
+
# @tmux detach-client
|
69
|
+
# @return [void]
|
70
|
+
def detach
|
71
|
+
@server.invoke_command "detach-client -t #@device"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Locks a client.
|
75
|
+
#
|
76
|
+
# @tmux lock-client
|
77
|
+
# @return [void]
|
78
|
+
# @tmuxver >=1.1
|
79
|
+
def lock
|
80
|
+
@server.check_for_version!("1.1")
|
81
|
+
|
82
|
+
@server.invoke_command "lock-client -t #@device"
|
83
|
+
end
|
84
|
+
|
85
|
+
# Suspends a client.
|
86
|
+
#
|
87
|
+
# @tmux suspend-client
|
88
|
+
# @return [void]
|
89
|
+
def suspend
|
90
|
+
@server.invoke_command "suspend-client -c #@device"
|
91
|
+
end
|
92
|
+
|
93
|
+
# Refreshs a client.
|
94
|
+
#
|
95
|
+
# @tmux refresh-client
|
96
|
+
# @return [void]
|
97
|
+
def refresh
|
98
|
+
@server.invoke_command "refresh-client -t #@device"
|
99
|
+
end
|
100
|
+
|
101
|
+
# @tmux show-messages
|
102
|
+
# @return [Array<String>] A log of messages
|
103
|
+
# @tmuxver >=1.2
|
104
|
+
attr_reader :messages
|
105
|
+
undef_method "messages"
|
106
|
+
def messages
|
107
|
+
@server.check_for_version!("1.2")
|
108
|
+
|
109
|
+
@server.invoke_command("show-messages -t #@device").split("\n")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Displays a visible indicator of each {Pane pane} shown by a client.
|
113
|
+
#
|
114
|
+
# @tmux display-panes
|
115
|
+
# @return [void]
|
116
|
+
# @tmuxver >=1.0
|
117
|
+
def display_panes
|
118
|
+
@server.check_for_version!("1.0")
|
119
|
+
|
120
|
+
@server.invoke_command("display-panes -t #@device")
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [Window] The currently displayed {Window window}.
|
124
|
+
# @tmuxver >=1.2
|
125
|
+
attr_reader :current_window
|
126
|
+
undef_method "current_window"
|
127
|
+
def current_window
|
128
|
+
@server.check_for_version!("1.2")
|
129
|
+
|
130
|
+
num = @server.invoke_command("display -p -t #@device '#I'").chomp
|
131
|
+
session.windows[num.to_i]
|
132
|
+
end
|
133
|
+
|
134
|
+
# @return [Pane] The currently displayed {Pane pane}.
|
135
|
+
# @tmuxver >=1.2
|
136
|
+
attr_reader :current_pane
|
137
|
+
undef_method "current_pane"
|
138
|
+
def current_pane
|
139
|
+
@server.check_for_version!("1.2")
|
140
|
+
|
141
|
+
output = @server.invoke_command "display-message -p -t #@device"
|
142
|
+
current_pane = output.match(/^.+?, current pane (\d+) . .+$/)[1]
|
143
|
+
current_window.panes[current_pane.to_i]
|
144
|
+
end
|
145
|
+
|
146
|
+
# Displays a message.
|
147
|
+
#
|
148
|
+
# @param [String] text The message to display
|
149
|
+
# @tmux display-message
|
150
|
+
# @return [void]
|
151
|
+
# @tmuxver >=1.0
|
152
|
+
def message(text)
|
153
|
+
@server.check_for_version!("1.0")
|
154
|
+
|
155
|
+
@server.invoke_command "display-message -t #@device \"#{text}\""
|
156
|
+
end
|
157
|
+
|
158
|
+
# Opens a prompt inside a client allowing a {Window window} index to be entered interactively.
|
159
|
+
#
|
160
|
+
# @tmux command-prompt + select-window
|
161
|
+
# @return [void]
|
162
|
+
def select_interactively
|
163
|
+
command_prompt "select-window -t:%%", ["index"]
|
164
|
+
end
|
165
|
+
|
166
|
+
# Opens a command prompt in the client. This may be used to
|
167
|
+
# execute commands interactively.
|
168
|
+
#
|
169
|
+
# @param [String] template The template is used as the command to
|
170
|
+
# execute. Before the command is executed, the first occurrence
|
171
|
+
# of the string '%%' and all occurrences of '%1' are replaced by
|
172
|
+
# the response to the first prompt, the second '%%' and all '%2'
|
173
|
+
# are replaced with the response to the second prompt, and so on
|
174
|
+
# for further prompts. Up to nine prompt responses may be
|
175
|
+
# replaced ('%1' to '%9')
|
176
|
+
#
|
177
|
+
# @param [Array<String>] prompts prompts is a list
|
178
|
+
# of prompts which are displayed in order; otherwise a single
|
179
|
+
# prompt is displayed, constructed from template
|
180
|
+
#
|
181
|
+
# @return [void]
|
182
|
+
# @tmux command-prompt
|
183
|
+
# @todo escape prompts and template
|
184
|
+
def command_prompt(template, prompts = [])
|
185
|
+
prompts = prompts.join(",")
|
186
|
+
flags = []
|
187
|
+
flags << "-p #{prompts}" unless prompts.empty?
|
188
|
+
flags << "-t #{identifier}"
|
189
|
+
flags << "\"#{template}\""
|
190
|
+
@server.invoke_command "command-prompt #{flags.join(" ")}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|