Class: Terminalwire::V2::Server::Terminal

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

Overview

The server's live model of the client's terminal. See ../../../TERMINAL.md.

Two orthogonal parts, deliberately not conflated:

* three Streams (stdin/stdout/stderr), each independently tty/pipe/file/null
* one Device (the controlling terminal): size, term, color, encoding, mode

Seeded from the hello terminal block; the device's size/mode are updated by control frames. Thread-safe: the read pump writes while the CLI reads.

Defined Under Namespace

Classes: Stream

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdin: "tty", stdout: "tty", stderr: "tty", cols: 80, rows: 24, xpixels: 0, ypixels: 0, term: "", color: "none", encoding: "UTF-8", mode: "cooked") ⇒ Terminal

Returns a new instance of Terminal.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/terminalwire/v2/server/terminal.rb', line 25

def initialize(stdin: "tty", stdout: "tty", stderr: "tty",
               cols: 80, rows: 24, xpixels: 0, ypixels: 0,
               term: "", color: "none", encoding: "UTF-8", mode: "cooked")
  @stdin = Stream.new(kind: stdin)
  @stdout = Stream.new(kind: stdout)
  @stderr = Stream.new(kind: stderr)
  @cols = cols
  @rows = rows
  @xpixels = xpixels
  @ypixels = ypixels
  @term = term
  @color = color
  @encoding = encoding
  @mode = mode
  @mutex = Mutex.new
end

Instance Attribute Details

#stderrObject (readonly)

Returns the value of attribute stderr.



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

def stderr
  @stderr
end

#stdinObject (readonly)

Returns the value of attribute stdin.



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

def stdin
  @stdin
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



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

def stdout
  @stdout
end

Instance Method Details

#apply(block) ⇒ Object

Apply a wire terminal block (string keys) from a hello frame.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/terminalwire/v2/server/terminal.rb', line 66

def apply(block)
  return if block.nil?

  @stdin  = Stream.new(kind: block.dig("stdin", "kind") || @stdin.kind)
  @stdout = Stream.new(kind: block.dig("stdout", "kind") || @stdout.kind)
  @stderr = Stream.new(kind: block.dig("stderr", "kind") || @stderr.kind)

  device = block["device"]
  return if device.nil?

  @mutex.synchronize do
    @cols = device["cols"] if device["cols"]
    @rows = device["rows"] if device["rows"]
    @xpixels = device["xpixels"] if device["xpixels"]
    @ypixels = device["ypixels"] if device["ypixels"]
    @term = device["term"] if device["term"]
    @color = device["color"] if device["color"]
    @encoding = device["encoding"] if device["encoding"]
    @mode = device["mode"] if device["mode"]
  end
end

#colorObject



49
# File 'lib/terminalwire/v2/server/terminal.rb', line 49

def color    = @mutex.synchronize { @color }

#color?Boolean

Returns:

  • (Boolean)


52
# File 'lib/terminalwire/v2/server/terminal.rb', line 52

def color? = color != "none"

#colsObject

Device attributes.



43
# File 'lib/terminalwire/v2/server/terminal.rb', line 43

def cols     = @mutex.synchronize { @cols }

#device?Boolean

A controlling terminal device exists iff some stream is a tty.

Returns:

  • (Boolean)


55
# File 'lib/terminalwire/v2/server/terminal.rb', line 55

def device? = @stdin.tty? || @stdout.tty? || @stderr.tty?

#encodingObject



48
# File 'lib/terminalwire/v2/server/terminal.rb', line 48

def encoding = @mutex.synchronize { @encoding }

#modeObject



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

def mode     = @mutex.synchronize { @mode }

#resize(cols:, rows:, xpixels: nil, ypixels: nil) ⇒ Object

Apply a resize control frame.



89
90
91
92
93
94
95
96
# File 'lib/terminalwire/v2/server/terminal.rb', line 89

def resize(cols:, rows:, xpixels: nil, ypixels: nil)
  @mutex.synchronize do
    @cols = cols if cols
    @rows = rows if rows
    @xpixels = xpixels if xpixels
    @ypixels = ypixels if ypixels
  end
end

#rowsObject



44
# File 'lib/terminalwire/v2/server/terminal.rb', line 44

def rows     = @mutex.synchronize { @rows }

#stream(name) ⇒ Object

Look up a stream by name (:stdin/:stdout/:stderr).



61
62
63
# File 'lib/terminalwire/v2/server/terminal.rb', line 61

def stream(name)
  { stdin: @stdin, stdout: @stdout, stderr: @stderr }.fetch(name.to_sym)
end

#termObject



47
# File 'lib/terminalwire/v2/server/terminal.rb', line 47

def term     = @mutex.synchronize { @term }

#winsizeObject

IO#winsize convention: [rows, cols].



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

def winsize = @mutex.synchronize { [@rows, @cols] }

#xpixelsObject



45
# File 'lib/terminalwire/v2/server/terminal.rb', line 45

def xpixels  = @mutex.synchronize { @xpixels }

#ypixelsObject



46
# File 'lib/terminalwire/v2/server/terminal.rb', line 46

def ypixels  = @mutex.synchronize { @ypixels }