diff options
Diffstat (limited to 'TUI')
| -rw-r--r-- | TUI/module.jai | 269 |
1 files changed, 232 insertions, 37 deletions
diff --git a/TUI/module.jai b/TUI/module.jai index 37c0f31..95ab8dc 100644 --- a/TUI/module.jai +++ b/TUI/module.jai @@ -50,18 +50,17 @@ Commands :: struct { TextMode :: "\e(B"; ClearScreen :: "\e[2J"; ClearLine :: "\e[2K"; + ClearScrollBack :: "\e[3J"; Bell :: "\x07"; - SetWindowTitle :: "\e]0;%\x07"; + SetWindowTitle :: "\e]0;%\e\\"; RefreshWindow :: "\e[7t"; // TODO Not yet tested. SetUTF8 :: "\e%G"; // TODO TEST ME PLEASE - // WIP WIP WIP - // Add commands to change StyleNormal/Italic/Bold/Color/WhatNot! - + SetGraphicsRendition :: "\e[%m"; // Cursor Position SetCursorPosition :: "\e[%;%H"; @@ -93,18 +92,44 @@ Commands :: struct { QueryCursorPosition :: "\e[6n"; // Emits the cursor position as: "ESC [ <r> ; <c> R" Where <r> = row and <c> = column. QueryDeviceAttributes :: "\e[0c"; QueryWindowSizeInChars :: "\e[18t"; // Emits the window size as: "ESC [ 8 <r> ; <c> t" Where <r> = row and <c> = column. TODO Does not work on windows. - } -GraphicsStyle :: struct { - BackgroundColor : u8; - ForegroundColor : u8; - Bold : bool; - Italic : bool; - Underline : bool; - Blinking : bool; - Inverse : bool; - StrikeThrough : bool; +clear_style :: () { + write_string(#run sprint(Commands.SetGraphicsRendition, "0")); +} + +Colors8b :: struct { + Black :: 0; + Maroon :: 1; + Green :: 2; + Olive :: 3; + Navy :: 4; + Purple :: 5; + Teal :: 6; + Silver :: 7; + Gray :: 8; + Red :: 9; + Lime :: 10; + Yellow :: 11; + Blue :: 12; + Magenta :: 13; + Cyan :: 14; + White :: 15; +} + +// TODO Maybe rename. +set_style_colors :: (foreground: u8, background: u8) { + print( + #run sprint(Commands.SetGraphicsRendition, "38;5;%;48;5;%"), + foreground, background); +} + +// set_colors_24b :: (foreground_r: u255) // TODO https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + +set_style :: (bold: bool, underline: bool = false, strike_through: bool = false, negative: bool = false) { + print( + #run sprint(Commands.SetGraphicsRendition, "%;%;%;%"), + ifx bold then 1 else 22, ifx underline then 4 else 24, ifx strike_through then 9 else 29, ifx negative then 7 else 27); } // TODO Maybe make the OS_* procedures as inline?! @@ -124,18 +149,187 @@ Key :: u64; KEY_SIZE :: #run type_info(Key).runtime_size; -Keys :: struct { +Keys :: struct #type_info_none { // Terminal key-codes have 1 to 6 bytes, so we can signal special cases setting the edge-bytes. - None : Key : 0xF0000000_0000000F; - Resize : Key : 0xF0000000_0000001F; + None : Key : 0xF0000000_0000000F; + Resize : Key : 0xF0000000_0000001F; - Up : Key : #run to_key("\e[A"); - Down : Key : #run to_key("\e[B"); - Right : Key : #run to_key("\e[C"); - Left : Key : #run to_key("\e[D"); - - PgUp : Key : #run to_key("\e[5~"); - PgDown : Key : #run to_key("\e[6~"); + Space : Key : #char " "; + Enter : Key : #char "\r"; + Tab : Key : #char "\t"; + + Up : Key : #run to_key("\e[A"); + Down : Key : #run to_key("\e[B"); + Right : Key : #run to_key("\e[C"); + Left : Key : #run to_key("\e[D"); + + MetaUp : Key : #run to_key("\e[1;1A"); + MetaDown : Key : #run to_key("\e[1;1B"); + MetaRight : Key : #run to_key("\e[1;1C"); + MetaLeft : Key : #run to_key("\e[1;1D"); + + ShiftUp : Key : #run to_key("\e[1;2A"); + ShiftDown : Key : #run to_key("\e[1;2B"); + ShiftRight : Key : #run to_key("\e[1;2C"); + ShiftLeft : Key : #run to_key("\e[1;2D"); + + AltUp : Key : #run to_key("\e[1;3A"); + AltDown : Key : #run to_key("\e[1;3B"); + AltRight : Key : #run to_key("\e[1;3C"); + AltLeft : Key : #run to_key("\e[1;3D"); + + AltShiftUp : Key : #run to_key("\e[1;4A"); + AltShiftDown : Key : #run to_key("\e[1;4B"); + AltShiftRight : Key : #run to_key("\e[1;4C"); + AltShiftLeft : Key : #run to_key("\e[1;4D"); + + CtrlUp : Key : #run to_key("\e[1;5A"); + CtrlDown : Key : #run to_key("\e[1;5B"); + CtrlRight : Key : #run to_key("\e[1;5C"); + CtrlLeft : Key : #run to_key("\e[1;5D"); + + CtrlShiftUp : Key : #run to_key("\e[1;6A"); + CtrlShiftDown : Key : #run to_key("\e[1;6B"); + CtrlShiftRight : Key : #run to_key("\e[1;6C"); + CtrlShiftLeft : Key : #run to_key("\e[1;6D"); + + CtrlAltUp : Key : #run to_key("\e[1;7A"); + CtrlAltDown : Key : #run to_key("\e[1;7B"); + CtrlAltRight : Key : #run to_key("\e[1;7C"); + CtrlAltLeft : Key : #run to_key("\e[1;7D"); + + CtrlAltShiftUp : Key : #run to_key("\e[1;7A"); + CtrlAltShiftDown : Key : #run to_key("\e[1;7B"); + CtrlAltShiftRight : Key : #run to_key("\e[1;7C"); + CtrlAltShiftLeft : Key : #run to_key("\e[1;7D"); + + Home : Key : #run to_key("\e[H"); + End : Key : #run to_key("\e[F"); + + Escape : Key : 0x00000000_0000001B; + Backspace : Key : 0x00000000_0000007F; + Pause : Key : 0x00000000_0000001A; + Insert : Key : #run to_key("\e[2~"); + Delete : Key : #run to_key("\e[3~"); + PgUp : Key : #run to_key("\e[5~"); + PgDown : Key : #run to_key("\e[6~"); + + F1 : Key : #run to_key("\eOP"); + F2 : Key : #run to_key("\eOQ"); + F3 : Key : #run to_key("\eOR"); + F4 : Key : #run to_key("\eOS"); + F5 : Key : #run to_key("\e[15~"); + F6 : Key : #run to_key("\e[17~"); + F7 : Key : #run to_key("\e[18~"); + F8 : Key : #run to_key("\e[19~"); + F9 : Key : #run to_key("\e[20~"); + F10 : Key : #run to_key("\e[21~"); + F11 : Key : #run to_key("\e[23~"); + F12 : Key : #run to_key("\e[24~"); + + MetaF1 : Key : #run to_key("\eO1P"); + MetaF2 : Key : #run to_key("\eO1Q"); + MetaF3 : Key : #run to_key("\eO1R"); + MetaF4 : Key : #run to_key("\eO1S"); + MetaF5 : Key : #run to_key("\e[15;1~"); + MetaF6 : Key : #run to_key("\e[17;1~"); + MetaF7 : Key : #run to_key("\e[18;1~"); + MetaF8 : Key : #run to_key("\e[19;1~"); + MetaF9 : Key : #run to_key("\e[20;1~"); + MetaF10 : Key : #run to_key("\e[21;1~"); + MetaF11 : Key : #run to_key("\e[23;1~"); + MetaF12 : Key : #run to_key("\e[24;1~"); + + ShiftF1 : Key : #run to_key("\eO2P"); + ShiftF2 : Key : #run to_key("\eO2Q"); + ShiftF3 : Key : #run to_key("\eO2R"); + ShiftF4 : Key : #run to_key("\eO2S"); + ShiftF5 : Key : #run to_key("\e[15;2~"); + ShiftF6 : Key : #run to_key("\e[17;2~"); + ShiftF7 : Key : #run to_key("\e[18;2~"); + ShiftF8 : Key : #run to_key("\e[19;2~"); + ShiftF9 : Key : #run to_key("\e[20;2~"); + ShiftF10 : Key : #run to_key("\e[21;2~"); + ShiftF11 : Key : #run to_key("\e[23;2~"); + ShiftF12 : Key : #run to_key("\e[24;2~"); + + AltF1 : Key : #run to_key("\eO3P"); + AltF2 : Key : #run to_key("\eO3Q"); + AltF3 : Key : #run to_key("\eO3R"); + AltF4 : Key : #run to_key("\eO3S"); + AltF5 : Key : #run to_key("\e[15;3~"); + AltF6 : Key : #run to_key("\e[17;3~"); + AltF7 : Key : #run to_key("\e[18;3~"); + AltF8 : Key : #run to_key("\e[19;3~"); + AltF9 : Key : #run to_key("\e[20;3~"); + AltF10 : Key : #run to_key("\e[21;3~"); + AltF11 : Key : #run to_key("\e[23;3~"); + AltF12 : Key : #run to_key("\e[24;3~"); + + AltShiftF1 : Key : #run to_key("\eO4P"); + AltShiftF2 : Key : #run to_key("\eO4Q"); + AltShiftF3 : Key : #run to_key("\eO4R"); + AltShiftF4 : Key : #run to_key("\eO4S"); + AltShiftF5 : Key : #run to_key("\e[15;4~"); + AltShiftF6 : Key : #run to_key("\e[17;4~"); + AltShiftF7 : Key : #run to_key("\e[18;4~"); + AltShiftF8 : Key : #run to_key("\e[19;4~"); + AltShiftF9 : Key : #run to_key("\e[20;4~"); + AltShiftF10 : Key : #run to_key("\e[21;4~"); + AltShiftF11 : Key : #run to_key("\e[23;4~"); + AltShiftF12 : Key : #run to_key("\e[24;4~"); + + CtrlF1 : Key : #run to_key("\eO5P"); + CtrlF2 : Key : #run to_key("\eO5Q"); + CtrlF3 : Key : #run to_key("\eO5R"); + CtrlF4 : Key : #run to_key("\eO5S"); + CtrlF5 : Key : #run to_key("\e[15;5~"); + CtrlF6 : Key : #run to_key("\e[17;5~"); + CtrlF7 : Key : #run to_key("\e[18;5~"); + CtrlF8 : Key : #run to_key("\e[19;5~"); + CtrlF9 : Key : #run to_key("\e[20;5~"); + CtrlF10 : Key : #run to_key("\e[21;5~"); + CtrlF11 : Key : #run to_key("\e[23;5~"); + CtrlF12 : Key : #run to_key("\e[24;5~"); + + CtrlShiftF1 : Key : #run to_key("\eO6P"); + CtrlShiftF2 : Key : #run to_key("\eO6Q"); + CtrlShiftF3 : Key : #run to_key("\eO6R"); + CtrlShiftF4 : Key : #run to_key("\eO6S"); + CtrlShiftF5 : Key : #run to_key("\e[15;6~"); + CtrlShiftF6 : Key : #run to_key("\e[17;6~"); + CtrlShiftF7 : Key : #run to_key("\e[18;6~"); + CtrlShiftF8 : Key : #run to_key("\e[19;6~"); + CtrlShiftF9 : Key : #run to_key("\e[20;6~"); + CtrlShiftF10 : Key : #run to_key("\e[21;6~"); + CtrlShiftF11 : Key : #run to_key("\e[23;6~"); + CtrlShiftF12 : Key : #run to_key("\e[24;6~"); + + CtrlAltF1 : Key : #run to_key("\eO7P"); + CtrlAltF2 : Key : #run to_key("\eO7Q"); + CtrlAltF3 : Key : #run to_key("\eO7R"); + CtrlAltF4 : Key : #run to_key("\eO7S"); + CtrlAltF5 : Key : #run to_key("\e[15;7~"); + CtrlAltF6 : Key : #run to_key("\e[17;7~"); + CtrlAltF7 : Key : #run to_key("\e[18;7~"); + CtrlAltF8 : Key : #run to_key("\e[19;7~"); + CtrlAltF9 : Key : #run to_key("\e[20;7~"); + CtrlAltF10 : Key : #run to_key("\e[21;7~"); + CtrlAltF11 : Key : #run to_key("\e[23;7~"); + CtrlAltF12 : Key : #run to_key("\e[24;7~"); + + CtrlAltShiftF1 : Key : #run to_key("\eO8P"); + CtrlAltShiftF2 : Key : #run to_key("\eO8Q"); + CtrlAltShiftF3 : Key : #run to_key("\eO8R"); + CtrlAltShiftF4 : Key : #run to_key("\eO8S"); + CtrlAltShiftF5 : Key : #run to_key("\e[15;8~"); + CtrlAltShiftF6 : Key : #run to_key("\e[17;8~"); + CtrlAltShiftF7 : Key : #run to_key("\e[18;8~"); + CtrlAltShiftF8 : Key : #run to_key("\e[19;8~"); + CtrlAltShiftF9 : Key : #run to_key("\e[20;8~"); + CtrlAltShiftF10 : Key : #run to_key("\e[21;8~"); + CtrlAltShiftF11 : Key : #run to_key("\e[23;8~"); + CtrlAltShiftF12 : Key : #run to_key("\e[24;8~"); } to_key :: inline (str: $T) -> Key #modify { return T == ([]u8) || T == string; } { @@ -160,6 +354,7 @@ to_string :: inline (key: Key) -> string { return str; } +// TODO FIXME DEBUG HACK test_union :: () { // ti := type_info(K); @@ -209,8 +404,9 @@ input_string : string; input_override : Key; #run { + // TODO FIXME DEBUG HACK or maybe... let it be?! // Some tests. - assert(input_buffer.count >= 6, "The input buffer size must be capable to hold an entire terminal (6 bytes) or UTF8 (4 bytes) code."); + assert(input_buffer.count >= KEY_SIZE, "The input buffer size must be capable to hold an entire terminal (6 bytes) or UTF8 (4 bytes) code."); } assert_is_initialized :: inline () { @@ -314,7 +510,8 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key { // Must be a terminal escape sequence. if utf8_bytes == 1 && input_string[0] == #char "\e" { - to_parse.count = ifx input_string.count > 6 then 6 else input_string.count; // TODO We should look into the input_string and search for the following escape sequence or somehting!? + assert(input_string.count <= KEY_SIZE, "Received oversized terminal sequence."); // TODO + to_parse.count = ifx input_string.count > KEY_SIZE then KEY_SIZE else input_string.count; // TODO We should look into the input_string and search for the following escape sequence or somehting!? } key := to_key(to_parse); @@ -345,13 +542,11 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key { return xx Keys.None; } -get_str :: (count_limit: int = -1, allocator: Allocator = temp) -> string { +get_str :: (count_limit: int = -1) -> string { assert_is_initialized(); - assert(allocator.proc != null, "Argument 'allocator.proc' has invalid null value."); if count_limit < 0 { - builder: String_Builder(); - builder.allocator = allocator; + builder: String_Builder; init_string_builder(*builder); while(1) { @@ -361,10 +556,10 @@ get_str :: (count_limit: int = -1, allocator: Allocator = temp) -> string { if buffer.count < buffer.allocated break; expand(*builder); } - return builder_to_string(*builder, allocator); + return builder_to_string(*builder); } else { - buffer := alloc_string(count_limit, allocator); + buffer := alloc_string(count_limit); buffer.count = OS_read_input(buffer.data, count_limit); return buffer; } @@ -395,7 +590,7 @@ flush_input :: () { OS_flush_input(); } -// WIP WIP WIP +// TODO move style related procedures here! // set_style :: () { // print("", Commands.) -- // } @@ -463,7 +658,7 @@ get_terminal_size :: () -> rows: int, columns: int { flush_input(); write_string(Commands.QueryWindowSizeInChars); - input := get_str(64); + input := get_str(64,, temporary_allocator); // Expected response format: \e[8;<r>;<c>t // where <r> is the number of rows and <c> of columns. @@ -483,7 +678,7 @@ get_terminal_size :: () -> rows: int, columns: int { input[0] == FORMAT[0] && input[1] == FORMAT[1] && input[2] == FORMAT[2] && input[input.count-1] == FORMAT[FORMAT.count-1], "Query window size in chars returned invalid response."); - parts := split(input, ";"); + parts := split(input, ";",, temporary_allocator); rows = parse_int(*parts[1]); columns = parse_int(*parts[2]); } @@ -504,7 +699,7 @@ get_cursor_position :: () -> row: int, column: int { flush_input(); write_string(Commands.QueryCursorPosition); - input := get_str(64); + input := get_str(64,, temporary_allocator); // Expected response format: \e[<r>;<c>R // where <r> is the number of rows and <c> of columns. @@ -526,7 +721,7 @@ get_cursor_position :: () -> row: int, column: int { advance(*input, 2); - parts := split(input, ";"); + parts := split(input, ";",, temporary_allocator); row := parse_int(*parts[0]); column := parse_int(*parts[1]); return row, column; |
