tmux-ruby 0.0.2
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/.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
@@ -0,0 +1,26 @@
|
|
1
|
+
require "tmux/options/option"
|
2
|
+
module Tmux
|
3
|
+
module Options
|
4
|
+
# @api private
|
5
|
+
# @see Option
|
6
|
+
class WordArrayOption < Option
|
7
|
+
class << self
|
8
|
+
# @param (see Option.from_tmux)
|
9
|
+
# @return [Array<String>, Symbol]
|
10
|
+
# @api private
|
11
|
+
# @see Option.from_tmux
|
12
|
+
def from_tmux(value)
|
13
|
+
super || StringOption.from_tmux(value).split(" ")
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param (see Option.to_tmux)
|
17
|
+
# @return (see Option.to_tmux)
|
18
|
+
# @see Option.to_tmux
|
19
|
+
# @api private
|
20
|
+
def to_tmux(value)
|
21
|
+
super || value.join(" ")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module Tmux
|
2
|
+
# OptionsList offers an easy way of querying and setting tmux
|
3
|
+
# options, taking care of typecasting. Note: You should not have to
|
4
|
+
# instantiate this class but use the respective `::options` and
|
5
|
+
# `#options` methods instead.
|
6
|
+
#
|
7
|
+
# @see Server#options
|
8
|
+
# @see Session.options
|
9
|
+
# @see Session#options
|
10
|
+
# @see Window.options
|
11
|
+
# @see Window#options
|
12
|
+
class OptionsList
|
13
|
+
include Enumerable
|
14
|
+
# @param [Symbol<:server, :session, :window>] kind Which options to operate on
|
15
|
+
# @param [Server, Session, Window] target The target to operate
|
16
|
+
# on. Should be an instance of {Server} for global options
|
17
|
+
# @param [Boolean] global Operate on global options?
|
18
|
+
def initialize(kind, target, global = false)
|
19
|
+
@kind = kind
|
20
|
+
@global = global
|
21
|
+
@target = target
|
22
|
+
end
|
23
|
+
|
24
|
+
# Calls block once for each option.
|
25
|
+
#
|
26
|
+
# @yield [option, value]
|
27
|
+
# @yieldparam [String] option Name of the option
|
28
|
+
# @yieldparam [Object] value Value of the option
|
29
|
+
# @return [OptionsList] self
|
30
|
+
def each
|
31
|
+
get_matching(//).each do |key, value|
|
32
|
+
yield [key, value]
|
33
|
+
end
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [Regexp] The regexp which all returned option names have
|
38
|
+
# to match
|
39
|
+
# @param [Boolean, nil] global Operate on global options? Inherits from @global if nil
|
40
|
+
# @return [Hash<String, Object>] Returns a hash of all options
|
41
|
+
# that match `regexp`, and their values.
|
42
|
+
# @api private
|
43
|
+
def get_matching(regexp, global = nil)
|
44
|
+
option_lines = server.invoke_command("show-options #{argument_string(global)}").each_line.select { |line|
|
45
|
+
line =~ /^#{regexp}/
|
46
|
+
}
|
47
|
+
|
48
|
+
values = {}
|
49
|
+
option_lines.each do |option_line|
|
50
|
+
option, value = option_line.chomp.split(" ", 2)
|
51
|
+
mapping = Options::Mapping[option]
|
52
|
+
value = mapping ? mapping.from_tmux(value) : value
|
53
|
+
values[option] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
values
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the value of an option. If the OptionsList does not
|
60
|
+
# operate on global options, but the requested option could not be
|
61
|
+
# found locally, it will be searched for globally, obeying option
|
62
|
+
# inheritance of Tmux.
|
63
|
+
#
|
64
|
+
# @param [String] option Name of the option
|
65
|
+
# @return [Object]
|
66
|
+
def get(option)
|
67
|
+
value = get_matching(option).values.first
|
68
|
+
if value.nil? && !@global
|
69
|
+
return get_matching(option, true).values.first
|
70
|
+
else
|
71
|
+
value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Sets an option.
|
76
|
+
#
|
77
|
+
# @param [String] option Name of the option
|
78
|
+
# @param [Object] value New value of the option. Will
|
79
|
+
# automatically be converted to a string valid to Tmux.
|
80
|
+
# @return [Object] `value`
|
81
|
+
# @raise [RuntimeError] Raised if the new value is invalid
|
82
|
+
def set(option, value)
|
83
|
+
mapping = Options::Mapping[option]
|
84
|
+
value = mapping.to_tmux(value) if mapping
|
85
|
+
ret = server.invoke_command "set-option #{argument_string} #{option} \"#{value}\""
|
86
|
+
if ret =~ /^value is invalid:/
|
87
|
+
raise RuntimeError, ret
|
88
|
+
end
|
89
|
+
value
|
90
|
+
end
|
91
|
+
|
92
|
+
# Unsets an option. Note: global options cannot be unset.
|
93
|
+
#
|
94
|
+
# @param [String] option Name of the option
|
95
|
+
# @raise [RuntimeError] Raised if you try to unset a global option.
|
96
|
+
# @return [void]
|
97
|
+
def unset(option)
|
98
|
+
raise RuntimeError, "Cannot unset global option" if @global
|
99
|
+
server.invoke_command "set-option #{argument_string(nil, ["-u"])} #{option}"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Unknown methods will be treated as {#get getters} and {#set
|
103
|
+
# setters} for options. Dashes in option names have to be replaced
|
104
|
+
# with underscores.
|
105
|
+
#
|
106
|
+
# @return [void]
|
107
|
+
def method_missing(m, *args)
|
108
|
+
option = m.to_s.tr("_", "-")
|
109
|
+
if option[-1..-1] == "="
|
110
|
+
option = option[0..-2]
|
111
|
+
set(option, args.first)
|
112
|
+
else
|
113
|
+
get(option)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [String, nil]
|
118
|
+
# @api private
|
119
|
+
def kind_flag
|
120
|
+
{
|
121
|
+
:server => "-s",
|
122
|
+
:session => nil,
|
123
|
+
:window => "-w",
|
124
|
+
}[@kind]
|
125
|
+
end
|
126
|
+
private :kind_flag
|
127
|
+
|
128
|
+
# @param [Boolean, nil] global Operate on global options? Inherits from @global if nil
|
129
|
+
# @param [Array<String>] inject Flags to inject into the argument string
|
130
|
+
# @return [String]
|
131
|
+
# @api private
|
132
|
+
def argument_string(global = nil, inject = [])
|
133
|
+
global = @global if global.nil?
|
134
|
+
flags = []
|
135
|
+
flags << "-g" if global
|
136
|
+
flags << kind_flag
|
137
|
+
flags.concat inject
|
138
|
+
flags << "-t #{@target.identifier}" if !global && @target && !@target.is_a?(Server)
|
139
|
+
|
140
|
+
flags.compact.join(" ")
|
141
|
+
end
|
142
|
+
private :argument_string
|
143
|
+
|
144
|
+
# @return [Server]
|
145
|
+
def server
|
146
|
+
@target.server
|
147
|
+
end
|
148
|
+
private :server
|
149
|
+
end
|
150
|
+
end
|
data/lib/tmux/pane.rb
ADDED
@@ -0,0 +1,496 @@
|
|
1
|
+
module Tmux
|
2
|
+
# A {Window window} occupies the entire
|
3
|
+
# screen and may be split into rectangular {Pane panes}, each of
|
4
|
+
# which is a separate pseudo terminal (the pty(4) manual page
|
5
|
+
# documents the technical details of pseudo terminals).
|
6
|
+
class Pane
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
# @return [Window]
|
10
|
+
attr_reader :window
|
11
|
+
# @return [Number]
|
12
|
+
attr_reader :number
|
13
|
+
def initialize(window, number)
|
14
|
+
@window, @number = window, number
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def ==(other)
|
19
|
+
self.class == other.class && @window == other.window && @number = other.number
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Number]
|
23
|
+
def hash
|
24
|
+
[@window.hash, @number].hash
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Boolean]
|
28
|
+
def eql?(other)
|
29
|
+
self == other
|
30
|
+
end
|
31
|
+
|
32
|
+
def <=>(other)
|
33
|
+
return nil unless other.is_a?(Pane)
|
34
|
+
[@window, @number] <=> [other.window, other.number]
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Server]
|
38
|
+
attr_reader :server
|
39
|
+
undef_method "server"
|
40
|
+
def server
|
41
|
+
@window.server
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
attr_reader :identifier
|
46
|
+
undef_method "identifier"
|
47
|
+
def identifier
|
48
|
+
@window.identifier + "." + @number.to_s
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [Integer]
|
52
|
+
# @tmuxver >=1.1
|
53
|
+
attr_reader :width
|
54
|
+
undef_method "width"
|
55
|
+
def width
|
56
|
+
server.check_for_version!("1.1")
|
57
|
+
|
58
|
+
@window.panes_information[@number][:width]
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Integer]
|
62
|
+
# @tmuxver >=1.1
|
63
|
+
attr_reader :height
|
64
|
+
undef_method "height"
|
65
|
+
def height
|
66
|
+
server.check_for_version!("1.1")
|
67
|
+
|
68
|
+
@window.panes_information[@number][:height]
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Integer]
|
72
|
+
# @tmuxver >=1.1
|
73
|
+
attr_reader :max_history_size
|
74
|
+
undef_method "max_history_size"
|
75
|
+
def max_history_size
|
76
|
+
server.check_for_version!("1.1")
|
77
|
+
|
78
|
+
@window.panes_information[@number][:max_history]
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Integer]
|
82
|
+
# @tmuxver >=1.1
|
83
|
+
attr_reader :current_history_size
|
84
|
+
undef_method "current_history_size"
|
85
|
+
def current_history_size
|
86
|
+
server.check_for_version!("1.1")
|
87
|
+
|
88
|
+
@window.panes_information[@number][:cur_history]
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Filesize]
|
92
|
+
# @tmuxver >=1.1
|
93
|
+
attr_reader :memory_usage
|
94
|
+
undef_method "memory_usage"
|
95
|
+
def memory_usage
|
96
|
+
server.check_for_version!("1.1")
|
97
|
+
|
98
|
+
@window.panes_information[@number][:memory]
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Boolean] True if the pane is the currently selected one
|
102
|
+
# in its window.
|
103
|
+
# @tmuxver >=1.4
|
104
|
+
attr_reader :active
|
105
|
+
undef_method "active"
|
106
|
+
def active
|
107
|
+
server.check_for_version!("1.4")
|
108
|
+
|
109
|
+
@window.panes_information[@number][:active]
|
110
|
+
end
|
111
|
+
alias_method :active?, :active
|
112
|
+
|
113
|
+
# @group Modes
|
114
|
+
|
115
|
+
# Enter copy mode.
|
116
|
+
#
|
117
|
+
# @return [void]
|
118
|
+
# @tmuxver >=1.0
|
119
|
+
# @tmux copy-mode
|
120
|
+
def copy_mode
|
121
|
+
server.check_for_version!("1.0")
|
122
|
+
|
123
|
+
server.invoke_command "copy-mode -t #{identifier}"
|
124
|
+
end
|
125
|
+
|
126
|
+
# Displays a clock in the pane.
|
127
|
+
#
|
128
|
+
# @return [void]
|
129
|
+
# @tmuxver >=1.0
|
130
|
+
# @tmux clock-mode
|
131
|
+
def clock_mode
|
132
|
+
server.check_for_version!("1.0")
|
133
|
+
|
134
|
+
server.invoke_command "clock-mode -t #{identifier}"
|
135
|
+
end
|
136
|
+
alias_method :show_clock, :clock_mode
|
137
|
+
|
138
|
+
# @endgroup
|
139
|
+
|
140
|
+
# Breaks the pane off from its containing {Window window} to make
|
141
|
+
# it the only pane in a new {Window window}.
|
142
|
+
#
|
143
|
+
# @param [Boolean] select If true, the new {Window window} will be
|
144
|
+
# selected automatically
|
145
|
+
# @return [Pane]
|
146
|
+
# @tmuxver >=1.0
|
147
|
+
# @tmux break-pane
|
148
|
+
def break(select = true)
|
149
|
+
server.check_for_version!("1.0")
|
150
|
+
|
151
|
+
server.invoke_command "break-pane -t #{identifier}"
|
152
|
+
num_window, num_pane = server.invoke_command("display -p -t #{@window.session.any_client.identifier} '#I:#P'").chomp.split(":")
|
153
|
+
session = @window.session
|
154
|
+
window = Window.new(session, num_window)
|
155
|
+
pane = Pane.new(window, num_pane)
|
156
|
+
unless select
|
157
|
+
session.select_last_window
|
158
|
+
end
|
159
|
+
return pane
|
160
|
+
end
|
161
|
+
|
162
|
+
# @group Killing
|
163
|
+
|
164
|
+
# Kills the pane.
|
165
|
+
#
|
166
|
+
# @tmux kill-pane
|
167
|
+
# @return [void]
|
168
|
+
# @tmuxver >=1.0
|
169
|
+
def kill
|
170
|
+
server.check_for_version!("1.0")
|
171
|
+
|
172
|
+
server.invoke_command "kill-pane -t #{identifier}"
|
173
|
+
end
|
174
|
+
|
175
|
+
# Kills all other panes.
|
176
|
+
#
|
177
|
+
# @tmux kill-pane -a
|
178
|
+
# @return [void]
|
179
|
+
# @tmuxver >=1.1
|
180
|
+
def kill_others
|
181
|
+
server.check_for_version!("1.1")
|
182
|
+
|
183
|
+
server.invoke_command "kill-pane -a -t #{identifier}"
|
184
|
+
end
|
185
|
+
|
186
|
+
# @endgroup
|
187
|
+
|
188
|
+
# Removes and frees the history of the pane.
|
189
|
+
#
|
190
|
+
# @tmux clear-history
|
191
|
+
# @return [void]
|
192
|
+
# @tmuxver >=1.0
|
193
|
+
def clear_history
|
194
|
+
server.check_for_version!("1.0")
|
195
|
+
|
196
|
+
server.invoke_command "clear-history -t #{identifier}"
|
197
|
+
end
|
198
|
+
|
199
|
+
# Swaps the pane with another one.
|
200
|
+
#
|
201
|
+
# @param [Pane] pane The pane to swap with.
|
202
|
+
# @return [void]
|
203
|
+
# @tmuxver >=1.0
|
204
|
+
def swap_with(pane)
|
205
|
+
server.check_for_version!("1.0")
|
206
|
+
|
207
|
+
server.invoke_command "swap-pane -s #{identifier} -t #{pane.identifier}"
|
208
|
+
end
|
209
|
+
|
210
|
+
# @group Input
|
211
|
+
|
212
|
+
# Sends a key to the pane.
|
213
|
+
#
|
214
|
+
# @param [String] key
|
215
|
+
# @see #send_keys
|
216
|
+
# @return [void]
|
217
|
+
# @tmuxver >=1.0
|
218
|
+
def send_key(key)
|
219
|
+
server.check_for_version!("1.0")
|
220
|
+
|
221
|
+
send_keys([key])
|
222
|
+
end
|
223
|
+
|
224
|
+
# Sends keys to the pane.
|
225
|
+
#
|
226
|
+
# @param [Array<String>] keys
|
227
|
+
# @return [void]
|
228
|
+
# @tmuxver >=1.0
|
229
|
+
def send_keys(keys)
|
230
|
+
server.check_for_version!("1.0")
|
231
|
+
|
232
|
+
keychain = []
|
233
|
+
keys.each do |key|
|
234
|
+
case key
|
235
|
+
when '"'
|
236
|
+
keychain << '"\\' + key + '"'
|
237
|
+
else
|
238
|
+
keychain << '"' + key + '"'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
server.invoke_command "send-keys -t #{identifier} #{keychain.join(" ")}"
|
242
|
+
end
|
243
|
+
|
244
|
+
# Runs a command in the pane. Note: this is experimental, hacky
|
245
|
+
# and might and will break.
|
246
|
+
#
|
247
|
+
# @param [String] command
|
248
|
+
# @return [void]
|
249
|
+
# @tmuxver >=1.0
|
250
|
+
def run(command)
|
251
|
+
server.check_for_version!("1.0")
|
252
|
+
|
253
|
+
write(command)
|
254
|
+
send_key "Enter"
|
255
|
+
end
|
256
|
+
|
257
|
+
# Writes text to the pane. This is basically the same as {Pane#run},
|
258
|
+
# but without sending a final Return.
|
259
|
+
#
|
260
|
+
# @param [String] text
|
261
|
+
# @tmuxver >=1.0
|
262
|
+
# @return [void]
|
263
|
+
# @see Pane#run
|
264
|
+
def write(text)
|
265
|
+
server.check_for_version!("1.0")
|
266
|
+
|
267
|
+
send_keys(text.split(""))
|
268
|
+
end
|
269
|
+
|
270
|
+
# Pastes a {Buffer buffer} into the pane.
|
271
|
+
#
|
272
|
+
# @param [Buffer] buffer The {Buffer buffer} to paste
|
273
|
+
# @param pop (see Buffer#paste)
|
274
|
+
# @param translate (see Buffer#paste)
|
275
|
+
# @param separator (see Buffer#paste)
|
276
|
+
# @return [void]
|
277
|
+
# @tmux paste-buffer
|
278
|
+
# @see Buffer#paste
|
279
|
+
# @see Window#paste
|
280
|
+
# @tmuxver >=1.3
|
281
|
+
def paste(buffer, pop = false, translate = true, separator = nil)
|
282
|
+
server.check_for_version!("1.3")
|
283
|
+
|
284
|
+
buffer.paste(self, pop, translate, separator)
|
285
|
+
end
|
286
|
+
|
287
|
+
# @endgroup
|
288
|
+
|
289
|
+
# Split the pane and move an existing pane into the new area.
|
290
|
+
#
|
291
|
+
# @param [Pane] pane The {Pane pane} to join
|
292
|
+
#
|
293
|
+
# @option args [Boolean] :make_active (true) Switch to the newly generated pane
|
294
|
+
# @option args [Symbol<:vertical, :horizontal>] :direction (:vertical) The direction to split in
|
295
|
+
# @option args [Number] :size Size of the new pane in lines (for vertical split) or in cells (for horizontal split)
|
296
|
+
# @option args [Number] :percentage Size of the new pane in percent.
|
297
|
+
def join(pane, args = {})
|
298
|
+
server.check_for_version!("1.2")
|
299
|
+
args = {
|
300
|
+
:make_active => true,
|
301
|
+
:direction => :vertical,
|
302
|
+
}.merge(args)
|
303
|
+
flags = split_or_join_flags(args)
|
304
|
+
flags << "-s #{pane.identifier}"
|
305
|
+
flags << "-t #{identifier}"
|
306
|
+
|
307
|
+
server.invoke_command "join-pane #{flags.join(" ")} "
|
308
|
+
if args[:make_active]
|
309
|
+
num = server.invoke_command("display -p -t #{@window.session.any_client.identifier} '#P'").chomp
|
310
|
+
return Pane.new(@window, num)
|
311
|
+
else
|
312
|
+
return nil
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
# join-pane [-dhv] [-l size | -p percentage] [-s src-pane] [-t dst-pane]
|
317
|
+
# split-window [-dhv] [-l size | -p percentage] [-t target-pane] [shell-command]
|
318
|
+
|
319
|
+
def split_or_join_flags(args)
|
320
|
+
flags = []
|
321
|
+
flags << "-d" unless args[:make_active]
|
322
|
+
flags << case args[:direction]
|
323
|
+
when :vertical
|
324
|
+
"-v"
|
325
|
+
when :horizontal
|
326
|
+
"-h"
|
327
|
+
else
|
328
|
+
raise ArgumentError
|
329
|
+
end
|
330
|
+
|
331
|
+
raise ArgumentError if args[:size] && args[:percentage]
|
332
|
+
if args[:size]
|
333
|
+
flags << "-l #{args[:size]}"
|
334
|
+
elsif args[:percentage]
|
335
|
+
flags << "-p #{args[:percentage]}"
|
336
|
+
end
|
337
|
+
|
338
|
+
return flags
|
339
|
+
end
|
340
|
+
private :split_or_join_flags
|
341
|
+
|
342
|
+
# Splits the pane.
|
343
|
+
#
|
344
|
+
# @return [Pane, nil] Returns the newly created pane, but only if
|
345
|
+
# :make_active is true or if using tmux >=1.4. See
|
346
|
+
# http://sourceforge.net/tracker/?func=detail&aid=3030471&group_id=200378&atid=973265
|
347
|
+
# for more information.
|
348
|
+
#
|
349
|
+
# @option args [Boolean] :make_active (true) Switch to the newly generated pane
|
350
|
+
# @option args [Symbol<:vertical, :horizontal>] :direction (:vertical) The direction to split in
|
351
|
+
# @option args [Number] :size Size of the new pane in lines (for vertical split) or in cells (for horizontal split)
|
352
|
+
# @option args [Number] :percentage Size of the new pane in percent.
|
353
|
+
# @option args [String] :command Command to run in the new pane (optional)
|
354
|
+
#
|
355
|
+
# @tmux split-window
|
356
|
+
# @tmuxver >=1.2
|
357
|
+
def split(args = {})
|
358
|
+
server.check_for_version!("1.2")
|
359
|
+
args = {
|
360
|
+
:make_active => true,
|
361
|
+
:direction => :vertical,
|
362
|
+
}.merge(args)
|
363
|
+
|
364
|
+
# Since tmux 1.4 we have the last-pane command, which allows us
|
365
|
+
# to temporarily select the new pane, get its identifer and
|
366
|
+
# select the last pane again.
|
367
|
+
temporarily_make_active = false
|
368
|
+
if server.version >= "1.4" && !args[:make_active]
|
369
|
+
args[:make_active] = true
|
370
|
+
temporarily_make_active = true
|
371
|
+
end
|
372
|
+
|
373
|
+
flags = split_or_join_flags(args)
|
374
|
+
|
375
|
+
flags << "-t #{identifier}"
|
376
|
+
flags << '"' + args[:command] + '"' if args[:command] # TODO escape
|
377
|
+
|
378
|
+
server.invoke_command "split-window #{flags.join(" ")} "
|
379
|
+
if args[:make_active]
|
380
|
+
num = server.invoke_command("display -p -t #{@window.session.any_client.identifier} '#P'").chomp
|
381
|
+
|
382
|
+
if temporarily_make_active
|
383
|
+
@window.select_last_pane(:never)
|
384
|
+
end
|
385
|
+
|
386
|
+
return Pane.new(@window, num)
|
387
|
+
else
|
388
|
+
return nil
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
# Resizes the pane.
|
393
|
+
#
|
394
|
+
# @param [Symbol<:up, :down, :left, :right>] direction Direction
|
395
|
+
# in which to resize
|
396
|
+
# @param [Number] adjustment How many lines or cells to resize.
|
397
|
+
# @return [void]
|
398
|
+
def resize(direction, adjustment = 1)
|
399
|
+
raise ArgumentError unless [:up, :down, :left, :right].include?(direction)
|
400
|
+
direction = direction.to_s.upcase[0..0]
|
401
|
+
server.invoke_command "resize-pane -#{direction} -t #{identifier} #{adjustment}"
|
402
|
+
end
|
403
|
+
|
404
|
+
# @group Selecting
|
405
|
+
|
406
|
+
# @param [Symbol<:up, :down, :left, :right>] direction direction to move to
|
407
|
+
# @param [Symbol<:never, :if_same_window, :always>] return_new whether to return the pane we moved
|
408
|
+
# to.
|
409
|
+
#
|
410
|
+
# Note: In tmux versions prior to 1.4, :always can lead to flickering
|
411
|
+
# Note: Since tmux version 1.4, :always is forced
|
412
|
+
# @tmuxver >=1.3
|
413
|
+
# @return [Pane, nil]
|
414
|
+
def select_direction(direction, return_new = :if_same_window)
|
415
|
+
raise ArgumentError unless [:up, :down, :left, :right].include?(direction)
|
416
|
+
direction = direction.to_s.upcase[0..0]
|
417
|
+
server.invoke_command "select-pane -#{direction} -t #{identifier}"
|
418
|
+
|
419
|
+
return @window.current_pane(return_new)
|
420
|
+
end
|
421
|
+
|
422
|
+
# @tmuxver (see Tmux::Pane#select_direction)
|
423
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
424
|
+
# @return (see Tmux::Pane#select_direction)
|
425
|
+
# @see Pane#select_direction
|
426
|
+
def select_up(return_new = :if_same_window)
|
427
|
+
select_direction(:up, return_new)
|
428
|
+
end
|
429
|
+
|
430
|
+
# @tmuxver (see Tmux::Pane#select_direction)
|
431
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
432
|
+
# @return (see Tmux::Pane#select_direction)
|
433
|
+
# @see Pane#select_direction
|
434
|
+
def select_down(return_new = :if_same_window)
|
435
|
+
select_direction(:down, return_new)
|
436
|
+
end
|
437
|
+
|
438
|
+
# @tmuxver (see Tmux::Pane#select_direction)
|
439
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
440
|
+
# @return (see Tmux::Pane#select_direction)
|
441
|
+
# @see Pane#select_direction
|
442
|
+
def select_left(return_new = :if_same_window)
|
443
|
+
select_direction(:left, return_new)
|
444
|
+
end
|
445
|
+
|
446
|
+
# @tmuxver (see Tmux::Pane#select_direction)
|
447
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
448
|
+
# @return (see Tmux::Pane#select_direction)
|
449
|
+
# @see Pane#select_direction
|
450
|
+
def select_right(return_new = :if_same_window)
|
451
|
+
select_direction(:right, return_new)
|
452
|
+
end
|
453
|
+
|
454
|
+
# @return [Pane, nil]
|
455
|
+
# @param [Number] num how many panes to move down. Note: will be ignored on tmux versions <1.3
|
456
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
457
|
+
# @tmuxver >=1.3 for `num` parameter
|
458
|
+
# @tmux down-pane or select-pane -t:+
|
459
|
+
def select_next(num = 1, return_new = :if_same_window)
|
460
|
+
if server.version > "1.2"
|
461
|
+
server.invoke_command "select-pane -t #{@window.identifier}.+#{num}"
|
462
|
+
else
|
463
|
+
server.invoke_command "down-pane -t #{identifier}"
|
464
|
+
end
|
465
|
+
|
466
|
+
return @window.current_pane(return_new)
|
467
|
+
end
|
468
|
+
|
469
|
+
# @return [Pane, nil]
|
470
|
+
# @param [Number] num how many panes to move up. Note: will be ignored on tmux versions <1.3
|
471
|
+
# @param return_new (see Tmux::Pane#select_direction)
|
472
|
+
# @tmuxver >=1.3 for `num` parameter
|
473
|
+
# @tmux up-pane or select-pane -t:-
|
474
|
+
def select_previous(num = 1, return_new = :if_same_window)
|
475
|
+
if server.version > "1.2"
|
476
|
+
server.invoke_command "select-pane -t #{@window.identifier}.-#{num}"
|
477
|
+
else
|
478
|
+
server.invoke_command "up-pane -t #{identifier}"
|
479
|
+
end
|
480
|
+
|
481
|
+
return @window.current_pane(return_new)
|
482
|
+
end
|
483
|
+
|
484
|
+
# Selects the pane.
|
485
|
+
#
|
486
|
+
# @return [void]
|
487
|
+
# @tmuxver >=1.0
|
488
|
+
def select
|
489
|
+
server.check_for_version!("1.0")
|
490
|
+
|
491
|
+
server.invoke_command "select-pane -t #{identifier}"
|
492
|
+
end
|
493
|
+
|
494
|
+
# @endgroup
|
495
|
+
end
|
496
|
+
end
|