Vtex.Mouse (Vtex v0.1.0)

Copy Markdown View Source

SGR mouse-reporting support: the control sequences that turn reporting on and off, and a decoder for the events the terminal sends back.

Mouse reporting is opt-in. Write enable/1 to the terminal to start receiving events and disable/0 (on teardown) to stop. While enabled, the terminal sends each event as an SGR mouse sequence — CSI < b ; x ; y M for a press/motion or … m for a release — which Vtex.Input surfaces as a {:mouse, event} tuple. How much motion is reported depends on the :motion level passed to enable/1.

Only the SGR encoding (mode 1006) is supported. It is the modern default and, unlike the legacy X10 encoding, is unambiguous and unbounded in coordinate range. Do not enable X10 mouse mode (CSI ? 1000 h without 1006): its raw coordinate bytes are not representable as a control sequence and cannot be tokenized.

enable/1 and disable/0 are the one place this otherwise input-only library emits output, because mouse reporting cannot be received without first being switched on. They return the bytes for you to write; the library performs no IO of its own.

Event

A decoded event is a map:

%{
  action: :press | :release | :drag | :move,
  button: :left | :middle | :right
         | :wheel_up | :wheel_down | :wheel_left | :wheel_right
         | :none | {:button, 8..11},
  x: pos_integer(),   # 1-based column
  y: pos_integer(),   # 1-based row
  mods: [:shift | :alt | :ctrl]
}

Summary

Functions

Decode an SGR mouse sequence body into an event map, or nil if malformed.

The control sequence that disables mouse reporting. Write it on teardown.

The control sequence that enables SGR mouse reporting. Write it to the terminal.

Types

button()

@type button() ::
  :left
  | :middle
  | :right
  | :wheel_up
  | :wheel_down
  | :wheel_left
  | :wheel_right
  | :none
  | {:button, 8..11}

event()

@type event() :: %{
  action: :press | :release | :drag | :move,
  button: button(),
  x: pos_integer(),
  y: pos_integer(),
  mods: [:shift | :alt | :ctrl]
}

Functions

decode(params, final)

@spec decode(binary(), byte()) :: event() | nil

Decode an SGR mouse sequence body into an event map, or nil if malformed.

params is the CSI parameter string ("b;x;y") and final is ?M (press/motion) or ?m (release).

Examples

iex> Vtex.Mouse.decode("0;10;5", ?M)
%{action: :press, button: :left, x: 10, y: 5, mods: []}

iex> Vtex.Mouse.decode("0;10;5", ?m)
%{action: :release, button: :left, x: 10, y: 5, mods: []}

iex> Vtex.Mouse.decode("64;3;3", ?M)
%{action: :press, button: :wheel_up, x: 3, y: 3, mods: []}

iex> Vtex.Mouse.decode("49;7;2", ?M)
%{action: :drag, button: :middle, x: 7, y: 2, mods: [:ctrl]}

disable()

@spec disable() :: binary()

The control sequence that disables mouse reporting. Write it on teardown.

Examples

iex> Vtex.Mouse.disable() =~ "1006l"
true

enable(opts \\ [])

@spec enable(keyword()) :: binary()

The control sequence that enables SGR mouse reporting. Write it to the terminal.

The :motion option chooses how much motion is reported:

  • :drag (default) — press, release, and motion while a button is held
  • :all — also bare pointer motion with no button (fires on every cell the pointer crosses; a firehose, but needed for hover)
  • :none — press and release only

Examples

iex> Vtex.Mouse.enable() =~ "1002h"
true

iex> Vtex.Mouse.enable(motion: :all) =~ "1003h"
true

iex> Vtex.Mouse.enable(motion: :none) =~ "1002h"
false