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 buffer queries.ex
Raw

lib/raxol/terminal/buffer/queries.ex

defmodule Raxol.Terminal.Buffer.Queries do
@moduledoc """
Handles buffer state querying operations.
This module provides functions for querying the state of the screen buffer,
including dimensions, content, and selection state.
"""
alias Raxol.Terminal.Cell
alias Raxol.Terminal.ScreenBuffer
@doc """
Gets the dimensions of the buffer.
"""
@spec get_dimensions(ScreenBuffer.t()) ::
{non_neg_integer(), non_neg_integer()}
def get_dimensions(buffer) do
{buffer.width, buffer.height}
end
@doc """
Gets the width of the buffer.
"""
@spec get_width(ScreenBuffer.t()) :: non_neg_integer()
def get_width(buffer) do
buffer.width
end
@doc """
Gets the height of the buffer.
"""
@spec get_height(ScreenBuffer.t()) :: non_neg_integer()
def get_height(buffer) do
buffer.height
end
@doc """
Gets the content of the buffer as a list of lines.
"""
@spec get_content(ScreenBuffer.t()) :: list(list(Cell.t()))
def get_content(buffer) do
buffer.cells
end
@doc """
Gets a specific line from the buffer.
"""
@spec get_line(ScreenBuffer.t(), non_neg_integer()) :: list(Cell.t())
def get_line(buffer, y) when y >= 0 and y < buffer.height do
case buffer.cells do
nil ->
# Return empty list if cells is nil
[]
cells ->
Enum.at(cells, y)
end
end
def get_line(_, _), do: []
@doc """
Gets a specific cell from the buffer.
"""
@spec get_cell(ScreenBuffer.t(), non_neg_integer(), non_neg_integer()) ::
Cell.t()
def get_cell(buffer, x, y) when x >= 0 and y >= 0 do
case x < buffer.width and y < buffer.height do
true ->
case buffer.cells do
nil ->
# Return a default cell if cells is nil
Cell.new()
cells ->
cells
|> Enum.at(y)
|> Enum.at(x)
end
false ->
Cell.new()
end
end
def get_cell(_, _, _), do: Cell.new()
@doc """
Gets text at a specific position with a given length.
"""
@spec get_text_at(
ScreenBuffer.t(),
non_neg_integer(),
non_neg_integer(),
non_neg_integer()
) :: String.t()
def get_text_at(buffer, x, y, length)
when x >= 0 and y >= 0 and length >= 0 do
case y < buffer.height do
true ->
case buffer.cells do
nil ->
""
cells ->
line = Enum.at(cells, y, [])
line
|> Enum.slice(x, length)
|> Enum.map_join("", fn
nil -> " "
cell -> cell.char || " "
end)
end
false ->
""
end
end
@doc """
Checks if the buffer has scrollback content.
"""
@spec has_scrollback?(ScreenBuffer.t()) :: boolean()
def has_scrollback?(buffer) do
case Map.get(buffer, :scrollback_buffer) do
nil -> false
[] -> false
_ -> true
end
end
@doc """
Gets the text content of the buffer.
"""
@spec get_text(ScreenBuffer.t()) :: String.t()
def get_text(buffer) do
case buffer.cells do
nil ->
# Return empty string if cells is nil
""
cells ->
cells
|> Enum.map_join("\n", fn line ->
line
|> Enum.map_join("", &Cell.get_char/1)
end)
end
end
@doc """
Gets the text content of a specific line.
"""
@spec get_line_text(ScreenBuffer.t(), non_neg_integer()) :: String.t()
def get_line_text(buffer, y) when y >= 0 and y < buffer.height do
case buffer.cells do
nil ->
# Return empty string if cells is nil
""
cells ->
cells
|> Enum.at(y)
|> Enum.map_join("", &Cell.get_char/1)
end
end
def get_line_text(_, _), do: ""
@doc """
Checks if a position is within the buffer bounds.
"""
@spec in_bounds?(ScreenBuffer.t(), non_neg_integer(), non_neg_integer()) ::
boolean()
def in_bounds?(buffer, x, y) when x >= 0 and y >= 0 do
x < buffer.width and y < buffer.height
end
def in_bounds?(_, _, _), do: false
@doc """
Checks if the buffer is empty.
## Parameters
* `buffer` - The screen buffer to check
## Returns
A boolean indicating if the buffer is empty.
## Examples
iex> buffer = ScreenBuffer.new(80, 24)
iex> Queries.empty?(buffer)
true
"""
@spec empty?(ScreenBuffer.t()) :: boolean()
def empty?(buffer) do
case buffer.cells do
nil ->
# Return true if cells is nil (empty buffer)
true
cells ->
Enum.all?(cells, fn line ->
Enum.all?(line, &Cell.empty?/1)
end)
end
end
@doc """
Gets the character at the given position in the buffer.
"""
@spec get_char(map(), integer(), integer()) :: String.t()
def get_char(_buffer, _x, _y) do
" "
end
@doc """
Gets the cell at the specified position in the buffer.
## Parameters
* `buffer` - The screen buffer to query
* `x` - The x-coordinate (column)
* `y` - The y-coordinate (row)
## Returns
The cell at the specified position, or an empty cell if the position is out of bounds.
## Examples
iex> buffer = ScreenBuffer.new(80, 24)
iex> cell = Queries.get_cell_at(buffer, 0, 0)
iex> cell.char
""
"""
@spec get_cell_at(ScreenBuffer.t(), non_neg_integer(), non_neg_integer()) ::
Cell.t()
def get_cell_at(buffer, x, y) do
get_cell(buffer, x, y)
end
@doc """
Gets the character at the specified position in the buffer.
## Parameters
* `buffer` - The screen buffer to query
* `x` - The x-coordinate (column)
* `y` - The y-coordinate (row)
## Returns
The character at the specified position, or a space if the position is out of bounds.
## Examples
iex> buffer = ScreenBuffer.new(80, 24)
iex> Queries.get_char_at(buffer, 0, 0)
" "
"""
@spec get_char_at(ScreenBuffer.t(), non_neg_integer(), non_neg_integer()) ::
String.t()
def get_char_at(buffer, x, y) do
get_char(buffer, x, y)
end
end