Class: Hiiro::Tmux

Inherits:
Object
  • Object
show all
Defined in:
lib/hiiro/tmux.rb,
lib/hiiro/tmux/pane.rb,
lib/hiiro/tmux/panes.rb,
lib/hiiro/tmux/buffer.rb,
lib/hiiro/tmux/window.rb,
lib/hiiro/tmux/buffers.rb,
lib/hiiro/tmux/session.rb,
lib/hiiro/tmux/windows.rb,
lib/hiiro/tmux/sessions.rb

Defined Under Namespace

Classes: Buffer, Buffers, Pane, Panes, Session, Sessions, Window, Windows

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hiiro = nil, executor: Hiiro::Effects::Executor.new) ⇒ Tmux

Returns a new instance of Tmux.



58
59
60
61
# File 'lib/hiiro/tmux.rb', line 58

def initialize(hiiro = nil, executor: Hiiro::Effects::Executor.new)
  @hiiro = hiiro
  @executor = executor
end

Instance Attribute Details

#hiiroObject (readonly)

Returns the value of attribute hiiro.



56
57
58
# File 'lib/hiiro/tmux.rb', line 56

def hiiro
  @hiiro
end

Class Method Details

.add_resolvers(hiiro) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/hiiro/tmux.rb', line 30

def self.add_resolvers(hiiro)
  hiiro.add_resolver(:pane,
    -> { hiiro.fuzzyfind_from_map(hiiro.tmux_client.panes(all: true).name_map) }
  ) { |ref| ref }

  hiiro.add_resolver(:window,
    -> { hiiro.fuzzyfind_from_map(hiiro.tmux_client.windows(all: true).name_map) }
  ) { |ref| ref }

  hiiro.add_resolver(:session,
    -> { hiiro.fuzzyfind_from_map(hiiro.tmux_client.sessions.name_map) }
  ) { |ref| ref }

  hiiro.add_resolver(:buffer,
    -> {
      buffers = hiiro.tmux_client.buffers
      return nil if buffers.empty?
      hiiro.fuzzyfind_from_map(buffers.name_map)
    }
  ) { |ref|
    buffers = hiiro.tmux_client.buffers
    matching = buffers.matching(ref)
    matching.size == 1 ? matching.first.name : ref
  }
end

.client(hiiro = nil) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/hiiro/tmux.rb', line 16

def self.client(hiiro = nil)
  return @client if @client && @client.hiiro == hiiro

  if hiiro
    client!(hiiro)
  else
    new
  end
end

.client!(hiiro = nil) ⇒ Object



12
13
14
# File 'lib/hiiro/tmux.rb', line 12

def self.client!(hiiro = nil)
  @client = new(hiiro)
end

.open_session(name, **opts) ⇒ Object



26
27
28
# File 'lib/hiiro/tmux.rb', line 26

def self.open_session(name, **opts)
  client.open_session(name, **opts)
end

Instance Method Details

#attach_session(name) ⇒ Object



157
158
159
160
# File 'lib/hiiro/tmux.rb', line 157

def attach_session(name)
  resolved = find_session(name)&.name || name.to_s.tr('.', '_')
  run_system('attach-session', '-t', "=#{resolved}")
end

#break_pane(src: nil, dst: nil) ⇒ Object



277
278
279
280
281
282
# File 'lib/hiiro/tmux.rb', line 277

def break_pane(src: nil, dst: nil)
  args = ['break-pane']
  args += ['-s', src] if src
  args += ['-t', dst] if dst
  run_system(*args)
end

#buffersObject



103
104
105
# File 'lib/hiiro/tmux.rb', line 103

def buffers
  Buffers.fetch
end

#capture_pane(target: nil, buffer: nil, print: true) ⇒ Object



299
300
301
302
303
304
305
306
307
308
309
# File 'lib/hiiro/tmux.rb', line 299

def capture_pane(target: nil, buffer: nil, print: true)
  args = ['capture-pane']
  args += ['-t', target] if target
  args += ['-b', buffer] if buffer
  args << '-p' if print
  if print
    run_safe(*args)
  else
    run_system(*args)
  end
