@@ -665,6 +665,9 @@ namespace console {
665665 bool is_special_char = false ;
666666 bool end_of_stream = false ;
667667 size_t history_index = history.size ();
668+ std::string original_backup;
669+ std::string prompt_backup;
670+ size_t backup_index = SIZE_MAX;
668671
669672 size_t byte_pos = 0 ; // current byte index
670673 size_t char_pos = 0 ; // current character index (one char can be multiple bytes)
@@ -673,6 +676,11 @@ namespace console {
673676 while (true ) {
674677 assert (char_pos <= byte_pos);
675678 assert (char_pos <= widths.size ());
679+ auto sync_history_line = [&]() {
680+ if (history_index < history.size ()) {
681+ history[history_index] = line;
682+ }
683+ };
676684
677685 fflush (out); // Ensure all output is displayed before waiting for input
678686 input_char = getchar32 ();
@@ -732,17 +740,27 @@ namespace console {
732740 // up/down
733741 if (!history.empty ()) {
734742 if (code == ' A' && history_index > 0 ) {
743+ sync_history_line ();
744+ const bool from_end = history_index == history.size ();
745+ if (from_end) {
746+ prompt_backup = line;
747+ }
735748 history_index--;
749+ original_backup = history[history_index];
750+ backup_index = history_index;
736751 set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
737752 is_special_char = false ;
738753 } else if (code == ' B' ) {
754+ sync_history_line ();
739755 if (history_index + 1 < history.size ()) {
740756 history_index++;
757+ original_backup = history[history_index];
758+ backup_index = history_index;
741759 set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
742760 is_special_char = false ;
743761 } else if (history_index < history.size ()) {
744762 history_index = history.size ();
745- set_line_contents (" " , line, widths, char_pos, byte_pos);
763+ set_line_contents (prompt_backup , line, widths, char_pos, byte_pos);
746764 is_special_char = false ;
747765 }
748766 }
@@ -801,20 +819,31 @@ namespace console {
801819 move_to_line_end (char_pos, byte_pos, widths, line);
802820 } else if (input_char == KEY_DELETE) {
803821 delete_at_cursor (line, widths, char_pos, byte_pos);
804- } else if (input_char == KEY_ARROW_UP || input_char == KEY_ARROW_DOWN) {
805- if (!history.empty ()) {
806- if (input_char == KEY_ARROW_UP && history_index > 0 ) {
807- history_index--;
808- set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
809- is_special_char = false ;
810- } else if (input_char == KEY_ARROW_DOWN) {
811- if (history_index + 1 < history.size ()) {
812- history_index++;
813- set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
814- is_special_char = false ;
815- } else if (history_index < history.size ()) {
816- history_index = history.size ();
817- set_line_contents (" " , line, widths, char_pos, byte_pos);
822+ sync_history_line ();
823+ } else if (input_char == KEY_ARROW_UP || input_char == KEY_ARROW_DOWN) {
824+ if (!history.empty ()) {
825+ if (input_char == KEY_ARROW_UP && history_index > 0 ) {
826+ sync_history_line ();
827+ const bool from_end = history_index == history.size ();
828+ if (from_end) {
829+ prompt_backup = line;
830+ }
831+ history_index--;
832+ original_backup = history[history_index];
833+ backup_index = history_index;
834+ set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
835+ is_special_char = false ;
836+ } else if (input_char == KEY_ARROW_DOWN) {
837+ sync_history_line ();
838+ if (history_index + 1 < history.size ()) {
839+ history_index++;
840+ original_backup = history[history_index];
841+ backup_index = history_index;
842+ set_line_contents (history[history_index], line, widths, char_pos, byte_pos);
843+ is_special_char = false ;
844+ } else if (history_index < history.size ()) {
845+ history_index = history.size ();
846+ set_line_contents (prompt_backup, line, widths, char_pos, byte_pos);
818847 is_special_char = false ;
819848 }
820849 }
@@ -848,6 +877,7 @@ namespace console {
848877 fputc (' ' , out);
849878 }
850879 move_cursor (-(tail_width + w));
880+ sync_history_line ();
851881 }
852882 } else {
853883 // insert character
@@ -925,6 +955,9 @@ namespace console {
925955 }
926956
927957 if (!end_of_stream && !line.empty ()) {
958+ if (backup_index < history.size ()) {
959+ history[backup_index] = original_backup;
960+ }
928961 std::string history_entry = line;
929962 if (!history_entry.empty () && history_entry.back () == ' \n ' ) {
930963 history_entry.pop_back ();
0 commit comments