fix(sh): fix prompt escape truncation, handle CRLF and filter ANSI escape sequences
This commit is contained in:
+50
-20
@@ -28,12 +28,16 @@ static VfsFile vfs_nodes[16] = {
|
|||||||
static size_t vfs_count = 11;
|
static size_t vfs_count = 11;
|
||||||
|
|
||||||
static void print_prompt() {
|
static void print_prompt() {
|
||||||
sys_log_debug("\033[1;32mroot@opencoreC\033[0m:\033[1;34m~\033[0m# ", 36);
|
const char prompt[] = "root@opencoreC:~# ";
|
||||||
|
sys_log_debug(prompt, sizeof(prompt) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_command(char *cmd) {
|
static void handle_command(char *cmd) {
|
||||||
|
while (*cmd && ((unsigned char)*cmd <= ' ' || (unsigned char)*cmd > 126)) {
|
||||||
|
cmd++;
|
||||||
|
}
|
||||||
size_t len = strlen(cmd);
|
size_t len = strlen(cmd);
|
||||||
while (len > 0 && (cmd[len - 1] == ' ' || cmd[len - 1] == '\t' || cmd[len - 1] == '\r')) {
|
while (len > 0 && (cmd[len - 1] == ' ' || cmd[len - 1] == '\t' || cmd[len - 1] == '\r' || (unsigned char)cmd[len - 1] <= ' ')) {
|
||||||
cmd[--len] = '\0';
|
cmd[--len] = '\0';
|
||||||
}
|
}
|
||||||
if (len == 0) return;
|
if (len == 0) return;
|
||||||
@@ -221,34 +225,60 @@ extern "C" void _start() {
|
|||||||
|
|
||||||
print_prompt();
|
print_prompt();
|
||||||
|
|
||||||
|
bool prev_was_cr = false;
|
||||||
|
bool in_escape = false;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int key = sys_key_read();
|
int key = sys_key_read();
|
||||||
if (key > 0) {
|
if (key > 0) {
|
||||||
char c = (char)key;
|
char c = (char)key;
|
||||||
if (c == '\n' || c == '\r') {
|
|
||||||
|
// Handle ANSI Escape sequences (e.g. arrow keys: ESC [ A)
|
||||||
|
if (in_escape) {
|
||||||
|
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '~') {
|
||||||
|
in_escape = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (c == 27) { // ESC
|
||||||
|
in_escape = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\r' || c == '\n') {
|
||||||
|
if (c == '\n' && prev_was_cr) {
|
||||||
|
prev_was_cr = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
prev_was_cr = (c == '\r');
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
input_line[line_len] = '\0';
|
input_line[line_len] = '\0';
|
||||||
handle_command(input_line);
|
handle_command(input_line);
|
||||||
line_len = 0;
|
line_len = 0;
|
||||||
print_prompt();
|
print_prompt();
|
||||||
} else if (c == 8 || c == 127) { // Backspace
|
} else {
|
||||||
if (line_len > 0) {
|
prev_was_cr = false;
|
||||||
line_len--;
|
if (c == 8 || c == 127) { // Backspace
|
||||||
sys_log_debug("\b \b", 3);
|
if (line_len > 0) {
|
||||||
|
line_len--;
|
||||||
|
sys_log_debug("\b \b", 3);
|
||||||
|
}
|
||||||
|
} else if (c == 3) { // Ctrl+C
|
||||||
|
sys_log_debug("^C\n", 3);
|
||||||
|
line_len = 0;
|
||||||
|
print_prompt();
|
||||||
|
} else if (c == 12) { // Ctrl+L (Clear)
|
||||||
|
sys_log_debug("\033[2J\033[H", 7);
|
||||||
|
print_prompt();
|
||||||
|
for (size_t i = 0; i < line_len; i++) {
|
||||||
|
putchar(input_line[i]);
|
||||||
|
}
|
||||||
|
} else if (c >= 32 && c <= 126) {
|
||||||
|
if (line_len < sizeof(input_line) - 1) {
|
||||||
|
input_line[line_len++] = c;
|
||||||
|
putchar(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (c == 3) { // Ctrl+C
|
|
||||||
sys_log_debug("^C\n", 3);
|
|
||||||
line_len = 0;
|
|
||||||
print_prompt();
|
|
||||||
} else if (c == 12) { // Ctrl+L (Clear)
|
|
||||||
sys_log_debug("\033[2J\033[H", 7);
|
|
||||||
print_prompt();
|
|
||||||
for (size_t i = 0; i < line_len; i++) {
|
|
||||||
putchar(input_line[i]);
|
|
||||||
}
|
|
||||||
} else if (line_len < sizeof(input_line) - 1) {
|
|
||||||
input_line[line_len++] = c;
|
|
||||||
putchar(c);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sys_yield();
|
sys_yield();
|
||||||
|
|||||||
Reference in New Issue
Block a user