|
28 | 28 | #include <cpp_utils/exception/InitializationException.hpp> |
29 | 29 | #include <cpp_utils/Log.hpp> |
30 | 30 |
|
| 31 | +namespace { |
| 32 | +#if defined(_WIN32) || defined(_WIN64) |
| 33 | +inline bool consume_tilde_if_present() |
| 34 | +{ |
| 35 | + // Windows special keys don’t have a trailing '~' |
| 36 | + return true; |
| 37 | +} |
| 38 | + |
| 39 | +#else |
| 40 | +inline bool consume_tilde_if_present() |
| 41 | +{ |
| 42 | + // POSIX: ESC [ <num> ~ → read and verify '~' |
| 43 | + int t = getchar(); |
| 44 | + return t == '~'; |
| 45 | +} |
| 46 | + |
| 47 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 48 | +} // namespace |
| 49 | + |
31 | 50 | namespace eprosima { |
32 | 51 | namespace utils { |
33 | 52 | namespace event { |
@@ -375,6 +394,122 @@ void StdinEventHandler::stdin_listener_thread_routine_() noexcept |
375 | 394 | break; |
376 | 395 | } |
377 | 396 |
|
| 397 | +#if defined(_WIN32) || defined(_WIN64) |
| 398 | + case 82: // Insert |
| 399 | +#else |
| 400 | + case '2': // Insert: ESC [ 2 ~ |
| 401 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 402 | + { |
| 403 | + int c3 = getchar(); (void)c3; // swallow trailing '~' |
| 404 | + // Minimal behavior: do nothing |
| 405 | + break; |
| 406 | + } |
| 407 | + |
| 408 | +#if defined(_WIN32) || defined(_WIN64) |
| 409 | + case 83: // Supr |
| 410 | +#else |
| 411 | + case '3': // Supr: ESC [ 3 ~ |
| 412 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 413 | + { |
| 414 | + if (consume_tilde_if_present()) |
| 415 | + { |
| 416 | + // delete-forward (char at cursor), if any |
| 417 | + if (cursor_index < read_str.size()) |
| 418 | + { |
| 419 | + update_line(">> ", read_str, cursor_index, |
| 420 | + [](std::string& line, size_t& index) |
| 421 | + { |
| 422 | + if (index < line.size()) |
| 423 | + { |
| 424 | + line.erase(line.begin() + index); |
| 425 | + } |
| 426 | + }); |
| 427 | + } |
| 428 | + } |
| 429 | + // do nothing. |
| 430 | + break; |
| 431 | + } |
| 432 | + |
| 433 | +#if defined(_WIN32) || defined(_WIN64) |
| 434 | + case 73: // Page Up |
| 435 | +#else |
| 436 | + case '5': // Page Up: ESC [ 5 ~ (history prev) |
| 437 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 438 | + { |
| 439 | + if (consume_tilde_if_present()) |
| 440 | + { |
| 441 | + std::string prev = history_handler_.get_previous_command(); |
| 442 | + if (!prev.empty()) |
| 443 | + { |
| 444 | + std::string prompt = ">> "; |
| 445 | + int term_width = get_terminal_width(); |
| 446 | + int lines = compute_lines_needed(prompt, read_str, term_width); |
| 447 | + clear_lines(lines); |
| 448 | + read_str = prev; |
| 449 | + cursor_index = read_str.size(); |
| 450 | + std::cout << "\033[38;5;82m" << prompt << "\033[0m" << read_str << std::flush; |
| 451 | + } |
| 452 | + } |
| 453 | + break; |
| 454 | + } |
| 455 | + |
| 456 | + |
| 457 | +#if defined(_WIN32) || defined(_WIN64) |
| 458 | + case 81: // Page Down |
| 459 | +#else |
| 460 | + case '6': // Page Down: ESC [ 6 ~ (history next) |
| 461 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 462 | + { |
| 463 | + if (consume_tilde_if_present()) |
| 464 | + { |
| 465 | + std::string next = history_handler_.get_next_command(); |
| 466 | + std::string prompt = ">> "; |
| 467 | + int term_width = get_terminal_width(); |
| 468 | + int lines = compute_lines_needed(prompt, read_str, term_width); |
| 469 | + clear_lines(lines); |
| 470 | + if (!next.empty()) |
| 471 | + { |
| 472 | + read_str = next; |
| 473 | + cursor_index = read_str.size(); |
| 474 | + std::cout << "\033[38;5;82m" << prompt << "\033[0m" << read_str << std::flush; |
| 475 | + } |
| 476 | + else |
| 477 | + { |
| 478 | + read_str.clear(); |
| 479 | + cursor_index = 0; |
| 480 | + std::cout << "\033[38;5;82m" << prompt << "\033[0m" << std::flush; |
| 481 | + } |
| 482 | + } |
| 483 | + break; |
| 484 | + } |
| 485 | + |
| 486 | +#if defined(_WIN32) || defined(_WIN64) |
| 487 | + case 71: // Home |
| 488 | +#else |
| 489 | + case 'H': // Home: ESC [ H |
| 490 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 491 | + { |
| 492 | + update_line(">> ", read_str, cursor_index, |
| 493 | + [](std::string&, size_t& index) |
| 494 | + { |
| 495 | + index = 0; |
| 496 | + }); |
| 497 | + break; |
| 498 | + } |
| 499 | + |
| 500 | +#if defined(_WIN32) || defined(_WIN64) |
| 501 | + case 79: // End |
| 502 | +#else |
| 503 | + case 'F': // End: ESC [ F |
| 504 | +#endif // if defined(_WIN32) || defined(_WIN64) |
| 505 | + { |
| 506 | + update_line(">> ", read_str, cursor_index, |
| 507 | + [](std::string& line, size_t& index) |
| 508 | + { |
| 509 | + index = line.size(); |
| 510 | + }); |
| 511 | + break; |
| 512 | + } |
378 | 513 | } |
379 | 514 | } |
380 | 515 | else if (c == '\n' || c == '\r') |
|
0 commit comments