end

#choose_bufferObject



349
350
351
# File 'lib/hiiro/tmux.rb', line 349

def choose_buffer
  run_system('choose-buffer')
end

#current_paneObject



85
86
87
# File 'lib/hiiro/tmux.rb', line 85

def current_pane
  Pane.current
end

#current_sessionObject



77
78
79
# File 'lib/hiiro/tmux.rb', line 77

def current_session
  Session.current
end

#current_windowObject



81
82
83
# File 'lib/hiiro/tmux.rb', line 81

def current_window
  Window.current
end

#delete_buffer(name) ⇒ Object



341
342
343
# File 'lib/hiiro/tmux.rb', line 341

def delete_buffer(name)
  run_system('delete-buffer', '-b', name)
end

#detach_client(session: nil) ⇒ Object



167
168
169
170
171
172
173
174
# File 'lib/hiiro/tmux.rb', line 167

def detach_client(session: nil)
  args = ['detach-client']
  if session
    resolved = find_session(session)&.name || session.to_s.tr('.', '_')
    args += ['-s', resolved]
  end
  run_system(*args)
end

#display_info(format_string, target: nil) ⇒ Object



362
363
364
365
366
367
# File 'lib/hiiro/tmux.rb', line 362

def display_info(format_string, target: nil)
  args = ['display-message', '-p']
  args += ['-t', target] if target
  args << format_string
  run_safe(*args)
end

#display_message(message, target: nil) ⇒ Object

Display methods



355
356
357
358
359
360
# File 'lib/hiiro/tmux.rb', line 355

def display_message(message, target: nil)
  args = ['display-message']
  args += ['-t', target] if target
  args << message
  run_system(*args)
end

#find_session(name) ⇒ Object

Session methods



109
110
111
112
113
114
115
116
117
# File 'lib/hiiro/tmux.rb', line 109

def find_session(name)
  normalized = name.to_s.tr('.', '_')
  sessions.find { |s| s.name == normalized } ||
    Matcher.by_prefix(sessions.map(&:name), normalized)&.resolved&.then do |m|
      # Don't cross path boundaries: 'oncall' must not match 'oncall/posoi'
      next nil if m.item.length > normalized.length && m.item[normalized.length] == '/'
      sessions.find { |s| s.name == m.item }
    end
end

#hsplit_window(**kwargs) ⇒ Object

Pane methods



233
234
235
236
# File 'lib/hiiro/tmux.rb', line 233

def hsplit_window(**kwargs)
  # tmux's horizontal/vertical is the opposite of vim's
  split_window(horizontal: false, **kwargs)
end

#in_nvim?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/hiiro/tmux.rb', line 69

def in_nvim?
  !ENV['NVIM'].nil? && !ENV['NVIM'].empty?
end

#in_tmux?Boolean

Context methods

Returns:

  • (Boolean)


65
66
67
# File 'lib/hiiro/tmux.rb', line 65

def in_tmux?
  !ENV['TMUX'].nil? && !ENV['TMUX'].empty?
end

#join_pane(src, dst, horizontal: false) ⇒ Object



284
285
286
287
288
# File 'lib/hiiro/tmux.rb', line 284

def join_pane(src, dst, horizontal: false)
  args = ['join-pane', '-s', src, '-t', dst]
  args << '-h' if horizontal
  run_system(*args)
end

#kill_pane(target) ⇒ Object



254
255
256
# File 'lib/hiiro/tmux.rb', line 254

def kill_pane(target)
  run_system('kill-pane', '-t', target)
end

#kill_session(name) ⇒ Object



152
153
154
155
# File 'lib/hiiro/tmux.rb', line 152

def kill_session(name)
  resolved = find_session(name)&.name || name.to_s.tr('.', '_')
  run_system('kill-session', '-t', resolved)
end

#kill_window(target) ⇒ Object



191
192
193
# File 'lib/hiiro/tmux.rb', line 191

def kill_window(target)
  run_system('kill-window', '-t', target)
