diff --git a/otp.c b/otp.c index 3ed61d1..49e26c5 100644 --- a/otp.c +++ b/otp.c @@ -2300,7 +2300,7 @@ void simple_entropy_mix(unsigned char* urandom_buffer, size_t buffer_size, } } -// Enhanced input function for filename with directory separation +// Enhanced input function with editable pre-filled text int get_filename_with_default(const char* prompt, const char* default_path, char* result, size_t result_size) { // Find the last directory separator char* last_slash = strrchr(default_path, '/'); @@ -2324,33 +2324,168 @@ int get_filename_with_default(const char* prompt, const char* default_path, char filename[sizeof(filename) - 1] = '\0'; } - // Display the enhanced prompt with directory and filename separated by colon - printf("\n%s\n%s: %s", prompt, directory, filename); + // Setup terminal for raw input + struct termios orig_termios; + if (tcgetattr(STDIN_FILENO, &orig_termios) != 0) { + // Fallback to simple input if terminal control fails + printf("\n%s\n%s: ", prompt, directory); + fflush(stdout); + + char input_buffer[512]; + if (!fgets(input_buffer, sizeof(input_buffer), stdin)) { + return 1; + } + input_buffer[strcspn(input_buffer, "\n")] = 0; + + if (strlen(input_buffer) == 0) { + strncpy(result, default_path, result_size - 1); + } else { + if (strlen(directory) > 0) { + snprintf(result, result_size, "%s%s", directory, input_buffer); + } else { + strncpy(result, input_buffer, result_size - 1); + } + } + result[result_size - 1] = '\0'; + return 0; + } + + // Set up raw terminal mode + struct termios raw_termios = orig_termios; + raw_termios.c_lflag &= ~(ECHO | ICANON); + raw_termios.c_cc[VMIN] = 1; + raw_termios.c_cc[VTIME] = 0; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_termios) != 0) { + // Fallback if terminal setup fails + printf("\n%s\n%s: ", prompt, directory); + fflush(stdout); + + char input_buffer[512]; + if (!fgets(input_buffer, sizeof(input_buffer), stdin)) { + return 1; + } + input_buffer[strcspn(input_buffer, "\n")] = 0; + + if (strlen(input_buffer) == 0) { + strncpy(result, default_path, result_size - 1); + } else { + if (strlen(directory) > 0) { + snprintf(result, result_size, "%s%s", directory, input_buffer); + } else { + strncpy(result, input_buffer, result_size - 1); + } + } + result[result_size - 1] = '\0'; + return 0; + } + + // Display prompt and directory + printf("\n%s\n%s", prompt, directory); fflush(stdout); - char input_buffer[512]; - if (!fgets(input_buffer, sizeof(input_buffer), stdin)) { - return 1; // Error reading input + // Initialize editing buffer with default filename + char edit_buffer[512]; + strncpy(edit_buffer, filename, sizeof(edit_buffer) - 1); + edit_buffer[sizeof(edit_buffer) - 1] = '\0'; + int cursor_pos = strlen(edit_buffer); + int buffer_len = cursor_pos; + + // Display initial filename + printf("%s", edit_buffer); + fflush(stdout); + + // Main editing loop + int c; + while ((c = getchar()) != EOF) { + if (c == '\n' || c == '\r') { + // Enter key - accept input + break; + } else if (c == 127 || c == 8) { + // Backspace/Delete + if (cursor_pos > 0) { + // Move everything after cursor one position left + memmove(&edit_buffer[cursor_pos - 1], &edit_buffer[cursor_pos], buffer_len - cursor_pos + 1); + cursor_pos--; + buffer_len--; + + // Redraw line: move cursor to start of filename area, clear to end, redraw buffer + printf("\r%s\033[K%s", directory, edit_buffer); + + // Position cursor correctly + if (cursor_pos < buffer_len) { + printf("\033[%dD", buffer_len - cursor_pos); + } + fflush(stdout); + } + } else if (c == 27) { + // Escape sequence (arrow keys, etc.) + int c1 = getchar(); + int c2 = getchar(); + if (c1 == '[') { + if (c2 == 'C' && cursor_pos < buffer_len) { + // Right arrow + cursor_pos++; + printf("\033[1C"); + fflush(stdout); + } else if (c2 == 'D' && cursor_pos > 0) { + // Left arrow + cursor_pos--; + printf("\033[1D"); + fflush(stdout); + } else if (c2 == 'H') { + // Home key + printf("\033[%dD", cursor_pos); + cursor_pos = 0; + fflush(stdout); + } else if (c2 == 'F') { + // End key + printf("\033[%dC", buffer_len - cursor_pos); + cursor_pos = buffer_len; + fflush(stdout); + } + } + } else if (c >= 32 && c <= 126) { + // Printable character + if (buffer_len < sizeof(edit_buffer) - 1) { + // Move everything after cursor one position right + memmove(&edit_buffer[cursor_pos + 1], &edit_buffer[cursor_pos], buffer_len - cursor_pos + 1); + edit_buffer[cursor_pos] = c; + cursor_pos++; + buffer_len++; + + // Redraw from cursor position + printf("%c", c); + if (cursor_pos < buffer_len) { + // Print remaining characters and move cursor back + printf("%s\033[%dD", &edit_buffer[cursor_pos], buffer_len - cursor_pos); + } + fflush(stdout); + } + } + // Ignore other control characters } - // Remove newline - input_buffer[strcspn(input_buffer, "\n")] = 0; + // Restore terminal + tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios); + printf("\n"); - // If user just pressed Enter, use the default filename - if (strlen(input_buffer) == 0) { + // Construct final result + if (buffer_len == 0) { + // Empty input, use default strncpy(result, default_path, result_size - 1); - result[result_size - 1] = '\0'; } else { - // Combine directory with user input + // Combine directory with edited filename + edit_buffer[buffer_len] = '\0'; if (strlen(directory) > 0) { - snprintf(result, result_size, "%s%s", directory, input_buffer); + snprintf(result, result_size, "%s%s", directory, edit_buffer); } else { - strncpy(result, input_buffer, result_size - 1); - result[result_size - 1] = '\0'; + strncpy(result, edit_buffer, result_size - 1); } } + result[result_size - 1] = '\0'; - return 0; // Success + return 0; } // Editor and file manager implementations diff --git a/toc.txt.otp b/toc.txt.otp new file mode 100644 index 0000000..cf08a74 Binary files /dev/null and b/toc.txt.otp differ