\brief Determine if input should continue
| 1002 | |
| 1003 | /// \brief Determine if input should continue |
| 1004 | bool CLIWide::should_continue_input(const InputState& state) { |
| 1005 | // If this is the first line and it's empty, continue |
| 1006 | if (state.current_line_index == 0 && state.lines[0].empty()) { |
| 1007 | return true; |
| 1008 | } |
| 1009 | |
| 1010 | // Check if this is a command (starts with /) |
| 1011 | if (state.current_line_index == 0 && !state.lines[0].empty() && state.lines[0][0] == '/') { |
| 1012 | return false; // Commands are always single-line |
| 1013 | } |
| 1014 | |
| 1015 | // Check for backslash continuation on current line |
| 1016 | if (!state.lines[state.current_line_index].empty() && state.lines[state.current_line_index].back() == '\\') { |
| 1017 | // Remove the backslash and continue |
| 1018 | const_cast<InputState&>(state).lines[state.current_line_index].pop_back(); |
| 1019 | const_cast<InputState&>(state).lines.push_back(""); |
| 1020 | const_cast<InputState&>(state).is_wrapped_line.push_back(false); // User-created line, not wrapped |
| 1021 | const_cast<InputState&>(state).current_line_index++; |
| 1022 | const_cast<InputState&>(state).cursor_pos = 0; |
| 1023 | |
| 1024 | // Safety check: ensure vectors stay in sync |
| 1025 | if (state.lines.size() != state.is_wrapped_line.size()) { |
| 1026 | size_t min_size = (state.lines.size() < state.is_wrapped_line.size()) ? state.lines.size() : state.is_wrapped_line.size(); |
| 1027 | const_cast<InputState&>(state).lines.resize(min_size); |
| 1028 | const_cast<InputState&>(state).is_wrapped_line.resize(min_size); |
| 1029 | } |
| 1030 | |
| 1031 | return true; |
| 1032 | } |
| 1033 | |
| 1034 | // If we're already in paste mode, be more lenient about continuing |
| 1035 | if (state.paste_mode) { |
| 1036 | // In paste mode, wait longer and check multiple times for more input |
| 1037 | for (int i = 0; i < 5; i++) { // Increased from 3 to 5 checks |
| 1038 | std::this_thread::sleep_for(std::chrono::milliseconds(15)); // Reduced from 20ms to 15ms |
| 1039 | if (is_paste_operation()) { |
| 1040 | // More input is coming |
| 1041 | const_cast<InputState&>(state).lines.push_back(""); |
| 1042 | const_cast<InputState&>(state).is_wrapped_line.push_back(false); // User-created line, not wrapped |
| 1043 | const_cast<InputState&>(state).current_line_index++; |
| 1044 | const_cast<InputState&>(state).cursor_pos = 0; |
| 1045 | |
| 1046 | // Safety check: ensure vectors stay in sync |
| 1047 | if (state.lines.size() != state.is_wrapped_line.size()) { |
| 1048 | size_t min_size = (state.lines.size() < state.is_wrapped_line.size()) ? state.lines.size() : state.is_wrapped_line.size(); |
| 1049 | const_cast<InputState&>(state).lines.resize(min_size); |
| 1050 | const_cast<InputState&>(state).is_wrapped_line.resize(min_size); |
| 1051 | } |
| 1052 | |
| 1053 | return true; |
| 1054 | } |
| 1055 | } |
| 1056 | |
| 1057 | // No more input detected after multiple checks - end paste mode |
| 1058 | const_cast<InputState&>(state).paste_mode = false; |
| 1059 | const_cast<InputState&>(state).utf8_buffer.clear(); |
| 1060 | |
| 1061 | // Clean up multiple empty lines at the end |