Class: Terminalwire::V2::Server::IO

Inherits:
Object
  • Object
show all
Defined in:
lib/terminalwire/v2/server/io.rb

Overview

An IO-shaped object backed by the Terminalwire Context. This is the universal adapter: anything that writes to an IO (Kernel#puts, OptionParser help/errors, Logger, a library's output:) or reads from one ($stdin.gets) works against the client's terminal when handed one of these.

Server.redirect swaps the global $stdout/$stderr/$stdin for these so an ordinary CLI needs no Terminalwire-specific code; Thor uses them directly because its shell captures the streams at construction.

Instance Method Summary collapse

Constructor Details

#initialize(context, stream) ⇒ IO

Returns a new instance of IO.

Parameters:

  • context (Context)
  • stream (:stdout, :stderr, :stdin)


16
17
18
19
# File 'lib/terminalwire/v2/server/io.rb', line 16

def initialize(context, stream)
  @context = context
  @stream = stream
end

Instance Method Details

#<<(arg) ⇒ Object



32
33
34
35
# File 'lib/terminalwire/v2/server/io.rb', line 32

def <<(arg)
  @context.print(arg.to_s, stream: @stream)
  self
end

#each_line(&block) ⇒ Object Also known as: each



62
63
64
65
66
67
68
# File 'lib/terminalwire/v2/server/io.rb', line 62

def each_line(&block)
  return enum_for(:each_line) unless block

  while (line = gets)
    block.call(line)
  end
end

#flushObject



50
# File 'lib/terminalwire/v2/server/io.rb', line 50

def flush = self

#getpassObject



59
# File 'lib/terminalwire/v2/server/io.rb', line 59

def getpass(*) = @context.stdin.getpass

#getsObject

--- reading (stdin) ---



58
# File 'lib/terminalwire/v2/server/io.rb', line 58

def gets(*) = @context.stdin.gets

#ioctl(_cmd, buf = nil) ⇒ Object

Answer the window-size ioctl (TIOCGWINSZ) that tty-screen probes, filling the caller's buffer with the CLIENT's [rows, cols] — so tty-screen-based libraries (tty-progressbar, tty-spinner, …) size to the client instead of crashing on a non-IO stream. Other ioctls are no-ops.



82
83
84
85
86
87
88
# File 'lib/terminalwire/v2/server/io.rb', line 82

def ioctl(_cmd, buf = nil)
  if buf.is_a?(String)
    rows, cols = @context.terminal.winsize
    buf[0, 8] = [rows.to_i, cols.to_i, 0, 0].pack("S4") # matches tty-screen's "SSSS"
  end
  0
end

#isattyObject



76
# File 'lib/terminalwire/v2/server/io.rb', line 76

def isatty = tty?

--- writing (stdout/stderr) ---



23
24
25
26
# File 'lib/terminalwire/v2/server/io.rb', line 23

def print(*args)
  args.each { |arg| @context.print(arg.to_s, stream: @stream) }
  nil
end

#printf(format, *args) ⇒ Object



46
47
48
# File 'lib/terminalwire/v2/server/io.rb', line 46

def printf(format, *args)
  print(format % args)
end

#puts(*args) ⇒ Object



37
38
39
40
41
42
43
44
# File 'lib/terminalwire/v2/server/io.rb', line 37

def puts(*args)
  if args.empty?
    @context.print("\n", stream: @stream)
  else
    args.flatten.each { |arg| @context.print("#{arg}\n", stream: @stream) }
  end
  nil
end

#readObject



60
# File 'lib/terminalwire/v2/server/io.rb', line 60

def read = @context.stdin.read

#syncObject



51
# File 'lib/terminalwire/v2/server/io.rb', line 51

def sync = true

#sync=(value) ⇒ Object



52
53
54
# File 'lib/terminalwire/v2/server/io.rb', line 52

def sync=(value)
  value
end

#tty?Boolean

Per-stream: this proxy's own stream is what isatty(stdout) etc. ask about.

Returns:

  • (Boolean)


74
# File 'lib/terminalwire/v2/server/io.rb', line 74

def tty? = @context.terminal.stream(@stream).tty?

#winsizeObject



75
# File 'lib/terminalwire/v2/server/io.rb', line 75

def winsize = @context.terminal.winsize

#write(*args) ⇒ Object



28
29
30
# File 'lib/terminalwire/v2/server/io.rb', line 28

def write(*args)
  args.sum { |arg| s = arg.to_s; @context.print(s, stream: @stream); s.bytesize }
end