end

#last_windowObject



207
208
209
# File 'lib/hiiro/tmux.rb', line 207

def last_window
  run_system('last-window')
end


223
224
225
# File 'lib/hiiro/tmux.rb', line 223

def link_window(src, dst)
  run_system('link-window', '-s', src, '-t', dst)
end

#load_buffer(path, name: nil) ⇒ Object



320
321
322
323
324
325
# File 'lib/hiiro/tmux.rb', line 320

def load_buffer(path, name: nil)
  args = ['load-buffer']
  args += ['-b', name] if name
  args << path
  run_system(*args)
end

#move_pane(src, dst) ⇒ Object



273
274
275
# File 'lib/hiiro/tmux.rb', line 273

def move_pane(src, dst)
  run_system('move-pane', '-s', src, '-t', dst)
end

#move_window(src, dst) ⇒ Object



219
220
221
# File 'lib/hiiro/tmux.rb', line 219

def move_window(src, dst)
  run_system('move-window', '-s', src, '-t', dst)
end

#new_session(name = nil, **opts) ⇒ Object



143
144
145
146
147
148
149
150
# File 'lib/hiiro/tmux.rb', line 143

def new_session(name = nil, **opts)
  args = ['new-session']
  args << '-d' if opts[:detached]
  args += ['-s', name] if name
  args += ['-c', opts[:start_directory]] if opts[:start_directory]
  args += ['-n', opts[:window_name]] if opts[:window_name]
  run_system(*args)
end

#new_window(name: nil, target: nil, start_directory: nil) ⇒ Object

Window methods



183
184
185
186
187
188
189
# File 'lib/hiiro/tmux.rb', line 183

def new_window(name: nil, target: nil, start_directory: nil)
  args = ['new-window']
  args += ['-t', target] if target
  args += ['-n', name] if name
  args += ['-c', start_directory] if start_directory
  run_system(*args)
end

#next_windowObject



199
200
201
# File 'lib/hiiro/tmux.rb', line 199

def next_window
  run_system('next-window')
end

#open_session(name, **opts) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/hiiro/tmux.rb', line 123

def open_session(name, **opts)
  session_name = name.to_s.tr('.', '_')
  existing = find_session(session_name)

  unless existing
    new_session(session_name, **opts, detached: true)
  end

  resolved_name = existing&.name || session_name

  if in_tmux?
    switch_client(resolved_name)
  elsif in_nvim?
    puts "Can't attach to tmux inside a vim terminal"
    false
  else
    attach_session(resolved_name)
  end
end

#panes(target: nil, all: false) ⇒ Object



99
100
101
# File 'lib/hiiro/tmux.rb', line 99

def panes(target: nil, all: false)
  Panes.fetch(target: target, all: all)
end

#paste_buffer(name: nil, target: nil) ⇒ Object



334
335
336
337
338
339
# File 'lib/hiiro/tmux.rb', line 334

def paste_buffer(name: nil, target: nil)
  args = ['paste-buffer']
  args += ['-b', name] if name
  args += ['-t', target] if target
  run_system(*args)
end

#previous_windowObject



203
204
205
# File 'lib/hiiro/tmux.rb', line 203

def previous_window
  run_system('previous-window')
end

#rename_session(old_name, new_name) ⇒ Object



176
177
178
179
# File 'lib/hiiro/tmux.rb', line 176

def rename_session(old_name, new_name)
  resolved = find_session(old_name)&.name || old_name.to_s.tr('.', '_')
  run_system('rename-session', '-t', resolved, new_name)
end

#rename_window(target, new_name) ⇒ Object



211
212
213
# File 'lib/hiiro/tmux.rb', line 211

def rename_window(target, new_name)
  run_system('rename-window', '-t', target, new_name)
end

#resize_pane(target: nil, width: nil, height: nil, zoom: false) ⇒ Object



290
291
292
293
294
295
296
297
# File 'lib/hiiro/tmux.rb', line 290

