Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol lib raxol terminal driver terminal_size.ex
Raw

lib/raxol/terminal/driver/terminal_size.ex

defmodule Raxol.Terminal.Driver.TerminalSize do
@moduledoc """
Terminal size detection: termbox, stty, and fallback strategies.
"""
# Suppressed: @termbox2_available is false at compile time in test env,
# making NIF branches unreachable for dialyzer analysis.
@dialyzer :no_match
alias Raxol.Terminal.IOTerminal
import Raxol.Terminal.TerminalUtils, only: [has_terminal_device?: 0]
@termbox2_available Code.ensure_loaded?(:termbox2_nif)
@doc """
Returns the current terminal size as {:ok, width, height}.
"""
def get_terminal_size do
determine_terminal_size()
end
defp determine_terminal_size do
case {Mix.env(), has_terminal_device?()} do
{:test, _} -> {:ok, 80, 24}
{_, true} -> get_termbox_size()
{_, false} -> stty_size_fallback()
end
end
defp get_termbox_size do
Raxol.Core.ErrorHandling.safe_call(fn ->
width = get_termbox_width()
height = get_termbox_height()
case width > 0 and height > 0 do
true -> {:ok, width, height}
false -> stty_size_fallback()
end
end)
|> case do
{:ok, result} -> result
{:error, _reason} -> stty_size_fallback()
end
end
@dialyzer {:nowarn_function, get_termbox_width: 0}
defp get_termbox_width do
if @termbox2_available do
:termbox2_nif.tb_width()
else
case IOTerminal.get_terminal_size() do
{:ok, {width, _height}} -> width
_ -> 80
end
end
end
@dialyzer {:nowarn_function, get_termbox_height: 0}
defp get_termbox_height do
if @termbox2_available do
:termbox2_nif.tb_height()
else
case IOTerminal.get_terminal_size() do
{:ok, {_width, height}} -> height
_ -> 24
end
end
end
defp stty_size_fallback do
case {:io.columns(), :io.rows()} do
{{:ok, cols}, {:ok, rows}} ->
{:ok, cols, rows}
_ ->
# In -noshell mode, :io.columns/rows fail. Use stty via /dev/tty.
case Raxol.Terminal.Driver.Stty.size() do
{:ok, cols, rows} -> {:ok, cols, rows}
:error -> {:ok, 80, 24}
end
end
end
end