glerm

Types

The possible events coming back from the terminal. Unknown should realistically never happen, since this library controls both ends of the message passing.

pub type Event {
  Focus(event: FocusEvent)
  Key(key: KeyCode, modifier: Option(Modifier))
  Mouse(event: MouseEvent)
  Resize(Int, Int)
  Unknown(tag: String, message: Dynamic)
}

Constructors

  • Focus(event: FocusEvent)
  • Key(key: KeyCode, modifier: Option(Modifier))
  • Mouse(event: MouseEvent)
  • Resize(Int, Int)
  • Unknown(tag: String, message: Dynamic)
pub type EventSubject =
  Subject(Event)

When the terminal window is focused or un-focused.

pub type FocusEvent {
  Lost
  Gained
}

Constructors

  • Lost
  • Gained

A particular keyboard key that was pressed. Either a character with its value, or a special key. The Unsupported is for things like PageUp, etc that I’m just not handling yet.

pub type KeyCode {
  Character(String)
  Enter
  Backspace
  Left
  Right
  Down
  Up
  Unsupported
}

Constructors

  • Character(String)
  • Enter
  • Backspace
  • Left
  • Right
  • Down
  • Up
  • Unsupported
pub type ListenerMessage(user_message) {
  Term(Event)
  User(user_message)
}

Constructors

  • Term(Event)
  • User(user_message)
pub type ListenerSpec(state, user_message) {
  ListenerSpec(
    init: fn() -> #(state, Option(Selector(user_message))),
    loop: fn(ListenerMessage(user_message), state) ->
      actor.Next(ListenerMessage(user_message), state),
  )
}

Constructors

  • ListenerSpec(
      init: fn() -> #(state, Option(Selector(user_message))),
      loop: fn(ListenerMessage(user_message), state) ->
        actor.Next(ListenerMessage(user_message), state),
    )
pub type ListenerSubject(user_message) =
  Subject(ListenerMessage(user_message))

These represent the noted keys being held down when another action is taken, like pressing another key or mouse button. For certain keys, things like Shift will not be set, but instead return something like A.

pub type Modifier {
  Shift
  Alt
  Control
}

Constructors

  • Shift
  • Alt
  • Control

Which mouse button was pressed. These are prefixed with Mouse in order to avoid conflicting with the arrow keys defined in KeyCode.

pub type MouseButton {
  MouseLeft
  MouseRight
  MouseMiddle
}

Constructors

  • MouseLeft
  • MouseRight
  • MouseMiddle

The possible types of mouse events. I think most of these will also have the mouse cursor position attached. That is not supported at the moment.

pub type MouseEvent {
  MouseDown(button: MouseButton, modifier: Option(Modifier))
  MouseUp(button: MouseButton, modifier: Option(Modifier))
  Drag(button: MouseButton, modifier: Option(Modifier))
  Moved
  ScrollDown
  ScrollUp
}

Constructors

  • MouseDown(button: MouseButton, modifier: Option(Modifier))
  • MouseUp(button: MouseButton, modifier: Option(Modifier))
  • Drag(button: MouseButton, modifier: Option(Modifier))
  • Moved
  • ScrollDown
  • ScrollUp

Functions

pub fn clear() -> Nil

Fully clears the terminal window

pub fn clear_current_line() -> Result(Nil, Nil)
pub fn cursor_position() -> Result(#(Int, Int), Nil)
pub fn disable_mouse_capture() -> Result(Nil, Nil)

This will stop the capture of mouse events in the terminal.

pub fn disable_raw_mode() -> Result(Nil, Nil)

Turns off raw mode. This will disable the features described in enable_raw_mode.

pub fn draw(commands: List(#(Int, Int, String))) -> Result(
  Nil,
  Nil,
)

Write some string to the screen at the given #(column, row) coordinate

pub fn enable_mouse_capture() -> Result(Nil, Nil)

This enables the capturing of mouse events. Without this, those event types will not be emitted by the NIF.

pub fn enable_raw_mode() -> Result(Nil, Nil)

Enables “raw mode” for the terminal. This will do a better job than I can at explaining what all that entails:

https://docs.rs/crossterm/latest/crossterm/terminal/index.html#raw-mode

If you want to control the entire screen, capture all input events, and place the cursor anywhere, this is what you want.

pub fn enter_alternate_screen() -> Result(Nil, Nil)

This will create a new terminal “window” that you can interact with. This will preserve the user’s existing terminal when exiting the program, or calling leave_alternate_screen.

pub fn leave_alternate_screen() -> Result(Nil, Nil)

See: enter_alternate_screen

pub fn move_to(column: Int, row: Int) -> Nil

Moves the cursor to the given location

pub fn print(data: BitString) -> Result(Nil, Nil)

Writes the given text wherever the cursor is

pub fn selector() -> Selector(Event)

The events from the NIF are sent as messages to the calling process. These do not go through a process.Subject, so they need to be explicitly extracted from the mailbox. This selector will grab the given Events for each message that comes in.

pub fn size() -> Result(#(Int, Int), Nil)

Gives back the #(column, row) count of the current terminal. This can be called to get the initial size, and then updated when Resize events come in.

pub fn start_listener(initial_state: a, loop: fn(Event, a) ->
    Next(ListenerMessage(b), a)) -> Result(
  Subject(Event),
  StartError,
)

If you are not planning on sending custom messages to the terminal listener, this method is the simplest. Give an initial state for the actor, and the loop will receive only Events and your provided state. To allow this actor to receive additional user-defined messages, see start_listener_spec

pub fn start_listener_spec(spec: ListenerSpec(a, b)) -> Result(
  Subject(ListenerMessage(b)),
  StartError,
)

This will start the NIF listener and set up the Event selector. The spec argument allows for behavior during the initialization of the actor. That function returns the initial state, and an optional user selector. This allows this actor to also receive any user-defined messages.

Search Document