-module(etch@erlang@tty). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/etch/erlang/tty.gleam"). -export([tty_state_init/0, is_raw_mode/0, window_size/0, start_input_loop/0, enter_raw/0, exit_raw/0]). -export_type([terminal_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type terminal_error() :: could_not_get_window_size | failed_to_enter_raw_mode | failed_to_exit_raw_mode. -file("src/etch/erlang/tty.gleam", 19). ?DOC(false). -spec tty_state_init() -> nil. tty_state_init() -> tty_state:init(). -file("src/etch/erlang/tty.gleam", 25). -spec is_raw_mode() -> boolean(). is_raw_mode() -> tty_state:is_raw_mode(). -file("src/etch/erlang/tty.gleam", 29). ?DOC(" Returns current window size.\n"). -spec window_size() -> {ok, {integer(), integer()}} | {error, terminal_error()}. window_size() -> terminal_ffi:window_size(). -file("src/etch/erlang/tty.gleam", 111). -spec push_events( list({ok, etch@event:event()} | {error, etch@event:event_error()}) ) -> nil. push_events(Events) -> case Events of [] -> nil; [E | Rest] -> input_ffi:push(E), push_events(Rest) end. -file("src/etch/erlang/tty.gleam", 100). -spec input_loop() -> any(). input_loop() -> Str = case tty_state:is_raw_mode() of true -> io:get_chars(<<""/utf8>>, 128); false -> io:get_line(<<""/utf8>>) end, Str@1 = gleam@string:to_graphemes(Str), Events = etch@event:parse_events(Str@1, <<""/utf8>>, [], false), push_events(Events), input_loop(). -file("src/etch/erlang/tty.gleam", 95). ?DOC(false). -spec start_input_loop() -> nil. start_input_loop() -> Input_loop_pid = proc_lib:spawn_link(fun() -> input_loop() end), tty_state:save_input_loop_pid(Input_loop_pid). -file("src/etch/erlang/tty.gleam", 41). ?DOC( " Enters raw mode.\n" "\n" " Raw mode is a mode where the terminal does not process input, but instead\n" " passes it directly to the application. This means that:\n" " - Input is not echoed to the screen\n" " - Input is not line-buffered (characters are available immediately)\n" " - Some special characters are not processed by the terminal\n" "\n" " This is necessary for terminal UI applications that need to handle\n" " keyboard input and mouse events directly.\n" ). -spec enter_raw() -> {ok, nil} | {error, terminal_error()}. enter_raw() -> tty_state:set_raw(true), case terminal_ffi:enter_raw() of {error, E} -> {error, E}; {ok, _} -> Input_loop_pid = tty_state:get_input_loop_pid(), case Input_loop_pid of {ok, Pid} -> gleam@erlang@process:send_exit(Pid), start_input_loop(), {ok, nil}; {error, _} -> {error, failed_to_enter_raw_mode} end end. -file("src/etch/erlang/tty.gleam", 66). ?DOC( " Exits raw mode.\n" "\n" " Raw mode is a mode where the terminal does not process input, but instead\n" " passes it directly to the application. This means that:\n" " - Input is not echoed to the screen\n" " - Input is not line-buffered (characters are available immediately)\n" " - Some special characters are not processed by the terminal\n" ). -spec exit_raw() -> {ok, nil} | {error, terminal_error()}. exit_raw() -> tty_state:set_raw(false), terminal_ffi:exit_raw().