@@ -924,18 +924,26 @@ unsigned char Editline::BufferEndCommand(int ch) {
924924
925925// / Prints completions and their descriptions to the given file. Only the
926926// / completions in the interval [start, end) are printed.
927- static void
927+ static size_t
928928PrintCompletion (FILE *output_file,
929929 llvm::ArrayRef<CompletionResult::Completion> results,
930- size_t max_completion_length, size_t max_length) {
930+ size_t max_completion_length, size_t max_length,
931+ std::optional<size_t > max_height = std::nullopt ) {
931932 constexpr size_t ellipsis_length = 3 ;
932933 constexpr size_t padding_length = 8 ;
933934 constexpr size_t separator_length = 4 ;
934935
935936 const size_t description_col =
936937 std::min (max_completion_length + padding_length, max_length);
937938
939+ size_t lines_printed = 0 ;
940+ size_t results_printed = 0 ;
938941 for (const CompletionResult::Completion &c : results) {
942+ if (max_height && lines_printed >= *max_height)
943+ break ;
944+
945+ results_printed++;
946+
939947 if (c.GetCompletion ().empty ())
940948 continue ;
941949
@@ -956,6 +964,7 @@ PrintCompletion(FILE *output_file,
956964 fprintf (output_file, " %.*s...\n " ,
957965 static_cast <int >(max_length - padding_length - ellipsis_length),
958966 c.GetCompletion ().c_str ());
967+ lines_printed++;
959968 continue ;
960969 }
961970
@@ -964,6 +973,7 @@ PrintCompletion(FILE *output_file,
964973 if (c.GetDescription ().empty () ||
965974 description_col + separator_length + ellipsis_length >= max_length) {
966975 fprintf (output_file, " \n " );
976+ lines_printed++;
967977 continue ;
968978 }
969979
@@ -990,6 +1000,8 @@ PrintCompletion(FILE *output_file,
9901000 for (llvm::StringRef line : llvm::split (c.GetDescription (), ' \n ' )) {
9911001 if (line.empty ())
9921002 break ;
1003+ if (max_height && lines_printed >= *max_height)
1004+ break ;
9931005 if (!first)
9941006 fprintf (output_file, " %*s" ,
9951007 static_cast <int >(description_col + separator_length), " " );
@@ -1000,14 +1012,17 @@ PrintCompletion(FILE *output_file,
10001012 if (position + description_length < max_length) {
10011013 fprintf (output_file, " %.*s\n " , static_cast <int >(description_length),
10021014 line.data ());
1015+ lines_printed++;
10031016 } else {
10041017 fprintf (output_file, " %.*s...\n " ,
10051018 static_cast <int >(max_length - position - ellipsis_length),
10061019 line.data ());
1020+ lines_printed++;
10071021 continue ;
10081022 }
10091023 }
10101024 }
1025+ return results_printed;
10111026}
10121027
10131028void Editline::DisplayCompletions (
@@ -1016,7 +1031,11 @@ void Editline::DisplayCompletions(
10161031
10171032 fprintf (editline.m_output_file ,
10181033 " \n " ANSI_CLEAR_BELOW " Available completions:\n " );
1019- const size_t page_size = 40 ;
1034+
1035+ // / Account for the current line, the line showing "Available completions"
1036+ // / before and the line saying "More" after.
1037+ const size_t page_size = editline.GetTerminalHeight () - 3 ;
1038+
10201039 bool all = false ;
10211040
10221041 auto longest =
@@ -1026,21 +1045,12 @@ void Editline::DisplayCompletions(
10261045
10271046 const size_t max_len = longest->GetCompletion ().size ();
10281047
1029- if (results.size () < page_size) {
1030- PrintCompletion (editline.m_output_file , results, max_len,
1031- editline.GetTerminalWidth ());
1032- return ;
1033- }
1034-
10351048 size_t cur_pos = 0 ;
10361049 while (cur_pos < results.size ()) {
1037- size_t remaining = results.size () - cur_pos;
1038- size_t next_size = all ? remaining : std::min (page_size, remaining);
1039-
1040- PrintCompletion (editline.m_output_file , results.slice (cur_pos, next_size),
1041- max_len, editline.GetTerminalWidth ());
1042-
1043- cur_pos += next_size;
1050+ cur_pos +=
1051+ PrintCompletion (editline.m_output_file , results.slice (cur_pos), max_len,
1052+ editline.GetTerminalWidth (),
1053+ all ? std::nullopt : std::optional<size_t >(page_size));
10441054
10451055 if (cur_pos >= results.size ())
10461056 break ;
@@ -1525,6 +1535,13 @@ void Editline::ApplyTerminalSizeChange() {
15251535 m_terminal_width = INT_MAX;
15261536 m_current_line_rows = 1 ;
15271537 }
1538+
1539+ int rows;
1540+ if (el_get (m_editline, EL_GETTC, " li" , &rows, nullptr ) == 0 ) {
1541+ m_terminal_height = rows;
1542+ } else {
1543+ m_terminal_height = INT_MAX;
1544+ }
15281545}
15291546
15301547const char *Editline::GetPrompt () { return m_set_prompt.c_str (); }
0 commit comments