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/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