Skip to content

Commit d2fae28

Browse files
committed
Keyboard reading modified
1 parent 3d51e72 commit d2fae28

1 file changed

Lines changed: 127 additions & 0 deletions

File tree

cpp_utils/src/cpp/event/StdinEventHandler.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@
2828
#include <cpp_utils/exception/InitializationException.hpp>
2929
#include <cpp_utils/Log.hpp>
3030

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+
#else
39+
inline bool consume_tilde_if_present()
40+
{
41+
// POSIX: ESC [ <num> ~ → read and verify '~'
42+
int t = getchar();
43+
return t == '~';
44+
}
45+
#endif
46+
}
47+
3148
namespace eprosima {
3249
namespace utils {
3350
namespace event {
@@ -375,6 +392,116 @@ void StdinEventHandler::stdin_listener_thread_routine_() noexcept
375392
break;
376393
}
377394

395+
#if defined(_WIN32) || defined(_WIN64)
396+
case 82: // Insert
397+
#else
398+
case '2': // Insert: ESC [ 2 ~
399+
#endif
400+
{
401+
int c3 = getchar(); (void)c3; // swallow trailing '~'
402+
// Minimal behavior: do nothing
403+
break;
404+
}
405+
406+
#if defined(_WIN32) || defined(_WIN64)
407+
case 83: // Supr
408+
#else
409+
case '3': // Supr: ESC [ 3 ~
410+
#endif
411+
{
412+
if (consume_tilde_if_present())
413+
{
414+
// delete-forward (char at cursor), if any
415+
if (cursor_index < read_str.size())
416+
{
417+
update_line(">> ", read_str, cursor_index,
418+
[](std::string& line, size_t& index)
419+
{
420+
if (index < line.size())
421+
{
422+
line.erase(line.begin() + index);
423+
}
424+
});
425+
}
426+
}
427+
// do nothing.
428+
break;
429+
}
430+
431+
#if defined(_WIN32) || defined(_WIN64)
432+
case 73: // Page Up
433+
#else
434+
case '5': // Page Up: ESC [ 5 ~ (history prev)
435+
#endif
436+
{
437+
if (consume_tilde_if_present())
438+
{
439+
std::string prev = history_handler_.get_previous_command();
440+
if (!prev.empty())
441+
{
442+
std::string prompt = ">> ";
443+
int term_width = get_terminal_width();
444+
int lines = compute_lines_needed(prompt, read_str, term_width);
445+
clear_lines(lines);
446+
read_str = prev;
447+
cursor_index = read_str.size();
448+
std::cout << "\033[38;5;82m" << prompt << "\033[0m" << read_str << std::flush;
449+
}
450+
}
451+
break;
452+
}
453+
454+
455+
#if defined(_WIN32) || defined(_WIN64)
456+
case 81: // Page Down
457+
#else
458+
case '6': // Page Down: ESC [ 6 ~ (history next)
459+
#endif
460+
{
461+
if (consume_tilde_if_present())
462+
{
463+
std::string next = history_handler_.get_next_command();
464+
std::string prompt = ">> ";
465+
int term_width = get_terminal_width();
466+
int lines = compute_lines_needed(prompt, read_str, term_width);
467+
clear_lines(lines);
468+
if (!next.empty())
469+
{
470+
read_str = next;
471+
cursor_index = read_str.size();
472+
std::cout << "\033[38;5;82m" << prompt << "\033[0m" << read_str << std::flush;
473+
}
474+
else
475+
{
476+
read_str.clear();
477+
cursor_index = 0;
478+
std::cout << "\033[38;5;82m" << prompt << "\033[0m" << std::flush;
479+
}
480+
}
481+
break;
482+
}
483+
484+
#if defined(_WIN32) || defined(_WIN64)
485+
case 71: // Home
486+
#else
487+
case 'H': // Home: ESC [ H
488+
#endif
489+
{
490+
update_line(">> ", read_str, cursor_index,
491+
[](std::string&, size_t& index){ index = 0; });
492+
break;
493+
}
494+
495+
#if defined(_WIN32) || defined(_WIN64)
496+
case 79: // End
497+
#else
498+
case 'F': // End: ESC [ F
499+
#endif
500+
{
501+
update_line(">> ", read_str, cursor_index,
502+
[](std::string& line, size_t& index){ index = line.size(); });
503+
break;
504+
}
378505
}
379506
}
380507
else if (c == '\n' || c == '\r')

0 commit comments

Comments
 (0)