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_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 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 Event
s 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 Event
s 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.