Add support for history editing

This commit is contained in:
logicog
2026-02-24 19:57:22 +01:00
parent 94d4ace88b
commit dfc96761b3
+84 -1
View File
@@ -9,14 +9,20 @@ __xdata uint8_t l;
// Properties of currently edited command line in cmd_buffer[CMD_BUF_SIZE] // Properties of currently edited command line in cmd_buffer[CMD_BUF_SIZE]
__xdata uint8_t cursor; __xdata uint8_t cursor;
__xdata uint8_t cmd_line_len; __xdata uint8_t cmd_line_len;
__xdata uint8_t current_cmdline[CMD_BUF_SIZE];
__xdata uint16_t history_editptr;
extern __xdata uint8_t cmd_history[CMD_HISTORY_SIZE];
extern __xdata uint16_t cmd_history_ptr;
void cmd_editor_init(void) __banked void cmd_editor_init(void) __banked
{ {
l = sbuf_ptr; // We have printed out entered characters until l l = sbuf_ptr; // We have printed out entered characters until l
cursor = 0; cursor = 0;
cmd_line_len = 0; cmd_line_len = 0;
cmd_available = 0; cmd_available = 0;
history_editptr = 0xffff;
} }
/* /*
@@ -84,6 +90,82 @@ void cmd_edit(void) __banked
l += 3; l += 3;
l &= SBUF_MASK; l &= SBUF_MASK;
continue; continue;
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'A') { // <CURSOR-UP>
for (uint8_t i = 0; i < cmd_line_len; i++)
current_cmdline[i] = cmd_buffer[i];
current_cmdline[cmd_line_len] = 0;
__xdata uint16_t p;
if (history_editptr == 0xffff)
p = (cmd_history_ptr - 2) & CMD_HISTORY_MASK;
else
p = history_editptr;
// Move cursor to beginning of line
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
cursor = 0;
while (cmd_history[p] && cmd_history[p] != '\n') {
cursor++;
p--;
p &= CMD_HISTORY_MASK;
}
history_editptr = (p - 1) & CMD_HISTORY_MASK;
p = (p + 1) & CMD_HISTORY_MASK;
if (cursor) {
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
for (uint8_t i = 0; i < cursor; i++) {
cmd_buffer[i] = cmd_history[p];
write_char(cmd_buffer[i]);
p = (p+1) & CMD_HISTORY_MASK;
}
cmd_line_len = cursor;
} else {
print_string("\033[2C"); // Move 2 right to start of editing space
}
l += 3;
l &= SBUF_MASK;
continue;
} else if (sbuf[l] == '\033' && sbuf[(l + 1) & SBUF_MASK] == '[' && sbuf[(l + 2) & SBUF_MASK] == 'B') { // <CURSOR-DOWN>
if (history_editptr != 0xffff) {
__xdata uint16_t p = (history_editptr + 2) & CMD_HISTORY_MASK;
// Move cursor to beginning of line
write_char('\033'); write_char('['); itoa(cursor + 2); write_char('D');
print_string("\033[2K> "); // Clear entire line: ^[[2K and print new prompt
uint8_t i = 0;
while (cmd_history[p] && cmd_history[p] != '\n') {
p = (p + 1) & CMD_HISTORY_MASK;
}
p = (p + 1) & CMD_HISTORY_MASK;
while (cmd_history[p] && cmd_history[p] != '\n') {
cmd_buffer[i] = cmd_history[p];
write_char(cmd_buffer[i++]);
p = (p + 1) & CMD_HISTORY_MASK;
}
history_editptr = (p - 1) & CMD_HISTORY_MASK;
if (!i) {
if (current_cmdline[i]) {
while (current_cmdline[i]) {
cmd_buffer[i] = current_cmdline[i];
write_char(cmd_buffer[i++]);
}
} else {
write_char('\033'); write_char('['); write_char('C');
}
history_editptr = 0xffff;
// Move cursor right
}
cmd_line_len = i;
cursor = 0;
// Move cursor again to beginning of line
write_char('\033'); write_char('['); itoa(i); write_char('D');
} else {
// If we are at the last entry of the history, just move the cursor to the end of the line
if (cursor < cmd_line_len) {
write_char('\033'); write_char('['); itoa(cmd_line_len - cursor); write_char('C');
}
cursor = cmd_line_len;
}
l += 3;
l &= SBUF_MASK;
continue;
} else { // An unknown or not yet complete Escape sequence: wait } else { // An unknown or not yet complete Escape sequence: wait
continue; continue;
} }
@@ -109,7 +191,7 @@ void cmd_edit(void) __banked
if (sbuf[l] == '\n' || sbuf[l] == '\r') { if (sbuf[l] == '\n' || sbuf[l] == '\r') {
write_char('\n'); write_char('\n');
cmd_buffer[cmd_line_len] = '\0'; cmd_buffer[cmd_line_len] = '\0';
write_char('>'); print_string_x(cmd_buffer); write_char('<'); // write_char('>'); print_string_x(cmd_buffer); write_char('<');
// If there is a command we print the prompt after execution // If there is a command we print the prompt after execution
// otherwise immediately because there is nothing to execute // otherwise immediately because there is nothing to execute
if (cmd_line_len) if (cmd_line_len)
@@ -118,6 +200,7 @@ void cmd_edit(void) __banked
print_string("\n> "); print_string("\n> ");
cursor = 0; cursor = 0;
cmd_line_len = 0; cmd_line_len = 0;
history_editptr = 0xffff;
} }
l++; l++;
l &= SBUF_MASK; l &= SBUF_MASK;