mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 01:27:43 +00:00
LibLine: Properly handle multiline suggestions
This commit is contained in:
parent
d09bea5beb
commit
32276cba7a
2 changed files with 32 additions and 7 deletions
|
@ -293,6 +293,7 @@ String Editor::get_line(const String& prompt)
|
||||||
m_suggestions = on_tab_complete_first_token(token);
|
m_suggestions = on_tab_complete_first_token(token);
|
||||||
else
|
else
|
||||||
m_suggestions = on_tab_complete_other_token(token);
|
m_suggestions = on_tab_complete_other_token(token);
|
||||||
|
m_prompt_lines_at_suggestion_initiation = num_lines();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust already incremented / decremented index when switching tab direction
|
// Adjust already incremented / decremented index when switching tab direction
|
||||||
|
@ -330,25 +331,43 @@ String Editor::get_line(const String& prompt)
|
||||||
if (m_times_tab_pressed > 1 && !m_suggestions.is_empty()) {
|
if (m_times_tab_pressed > 1 && !m_suggestions.is_empty()) {
|
||||||
size_t longest_suggestion_length = 0;
|
size_t longest_suggestion_length = 0;
|
||||||
|
|
||||||
for (auto& suggestion : m_suggestions)
|
for (auto& suggestion : m_suggestions) {
|
||||||
longest_suggestion_length = max(longest_suggestion_length, suggestion.length());
|
longest_suggestion_length = max(longest_suggestion_length, suggestion.length());
|
||||||
|
}
|
||||||
|
|
||||||
size_t num_printed = 0;
|
size_t num_printed = 0;
|
||||||
size_t lines_used { 1 };
|
size_t lines_used { 1 };
|
||||||
size_t index { 0 };
|
size_t index { 0 };
|
||||||
putchar('\n');
|
vt_save_cursor();
|
||||||
|
vt_clear_lines(0, m_lines_used_for_last_suggestions);
|
||||||
|
vt_restore_cursor();
|
||||||
|
auto spans_entire_line { false };
|
||||||
|
auto max_line_count = (m_cached_prompt_length + longest_suggestion_length + m_num_columns - 1) / m_num_columns;
|
||||||
|
if (longest_suggestion_length >= m_num_columns - 2) {
|
||||||
|
spans_entire_line = true;
|
||||||
|
// we should make enough space for the biggest entry in
|
||||||
|
// the suggestion list to fit in the prompt line
|
||||||
|
auto start = max_line_count - m_prompt_lines_at_suggestion_initiation;
|
||||||
|
for (size_t i = start; i < max_line_count; ++i) {
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
lines_used += max_line_count;
|
||||||
|
longest_suggestion_length = 0;
|
||||||
|
}
|
||||||
|
vt_move_absolute(max_line_count + m_origin_x, 1);
|
||||||
for (auto& suggestion : m_suggestions) {
|
for (auto& suggestion : m_suggestions) {
|
||||||
size_t next_column = num_printed + suggestion.length() + longest_suggestion_length + 2;
|
size_t next_column = num_printed + suggestion.length() + longest_suggestion_length + 2;
|
||||||
|
|
||||||
if (next_column > m_num_columns) {
|
if (next_column > m_num_columns) {
|
||||||
++lines_used;
|
auto lines = (suggestion.length() + m_num_columns - 1) / m_num_columns;
|
||||||
|
lines_used += lines;
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
num_printed = 0;
|
num_printed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show just enough suggestions to fill up the screen
|
// show just enough suggestions to fill up the screen
|
||||||
// without moving the prompt out of view
|
// without moving the prompt out of view
|
||||||
if (lines_used + num_lines() >= m_num_lines)
|
if (lines_used + m_prompt_lines_at_suggestion_initiation >= m_num_lines)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (index == current_suggestion_index) {
|
if (index == current_suggestion_index) {
|
||||||
|
@ -356,7 +375,12 @@ String Editor::get_line(const String& prompt)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_printed += fprintf(stderr, "%-*s", static_cast<int>(longest_suggestion_length) + 2, suggestion.characters());
|
if (spans_entire_line) {
|
||||||
|
num_printed += m_num_columns;
|
||||||
|
fprintf(stderr, "%s", suggestion.characters());
|
||||||
|
} else {
|
||||||
|
num_printed += fprintf(stderr, "%-*s", static_cast<int>(longest_suggestion_length) + 2, suggestion.characters());
|
||||||
|
}
|
||||||
|
|
||||||
if (index == current_suggestion_index) {
|
if (index == current_suggestion_index) {
|
||||||
vt_apply_style({});
|
vt_apply_style({});
|
||||||
|
|
|
@ -151,12 +151,12 @@ private:
|
||||||
|
|
||||||
size_t num_lines() const
|
size_t num_lines() const
|
||||||
{
|
{
|
||||||
return (m_cached_buffer_size + m_num_columns + current_prompt_length()) / m_num_columns;
|
return (m_cached_buffer_size + m_num_columns + current_prompt_length() - 1) / m_num_columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t cursor_line() const
|
size_t cursor_line() const
|
||||||
{
|
{
|
||||||
return (m_drawn_cursor + m_num_columns + current_prompt_length()) / m_num_columns;
|
return (m_drawn_cursor + m_num_columns + current_prompt_length() - 1) / m_num_columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t offset_in_line() const
|
size_t offset_in_line() const
|
||||||
|
@ -187,6 +187,7 @@ private:
|
||||||
size_t m_old_prompt_length { 0 };
|
size_t m_old_prompt_length { 0 };
|
||||||
size_t m_cached_buffer_size { 0 };
|
size_t m_cached_buffer_size { 0 };
|
||||||
size_t m_lines_used_for_last_suggestions { 0 };
|
size_t m_lines_used_for_last_suggestions { 0 };
|
||||||
|
size_t m_prompt_lines_at_suggestion_initiation { 0 };
|
||||||
bool m_cached_prompt_valid { false };
|
bool m_cached_prompt_valid { false };
|
||||||
|
|
||||||
// exact position before our prompt in the terminal
|
// exact position before our prompt in the terminal
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue