#include "arena_alloc.h" #include "context.h" #include "gapbuffer.h" #include "interp.h" #include "mprintf.h" #include "self.h" #include "strbuf.h" #include #include #include #include #include #include #include #include #include #include #include #define LINE_INIT_MAX 2 #define PROMPT "$ " struct edit_line { struct gapbuffer gb; size_t cursor; }; static void exec_line (const char* line) { struct list_node_link* tokens = NULL; tokenize (&tokens, line); if (tokens != NULL) parse_and_execute (tokens); } void app_main (void) { e_pid = get_exec_pid (); e_pgid = get_procgroup (e_pid); struct edit_line edit_line; const char* render = NULL; while (interp_is_running ()) { gapbuffer_init (&edit_line.gb, LINE_INIT_MAX); edit_line.cursor = 0; mprintf (PROMPT); uint8_t ch = 0; for (;;) { mail_receive (&ch, 1); if (ch == '\n') break; switch (ch) { case '\b': if (edit_line.cursor > 0) { gapbuffer_backspace (&edit_line.gb); edit_line.cursor--; mprintf ("\b"); char* tail = gapbuffer_string_at (&edit_line.gb, edit_line.cursor); mprintf ("%s" ANSIQ_SCR_CLR2END, tail); int move_back = (int)strlen (tail); if (move_back > 0) mprintf (ANSIQ_DYN_CUR_LEFT, move_back); } break; case KB_LEFT: if (edit_line.cursor > 0) { edit_line.cursor--; mprintf (ANSIQ_CUR_LEFT (1)); } break; case KB_RIGHT: if (edit_line.cursor < gapbuffer_length (&edit_line.gb)) { edit_line.cursor++; mprintf (ANSIQ_CUR_RIGHT (1)); } break; default: if (isascii (ch)) { gapbuffer_insert (&edit_line.gb, ch); edit_line.cursor++; char* tail = gapbuffer_string_at (&edit_line.gb, edit_line.cursor - 1); mprintf ("%s" ANSIQ_SCR_CLR2LEND, tail); int move_back = (int)strlen (tail) - 1; if (move_back > 0) mprintf (ANSIQ_DYN_CUR_LEFT, move_back); } break; } gapbuffer_move (&edit_line.gb, edit_line.cursor); } mprintf ("\n"); render = gapbuffer_get_string (&edit_line.gb); if (render != NULL) exec_line (render); gapbuffer_fini (&edit_line.gb); arena_reset (&arena); } arena_destroy (&arena); }