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/lib/tmux/server.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module Tmux
|
3
|
+
class Server
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
# Creates a new session
|
7
|
+
#
|
8
|
+
# @option args [Boolean] :attach (false) Attach to the new session?
|
9
|
+
# @option args [String] :name (nil) Name of the new session. Will
|
10
|
+
# be automatically generated of nil.
|
11
|
+
# @option args [String] :window_name (nil) Name of the initial
|
12
|
+
# window. Cannot be used when grouping sessions.
|
13
|
+
# @option args [Session] :group_with (nil) Group with this
|
14
|
+
# session, sharing all windows.
|
15
|
+
# @option args [String] :command (nil) Execute this command in the
|
16
|
+
# initial window. Cannot be used when grouping sessions.
|
17
|
+
#
|
18
|
+
# @return [Session, nil] Returns the new {Session session} if a
|
19
|
+
# `:name` has been given and if `:attach` is false
|
20
|
+
#
|
21
|
+
# @raise [ArgumentError] if combining `:group_with` and `:window_name`
|
22
|
+
# or :command
|
23
|
+
#
|
24
|
+
# @tmuxver >=1.4
|
25
|
+
def create_session(args = {})
|
26
|
+
check_for_version!("1.4")
|
27
|
+
|
28
|
+
if args[:group_with] && (args[:window_name] || args[:command])
|
29
|
+
raise ArgumentError, "Cannot combine :group_with and :window_name or :command"
|
30
|
+
end
|
31
|
+
|
32
|
+
# FIXME shell escape names
|
33
|
+
flags = []
|
34
|
+
flags << "-d" unless args[:attach]
|
35
|
+
flags << "-n '#{args[:window_name]}'" if args[:window_name]
|
36
|
+
flags << "-s '#{args[:name]}'" if args[:name]
|
37
|
+
flags << "-t '#{args[:group_with].name}'" if args[:group_with]
|
38
|
+
flags << args[:command] if args[:command]
|
39
|
+
|
40
|
+
command = "new-session #{flags.join(" ")}"
|
41
|
+
|
42
|
+
ret = invoke_command(command, true)
|
43
|
+
if ret.start_with?("duplicate session:")
|
44
|
+
raise RuntimeError, ret
|
45
|
+
elsif ret.start_with?("sessions should be nested with care.")
|
46
|
+
raise Exception::InTmux("new-session")
|
47
|
+
else
|
48
|
+
if args[:name] and !args[:attach]
|
49
|
+
return Session.new(self, args[:name])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String]
|
55
|
+
attr_reader :socket
|
56
|
+
# @return [OptionsList]
|
57
|
+
attr_reader :options
|
58
|
+
# @param [String] socket A socket *name*.
|
59
|
+
def initialize(socket = "default")
|
60
|
+
@socket = socket
|
61
|
+
@options = OptionsList.new(:server, self, false)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [-1, 0, 1]
|
65
|
+
def <=>(other)
|
66
|
+
return nil unless other.is_a?(Server)
|
67
|
+
@socket <=> other.socket
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Server] Returns self. This is useful for other classes
|
71
|
+
# which can operate on Server, {Session}, {Window}, {Pane} and so
|
72
|
+
# on
|
73
|
+
attr_reader :server
|
74
|
+
undef_method "server"
|
75
|
+
def server
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# Invokes a tmux command.
|
80
|
+
#
|
81
|
+
# @param [String] command The command to invoke
|
82
|
+
# @return [void]
|
83
|
+
def invoke_command(command, unset_tmux = false)
|
84
|
+
Tmux.invoke_command("-L #@socket #{command}", unset_tmux)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Kills a server and thus all {Session sessions}, {Window windows} and {Client clients}.
|
88
|
+
#
|
89
|
+
# @tmux kill-server
|
90
|
+
# @return [void]
|
91
|
+
def kill
|
92
|
+
invoke_command "kill-server"
|
93
|
+
end
|
94
|
+
|
95
|
+
# Sources a file, that is load and evaluate it in tmux.
|
96
|
+
#
|
97
|
+
# @param [String] file Name of the file to source
|
98
|
+
# @tmux source-file
|
99
|
+
# @return [void]
|
100
|
+
def source_file(file)
|
101
|
+
invoke_command "source-file #{file}"
|
102
|
+
end
|
103
|
+
alias_method :load, :source_file
|
104
|
+
|
105
|
+
# @tmux list-sessions
|
106
|
+
# @param [Hash] search Filters the resulting hash using {FilterableHash#filter}
|
107
|
+
# @return [Hash] A hash with information for all sessions
|
108
|
+
def sessions_information(search = {})
|
109
|
+
hash = {}
|
110
|
+
output = invoke_command "list-sessions"
|
111
|
+
output.each_line do |session|
|
112
|
+
params = session.match(/^(?<name>\w+?): (?<num_windows>\d+) windows \(created (?<creation_time>.+?)\) \[(?<width>\d+)x(?<height>\d+)\](?: \((?<attached>attached)\))?$/)
|
113
|
+
|
114
|
+
name = params[:name]
|
115
|
+
num_windows = params[:num_windows].to_i
|
116
|
+
creation_time = Date.parse(params[:creation_time])
|
117
|
+
width = params[:width].to_i
|
118
|
+
height = params[:height].to_i
|
119
|
+
attached = !!params[:attached]
|
120
|
+
|
121
|
+
hash[name] = {
|
122
|
+
:name => name,
|
123
|
+
:num_windows => num_windows,
|
124
|
+
:creation_time => creation_time,
|
125
|
+
:width => width,
|
126
|
+
:height => height,
|
127
|
+
:attached => attached,
|
128
|
+
}
|
129
|
+
end
|
130
|
+
hash.extend FilterableHash
|
131
|
+
hash.filter(search)
|
132
|
+
end
|
133
|
+
|
134
|
+
# @tmux list-sessions
|
135
|
+
# @return [Array<Session>] All {Session sessions}
|
136
|
+
attr_reader :sessions
|
137
|
+
undef_method "sessions"
|
138
|
+
def sessions(search = {})
|
139
|
+
sessions_information(search).map do |name, information|
|
140
|
+
Session.new(self, name)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# @return [Session] The first {Session session}. This is
|
145
|
+
# especially useful if working with a server that only has one
|
146
|
+
# {Session session}.
|
147
|
+
attr_reader :session
|
148
|
+
undef_method "session"
|
149
|
+
def session
|
150
|
+
sessions.first
|
151
|
+
end
|
152
|
+
|
153
|
+
# @tmux list-clients
|
154
|
+
# @param [Hash] search Filters the resulting hash using {FilterableHash#filter}
|
155
|
+
# @return [Hash] A hash with information for all clients
|
156
|
+
def clients_information(search = {})
|
157
|
+
clients = invoke_command "list-clients"
|
158
|
+
hash = {}
|
159
|
+
clients.each_line do |client|
|
160
|
+
params = client.match(/^(?<device>.+?): (?<session>\d+) \[(?<width>\d+)x(?<height>\d+) (?<term>.+?)\](?: \((?<utf8>utf8)\))?$/)
|
161
|
+
device = params[:device]
|
162
|
+
session = sessions[params[:session].to_i]
|
163
|
+
width = params[:width].to_i
|
164
|
+
height = params[:height].to_i
|
165
|
+
term = params[:term]
|
166
|
+
utf8 = !!params[:utf8]
|
167
|
+
|
168
|
+
hash[device] = {
|
169
|
+
:device => device,
|
170
|
+
:session => session,
|
171
|
+
:width => width,
|
172
|
+
:height => height,
|
173
|
+
:term => term,
|
174
|
+
:utf8 => utf8,
|
175
|
+
}
|
176
|
+
end
|
177
|
+
hash.extend FilterableHash
|
178
|
+
hash.filter(search)
|
179
|
+
end
|
180
|
+
|
181
|
+
# @tmux list-clients
|
182
|
+
# @return [Array<Client>]
|
183
|
+
attr_reader :clients
|
184
|
+
undef_method "clients"
|
185
|
+
def clients(search = {})
|
186
|
+
clients_information(search).map { |device, information|
|
187
|
+
Client.new(self, device)
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
# @tmux server-info
|
192
|
+
# @return [String] Information about the server
|
193
|
+
attr_reader :info
|
194
|
+
undef_method "info"
|
195
|
+
def info
|
196
|
+
invoke_command "server-info"
|
197
|
+
end
|
198
|
+
|
199
|
+
# @return [String] Version of the tmux server
|
200
|
+
attr_reader :version
|
201
|
+
undef_method "version"
|
202
|
+
def version
|
203
|
+
@version ||= info.lines.first.split(",").first[/([.\d]+)/]
|
204
|
+
end
|
205
|
+
|
206
|
+
# Checks if a version requirement is being met
|
207
|
+
#
|
208
|
+
# @param [String] required The version at least required
|
209
|
+
# @raise [Exception::UnsupportedVersion] Raised if a version requirement isn't met
|
210
|
+
# @return [void]
|
211
|
+
def check_for_version!(required)
|
212
|
+
if required > version
|
213
|
+
raise Exception::UnsupportedVersion, required
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/lib/tmux/session.rb
ADDED
@@ -0,0 +1,312 @@
|
|
1
|
+
module Tmux
|
2
|
+
# A session is a single collection of pseudo terminals under the
|
3
|
+
# management of {Tmux tmux}. Each session has one or more {Window
|
4
|
+
# windows} linked to it. A {Window window} occupies the entire
|
5
|
+
# screen and may be split into rectangular {Pane panes}, each of
|
6
|
+
# which is a separate pseudo terminal (the pty(4) manual page
|
7
|
+
# documents the technical details of pseudo terminals). Any number
|
8
|
+
# of tmux instances may connect to the same session, and any number
|
9
|
+
# of {Window windows} may be present in the same session. Once all
|
10
|
+
# sessions are {Session#kill killed}, tmux exits.
|
11
|
+
class Session
|
12
|
+
include Comparable
|
13
|
+
|
14
|
+
# @return [Options]
|
15
|
+
def self.options(session)
|
16
|
+
OptionsList.new(:session, session, true)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Creates a new {Window window}.
|
20
|
+
#
|
21
|
+
# @option args [Boolean] :after_number (false) If true, the new
|
22
|
+
# {Window window} will be inserted at the next index up from the
|
23
|
+
# specified number (or the {Client#current_window current}
|
24
|
+
# {Window window}), moving {Window windows} up if necessary
|
25
|
+
# @option args [Boolean] :kill_existing (false) Kill an existing
|
26
|
+
# {Window window} if it conflicts with a desired number
|
27
|
+
# @option args [Boolean] :make_active (true) Switch to the newly
|
28
|
+
# generated {Window window}
|
29
|
+
# @option args [String] :name Name of the new {Window window}
|
30
|
+
# (optional)
|
31
|
+
# @option args [Number] :number Number of the new {Window window}
|
32
|
+
# (optional)
|
33
|
+
# @option args [String] :command Command to run in the new {Window
|
34
|
+
# window} (optional)
|
35
|
+
#
|
36
|
+
# @tmux new-window
|
37
|
+
# @return [Window] The newly created {Window window}
|
38
|
+
def create_window(args = {})
|
39
|
+
args = {
|
40
|
+
:kill_existing => false,
|
41
|
+
:make_active => true,
|
42
|
+
:after_number => false,
|
43
|
+
}.merge(args)
|
44
|
+
|
45
|
+
flags = []
|
46
|
+
# flags << "-d" unless args[:make_active]
|
47
|
+
flags << "-a" if args[:after_number]
|
48
|
+
flags << "-k" if args[:kill_existing]
|
49
|
+
flags << "-n '#{args[:name]}'" if args[:name] # FIXME escaping
|
50
|
+
flags << "-t #{args[:number]}" if args[:number]
|
51
|
+
flags << args[:command] if args[:command]
|
52
|
+
|
53
|
+
@server.invoke_command "new-window #{flags.join(" ")}"
|
54
|
+
new_window = current_window
|
55
|
+
unless args[:make_active]
|
56
|
+
select_last_window
|
57
|
+
end
|
58
|
+
# return Window.new(self, num)
|
59
|
+
return new_window
|
60
|
+
end
|
61
|
+
|
62
|
+
# @see Client#current_window
|
63
|
+
# @return (see Client#current_window)
|
64
|
+
attr_reader :current_window
|
65
|
+
undef_method "current_window"
|
66
|
+
def current_window
|
67
|
+
any_client.current_window
|
68
|
+
end
|
69
|
+
|
70
|
+
# @see Client#current_pane
|
71
|
+
# @return (see Client#current_pane)
|
72
|
+
attr_reader :current_pane
|
73
|
+
undef_method "current_pane"
|
74
|
+
def current_pane
|
75
|
+
any_client.current_pane
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns a {Client client} that is displaying the session.
|
79
|
+
#
|
80
|
+
# @return [Client, nil] A {Client client} that is displaying the session.
|
81
|
+
def any_client
|
82
|
+
@server.clients({:session => self}).first
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Boolean]
|
86
|
+
def ==(other)
|
87
|
+
self.class == other.class && @server == other.server && @name == other.name
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [Number]
|
91
|
+
def hash
|
92
|
+
[@server.hash, @number].hash
|
93
|
+
end
|
94
|
+
|
95
|
+
# @return [Boolean]
|
96
|
+
def eql?(other)
|
97
|
+
self == other
|
98
|
+
end
|
99
|
+
|
100
|
+
def <=>(other)
|
101
|
+
return nil unless other.is_a?(Session)
|
102
|
+
[@server, @name] <=> [other.server, other.name]
|
103
|
+
end
|
104
|
+
|
105
|
+
# @overload name
|
106
|
+
# @return [String]
|
107
|
+
# @overload name=(new_name)
|
108
|
+
# Renames the session.
|
109
|
+
#
|
110
|
+
# @todo escape name
|
111
|
+
# @return [String]
|
112
|
+
# @tmux rename-session
|
113
|
+
# @return [String]
|
114
|
+
attr_accessor :name
|
115
|
+
undef_method "name="
|
116
|
+
# @return [Server]
|
117
|
+
attr_reader :server
|
118
|
+
# @return [OptionsList]
|
119
|
+
attr_reader :options
|
120
|
+
# @return [StatusBar]
|
121
|
+
attr_reader :status_bar
|
122
|
+
def initialize(server, name)
|
123
|
+
@server, @name = server, name
|
124
|
+
@status_bar = StatusBar.new(self)
|
125
|
+
@options = OptionsList.new(:session, self, false)
|
126
|
+
end
|
127
|
+
|
128
|
+
def name=(new_name)
|
129
|
+
raise ArgumentError if new_name.to_s.strip.empty?
|
130
|
+
ret = @server.invoke_command("rename-session -t #{identifier} '#{new_name}'")
|
131
|
+
|
132
|
+
if ret.start_with?("duplicate session:")
|
133
|
+
raise RuntimeError, ret
|
134
|
+
end
|
135
|
+
|
136
|
+
@name = new_name
|
137
|
+
end
|
138
|
+
|
139
|
+
# @return [String]
|
140
|
+
attr_reader :identifier
|
141
|
+
undef_method "identifier"
|
142
|
+
def identifier
|
143
|
+
@name
|
144
|
+
end
|
145
|
+
|
146
|
+
# Locks the session.
|
147
|
+
#
|
148
|
+
# @tmux lock-session
|
149
|
+
# @return [void]
|
150
|
+
# @tmuxver >=1.1
|
151
|
+
def lock
|
152
|
+
@server.check_for_version!("1.1")
|
153
|
+
|
154
|
+
@server.invoke_command "lock-session -t #{identifier}"
|
155
|
+
end
|
156
|
+
|
157
|
+
# @return [Integer]
|
158
|
+
attr_reader :num_windows
|
159
|
+
undef_method "num_windows"
|
160
|
+
def num_windows
|
161
|
+
@server.sessions_information[@name][:num_windows]
|
162
|
+
end
|
163
|
+
|
164
|
+
# @return [Time]
|
165
|
+
attr_reader :creation_time
|
166
|
+
undef_method "creation_time"
|
167
|
+
def creation_time
|
168
|
+
@server.sessions_information[@name][:creation_time]
|
169
|
+
end
|
170
|
+
alias_method :created_at, :creation_time
|
171
|
+
|
172
|
+
# @return [Integer]
|
173
|
+
attr_reader :width
|
174
|
+
undef_method "width"
|
175
|
+
def width
|
176
|
+
@server.sessions_information[@name][:width]
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [Integer]
|
180
|
+
attr_reader :height
|
181
|
+
undef_method "height"
|
182
|
+
def height
|
183
|
+
@server.sessions_information[@name][:height]
|
184
|
+
end
|
185
|
+
|
186
|
+
# @return [Boolean]
|
187
|
+
attr_reader :attached
|
188
|
+
undef_method "attached"
|
189
|
+
def attached
|
190
|
+
@server.sessions_information[@name][:attached]
|
191
|
+
end
|
192
|
+
alias_method :attached?, :attached
|
193
|
+
|
194
|
+
# @return [Array<Client>] All {Client clients}
|
195
|
+
attr_reader :clients
|
196
|
+
undef_method "clients"
|
197
|
+
def clients
|
198
|
+
@server.clients({:session => self})
|
199
|
+
end
|
200
|
+
|
201
|
+
# Attach to a session. Replaces the ruby process.
|
202
|
+
#
|
203
|
+
# @return [void]
|
204
|
+
# @tmux attach
|
205
|
+
def attach
|
206
|
+
exec "#{Tmux::BINARY} attach -t #{identifier}"
|
207
|
+
end
|
208
|
+
|
209
|
+
# Kills the session.
|
210
|
+
#
|
211
|
+
# @tmux kill-session
|
212
|
+
# @return [void]
|
213
|
+
def kill
|
214
|
+
@server.invoke_command "kill-session -t #{identifier}"
|
215
|
+
end
|
216
|
+
|
217
|
+
# @tmux list-windows
|
218
|
+
# @tmuxver >=1.1
|
219
|
+
# @param [Hash] search Filters the resulting hash using {FilterableHash#filter}
|
220
|
+
# @return [Hash] A hash with information for all windows
|
221
|
+
# @return [Hash]
|
222
|
+
def windows_information(search = {})
|
223
|
+
@server.check_for_version!("1.1")
|
224
|
+
|
225
|
+
hash = {}
|
226
|
+
output = @server.invoke_command "list-windows -t #{identifier}"
|
227
|
+
output.each_line do |session|
|
228
|
+
params = session.match(/^(?<num>\d+): (?<name>.+?) \[(?<width>\d+)x(?<height>\d+)\]$/)
|
229
|
+
next if params.nil? # >=1.3 displays layout information in indented lines
|
230
|
+
num = params[:num].to_i
|
231
|
+
name = params[:name]
|
232
|
+
width = params[:width].to_i
|
233
|
+
height = params[:height].to_i
|
234
|
+
|
235
|
+
hash[num] = {:num => num, :name => name, :width => width, :height => height}
|
236
|
+
end
|
237
|
+
hash.extend FilterableHash
|
238
|
+
hash.filter(search)
|
239
|
+
end
|
240
|
+
|
241
|
+
# @tmux list-windows
|
242
|
+
# @return [Hash{Number => Window}] All {Window windows}
|
243
|
+
# @tmuxver >=1.1
|
244
|
+
attr_reader :windows
|
245
|
+
undef_method "windows"
|
246
|
+
def windows
|
247
|
+
hash = {}
|
248
|
+
@server.check_for_version!("1.1")
|
249
|
+
|
250
|
+
windows_information.each do |num, information|
|
251
|
+
hash[num] = Window.new(self, num)
|
252
|
+
end
|
253
|
+
hash
|
254
|
+
end
|
255
|
+
|
256
|
+
# @param [Hash] search Filters the resulting hash using {FilterableHash#filter}
|
257
|
+
# @return [Hash] A hash with information for all buffers
|
258
|
+
# @tmux list-buffers
|
259
|
+
def buffers_information(search = {})
|
260
|
+
hash = {}
|
261
|
+
buffers = @server.invoke_command "list-buffers -t #{identifier}"
|
262
|
+
buffers.each_line do |buffer|
|
263
|
+
num, size = buffer.match(/^(\d+): (\d+) bytes/)[1..2]
|
264
|
+
hash[num] = {:size => size}
|
265
|
+
end
|
266
|
+
hash.extend FilterableHash
|
267
|
+
hash.filter(search)
|
268
|
+
end
|
269
|
+
|
270
|
+
# @tmux list-buffers
|
271
|
+
# @return [Array<Buffer>] All {Buffer buffers}
|
272
|
+
attr_reader :buffers
|
273
|
+
undef_method "buffers"
|
274
|
+
def buffers
|
275
|
+
buffers_information.map do |num, information|
|
276
|
+
Buffer.new(num, self)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# @group Selecting
|
281
|
+
|
282
|
+
# Select the last (previously selected) window.
|
283
|
+
#
|
284
|
+
# @return [Window]
|
285
|
+
def select_last_window
|
286
|
+
@server.invoke_command "last-window -t #{identifier}"
|
287
|
+
current_window
|
288
|
+
end
|
289
|
+
|
290
|
+
# Selects the next (higher index) window
|
291
|
+
#
|
292
|
+
# @param [Number] num How many windows to move
|
293
|
+
# @tmuxver >=1.3
|
294
|
+
# @return [Window]
|
295
|
+
def select_next_window(num = 1)
|
296
|
+
@server.invoke_command "select-window -t #{identifier}:+#{num}"
|
297
|
+
current_window
|
298
|
+
end
|
299
|
+
|
300
|
+
# Selects the previous (lower index) window
|
301
|
+
#
|
302
|
+
# @param [Number] num How many windows to move
|
303
|
+
# @tmuxver >=1.3
|
304
|
+
# @return [Window]
|
305
|
+
def select_previous_window(num = 1)
|
306
|
+
@server.invoke_command "select-window -t:-#{num}"
|
307
|
+
current_window
|
308
|
+
end
|
309
|
+
|
310
|
+
# @endgroup
|
311
|
+
end
|
312
|
+
end
|