diff --git a/brewos.iso b/brewos.iso index 3bee791..8418390 100644 Binary files a/brewos.iso and b/brewos.iso differ diff --git a/build/about.o b/build/about.o index 189d10b..2cf7426 100644 Binary files a/build/about.o and b/build/about.o differ diff --git a/build/brewos.elf b/build/brewos.elf index c7ac4d9..b5e8b88 100755 Binary files a/build/brewos.elf and b/build/brewos.elf differ diff --git a/build/cli_apps/about.o b/build/cli_apps/about.o index 34cc8ac..84c1a51 100644 Binary files a/build/cli_apps/about.o and b/build/cli_apps/about.o differ diff --git a/build/cmd.o b/build/cmd.o index ede5399..f34cd16 100644 Binary files a/build/cmd.o and b/build/cmd.o differ diff --git a/iso_root/README.md b/iso_root/README.md index 2b02f66..ee712f3 100644 --- a/iso_root/README.md +++ b/iso_root/README.md @@ -1,4 +1,4 @@ -# Brew OS 1.10 Alpha +# Brew OS 1.12 Alpha ## Brewkernel is now BrewOS! Brewkernel will from now on be deprecated as it's core became too messy. I have built a less bloated kernel and wrote a DE above it, which is why it is now an OS instead of a kernel (in my opinion). diff --git a/iso_root/brewos.elf b/iso_root/brewos.elf index c7ac4d9..b5e8b88 100755 Binary files a/iso_root/brewos.elf and b/iso_root/brewos.elf differ diff --git a/limine b/limine new file mode 160000 index 0000000..5468ab2 --- /dev/null +++ b/limine @@ -0,0 +1 @@ +Subproject commit 5468ab25166aed2f4cce9fe1a71066acf492f5ea diff --git a/src/kernel/cmd.c b/src/kernel/cmd.c index 1ddfe29..8934eeb 100644 --- a/src/kernel/cmd.c +++ b/src/kernel/cmd.c @@ -181,6 +181,47 @@ static void itoa(int n, char *buf) { } } +// --- History --- +#define HISTORY_MAX 16 +static char cmd_history[HISTORY_MAX][CMD_COLS + 1]; +static int history_head = 0; +static int history_len = 0; +static int history_pos = -1; +static char history_save_buf[CMD_COLS + 1]; + +static void cmd_history_add(const char *cmd) { + if (!cmd || !*cmd) return; + + // Don't add if same as last command + int last_idx = (history_head - 1 + HISTORY_MAX) % HISTORY_MAX; + if (history_len > 0 && cmd_strcmp(cmd, cmd_history[last_idx]) == 0) { + return; + } + + cmd_strcpy(cmd_history[history_head], cmd); + history_head = (history_head + 1) % HISTORY_MAX; + if (history_len < HISTORY_MAX) history_len++; +} + +static void cmd_clear_line_content(void) { + int prompt_len = cmd_strlen(PROMPT); + for (int i = prompt_len; i < CMD_COLS; i++) { + screen_buffer[cursor_row][i].c = ' '; + screen_buffer[cursor_row][i].color = current_color; + } + cursor_col = prompt_len; +} + +static void cmd_set_line_content(const char *str) { + cmd_clear_line_content(); + while (*str && cursor_col < CMD_COLS) { + screen_buffer[cursor_row][cursor_col].c = *str; + screen_buffer[cursor_row][cursor_col].color = current_color; + cursor_col++; + str++; + } +} + // Manual and license pages are now in the individual command files // --- Terminal Emulation --- @@ -770,13 +811,46 @@ static void cmd_key(Window *target, char c) { cmd_putchar('\n'); + if (len > 0) cmd_history_add(cmd_buf); + history_pos = -1; + cmd_exec(cmd_buf); cmd_write(PROMPT); } else if (c == 17) { // UP - // History not implemented + if (history_len > 0) { + if (history_pos == -1) { + // Save current line + int len = 0; + int prompt_len = cmd_strlen(PROMPT); + for (int i = prompt_len; i < CMD_COLS; i++) { + char ch = screen_buffer[cursor_row][i].c; + if (ch == 0) break; + history_save_buf[len++] = ch; + } + while (len > 0 && history_save_buf[len-1] == ' ') len--; + history_save_buf[len] = 0; + + history_pos = (history_head - 1 + HISTORY_MAX) % HISTORY_MAX; + } else { + int oldest = (history_head - history_len + HISTORY_MAX) % HISTORY_MAX; + if (history_pos != oldest) { + history_pos = (history_pos - 1 + HISTORY_MAX) % HISTORY_MAX; + } + } + cmd_set_line_content(cmd_history[history_pos]); + } } else if (c == 18) { // DOWN - + if (history_pos != -1) { + int newest = (history_head - 1 + HISTORY_MAX) % HISTORY_MAX; + if (history_pos == newest) { + history_pos = -1; + cmd_set_line_content(history_save_buf); + } else { + history_pos = (history_pos + 1) % HISTORY_MAX; + cmd_set_line_content(cmd_history[history_pos]); + } + } } else if (c == 19) { // LEFT if (cursor_col > (int)cmd_strlen(PROMPT)) { cursor_col--;