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 screen screen_manager.ex
Raw

lib/raxol/terminal/screen/screen_manager.ex

defmodule Raxol.Terminal.ScreenManager do
@moduledoc """
Manages screen buffer operations for the terminal emulator.
This module handles operations related to the main and alternate screen buffers,
including buffer switching, initialization, and state management.
"""
@default_scrollback Raxol.Core.Defaults.scrollback_limit()
alias Raxol.Terminal.ScreenBuffer
alias Raxol.Terminal.ScreenBuffer.Manager
@doc """
Gets the currently active screen buffer.
"""
def get_screen_buffer(%{active_buffer_type: :main} = emulator) do
emulator.main_screen_buffer
end
def get_screen_buffer(%{active_buffer_type: :alternate} = emulator) do
emulator.alternate_screen_buffer
end
@doc """
Updates the currently active screen buffer.
"""
def update_active_buffer(%{active_buffer_type: :main} = emulator, new_buffer) do
%{emulator | main_screen_buffer: new_buffer}
end
def update_active_buffer(
%{active_buffer_type: :alternate} = emulator,
new_buffer
) do
%{emulator | alternate_screen_buffer: new_buffer}
end
@doc """
Switches between main and alternate screen buffers.
"""
def switch_buffer(emulator) do
new_type =
case emulator.active_buffer_type do
:main -> :alternate
:alternate -> :main
_ -> :main
end
%{emulator | active_buffer_type: new_type}
end
@doc """
Initializes both main and alternate screen buffers.
"""
def initialize_buffers(width, height, scrollback_limit) do
Manager.initialize_buffers(width, height, scrollback_limit)
end
@doc """
Initializes both main and alternate screen buffers with default scrollback limit.
"""
def initialize_buffers(width, height) do
initialize_buffers(width, height, @default_scrollback)
end
@doc """
Resizes both screen buffers.
"""
def resize_buffers(emulator, new_width, new_height) do
new_main_buffer =
ScreenBuffer.resize(emulator.main_screen_buffer, new_width, new_height)
new_alt_buffer =
ScreenBuffer.resize(
emulator.alternate_screen_buffer,
new_width,
new_height
)
%{
emulator
| main_screen_buffer: new_main_buffer,
alternate_screen_buffer: new_alt_buffer,
width: new_width,
height: new_height
}
end
@doc """
Gets the current buffer type (main or alternate).
"""
def get_buffer_type(emulator) do
emulator.active_buffer_type
end
@doc """
Sets the buffer type.
"""
def set_buffer_type(emulator, type) when type in [:main, :alternate] do
%{emulator | active_buffer_type: type}
end
@doc """
Gets the scroll region from the active buffer.
"""
def get_scroll_region(buffer) do
ScreenBuffer.get_scroll_region(buffer)
end
@doc """
Sets the scroll region on the buffer.
"""
def set_scroll_region(buffer, {top, bottom}) do
ScreenBuffer.set_scroll_region(buffer, {top, bottom})
end
@doc """
Gets the scroll top from the active buffer.
"""
def get_scroll_top(buffer) do
ScreenBuffer.get_scroll_top(buffer)
end
@doc """
Gets the scroll bottom from the active buffer.
"""
def get_scroll_bottom(buffer) do
ScreenBuffer.get_scroll_bottom(buffer)
end
# Selection-related functions
@doc """
Gets the current selection from the buffer.
"""
def get_selection(buffer) do
ScreenBuffer.get_selection(buffer)
end
@doc """
Gets the selected text from the buffer.
"""
def get_selected_text(buffer) do
ScreenBuffer.get_selected_text(buffer)
end
@doc """
Gets the selection start coordinates.
"""
def get_selection_start(buffer) do
ScreenBuffer.get_selection_start(buffer)
end
@doc """
Gets the selection end coordinates.
"""
def get_selection_end(buffer) do
ScreenBuffer.get_selection_end(buffer)
end
@doc """
Gets the selection boundaries as {start, end} tuple.
"""
def get_selection_boundaries(buffer) do
ScreenBuffer.get_selection_boundaries(buffer)
end
@doc """
Starts a selection at the specified position.
"""
def start_selection(buffer, x, y) do
ScreenBuffer.start_selection(buffer, x, y)
end
@doc """
Updates the selection end position.
"""
def update_selection(buffer, x, y) do
ScreenBuffer.update_selection(buffer, x, y)
end
@doc """
Clears the current selection.
"""
def clear_selection(buffer) do
ScreenBuffer.clear_selection(buffer)
end
@doc """
Checks if a selection is currently active.
"""
def selection_active?(buffer) do
ScreenBuffer.selection_active?(buffer)
end
@doc """
Checks if a position is within the current selection.
"""
def in_selection?(buffer, x, y) do
ScreenBuffer.in_selection?(buffer, x, y)
end
@doc """
Writes a string to the buffer at the given position with the given style.
"""
def write_string(buffer, x, y, string, style) do
Raxol.Terminal.ScreenBuffer.write_string(buffer, x, y, string, style)
end
@doc """
Parses scrollback limit from options, defaulting to 1000.
"""
def parse_scrollback_limit(opts) do
Keyword.get(opts, :scrollback_limit, @default_scrollback)
end
# === Additional ScreenManager Functions ===
@doc """
Gets the style at a specific position.
"""
def get_style_at(buffer, x, y) do
case ScreenBuffer.get_cell(buffer, x, y) do
%{style: style} when not is_nil(style) -> style
_ -> %{}
end
end
@doc """
Gets the style at the cursor position.
"""
def get_style_at_cursor(buffer) do
{x, y} = buffer.cursor_position
get_style_at(buffer, x, y)
end
@doc """
Gets the current state of the buffer.
"""
def get_state(buffer) do
%{
width: buffer.width,
height: buffer.height,
cursor_position: buffer.cursor_position,
scroll_region: buffer.scroll_region,
selection: buffer.selection
}
end
@doc """
Gets the current style of the buffer.
"""
def get_style(buffer) do
buffer.default_style || %{}
end
end