-module(etch@erlang@input). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/etch/erlang/input.gleam"). -export([poll/1, read/0, input_loop/1, get_keyboard_enhancement_flags/0, get_cursor_position/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. -file("src/etch/erlang/input.gleam", 14). ?DOC( " Checks if there is an [`Event`](https://hexdocs.pm/etch/etch/event.html#Event) available.\n" " Returns None if no events were received within the timeout.\n" " See also [`read`](input.html#read).\n" ). -spec poll(integer()) -> gleam@option:option({ok, etch@event:event()} | {error, etch@event:event_error()}). poll(Timeout) -> input_ffi:poll(Timeout). -file("src/etch/erlang/input.gleam", 20). ?DOC( " Checks if there is an [`Event`](https://hexdocs.pm/etch/etch/event.html#Event) available.\n" " Waits forever for an available event.\n" " See also [`poll`](input.html#poll).\n" ). -spec read() -> gleam@option:option({ok, etch@event:event()} | {error, etch@event:event_error()}). read() -> input_ffi:read(). -file("src/etch/erlang/input.gleam", 43). -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/input.gleam", 32). ?DOC(false). -spec input_loop(boolean()) -> any(). input_loop(Is_raw_mode) -> Str = case 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(Is_raw_mode). -file("src/etch/erlang/input.gleam", 57). ?DOC( " Get keyboard enhancement flags. See \n" " This function shouldn't be called in a tight loop. It's fine to call it when\n" " responding to specific user input (e.g., after a key press), but avoid calling\n" " it on every loop iteration.\n" ). -spec get_keyboard_enhancement_flags() -> {ok, list(etch@event:keyboard_enhancement_flag())} | {error, etch@event:event_error()}. get_keyboard_enhancement_flags() -> gleam_stdlib:print(<<"\x{001b}["/utf8, "?u"/utf8>>), Flags = io:get_chars(<<""/utf8>>, 32), case Flags of <<"\x{001b}[?"/utf8, S/binary>> -> case gleam@string:last(S) of {ok, <<"u"/utf8>>} -> {ok, etch@event:parse_keyboard_enhancement_flags(S)}; _ -> {error, {failed_to_parse_event, <<"Could not get enhancment flags"/utf8>>}} end; _ -> {error, {failed_to_parse_event, <<"Could not get cursor position"/utf8>>}} end. -file("src/etch/erlang/input.gleam", 78). ?DOC( " Returns cursor position.\n" " This function shouldn't be called in a tight loop. It's fine to call it when\n" " responding to specific user input (e.g., after a key press), but avoid calling\n" " it on every loop iteration.\n" ). -spec get_cursor_position() -> {ok, {integer(), integer()}} | {error, etch@event:event_error()}. get_cursor_position() -> gleam_stdlib:print(<<"\x{001b}["/utf8, "6n"/utf8>>), Pos = io:get_chars(<<""/utf8>>, 32), case Pos of <<"\x{001b}["/utf8, S/binary>> -> case gleam@string:last(S) of {ok, <<"R"/utf8>>} -> etch@event:parse_cursor_position(S); _ -> {error, {failed_to_parse_event, <<"Could not get cursor position"/utf8>>}} end; _ -> {error, {failed_to_parse_event, <<"Could not get cursor position"/utf8>>}} end.