mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
LibLine: Properly handle multiline suggestions
This commit is contained in:
parent
d09bea5beb
commit
32276cba7a
Notes:
sideshowbarker
2024-07-19 07:35:30 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/32276cba7a4 Pull-request: https://github.com/SerenityOS/serenity/pull/1801 Issue: https://github.com/SerenityOS/serenity/issues/1796
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);
|
||||
else
|
||||
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
|
||||
|
@ -330,25 +331,43 @@ String Editor::get_line(const String& prompt)
|
|||
if (m_times_tab_pressed > 1 && !m_suggestions.is_empty()) {
|
||||
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());
|
||||
}
|
||||
|
||||
size_t num_printed = 0;
|
||||
size_t lines_used { 1 };
|
||||
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) {
|
||||
size_t next_column = num_printed + suggestion.length() + longest_suggestion_length + 2;
|
||||
|
||||
if (next_column > m_num_columns) {
|
||||
++lines_used;
|
||||
auto lines = (suggestion.length() + m_num_columns - 1) / m_num_columns;
|
||||
lines_used += lines;
|
||||
putchar('\n');
|
||||
num_printed = 0;
|
||||
}
|
||||
|
||||
// show just enough suggestions to fill up the screen
|
||||
// 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;
|
||||
|
||||
if (index == current_suggestion_index) {
|
||||
|
@ -356,7 +375,12 @@ String Editor::get_line(const String& prompt)
|
|||
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) {
|
||||
vt_apply_style({});
|
||||
|
|
|
@ -151,12 +151,12 @@ private:
|
|||
|
||||
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
|
||||
{
|
||||
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
|
||||
|
@ -187,6 +187,7 @@ private:
|
|||
size_t m_old_prompt_length { 0 };
|
||||
size_t m_cached_buffer_size { 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 };
|
||||
|
||||
// exact position before our prompt in the terminal
|
||||
|
|
Loading…
Add table
Reference in a new issue