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
raxol_terminal lib raxol terminal integration integration_buffer.ex
Raw

lib/raxol/terminal/integration/integration_buffer.ex

defmodule Raxol.Terminal.Integration.Buffer do
@moduledoc """
Handles buffer and cursor management for the terminal.
"""
alias Raxol.Terminal.{
Buffer.Scroll,
Integration.State,
ScreenBuffer.Manager
}
alias Raxol.Terminal.Cursor.Manager, as: CursorManager
@doc """
Writes text to the terminal buffer.
"""
def write(%State{} = state, text) do
# Update the buffer manager with the new text
{:ok, buffer_manager} = Manager.write(state.buffer_manager, text)
# Update the cursor position - handle different cursor_manager types
cursor_manager =
case state.cursor_manager do
nil ->
nil
cursor when is_map(cursor) ->
# If it's a Cursor.Manager struct, use its update function
{x, y} = CursorManager.get_position(cursor)
CursorManager.set_position(cursor, {x + String.length(text), y})
cursor ->
# For other types, return as-is
cursor
end
# Update the state
State.update(state,
buffer_manager: buffer_manager,
cursor_manager: cursor_manager
)
end
@doc """
Clears the terminal buffer.
"""
def clear(%State{} = state) do
# Clear the buffer manager
buffer_manager = Manager.clear(state.buffer_manager)
# Reset the cursor position - handle different cursor_manager types
cursor_manager =
case state.cursor_manager do
nil ->
nil
cursor when is_map(cursor) ->
CursorManager.set_position(cursor, {0, 0})
cursor ->
cursor
end
# Update the state
State.update(state,
buffer_manager: buffer_manager,
cursor_manager: cursor_manager
)
end
@doc """
Scrolls the terminal buffer.
"""
def scroll(%State{} = state, direction, amount \\ 1) do
# Update the scroll buffer
scroll_buffer = Scroll.scroll(state.scroll_buffer, direction, amount)
# Update the buffer manager's visible region (expects non_neg_integer, not region)
# Scroll.get_visible_region always returns {offset, height}
{scroll_offset, _height} = Scroll.get_visible_region(scroll_buffer)
buffer_manager =
Manager.update_visible_region(
state.buffer_manager,
scroll_offset
)
# Update the state
State.update(state,
buffer_manager: buffer_manager,
scroll_buffer: scroll_buffer
)
end
@doc """
Moves the cursor to a specific position.
"""
def move_cursor(%State{} = state, x, y) do
# Update the cursor position - handle different cursor_manager types
cursor_manager =
case state.cursor_manager do
nil ->
nil
cursor when is_map(cursor) ->
CursorManager.set_position(cursor, {x, y})
cursor ->
cursor
end
# Update the state
State.update(state, cursor_manager: cursor_manager)
end
@doc """
Gets the current cursor position.
"""
def get_cursor_position(%State{} = state) do
case state.cursor_manager do
nil ->
{0, 0}
cursor when is_map(cursor) ->
CursorManager.get_position(cursor)
_cursor ->
{0, 0}
end
end
@doc """
Gets the current visible content.
"""
def get_visible_content(%State{} = state) do
Manager.get_visible_content(state.buffer_manager)
end
@doc """
Gets the current scroll position.
"""
def get_scroll_position(%State{} = state) do
Scroll.get_position(state.scroll_buffer)
end
@doc """
Gets the total number of lines in the buffer.
"""
def get_total_lines(%State{} = state) do
Manager.get_total_lines(state.buffer_manager)
end
@doc """
Gets the number of visible lines.
"""
def get_visible_lines(%State{} = state) do
Manager.get_visible_lines(state.buffer_manager)
end
@doc """
Resizes the terminal buffer.
"""
def resize(%State{} = state, width, height) do
# Resize the buffer manager
buffer_manager = Manager.resize(state.buffer_manager, width, height)
# Update the scroll buffer
scroll_buffer = Scroll.resize(state.scroll_buffer, height)
# Constrain cursor position to new dimensions
cursor_manager =
case state.cursor_manager do
nil ->
nil
cursor when is_map(cursor) ->
{x, y} = CursorManager.get_position(cursor)
# Constrain to new bounds
new_x = max(0, min(x, width - 1))
new_y = max(0, min(y, height - 1))
CursorManager.set_position(cursor, {new_x, new_y})
cursor ->
cursor
end
# Update the state
State.update(state,
buffer_manager: buffer_manager,
scroll_buffer: scroll_buffer,
cursor_manager: cursor_manager
)
end
end