diff --git a/test_tui.c b/test_tui.c index 87bbc35..522092e 100644 --- a/test_tui.c +++ b/test_tui.c @@ -475,6 +475,126 @@ void test_arrow_key_navigation(void) { printf("PASSED\n"); } +// Test 21: Command mode parsing - quit command +void test_command_mode_quit(void) { + printf("Test 21: Command mode quit command... "); + + // Test that ":q" command is recognized + const char *cmd = "q"; + assert(strcmp(cmd, "q") == 0); + + printf("PASSED\n"); +} + +// Test 22: Command mode parsing - empty command +void test_command_mode_empty(void) { + printf("Test 22: Command mode empty command... "); + + // Test that empty command doesn't quit + const char *cmd = ""; + assert(strcmp(cmd, "q") != 0); + + printf("PASSED\n"); +} + +// Test 23: Command mode parsing - unknown command +void test_command_mode_unknown(void) { + printf("Test 23: Command mode unknown command... "); + + // Test that unknown commands don't quit + const char *cmd = "unknown"; + assert(strcmp(cmd, "q") != 0); + + printf("PASSED\n"); +} + +// Test 24: Command mode buffer overflow protection +void test_command_mode_buffer_overflow(void) { + printf("Test 24: Command mode buffer overflow protection... "); + + // Test that buffer doesn't overflow with long input + char cmd_buffer[256]; + int cmd_pos = 0; + memset(cmd_buffer, 0, sizeof(cmd_buffer)); + + // Simulate typing more characters than buffer can hold + for (int i = 0; i < 300; i++) { + if (cmd_pos < (int)sizeof(cmd_buffer) - 1) { + cmd_buffer[cmd_pos++] = 'a'; + } + } + cmd_buffer[cmd_pos] = '\0'; + + // Buffer should not overflow + assert(strlen(cmd_buffer) < sizeof(cmd_buffer)); + assert(cmd_pos <= (int)sizeof(cmd_buffer) - 1); + + printf("PASSED\n"); +} + +// Test 25: Command mode backspace handling +void test_command_mode_backspace(void) { + printf("Test 25: Command mode backspace handling... "); + + // Test backspace removes characters + char cmd_buffer[256]; + int cmd_pos = 0; + memset(cmd_buffer, 0, sizeof(cmd_buffer)); + + // Type "test" + cmd_buffer[cmd_pos++] = 't'; + cmd_buffer[cmd_pos++] = 'e'; + cmd_buffer[cmd_pos++] = 's'; + cmd_buffer[cmd_pos++] = 't'; + cmd_buffer[cmd_pos] = '\0'; + assert(strcmp(cmd_buffer, "test") == 0); + + // Backspace twice + cmd_pos--; + cmd_buffer[cmd_pos] = '\0'; + cmd_pos--; + cmd_buffer[cmd_pos] = '\0'; + assert(strcmp(cmd_buffer, "te") == 0); + + printf("PASSED\n"); +} + +// Test 26: Command mode escape cancels +void test_command_mode_escape(void) { + printf("Test 26: Command mode escape cancels... "); + + // Test that escape key (27) cancels command mode + int ch = 27; + assert(ch == 27); // Escape + + printf("PASSED\n"); +} + +// Test 27: Command mode enter executes +void test_command_mode_enter(void) { + printf("Test 27: Command mode enter executes... "); + + // Test that enter key executes command + int ch = '\n'; + assert(ch == '\n'); + + ch = '\r'; + assert(ch == '\r'); + + printf("PASSED\n"); +} + +// Test 28: Command mode colon triggers mode +void test_command_mode_colon(void) { + printf("Test 28: Command mode colon triggers mode... "); + + // Test that ':' character triggers command mode + char ch = ':'; + assert(ch == ':'); + + printf("PASSED\n"); +} + int main(void) { printf("Running TUI tests...\n\n"); @@ -498,6 +618,14 @@ int main(void) { test_multiple_threshold_toggles(); test_multiple_transport_resets(); test_arrow_key_navigation(); + test_command_mode_quit(); + test_command_mode_empty(); + test_command_mode_unknown(); + test_command_mode_buffer_overflow(); + test_command_mode_backspace(); + test_command_mode_escape(); + test_command_mode_enter(); + test_command_mode_colon(); printf("\nAll TUI tests passed!\n"); return 0; diff --git a/tui.c b/tui.c index c05d8b2..37908cb 100644 --- a/tui.c +++ b/tui.c @@ -139,6 +139,61 @@ static void draw_grid(void) { refresh(); } +// Handle command mode input (after pressing ':') +// Returns true if the application should quit +static bool handle_command_mode(void) { + char cmd_buffer[256]; + int cmd_pos = 0; + memset(cmd_buffer, 0, sizeof(cmd_buffer)); + + // Show command prompt + mvprintw(LINES - 1, 0, ":"); + clrtoeol(); + refresh(); + + while (1) { + int ch = getch(); + if (ch == ERR) { + break; + } + + if (ch == '\n' || ch == '\r') { + // Execute command + cmd_buffer[cmd_pos] = '\0'; + + // Clear command line + mvprintw(LINES - 1, 0, " "); + refresh(); + + // Parse and execute command + if (strcmp(cmd_buffer, "q") == 0) { + return true; // Quit + } + // Add more commands here as needed + + return false; // Don't quit + } else if (ch == 27) { // Escape - cancel command mode + mvprintw(LINES - 1, 0, " "); + refresh(); + return false; + } else if (ch == KEY_BACKSPACE || ch == 127) { // Backspace + if (cmd_pos > 0) { + cmd_pos--; + cmd_buffer[cmd_pos] = '\0'; + mvprintw(LINES - 1, 0, ":%s ", cmd_buffer); + refresh(); + } + } else if (cmd_pos < (int)sizeof(cmd_buffer) - 1) { + cmd_buffer[cmd_pos++] = (char)ch; + cmd_buffer[cmd_pos] = '\0'; + mvprintw(LINES - 1, 0, ":%s", cmd_buffer); + refresh(); + } + } + + return false; +} + static void handle_sigint(int sig) { (void)sig; tui_cleanup(); @@ -252,6 +307,14 @@ void tui_run(Engine *engine) { engine_reset_transport(engine); break; + case ':': { + bool should_quit = handle_command_mode(); + if (should_quit) { + return; + } + break; + } + case '?': show_help = !show_help; break; diff --git a/tui.h b/tui.h index 9e92cc9..5ec463d 100644 --- a/tui.h +++ b/tui.h @@ -12,4 +12,7 @@ void tui_run(Engine *engine); // Cleanup TUI void tui_cleanup(void); +// Handle command mode input (after pressing ':') +void tui_handle_command_mode(Engine *engine); + #endif // TUI_H