mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-23 04:55:15 +00:00
LibLine: Properly show and cleanup suggestions
Prior to this, we would display them and never clean then up.
This commit is contained in:
parent
502299919a
commit
173c65660a
Notes:
sideshowbarker
2024-07-19 07:43:11 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/173c65660af Pull-request: https://github.com/SerenityOS/serenity/pull/1741
2 changed files with 35 additions and 26 deletions
|
@ -37,10 +37,14 @@ Editor::Editor()
|
|||
{
|
||||
m_pending_chars = ByteBuffer::create_uninitialized(0);
|
||||
struct winsize ws;
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
|
||||
m_num_columns = 80;
|
||||
else
|
||||
m_num_lines = 25;
|
||||
} else {
|
||||
m_num_columns = ws.ws_col;
|
||||
m_num_lines = ws.ws_row;
|
||||
dbg() << m_num_lines;
|
||||
}
|
||||
}
|
||||
|
||||
Editor::~Editor()
|
||||
|
@ -68,18 +72,8 @@ void Editor::clear_line()
|
|||
|
||||
void Editor::insert(const String& string)
|
||||
{
|
||||
m_pending_chars.append(string.characters(), string.length());
|
||||
if (m_cursor == m_buffer.size()) {
|
||||
m_buffer.append(string.characters(), string.length());
|
||||
m_cursor = m_buffer.size();
|
||||
return;
|
||||
}
|
||||
|
||||
m_buffer.ensure_capacity(m_buffer.size() + string.length());
|
||||
m_chars_inserted_in_the_middle += string.length();
|
||||
for (size_t i = 0; i < string.length(); ++i)
|
||||
m_buffer.insert(m_cursor + i, string[i]);
|
||||
m_cursor += string.length();
|
||||
for (auto ch : string)
|
||||
insert(ch);
|
||||
}
|
||||
|
||||
void Editor::insert(const char ch)
|
||||
|
@ -302,33 +296,43 @@ String Editor::get_line(const String& prompt)
|
|||
longest_suggestion_length = max(longest_suggestion_length, suggestion.length());
|
||||
|
||||
size_t num_printed = 0;
|
||||
size_t lines_used { 1 };
|
||||
putchar('\n');
|
||||
// FIXME: what if we use more lines than the terminal has?
|
||||
// this would put the actual prompt out of view
|
||||
for (auto& suggestion : suggestions) {
|
||||
size_t next_column = num_printed + suggestion.length() + longest_suggestion_length + 2;
|
||||
|
||||
if (next_column > m_num_columns) {
|
||||
++lines_used;
|
||||
putchar('\n');
|
||||
num_printed = 0;
|
||||
}
|
||||
|
||||
num_printed += fprintf(stderr, "%-*s", static_cast<int>(longest_suggestion_length) + 2, suggestion.characters());
|
||||
m_lines_used_for_last_suggestions = lines_used;
|
||||
}
|
||||
|
||||
StringBuilder builder;
|
||||
builder.append('\n');
|
||||
builder.append(prompt);
|
||||
builder.append(m_buffer.data(), m_cursor);
|
||||
builder.append(m_buffer.data() + m_cursor, m_buffer.size() - m_cursor);
|
||||
fputs(builder.to_string().characters(), stdout);
|
||||
fflush(stdout);
|
||||
|
||||
m_cursor = m_buffer.size();
|
||||
// adjust for the case that we scroll up after writing the suggestions
|
||||
if (m_origin_x + lines_used >= m_num_lines) {
|
||||
m_origin_x = m_num_lines - lines_used;
|
||||
}
|
||||
reposition_cursor();
|
||||
}
|
||||
|
||||
suggestions.clear_with_capacity();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_times_tab_pressed) {
|
||||
// we probably have some suggestions drawn
|
||||
// let's clean them up
|
||||
if (m_lines_used_for_last_suggestions) {
|
||||
vt_clear_lines(1, m_lines_used_for_last_suggestions);
|
||||
m_refresh_needed = true;
|
||||
m_lines_used_for_last_suggestions = 0;
|
||||
}
|
||||
}
|
||||
m_times_tab_pressed = 0; // Safe to say if we get here, the user didn't press TAB
|
||||
|
||||
auto do_backspace = [&] {
|
||||
|
@ -410,7 +414,7 @@ void Editor::refresh_display()
|
|||
auto current_line = cursor_line();
|
||||
|
||||
vt_clear_lines(current_line - 1, num_lines() - current_line);
|
||||
vt_move_relative(-num_lines() + 1, -offset_in_line() - m_old_prompt_length + m_chars_inserted_in_the_middle);
|
||||
vt_move_relative(-num_lines() + 1, -offset_in_line() - m_old_prompt_length - m_pending_chars.size() + m_chars_inserted_in_the_middle);
|
||||
};
|
||||
auto has_cleaned_up = false;
|
||||
// someone changed the window size, figure it out
|
||||
|
@ -419,10 +423,13 @@ void Editor::refresh_display()
|
|||
auto previous_num_columns = m_num_columns;
|
||||
|
||||
struct winsize ws;
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
|
||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) {
|
||||
m_num_columns = 80;
|
||||
else
|
||||
m_num_lines = 25;
|
||||
} else {
|
||||
m_num_columns = ws.ws_col;
|
||||
m_num_lines = ws.ws_row;
|
||||
}
|
||||
|
||||
if (previous_num_columns != m_num_columns) {
|
||||
// we need to cleanup and redo everything
|
||||
|
|
|
@ -177,9 +177,11 @@ private:
|
|||
size_t m_chars_inserted_in_the_middle { 0 };
|
||||
size_t m_times_tab_pressed { 0 };
|
||||
size_t m_num_columns { 0 };
|
||||
size_t m_num_lines { 1 };
|
||||
size_t m_cached_prompt_length { 0 };
|
||||
size_t m_old_prompt_length { 0 };
|
||||
size_t m_cached_buffer_size { 0 };
|
||||
size_t m_lines_used_for_last_suggestions { 0 };
|
||||
bool m_cached_prompt_valid { false };
|
||||
|
||||
// exact position before our prompt in the terminal
|
||||
|
|
Loading…
Add table
Reference in a new issue