Binary protocol encoder/decoder for BEAM ↔ Zig communication.
Messages are length-prefixed binaries (4-byte big-endian header,
handled by Erlang's {:packet, 4} Port option). The payload
starts with a 1-byte opcode followed by opcode-specific fields.
Input Events (Zig → BEAM)
| Opcode | Name | Payload |
|---|---|---|
| 0x01 | key_press | codepoint::32, modifiers::8 |
| 0x02 | resize | width::16, height::16 |
| 0x03 | ready | width::16, height::16 |
| 0x04 | mouse_event | row::16-signed, col::16-signed, button::8, mods::8, type::8 |
Render Commands (BEAM → Zig)
| Opcode | Name | Payload |
|---|---|---|
| 0x10 | draw_text | row::16, col::16, fg::24, bg::24, attrs::8, text_len::16, text |
| 0x1C | draw_styled_text | row::16, col::16, fg::24, bg::24, attrs::16, ul_color::24, blend::8, font_weight::8, font_id::8, text_len::16, text |
| 0x11 | set_cursor | row::16, col::16 |
| 0x12 | clear | (empty) |
| 0x13 | batch_end | (empty) |
| 0x15 | set_cursor_shape | shape::8 (BLOCK=0, BEAM=1, UNDERLINE=2) |
| 0x1B | scroll_region | top_row::16, bottom_row::16, delta::16-signed |
Modifier Flags
| Flag | Value |
|---|---|
| SHIFT | 0x01 |
| CTRL | 0x02 |
| ALT | 0x04 |
| SUPER | 0x08 |
Summary
Types
Cursor shape.
A highlight span from tree-sitter.
An input event decoded from Zig.
Modifier flag bitmask.
Mouse button identifier.
Mouse event type.
Region role atom.
Text style attributes.
Functions
Decodes a render command from a binary payload (primarily for testing).
Decodes an input event from a binary payload.
Encodes a batch_end command (triggers render flush).
Encodes a clear screen command.
Encodes a clear_region command.
Encodes a set_cursor command.
Encodes a set_cursor_shape command.
Encodes a define_region command.
Encodes a destroy_region command.
Encodes a draw_text command.
Smart encoder: uses draw_styled_text if the style contains extended
attributes, otherwise falls back to the more compact draw_text.
Encodes a draw_styled_text command with extended attributes.
Encodes a register_font command to associate a font_id with a font family.
Encodes a scroll_region command for terminal scroll optimization.
Encodes a set_active_region command. Pass 0 to reset to root.
Encodes a set_font command to configure the GUI frontend's font.
Encodes a set_font_fallback command to configure the GUI's font fallback chain.
Encodes a set_title command to update the terminal window title.
Encodes a set_window_bg command to set the default background color.
Checks if a modifier flag is set.
Returns the ALT modifier flag.
Returns the CTRL modifier flag.
Returns the SHIFT modifier flag.
Returns the SUPER modifier flag.
Types
@type conceal_span() :: Minga.Parser.Protocol.conceal_span()
@type cursor_shape() :: :block | :beam | :underline
Cursor shape.
@type edit_delta() :: Minga.Parser.Protocol.edit_delta()
@type highlight_span() :: Minga.Language.Highlight.Span.t()
A highlight span from tree-sitter.
@type input_event() :: {:key_press, codepoint :: non_neg_integer(), modifiers()} | {:resize, width :: pos_integer(), height :: pos_integer()} | {:ready, width :: pos_integer(), height :: pos_integer()} | {:ready, width :: pos_integer(), height :: pos_integer(), MingaEditor.Frontend.Capabilities.t()} | {:capabilities_updated, MingaEditor.Frontend.Capabilities.t()} | {:paste_event, text :: String.t()} | {:mouse_event, row :: integer(), col :: integer(), mouse_button(), modifiers(), mouse_event_type(), click_count :: pos_integer()} | {:highlight_spans, buffer_id :: non_neg_integer(), version :: non_neg_integer(), [highlight_span()]} | {:highlight_names, buffer_id :: non_neg_integer(), [String.t()]} | {:conceal_spans, buffer_id :: non_neg_integer(), version :: non_neg_integer(), [conceal_span()]} | {:grammar_loaded, success :: boolean(), name :: String.t()} | {:injection_ranges, buffer_id :: non_neg_integer(), [Minga.Language.Highlight.InjectionRange.t()]} | {:language_at_response, request_id :: non_neg_integer(), language :: String.t()} | {:fold_ranges, buffer_id :: non_neg_integer(), version :: non_neg_integer(), [{start_line :: non_neg_integer(), end_line :: non_neg_integer()}]} | {:indent_result, request_id :: non_neg_integer(), line :: non_neg_integer(), indent_level :: integer()} | {:textobject_result, request_id :: non_neg_integer(), result :: {non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()} | nil} | {:textobject_positions, buffer_id :: non_neg_integer(), version :: non_neg_integer(), %{required(atom()) => [{non_neg_integer(), non_neg_integer()}]}} | {:request_reparse, buffer_id :: non_neg_integer()} | {:log_message, level :: String.t(), text :: String.t()} | {:gui_action, MingaEditor.Frontend.Protocol.GUI.gui_action()}
An input event decoded from Zig.
@type modifiers() :: non_neg_integer()
Modifier flag bitmask.
@type mouse_button() :: :left | :middle | :right | :none | :wheel_up | :wheel_down | :wheel_right | :wheel_left | {:unknown, non_neg_integer()}
Mouse button identifier.
@type mouse_event_type() :: :press | :release | :motion | :drag | {:unknown, non_neg_integer()}
Mouse event type.
@type region_role() ::
:editor | :modeline | :minibuffer | :gutter | :popup | :panel | :border
Region role atom.
@type style() :: [ fg: non_neg_integer(), bg: non_neg_integer(), bold: boolean(), underline: boolean(), italic: boolean(), reverse: boolean(), strikethrough: boolean(), underline_style: :line | :curl | :dashed | :dotted | :double, underline_color: non_neg_integer(), blend: 0..100, font_weight: :thin | :light | :regular | :medium | :semibold | :bold | :heavy | :black, font_id: non_neg_integer() ]
Text style attributes.
Functions
@spec decode_command(binary()) :: {:ok, :clear | :batch_end | {:draw_text, map()} | {:draw_styled_text, map()} | {:set_cursor, non_neg_integer(), non_neg_integer()} | {:set_cursor_shape, cursor_shape()}} | {:error, :unknown_opcode | :malformed}
Decodes a render command from a binary payload (primarily for testing).
@spec decode_event(binary()) :: {:ok, input_event()} | {:error, :unknown_opcode | :malformed}
Decodes an input event from a binary payload.
@spec encode_batch_end() :: binary()
Encodes a batch_end command (triggers render flush).
@spec encode_clear() :: binary()
Encodes a clear screen command.
@spec encode_clear_region(non_neg_integer()) :: binary()
Encodes a clear_region command.
@spec encode_cursor(non_neg_integer(), non_neg_integer()) :: binary()
Encodes a set_cursor command.
@spec encode_cursor_shape(cursor_shape()) :: binary()
Encodes a set_cursor_shape command.
@spec encode_define_region( non_neg_integer(), non_neg_integer(), region_role(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer() ) :: binary()
Encodes a define_region command.
@spec encode_destroy_region(non_neg_integer()) :: binary()
Encodes a destroy_region command.
@spec encode_draw(non_neg_integer(), non_neg_integer(), String.t(), style()) :: binary()
Encodes a draw_text command.
@spec encode_draw_smart(non_neg_integer(), non_neg_integer(), String.t(), style()) :: binary()
Smart encoder: uses draw_styled_text if the style contains extended
attributes, otherwise falls back to the more compact draw_text.
@spec encode_draw_styled(non_neg_integer(), non_neg_integer(), String.t(), style()) :: binary()
Encodes a draw_styled_text command with extended attributes.
Extended over draw_text with:
attrsexpanded to 16 bits (adds strikethrough 0x10, underline_style 3 bits at 0xE0)underline_coloras a separate 24-bit RGB field (0x000000 = use fg)blendas an 8-bit opacity value (0-100, 100 = fully opaque)font_weightas an 8-bit weight index (0-7, maps to thin through black)
Use this for text that needs underline styles, strikethrough, underline
color, blend, or per-span font weight. For simple text
(fg/bg/bold/italic/underline/reverse), encode_draw/4 is more compact.
@spec encode_register_font(non_neg_integer(), String.t()) :: binary()
Encodes a register_font command to associate a font_id with a font family.
Font ID 0 is the primary font (set via set_font). IDs 1-255 are
secondary fonts that can be referenced by font_id in draw_styled_text.
The GUI creates a FontFace for each registered font at the same size as
the primary. If the secondary font's cell metrics differ from the primary,
the GUI logs a warning and falls back to the primary for those glyphs.
Format: opcode:8, font_id:8, name_len:16, name:bytes
@spec encode_scroll_region(non_neg_integer(), non_neg_integer(), integer()) :: binary()
Encodes a scroll_region command for terminal scroll optimization.
Tells the Zig renderer to use ANSI scroll region sequences to shift
content within the given screen row range by delta lines, avoiding
a full redraw.
top_row/bottom_row— screen row range (inclusive) for the scroll region.delta— positive = scroll up (content moves up, new lines at bottom),negative = scroll down (content moves down, new lines at top).
Wire format: opcode(1) + top_row(2) + bottom_row(2) + delta(2, signed) = 7 bytes.
@spec encode_set_active_region(non_neg_integer()) :: binary()
Encodes a set_active_region command. Pass 0 to reset to root.
@spec encode_set_font(String.t(), pos_integer(), boolean(), atom()) :: binary()
Encodes a set_font command to configure the GUI frontend's font.
The font family is resolved by the frontend using NSFontManager (macOS) so both display names ("JetBrains Mono") and PostScript names ("JetBrainsMonoNF-Regular") work. The TUI ignores this command.
Format: opcode:8, size:16, weight:8, ligatures:8, name_len:16, name:bytes
Fields are ordered by category: font identity (size, weight, name) then rendering features (ligatures). The variable-length name stays at the end.
Encodes a set_font_fallback command to configure the GUI's font fallback chain.
The fallback chain is tried in order when the primary font (set via set_font)
doesn't have a glyph. Each entry is a font family name resolved by the frontend
via NSFontManager. After the configured fallbacks, the system fallback
(CTFontCreateForString) is used as a last resort.
Format: opcode:8, count:8, [name_len:16, name:bytes]*
Encodes a set_title command to update the terminal window title.
@spec encode_set_window_bg(non_neg_integer()) :: binary()
Encodes a set_window_bg command to set the default background color.
The Zig renderer uses this as the fallback background for any cell
that doesn't specify an explicit bg: value. This prevents cells
from falling back to the terminal's default background, which may
not match the editor theme.
Checks if a modifier flag is set.
@spec mod_alt() :: modifiers()
Returns the ALT modifier flag.
@spec mod_ctrl() :: modifiers()
Returns the CTRL modifier flag.
@spec mod_shift() :: modifiers()
Returns the SHIFT modifier flag.
@spec mod_super() :: modifiers()
Returns the SUPER modifier flag.