Module: Echoes::Client

Defined in:
lib/echoes/client.rb

Overview

Helpers that emit Echoes-private OSC sequences for tools running inside an Echoes pane (e.g. a Ruby presentation tool that wants Keynote-style gradient slide backgrounds). Other terminals ignore the OSC code, so emitters degrade gracefully.

Example:

Echoes::Client.bg_gradient(from: '#1a1a2e', to: '#16213e', angle: 90)
# ...later, restore the solid background:
Echoes::Client.bg_clear

Constant Summary collapse

OSC =
"\e]7772"
BEL =
"\a"

Class Method Summary collapse

Class Method Details

.bg_clear(io: $stdout) ⇒ Object

Drop any pane background override (bg-color/bg-gradient) AND all bg-fill overlays. Safe to call when nothing is set.



67
68
69
70
71
# File 'lib/echoes/client.rb', line 67

def bg_clear(io: $stdout)
  io.write("#{OSC};bg-clear#{BEL}")
  io.flush if io.respond_to?(:flush)
  nil
end

.bg_color(color, io: $stdout) ⇒ Object

Paint the pane’s background with a single solid color. The color paints beneath cell content, so cells with their own bg color (selection, themed cells, etc.) still occlude correctly. Pair with bg_clear to revert.

Example:

Echoes::Client.bg_color('#1a1a2e')


41
42
43
44
45
# File 'lib/echoes/client.rb', line 41

def bg_color(color, io: $stdout)
  io.write("#{OSC};bg-color;#{color}#{BEL}")
  io.flush if io.respond_to?(:flush)
  nil
end

.bg_fill(color, row1:, col1:, row2:, col2:, io: $stdout) ⇒ Object

Paint a rectangular region of the pane on top of the base background. Calls accumulate — emit several to build up a layout (header/footer bars, sidebars, accent stripes, etc.). ‘bg_clear` wipes the whole list along with the base background.

Coordinates are 0-indexed cell positions, inclusive on both ends — i.e. row1=0, col1=0, row2=2, col2=9 paints a 3x10 block.

Example:

Echoes::Client.bg_fill('#222',  row1: 0,  col1: 0, row2: 0,  col2: 79)  # status bar
Echoes::Client.bg_fill('#3a3', row1: 24, col1: 0, row2: 24, col2: 79)  # footer


58
59
60
61
62
63
# File 'lib/echoes/client.rb', line 58

def bg_fill(color, row1:, col1:, row2:, col2:, io: $stdout)
  args = "color=#{color}:rect=#{row1},#{col1},#{row2},#{col2}"
  io.write("#{OSC};bg-fill;#{args}#{BEL}")
  io.flush if io.respond_to?(:flush)
  nil
end

.bg_gradient(from: nil, to: nil, colors: nil, angle: 0, type: :linear, io: $stdout) ⇒ Object

Paint a linear gradient as the pane’s background. ‘angle` is in degrees (0 = left→right, 90 = bottom→top, matches NSGradient). Pass an array of hex strings via `colors:` for endpoints beyond two (the renderer currently uses first/last only).

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
30
31
32
# File 'lib/echoes/client.rb', line 23

def bg_gradient(from: nil, to: nil, colors: nil, angle: 0, type: :linear, io: $stdout)
  colors ||= [from, to]
  colors = colors.compact.map(&:to_s)
  raise ArgumentError, 'need at least 2 colors' if colors.size < 2

  args = "type=#{type}:angle=#{angle}:colors=#{colors.join(',')}"
  io.write("#{OSC};bg-gradient;#{args}#{BEL}")
  io.flush if io.respond_to?(:flush)
  nil
end

.styled_text(text, scale: 1, width: nil, frac_n: nil, frac_d: nil, valign: nil, halign: nil, family: nil, io: $stdout) ⇒ Object

Emit text via OSC 66 (multicell), with optional cell-scale, sub-cell fraction, vertical/horizontal alignment, and font family. ‘family:` is an Echoes-specific extension other terminals ignore. On unknown families, Echoes falls back to the monospaced system font.

Examples:

Echoes::Client.styled_text("Title",   scale: 3, family: "Helvetica Neue")
Echoes::Client.styled_text("• item",  scale: 1, family: "Menlo")


82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/echoes/client.rb', line 82

def styled_text(text, scale: 1, width: nil, frac_n: nil, frac_d: nil,
                valign: nil, halign: nil, family: nil, io: $stdout)
  meta = +"s=#{scale}"
  meta << ":w=#{width}"   if width
  meta << ":n=#{frac_n}"  if frac_n
  meta << ":d=#{frac_d}"  if frac_d
  meta << ":v=#{valign}"  if valign
  meta << ":h=#{halign}"  if halign
  meta << ":f=#{family}"  if family
  io.write("\e]66;#{meta};#{text}\a")
  io.flush if io.respond_to?(:flush)
  nil
end