Skip to main content

src/etui@keys.erl

-module(etui@keys).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/etui/keys.gleam").
-export([match/1, is_char/1, char_value/1, is_navigation/1, is_modifier/1]).
-export_type([key/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 key() :: {char, binary()} |
    up |
    down |
    left |
    right |
    enter |
    backspace |
    delete |
    tab |
    back_tab |
    home |
    'end' |
    page_up |
    page_down |
    escape |
    insert |
    {f, integer()} |
    {ctrl, binary()} |
    {alt, binary()} |
    {unknown, binary()}.

-file("src/etui/keys.gleam", 69).
?DOC(
    " Parse a raw key string (from `backend.KeyPress`) into a `Key`.\n"
    "\n"
    " Raw strings from the Erlang backend follow these conventions:\n"
    " - Printable ASCII/Unicode: the character itself (e.g. `\"a\"`, `\"A\"`, `\"\"`)\n"
    " - Arrow keys: `\"up\"`, `\"down\"`, `\"left\"`, `\"right\"`\n"
    " - Control keys: `\"enter\"`, `\"backspace\"`, `\"delete\"`, `\"tab\"`, `\"backtab\"`,\n"
    "   `\"home\"`, `\"end\"`, `\"pageup\"`, `\"pagedown\"`, `\"esc\"`, `\"insert\"`\n"
    " - Function keys: `\"f1\"` … `\"f12\"`\n"
    " - Ctrl combos: `\"ctrl+a\"` … `\"ctrl+z\"`, `\"ctrl+[\"`, etc.\n"
    " - Alt combos:  `\"alt+a\"` … `\"alt+z\"`, etc.\n"
).
-spec match(binary()) -> key().
match(Raw) ->
    case Raw of
        <<"up"/utf8>> ->
            up;

        <<"down"/utf8>> ->
            down;

        <<"left"/utf8>> ->
            left;

        <<"right"/utf8>> ->
            right;

        <<"enter"/utf8>> ->
            enter;

        <<"backspace"/utf8>> ->
            backspace;

        <<"delete"/utf8>> ->
            delete;

        <<"tab"/utf8>> ->
            tab;

        <<"backtab"/utf8>> ->
            back_tab;

        <<"home"/utf8>> ->
            home;

        <<"end"/utf8>> ->
            'end';

        <<"pageup"/utf8>> ->
            page_up;

        <<"pagedown"/utf8>> ->
            page_down;

        <<"esc"/utf8>> ->
            escape;

        <<"insert"/utf8>> ->
            insert;

        <<"f1"/utf8>> ->
            {f, 1};

        <<"f2"/utf8>> ->
            {f, 2};

        <<"f3"/utf8>> ->
            {f, 3};

        <<"f4"/utf8>> ->
            {f, 4};

        <<"f5"/utf8>> ->
            {f, 5};

        <<"f6"/utf8>> ->
            {f, 6};

        <<"f7"/utf8>> ->
            {f, 7};

        <<"f8"/utf8>> ->
            {f, 8};

        <<"f9"/utf8>> ->
            {f, 9};

        <<"f10"/utf8>> ->
            {f, 10};

        <<"f11"/utf8>> ->
            {f, 11};

        <<"f12"/utf8>> ->
            {f, 12};

        _ ->
            case gleam_stdlib:string_starts_with(Raw, <<"ctrl+"/utf8>>) of
                true ->
                    {ctrl, gleam@string:drop_start(Raw, 5)};

                false ->
                    case gleam_stdlib:string_starts_with(Raw, <<"alt+"/utf8>>) of
                        true ->
                            {alt, gleam@string:drop_start(Raw, 4)};

                        false ->
                            case string:length(Raw) > 0 of
                                true ->
                                    {char, Raw};

                                false ->
                                    {unknown, Raw}
                            end
                    end
            end
    end.

-file("src/etui/keys.gleam", 118).
?DOC(" True if key is a printable character (not a control/special key).\n").
-spec is_char(key()) -> boolean().
is_char(K) ->
    case K of
        {char, _} ->
            true;

        _ ->
            false
    end.

-file("src/etui/keys.gleam", 126).
?DOC(" Extract the character string from a `Char` key. Returns `\"\"` for others.\n").
-spec char_value(key()) -> binary().
char_value(K) ->
    case K of
        {char, C} ->
            C;

        _ ->
            <<""/utf8>>
    end.

-file("src/etui/keys.gleam", 134).
?DOC(" True if the key is a navigation key (arrows, home, end, page up/down).\n").
-spec is_navigation(key()) -> boolean().
is_navigation(K) ->
    case K of
        up ->
            true;

        down ->
            true;

        left ->
            true;

        right ->
            true;

        home ->
            true;

        'end' ->
            true;

        page_up ->
            true;

        page_down ->
            true;

        _ ->
            false
    end.

-file("src/etui/keys.gleam", 142).
?DOC(" True if the key is a modifier combo (Ctrl or Alt).\n").
-spec is_modifier(key()) -> boolean().
is_modifier(K) ->
    case K of
        {ctrl, _} ->
            true;

        {alt, _} ->
            true;

        _ ->
            false
    end.