\brief Handle history navigation
| 898 | |
| 899 | /// \brief Handle history navigation |
| 900 | void CLIWide::handle_history_navigation(bool up, InputState& state) { |
| 901 | if (state.lines.size() > 1) return; // Only in single-line mode |
| 902 | |
| 903 | if (up) { |
| 904 | if (!command_history.empty()) { |
| 905 | if (state.history_nav_index == -1) { |
| 906 | state.history_nav_index = command_history.size() - 1; |
| 907 | } else if (state.history_nav_index > 0) { |
| 908 | state.history_nav_index--; |
| 909 | } |
| 910 | |
| 911 | // Clear current line and replace with history entry |
| 912 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 913 | if (GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) { |
| 914 | COORD pos = {static_cast<SHORT>(state.prompt_len), csbi.dwCursorPosition.Y}; |
| 915 | SetConsoleCursorPosition(hConsoleOutput, pos); |
| 916 | clear_line_from_cursor(); |
| 917 | state.lines[state.current_line_index] = command_history[state.history_nav_index]; |
| 918 | state.cursor_pos = state.lines[state.current_line_index].length(); |
| 919 | std::cout << visualize_tabs(state.lines[state.current_line_index]); |
| 920 | std::cout.flush(); |
| 921 | } |
| 922 | } |
| 923 | } else { |
| 924 | if (!command_history.empty() && state.history_nav_index != -1) { |
| 925 | if (state.history_nav_index < static_cast<int>(command_history.size()) - 1) { |
| 926 | state.history_nav_index++; |
| 927 | // Clear current line and replace with history entry |
| 928 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 929 | if (GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) { |
| 930 | COORD pos = {static_cast<SHORT>(state.prompt_len), csbi.dwCursorPosition.Y}; |
| 931 | SetConsoleCursorPosition(hConsoleOutput, pos); |
| 932 | clear_line_from_cursor(); |
| 933 | state.lines[state.current_line_index] = command_history[state.history_nav_index]; |
| 934 | state.cursor_pos = state.lines[state.current_line_index].length(); |
| 935 | std::cout << visualize_tabs(state.lines[state.current_line_index]); |
| 936 | std::cout.flush(); |
| 937 | } |
| 938 | } else { |
| 939 | // Go to empty line (beyond history) |
| 940 | state.history_nav_index = -1; |
| 941 | CONSOLE_SCREEN_BUFFER_INFO csbi; |
| 942 | if (GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) { |
| 943 | COORD pos = {static_cast<SHORT>(state.prompt_len), csbi.dwCursorPosition.Y}; |
| 944 | SetConsoleCursorPosition(hConsoleOutput, pos); |
| 945 | clear_line_from_cursor(); |
| 946 | state.lines[state.current_line_index].clear(); |
| 947 | state.cursor_pos = 0; |
| 948 | } |
| 949 | } |
| 950 | } |
| 951 | } |
| 952 | } |
| 953 | |
| 954 | /// \brief Handle multiline navigation |
| 955 | void CLIWide::handle_multiline_navigation(bool up, InputState& state) { |