def resize_pane(target: nil, width: nil, height: nil, zoom: false)
  args = ['resize-pane']
  args += ['-t', target] if target
  args << '-Z' if zoom
  args += ['-x', width.to_s] if width
  args += ['-y', height.to_s] if height
  run_system(*args)
end

#save_buffer(path, name: nil) ⇒ Object



327
328
329
330
331
332
# File 'lib/hiiro/tmux.rb', line 327

def save_buffer(path, name: nil)
  args = ['save-buffer']
  args += ['-b', name] if name
  args << path
  run_system(*args)
end

#select_pane(target) ⇒ Object



258
259
260
# File 'lib/hiiro/tmux.rb', line 258

def select_pane(target)
  run_system('select-pane', '-t', target)
end

#select_window(target) ⇒ Object



195
196
197
# File 'lib/hiiro/tmux.rb', line 195

def select_window(target)
  run_system('select-window', '-t', target)
end

#server_running?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/hiiro/tmux.rb', line 73

def server_running?
  run_success?('has-session')
end

#session_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/hiiro/tmux.rb', line 119

def session_exists?(name)
  !find_session(name).nil?
end

#sessionsObject

Collection accessors



91
92
93
# File 'lib/hiiro/tmux.rb', line 91

def sessions
  Sessions.fetch
end

#set_buffer(content, name: nil) ⇒ Object

Buffer methods



313
314
315
316
317
318
# File 'lib/hiiro/tmux.rb', line 313

def set_buffer(content, name: nil)
  args = ['set-buffer']
  args += ['-b', name] if name
  args << content
  run_system(*args)
end

#show_buffer(name) ⇒ Object



345
346
347
# File 'lib/hiiro/tmux.rb', line 345

def show_buffer(name)
  run_safe('show-buffer', '-b', name)
end

#split_window(horizontal: false, target: nil, start_directory: nil, size: nil, command: nil) ⇒ Object



243
244
245
246
247
248
249
250
251
252
# File 'lib/hiiro/tmux.rb', line 243

def split_window(horizontal: false, target: nil, start_directory: nil, size: nil, command: nil)
  args = ['split-window']
  args << '-h' if horizontal
  args << '-v' unless horizontal
  args += ['-t', target] if target
  args += ['-c', start_directory] if start_directory
  args += ['-l', size] if size
  args << command if command
  run_system(*args)
end

#swap_current_pane(dst = 0, keep_active: false) ⇒ Object



262
263
264
265
266
267
# File 'lib/hiiro/tmux.rb', line 262

def swap_current_pane(dst=0, keep_active: false)
  args = ['swap-pane']
  args << '-d' if keep_active
  args += ['-t', dst&.to_s]
  run_system(*args)
end

#swap_pane(src, dst) ⇒ Object



269
270
271
# File 'lib/hiiro/tmux.rb', line 269

def swap_pane(src, dst)
  run_system('swap-pane', '-s', src, '-t', dst)
end

#swap_window(src, dst) ⇒ Object



215
216
217
# File 'lib/hiiro/tmux.rb', line 215

def swap_window(src, dst)
  run_system('swap-window', '-s', src, '-t', dst)
end

#switch_client(name) ⇒ Object



162
163
164
165
# File 'lib/hiiro/tmux.rb', line 162

def switch_client(name)
  resolved = find_session(name)&.name || name.to_s.tr('.', '_')
  run_system('switch-client', '-t', "=#{resolved}")
end


227
228
229
# File 'lib/hiiro/tmux.rb', line 227

def unlink_window(target)
  run_system('unlink-window', '-t', target)
end

#vsplit_window(**kwargs) ⇒ Object



238
239
240
241
# File 'lib/hiiro/tmux.rb', line 238

def vsplit_window(**kwargs)
  # tmux's horizontal/vertical is the opposite of vim's
  split_window(horizontal: true, **kwargs)
end

#windows(session: nil, all: false) ⇒ Object



95
96
97
# File 'lib/hiiro/tmux.rb', line 95

def windows(session: nil, all: false)
  Windows.fetch(session: session, all: all)
end