Packages
Terminal emulation and driver infrastructure for Raxol. ANSI parsing, screen buffers, command processing, cursor management, input handling, session management, and termbox2 NIF integration.
Current section
Files
Jump to
Current section
Files
lib/raxol/terminal/cursor/style.ex
defmodule Raxol.Terminal.Cursor.Style do
@moduledoc """
Handles cursor style and visibility control for the terminal emulator.
This module provides functions for changing cursor appearance, controlling
visibility, and managing cursor blinking.
"""
@behaviour Raxol.Terminal.Cursor.Style
# Define the behavior for cursor style operations
@callback set_block(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback set_underline(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback set_bar(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback set_custom(
cursor :: Raxol.Terminal.Cursor.Manager.t(),
shape :: term(),
dimensions :: term()
) :: Raxol.Terminal.Cursor.Manager.t()
@callback show(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback hide(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback toggle_visibility(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback toggle_blink(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback set_blink_rate(
cursor :: Raxol.Terminal.Cursor.Manager.t(),
rate :: integer()
) :: Raxol.Terminal.Cursor.Manager.t()
@callback update_blink(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
{Raxol.Terminal.Cursor.Manager.t(), boolean()}
@callback get_state(cursor :: Raxol.Terminal.Cursor.Manager.t()) :: atom()
@callback get_blink(cursor :: Raxol.Terminal.Cursor.Manager.t()) :: boolean()
@callback blink(cursor :: Raxol.Terminal.Cursor.Manager.t()) ::
Raxol.Terminal.Cursor.Manager.t()
@callback get_style(cursor :: Raxol.Terminal.Cursor.Manager.t()) :: atom()
alias Raxol.Terminal.Cursor.Manager
@impl Raxol.Terminal.Cursor.Style
@doc """
Sets the cursor style to block.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.set_block(cursor)
iex> cursor.style
:block
"""
def set_block(%Manager{} = cursor) do
%{cursor | style: :block}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Sets the cursor style to underline.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.set_underline(cursor)
iex> cursor.style
:underline
"""
def set_underline(%Manager{} = cursor) do
%{cursor | style: :underline}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Sets the cursor style to bar.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.set_bar(cursor)
iex> cursor.style
:bar
"""
def set_bar(%Manager{} = cursor) do
%{cursor | style: :bar}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Sets a custom cursor shape.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.set_custom(cursor, "█", {2, 1})
iex> cursor.style
:custom
iex> cursor.custom_shape
"█"
"""
def set_custom(%Manager{} = cursor, shape, dimensions) do
%{
cursor
| style: :custom,
custom_shape: shape,
custom_dimensions: dimensions
}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Makes the cursor visible.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Manager.set_state(cursor, :hidden)
iex> cursor = Style.show(cursor)
iex> cursor.state
:visible
"""
def show(%Manager{} = cursor) do
%{cursor | visible: true, state: :visible}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Hides the cursor.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.hide(cursor)
iex> cursor.state
:hidden
"""
def hide(%Manager{} = cursor) do
%{cursor | visible: false, state: :hidden}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Makes the cursor blink.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.blink(cursor)
iex> cursor.state
:blinking
"""
def blink(%Manager{} = cursor) do
%{cursor | blinking: true, blink: true, state: :blinking}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Sets the cursor blink rate in milliseconds.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.set_blink_rate(cursor, 1000)
iex> cursor.blink_rate
1000
"""
def set_blink_rate(%Manager{} = cursor, rate)
when is_integer(rate) and rate > 0 do
%{cursor | blink_rate: rate}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Updates the cursor blink state and returns the updated cursor and visibility.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.blink(cursor)
iex> {_cursor, visible} = Style.update_blink(cursor)
iex> is_boolean(visible)
true
"""
def update_blink(%Manager{} = cursor) do
new_blink_state = !cursor.blink
new_cursor = %{cursor | blink: new_blink_state}
{new_cursor, new_blink_state}
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Toggles the cursor visibility.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.toggle_visibility(cursor)
iex> cursor.state
:hidden
iex> cursor = Style.toggle_visibility(cursor)
iex> cursor.state
:visible
"""
def toggle_visibility(%Manager{} = cursor) do
case cursor.state do
:visible -> hide(cursor)
:hidden -> show(cursor)
:blinking -> hide(cursor)
end
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Toggles the cursor blinking state.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> cursor = Style.toggle_blink(cursor)
iex> cursor.state
:blinking
iex> cursor = Style.toggle_blink(cursor)
iex> cursor.state
:visible
"""
def toggle_blink(%Manager{} = cursor) do
case cursor.state do
:blinking -> show(cursor)
_ -> blink(cursor)
end
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Gets the current cursor style.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> Style.get_style(cursor)
:block
"""
def get_style(%Manager{} = cursor) do
cursor.style
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Gets the current cursor state.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> Style.get_state(cursor)
:visible
"""
def get_state(%Manager{} = cursor) do
cursor.state
end
@impl Raxol.Terminal.Cursor.Style
@doc """
Gets the current cursor blink mode.
## Examples
iex> alias Raxol.Terminal.Cursor.{Manager, Style}
iex> cursor = Manager.new()
iex> Style.get_blink(cursor)
true
"""
def get_blink(%Manager{} = cursor) do
cursor.blink
end
end