Class: Muxr::Renderer

Inherits:
Object
  • Object
show all
Defined in:
lib/muxr/renderer.rb

Overview

The Renderer composites the Session into a single grid of cells and then emits ANSI escape sequences to write that grid to STDOUT. It compares the new frame against the previous one and only repositions/redraws cells whose contents changed, keeping output volume low between ticks.

Defined Under Namespace

Classes: Cell

Constant Summary collapse

BORDER_FOCUSED =

yellow (fallback when no mode color)

[:c256, 11].freeze
BORDER_UNFOCUSED =

grey

[:c256, 8].freeze
BORDER_DRAWER_FOCUS =

magenta

[:c256, 13].freeze
BORDER_DRAWER_IDLE =

dark magenta

[:c256, 5].freeze
STATUS_BG =
[:c256, 236].freeze
STATUS_FG =
[:c256, 252].freeze
MODE_COLOR =

Vim-style mode palette. Used in two places: the focused pane border (so the user can see at a glance what mode they’re in) and the

MODE

chip in the status bar (same color, smaller real estate).

:prefix maps to the same green as :passthrough because :prefix is a transient sub-state under passthrough — sharing the color avoids a one-frame border flicker when pressing Ctrl-a.

{
  normal:       [:c256, 51].freeze,   # cyan
  passthrough:  [:c256, 42].freeze,   # green
  prefix:       [:c256, 42].freeze,   # green (passthrough sub-state)
  command:      [:c256, 226].freeze,  # yellow
  scrollback:   [:c256, 214].freeze,  # orange
  search:       [:c256, 214].freeze,  # orange (scrollback sub-state)
  selection:    [:c256, 201].freeze,  # magenta
  confirm_quit:  [:c256, 196].freeze, # red
  confirm_close: [:c256, 196].freeze, # red
  help:          [:c256, 39].freeze   # blue
}.freeze
SEARCH_MATCH_BG =

Background applied to cells that match the active scrollback search. Bright enough to stand out over typical foreground SGRs while leaving the original glyph readable.

[:c256, 226].freeze
SEARCH_MATCH_FG =

black

[:c256, 16].freeze
HORIZONTAL =
"".freeze
VERTICAL =
"".freeze
TL =
"".freeze
TR =
"".freeze
BL =
"".freeze
BR =
"".freeze

Instance Method Summary collapse

Constructor Details

#initialize(out: $stdout) ⇒ Renderer

Returns a new instance of Renderer.



52
53
54
55
56
57
# File 'lib/muxr/renderer.rb', line 52

def initialize(out: $stdout)
  @out = out
  @prev = nil
  @prev_w = 0
  @prev_h = 0
end

Instance Method Details

#enter_alt_screenObject



59
60
61
62
63
64
65
66
# File 'lib/muxr/renderer.rb', line 59

def enter_alt_screen
  # Close any stale OSC 8 hyperlink the outer terminal might be carrying
  # from before we attached, so the first frame's run-tracker matches
  # reality.
  @out.write("\e[?1049h\e[?25l\e[2J\e[H\e[0m\e]8;;\e\\")
  @out.flush
  @prev = nil
end

#exit_alt_screenObject



68
69
70
71
# File 'lib/muxr/renderer.rb', line 68

def exit_alt_screen
  @out.write("\e[0m\e[?25h\e[?1049l")
  @out.flush
end

#render(session, input_state: :normal, command_buffer: "", search_buffer: "", search_direction: :forward, message: nil, help: false) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/muxr/renderer.rb', line 77

def render(session, input_state: :normal, command_buffer: "", search_buffer: "", search_direction: :forward, message: nil, help: false)
  w = session.width
  h = session.height
  return if w < 4 || h < 3

  frame = Array.new(h) { Array.new(w) { Cell.new(" ", nil, nil, 0, nil) } }

  compose_panes(frame, session, input_state: input_state)
  compose_drawer(frame, session, input_state: input_state) if session.drawer&.visible?
  compose_status_bar(
    frame, session,
    input_state: input_state,
    command_buffer: command_buffer,
    search_buffer: search_buffer,
    search_direction: search_direction,
    message: message
  )
  compose_help(frame, session) if help

  emit_frame(frame, session, input_state: input_state, command_buffer: command_buffer, search_buffer: search_buffer)
end

#reset_frame!Object



73
74
75
# File 'lib/muxr/renderer.rb', line 73

def reset_frame!
  @prev = nil
end