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/commands/csi_handler/mode_processor.ex
defmodule Raxol.Terminal.Commands.CSIHandler.ModeProcessor do
@moduledoc false
alias Raxol.Terminal.Commands.CursorUtils
alias Raxol.Terminal.ModeManager
def handle_h_or_l(emulator, params, intermediates, final_byte) do
is_set = final_byte == ?h
is_private = intermediates == "?"
result =
Enum.reduce(params, emulator, fn param, acc ->
mode_value =
if is_integer(param), do: param, else: String.to_integer(param)
if is_private do
handle_private_mode(acc, mode_value, is_set)
else
handle_standard_mode(acc, mode_value, is_set)
end
end)
result
end
defp handle_private_mode(emulator, mode, is_set) do
mode_name = private_mode_name(mode)
if mode_name do
category = private_mode_category(mode)
updated_emulator =
apply_mode_change(emulator, mode_name, category, is_set)
apply_screen_buffer_switch(updated_emulator, mode_name, is_set)
else
emulator
end
end
defp private_mode_name(mode) do
case mode do
1 -> :decckm
3 -> :deccolm_132
5 -> :decscnm
6 -> :decom
7 -> :decawm
8 -> :decarm
9 -> :decinlm
12 -> :decsrm
25 -> :dectcem
47 -> :dec_alt_screen
1000 -> :mouse_report_x10
1002 -> :mouse_report_cell_motion
1003 -> :mouse_any_event
1004 -> :focus_events
1047 -> :dec_alt_screen_save
1048 -> :decsc_deccara
1049 -> :alt_screen_buffer
2004 -> :bracketed_paste
_ -> nil
end
end
defp private_mode_category(mode) do
case mode do
47 -> :screen_buffer
1047 -> :screen_buffer
1048 -> :screen_buffer
1049 -> :screen_buffer
_ -> :dec_private
end
end
defp apply_screen_buffer_switch(emulator, mode_name, is_set) do
case {mode_name, is_set} do
{:dec_alt_screen, true} ->
%{emulator | active_buffer_type: :alternate}
{:dec_alt_screen, false} ->
%{emulator | active_buffer_type: :main}
{:dec_alt_screen_save, true} ->
%{emulator | active_buffer_type: :alternate}
{:dec_alt_screen_save, false} ->
%{emulator | active_buffer_type: :main}
{:alt_screen_buffer, true} ->
emulator = save_cursor_position(emulator)
%{emulator | active_buffer_type: :alternate}
{:alt_screen_buffer, false} ->
emulator = %{emulator | active_buffer_type: :main}
restore_cursor_position(emulator)
_ ->
emulator
end
end
defp handle_standard_mode(emulator, mode, is_set) do
mode_name =
case mode do
4 -> :irm
12 -> :srm
20 -> :lnm
_ -> nil
end
if mode_name do
apply_mode_change(emulator, mode_name, :standard, is_set)
else
emulator
end
end
defp apply_mode_change(emulator, mode_name, category, is_set) do
if is_set do
case ModeManager.set_mode(emulator, [mode_name], category) do
{:ok, emu} -> emu
_ -> emulator
end
else
case ModeManager.reset_mode(emulator, [mode_name], category) do
{:ok, emu} -> emu
_ -> emulator
end
end
end
defp save_cursor_position(emulator),
do: CursorUtils.save_cursor_position(emulator)
defp restore_cursor_position(emulator),
do: CursorUtils.restore_cursor_position(emulator)
end